From 9750da47612a9a4985427a293c3d776ec9c88d43 Mon Sep 17 00:00:00 2001 From: dinoocch Date: Tue, 5 Jul 2016 22:01:19 -0500 Subject: [PATCH 01/28] Add LDAP Authentication Documentation Addresses #65 This commit adds documentation for installing and configuring ldap authentication for netbox. It may be beneficial to add settings to the configuration.py instead of editing settings.py if this is an important feature. --- docs/ldap.md | 123 +++++++++++++++++++++++++++++++++++++ netbox/templates/docs.html | 1 + 2 files changed, 124 insertions(+) create mode 100644 docs/ldap.md diff --git a/docs/ldap.md b/docs/ldap.md new file mode 100644 index 00000000000..dc1130ca5ed --- /dev/null +++ b/docs/ldap.md @@ -0,0 +1,123 @@ + +

LDAP Authentication

+ +This section details configuration of alternatives to standard django authentication, specifically LDAP and Active Directory. + +[TOC] + +# Requirements + +**Install openldap-devel** + +On Ubuntu: +``` +sudo apt-get install -y python-dev libldap2-dev libsasl2-dev libssl-dev +``` +or on CentOS: +``` +sudo yum install -y python-devel openldap-devel +``` + +**Install django-auth-ldap** +``` +sudo pip install django-auth-ldap +``` + +# General Configuration +In this guide, all shown configuration ought to be appended to the `settings.py` file. + +# Basic Setup +The following configuration adds the LDAP Authentication backend to your netbox site: +```python +AUTHENTICATION_BACKENDS = ( + 'django_auth_ldap.backend.LDAPBackend', + 'django.contrib.auth.backends.ModelBackend', +) +``` + +# General Server Configuration +```python +# Set the server +AUTH_LDAP_SERVER_URI = "ldaps://ad.example.com" + +# The following may be needed if you are binding to active directory +import ldap +AUTH_LDAP_CONNECTION_OPTIONS = { + ldap.OPT_REFERRALS: 0 +} + +# Set the DN and password for the netbox service account +AUTH_LDAP_BIND_DN = "CN=NETBOXSA, OU=Service Accounts,DC=example,DC=com" +AUTH_LDAP_BIND_PASSWORD = "demo" +``` + +# User Authentication +```python +from django_auth_ldap.config import LDAPSearch +# Search for a users DN. + +# This search matches users with the sAMAccountName equal to the inputed username. +# This is required if the user's username is not in their DN. (Active Directory) +AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Users,dc=example,dc=com", + ldap.SCOPE_SUBTREE, + "(sAMAccountName=%(user)s)") + +# If a users dn is producable from their username, we don't need to search +AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com" + +# You can map user attributes to django attributes as so. +AUTH_LDAP_USER_ATTR_MAP = { + "first_name": "givenName", + "last_name": "sn" +} +``` + +# User Groups for permissions +```python +from django_auth_ldap.config import LDAPSearch, GroupOfNamesType + +# This search ought to return all groups that a user may be part of. +# django_auth_ldap uses this to determine group heirarchy +AUTH_LDAP_GROUP_SEARCH = LDAPSearch("dc=example,dc=com", ldap.SCOPE_SUBTREE, + "(objectClass=group)") +AUTH_LDAP_GROUP_TYPE = GroupOfNamesType() + +# Define a group required to login +AUTH_LDAP_REQUIRE_GROUP = "CN=NETBOX_USERS,DC=example,DC=com" + +# Define user type using groups +AUTH_LDAP_USER_FLAGS_BY_GROUP = { + "is_active": "cn=active,ou=groups,dc=example,dc=com", + "is_staff": "cn=staff,ou=groups,dc=example,dc=com", + "is_superuser": "cn=superuser,ou=groups,dc=example,dc=com" +} + +# For more granular permissions, we can map ldap groups to django groups +AUTH_LDAP_FIND_GROUP_PERMS = True + +# Cache groups for one hour to reduce ldap traffic +AUTH_LDAP_CACHE_GROUPS = True +AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600 +``` + +# Certificate Checking +```python +# If your certificate is valid and trusted, you probably don't need to do anything +# Otherwise, see the solutions below: + +# Don't check the ldap server's certificate as much +ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW) + +# Don't check the cert at all +ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) +``` + +# Logging +If authentication isn't working, you can add the following to your `settings.py`. +```python +import logging + +logger = logging.getLogger('django_auth_ldap') +logger.addHandler(logging.StreamHandler()) +logger.setLevel(logging.DEBUG) +``` diff --git a/netbox/templates/docs.html b/netbox/templates/docs.html index 9875232d4f3..c72557b4e1d 100644 --- a/netbox/templates/docs.html +++ b/netbox/templates/docs.html @@ -19,6 +19,7 @@ Circuits Secrets Extras + LDAP From 1338bf601229497c3070184483c6d408b56775f1 Mon Sep 17 00:00:00 2001 From: Gelob Date: Tue, 28 Jun 2016 11:12:36 -0400 Subject: [PATCH 02/28] Banner/MOTD Support --- netbox/netbox/configuration.example.py | 2 ++ netbox/netbox/settings.py | 2 ++ netbox/templates/_base.html | 10 ++++++++++ 3 files changed, 14 insertions(+) diff --git a/netbox/netbox/configuration.example.py b/netbox/netbox/configuration.example.py index 96e60585985..60eceaf289a 100644 --- a/netbox/netbox/configuration.example.py +++ b/netbox/netbox/configuration.example.py @@ -73,3 +73,5 @@ SHORT_TIME_FORMAT = 'H:i:s' DATETIME_FORMAT = 'N j, Y g:i a' SHORT_DATETIME_FORMAT = 'Y-m-d H:i' +BANNER_TOP = '' +BANNER_BOTTOM = '' diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 860c2828827..0feb2c8b58e 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -38,6 +38,8 @@ DATETIME_FORMAT = getattr(configuration, 'DATETIME_FORMAT', 'N j, Y g:i a') SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS +BANNER_TOP = getattr(configuration, 'BANNER_TOP', False) +BANNER_BOTTOM = getattr(configuration, 'BANNER_BOTTOM', False) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index bb6d8bd8ff6..66614888efd 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -224,6 +224,11 @@
+ {% if settings.BANNER_TOP %} + + {% endif %} {% if settings.MAINTENANCE_MODE %}
From 9c48340b9adfec67f053a45d32e14b5603f79ea9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 7 Jul 2016 12:54:25 -0400 Subject: [PATCH 03/28] Dev version bump --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index b4e0c24bda3..273ed3ab424 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -11,7 +11,7 @@ "the documentation.") -VERSION = '1.1.0' +VERSION = '1.1.1-dev' # Import local configuration for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']: From b9e0739f725149cb8a2798ba05554803ba7209d1 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 7 Jul 2016 13:39:54 -0400 Subject: [PATCH 04/28] Fixes #228: Correct conditional inclusion of device bays --- netbox/templates/dcim/devicetype.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/templates/dcim/devicetype.html b/netbox/templates/dcim/devicetype.html index 79246046c9b..f3ae5aa78ab 100644 --- a/netbox/templates/dcim/devicetype.html +++ b/netbox/templates/dcim/devicetype.html @@ -81,7 +81,7 @@

{{ devicetype }}

{% include 'dcim/inc/devicetype_component_table.html' with table=powerport_table title='Power Ports' add_url='dcim:devicetype_add_powerport' delete_url='dcim:devicetype_delete_powerport' %}
- {% if devicetype.is_network_device %} + {% if devicetype.is_parent_device %} {% include 'dcim/inc/devicetype_component_table.html' with table=devicebay_table title='Device Bays' add_url='dcim:devicetype_add_devicebay' delete_url='dcim:devicetype_delete_devicebay' %} {% endif %} {% if devicetype.is_network_device %} From eb9315c11ca81f2250b3b37316710eed6ef3cc0b Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Thu, 7 Jul 2016 16:15:33 -0400 Subject: [PATCH 05/28] Add initial API Integration document --- docs/api-integration.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/api-integration.md diff --git a/docs/api-integration.md b/docs/api-integration.md new file mode 100644 index 00000000000..99185adf6f4 --- /dev/null +++ b/docs/api-integration.md @@ -0,0 +1,19 @@ +# API Integration + +NetBox features a read-only REST API which can be used to integrate it with +other applications. + +In the future, both read and write actions will be available via the API. + +## Clients + +The easiest way to start integrating your applications with NetBox is to make +use of an API client. If you build or discover an API client that is not part +of this list, please send a pull request! + +- **Go**: [github.com/digitalocean/go-netbox](https://github.com/digitalocean/go-netbox) + +## Documentation + +If you wish to build a new API client or simply explore the NetBox API, +Swagger documentation can be found at the URL `/api/docs/` on a NetBox server. From db72a64ef7639a34ebd96038e05443222566a790 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 7 Jul 2016 22:30:51 -0400 Subject: [PATCH 06/28] Changed DeviceForm.device_type label --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 8a00086966b..bc3c8d8e8eb 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -340,7 +340,7 @@ class DeviceForm(forms.ModelForm, BootstrapMixin): disabled_indicator='device')) manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all(), widget=forms.Select(attrs={'filter-for': 'device_type'})) - device_type = forms.ModelChoiceField(queryset=DeviceType.objects.all(), label='Model', widget=APISelect( + device_type = forms.ModelChoiceField(queryset=DeviceType.objects.all(), label='Device type', widget=APISelect( api_url='/api/dcim/device-types/?manufacturer_id={{manufacturer}}', display_field='model' )) From 4372043ddbe363a91cd190608da514552094ab3c Mon Sep 17 00:00:00 2001 From: stanley karunditu Date: Fri, 8 Jul 2016 06:17:08 -0700 Subject: [PATCH 07/28] Potential quick fix for Issue #215. The proper solution is to redo the grid layout for the page so that its fully responsive. It is only partial responsive. Did tests using Firefox developer tools. --- netbox/templates/dcim/rack.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html index 70d8b3b9c59..552716d392b 100644 --- a/netbox/templates/dcim/rack.html +++ b/netbox/templates/dcim/rack.html @@ -154,17 +154,19 @@

Rack {{ rack.name }}

-
-
+
+
+

Front

-
- {% include 'dcim/_rack_elevation.html' with primary_face=front_elevation secondary_face=rear_elevation face_id=0 %} -
-
+
+ {% include 'dcim/_rack_elevation.html' with primary_face=front_elevation secondary_face=rear_elevation face_id=0 %} +
+

Rear

{% include 'dcim/_rack_elevation.html' with primary_face=rear_elevation secondary_face=front_elevation face_id=1 %} +
{% endblock %} From 90dadfc5d9e5cd34fafd98816d55459ec7a914f2 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 12:07:04 -0400 Subject: [PATCH 08/28] Moving docs to readthedocs.org --- README.md | 54 ++----------------------------- docs/getting-started.md | 2 -- docs/index.md | 40 +++++++++++++++++++++-- docs/{ => media}/screenshot1.png | Bin docs/{ => media}/screenshot2.png | Bin docs/{ => media}/screenshot3.png | Bin netbox/netbox/urls.py | 6 +--- netbox/netbox/views.py | 19 ----------- netbox/templates/_base.html | 2 +- 9 files changed, 43 insertions(+), 80 deletions(-) rename docs/{ => media}/screenshot1.png (100%) rename docs/{ => media}/screenshot2.png (100%) rename docs/{ => media}/screenshot3.png (100%) diff --git a/README.md b/README.md index cc563c284db..00343a85574 100644 --- a/README.md +++ b/README.md @@ -15,62 +15,14 @@ Questions? Comments? Please join us on IRC in **#netbox** on **irc.freenode.net* ## Screenshots -![Screenshot of main page](docs/screenshot1.png "Main page") +![Screenshot of main page](docs/media/screenshot1.png "Main page") -![Screenshot of rack elevation](docs/screenshot2.png "Rack elevation") +![Screenshot of rack elevation](docs/media/screenshot2.png "Rack elevation") -![Screenshot of prefix hierarchy](docs/screenshot3.png "Prefix hierarchy") +![Screenshot of prefix hierarchy](docs/media/screenshot3.png "Prefix hierarchy") # Installation Please see docs/getting-started.md for instructions on installing NetBox. To upgrade NetBox, please download the [latest release](https://github.com/digitalocean/netbox/releases) and run `upgrade.sh`. - -# Components - -NetBox understands all of the physical and logical building blocks that comprise network infrastructure, and the manners in which they are all related. - -## DCIM - -DCIM comprises all the physical installations and connections which comprise a network. NetBox tracks where devices are installed, as well as their individual power, console, and network connections. - -**Site:** A physical location (typically a building) where network devices are installed. Devices in different sites cannot be directly connected to one another. - -**Rack:** An equipment rack into which devices are installed. Each rack belongs to a site. - -**Device:** Any type of rack-mounted device. For example, routers, switches, servers, console servers, PDUs, etc. 0U (non-rack-mounted) devices are supported. - -## IPAM - -IPAM deals with the IP addressing and VLANs in use on a network. NetBox makes a distinction between IP prefixes (networks) and individual IP addresses. - -Because NetBox is a combined DCIM/IPAM system, IP addresses can be assigned to device interfaces in the application just as they are in the real world. - -**Aggregate:** A top-level aggregate of IP address space; for example, 10.0.0.0/8 or 2001:db8::/32. Each aggregate belongs to a regional Internet registry (RIR) like ARIN or RIPE, or to an authoritative standard such as RFC 1918. - -**VRF:** A virtual routing table. VRF support is currently still under development. - -**Prefix:** An IPv4 or IPv6 network. A prefix can be assigned to a VRF; if not, it is considered to belong to the global table. Prefixes are grouped by aggregates automatically and can optionally be assigned to sites. - -**IP Address:** An individual IPv4 or IPv6 address (with CIDR mask). IP address can be assigned to device interfaces. - -**VLAN:** VLANs are assigned to sites, and can optionally have one or more IP prefixes assigned to them. VLAN IDs are unique only within the scope of a site. - -## Circuits - -Long-distance data connections are typically referred to as _circuits_. NetBox provides a method for managing circuits and their providers. Individual circuits can be terminated to device interfaces. - -**Provider:** An entity to which a network connects to. This can be a transit provider, peer, or some other organization. - -**Circuit:** A data circuit which connects to a provider. The local end of a circuit can be assigned to a device interface. - -## Secrets - -NetBox provides encrypted storage of sensitive data it calls _secrets_. Each user may be issued an encryption key with which stored secrets can be retrieved. - -Note that NetBox does not merely hash secrets, a function which is only useful for validation. It employs fully reversible AES-256 encryption so that secret data can be retrieved and consumed by other services. - -**Secrets** Any piece of confidential data which must be retrievable. For example: passwords, SNMP communities, RADIUS shared secrets, etc. - -**User Key:** An individual user's encrypted copy of the master key, which can be used to retrieve secret data. diff --git a/docs/getting-started.md b/docs/getting-started.md index d3215ab51e8..cda1d4cd875 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,5 +1,3 @@ -

Getting Started

- This guide documents the process of installing NetBox on an Ubuntu 14.04 server with [nginx](https://www.nginx.com/) and [gunicorn](http://gunicorn.org/). [TOC] diff --git a/docs/index.md b/docs/index.md index 86ece6841b0..86d47ea2c4e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,39 @@ -# NetBox Documentation +# What is NetBox? -NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) application. +NetBox is an open source web application designed to help manage and document computer networks. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers. It encompasses the following aspects of network management: + +* **IP address management (IPAM)** - IP networks and addresses, VRFs, and VLANs +* **Equipment racks** - Organized by group and site +* **Devices** - Types of devices and where they are installed +* **Connections** - Network, console, and power connections among devices +* **Data circuits** - Long-haul communications circuits and providers +* **Secrets** - Encrypted storage of sensitive credentials + +It was designed with the following tenets foremost in mind. + +### Replicate the Real World + +Careful consideration has been given to the data model to ensure that it can accurately reflect a real-world network. For instance, IP addresses are assigned not to devices, but to specific interfaces attached to a device, and an interface may have multiple IP addresses assigned to it. + +### Serve as a "Source of Truth" + +NetBox intends to represent the _desired_ state of a network versus its _operational_ state. As such, automated import of live network state is strongly discouraged. All data created in NetBox should first be vetted by a human to ensure its integrity. NetBox can then be used to populate monitoring and provisioning systems with a high degree of confidence. + +### Keep it Simple + +When given a choice between a relatively simple [80% solution](https://en.wikipedia.org/wiki/Pareto_principle) and a much more complex complete solution, the former will typically be favored. This ensures a lean codebase with a low learning curve. + +# Application Stack + +NetBox is built on the [Django](https://djangoproject.com/) Python framework and utilizes a [PostgreSQL](https://www.postgresql.org/) database. It runs as a WSGI service behind your choice of HTTP server. + +| Function | Component | +|--------------|-------------------| +| HTTP Service | nginx or Apache | +| WSGI Service | gunicorn or uWSGI | +| Application | Django/Python | +| Database | PostgreSQL | + +# Getting Started + +See the [getting started](getting-started.md) guide for help with getting NetBox up and running quickly. diff --git a/docs/screenshot1.png b/docs/media/screenshot1.png similarity index 100% rename from docs/screenshot1.png rename to docs/media/screenshot1.png diff --git a/docs/screenshot2.png b/docs/media/screenshot2.png similarity index 100% rename from docs/screenshot2.png rename to docs/media/screenshot2.png diff --git a/docs/screenshot3.png b/docs/media/screenshot3.png similarity index 100% rename from docs/screenshot3.png rename to docs/media/screenshot3.png diff --git a/netbox/netbox/urls.py b/netbox/netbox/urls.py index 39502e4d0b4..a7f90854400 100644 --- a/netbox/netbox/urls.py +++ b/netbox/netbox/urls.py @@ -2,7 +2,7 @@ from django.contrib import admin from django.views.defaults import page_not_found -from views import home, docs, trigger_500 +from views import home, trigger_500 from users.views import login, logout @@ -30,10 +30,6 @@ url(r'^api/docs/', include('rest_framework_swagger.urls')), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), - # Dcoumentation - url(r'^docs/$', docs, kwargs={'path': 'index'}, name='docs_root'), - url(r'^docs/(?P[\w-]+)/$', docs, name='docs'), - # Error testing url(r'^404/$', page_not_found), url(r'^500/$', trigger_500), diff --git a/netbox/netbox/views.py b/netbox/netbox/views.py index fa7e213123c..38988f6c7b1 100644 --- a/netbox/netbox/views.py +++ b/netbox/netbox/views.py @@ -45,25 +45,6 @@ def home(request): }) -def docs(request, path): - """ - Display a page of Markdown-formatted documentation. - """ - filename = '{}/docs/{}.md'.format(settings.BASE_DIR.rsplit('/', 1)[0], path) - try: - with open(filename, 'r') as docfile: - markup = docfile.read() - except: - raise Http404 - - content = mark_safe(markdown(markup, extensions=['mdx_gfm', 'toc'])) - - return render(request, 'docs.html', { - 'content': content, - 'path': path, - }) - - def trigger_500(request): """Hot-wired method of triggering a server error to test reporting.""" diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index bb6d8bd8ff6..064aaff94bb 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -252,7 +252,7 @@

Maintenance Mode

- Docs · + Docs · API · Code

From 27c8cb046cb5ea9531f929099799cc5ed6654d9e Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 12:55:57 -0400 Subject: [PATCH 09/28] Structured docs layout --- docs/{ => data-model}/circuits.md | 2 -- docs/{ => data-model}/dcim.md | 2 -- docs/{ => data-model}/extras.md | 2 -- docs/{ => data-model}/ipam.md | 2 -- docs/{ => data-model}/secrets.md | 2 -- docs/index.md | 6 +++--- mkdocs.yml | 12 ++++++++++++ 7 files changed, 15 insertions(+), 13 deletions(-) rename docs/{ => data-model}/circuits.md (98%) rename docs/{ => data-model}/dcim.md (99%) rename docs/{ => data-model}/extras.md (99%) rename docs/{ => data-model}/ipam.md (99%) rename docs/{ => data-model}/secrets.md (99%) create mode 100644 mkdocs.yml diff --git a/docs/circuits.md b/docs/data-model/circuits.md similarity index 98% rename from docs/circuits.md rename to docs/data-model/circuits.md index 357e5eae68c..9246add300a 100644 --- a/docs/circuits.md +++ b/docs/data-model/circuits.md @@ -1,5 +1,3 @@ -

Circuits

- The circuits component of NetBox deals with the management of long-haul Internet and private transit links and providers. [TOC] diff --git a/docs/dcim.md b/docs/data-model/dcim.md similarity index 99% rename from docs/dcim.md rename to docs/data-model/dcim.md index cc2cf5073be..3595b09af9b 100644 --- a/docs/dcim.md +++ b/docs/data-model/dcim.md @@ -1,5 +1,3 @@ -

DCIM

- Data center infrastructure management (DCIM) entails all physical assets: sites, racks, devices, cabling, etc. [TOC] diff --git a/docs/extras.md b/docs/data-model/extras.md similarity index 99% rename from docs/extras.md rename to docs/data-model/extras.md index bd47d35d957..6ad9589af58 100644 --- a/docs/extras.md +++ b/docs/data-model/extras.md @@ -1,5 +1,3 @@ -

Extras

- This section entails features of NetBox which are not crucial to its primary functions, but that provide additional value. [TOC] diff --git a/docs/ipam.md b/docs/data-model/ipam.md similarity index 99% rename from docs/ipam.md rename to docs/data-model/ipam.md index ff381009795..2313eeb99cd 100644 --- a/docs/ipam.md +++ b/docs/data-model/ipam.md @@ -1,5 +1,3 @@ -

IPAM

- IP address management (IPAM) entails the allocation of IP networks, addresses, and related numeric resources. [TOC] diff --git a/docs/secrets.md b/docs/data-model/secrets.md similarity index 99% rename from docs/secrets.md rename to docs/data-model/secrets.md index 9b7519fba42..323b623b5e4 100644 --- a/docs/secrets.md +++ b/docs/data-model/secrets.md @@ -1,5 +1,3 @@ -

Secrets

- "Secrets" are small amounts of data that must be kept confidential; for example, passwords and SNMP community strings. NetBox provides encrypted storage of secret data. [TOC] diff --git a/docs/index.md b/docs/index.md index 86d47ea2c4e..1c99bab4bbe 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,15 +11,15 @@ NetBox is an open source web application designed to help manage and document co It was designed with the following tenets foremost in mind. -### Replicate the Real World +## Replicate the Real World Careful consideration has been given to the data model to ensure that it can accurately reflect a real-world network. For instance, IP addresses are assigned not to devices, but to specific interfaces attached to a device, and an interface may have multiple IP addresses assigned to it. -### Serve as a "Source of Truth" +## Serve as a "Source of Truth" NetBox intends to represent the _desired_ state of a network versus its _operational_ state. As such, automated import of live network state is strongly discouraged. All data created in NetBox should first be vetted by a human to ensure its integrity. NetBox can then be used to populate monitoring and provisioning systems with a high degree of confidence. -### Keep it Simple +## Keep it Simple When given a choice between a relatively simple [80% solution](https://en.wikipedia.org/wiki/Pareto_principle) and a much more complex complete solution, the former will typically be favored. This ensures a lean codebase with a low learning curve. diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000000..a3fb91b376d --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,12 @@ +site_name: NetBox +pages: + - 'Introduction': 'index.md' + - 'Getting Started': 'getting-started.md' + - 'Configuration': 'configuration.md' + - 'Data Model': + - 'Circuits': 'data-model/circuits.md' + - 'DCIM': 'data-model/dcim.md' + - 'IPAM': 'data-model/ipam.md' + - 'Secrets': 'data-model/secrets.md' + - 'Extras': 'data-model/extras.md' + - 'API Integration': 'api-integration.md' From 5758ce2be4fad5daf9f649fcc5d6a42892099526 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 16:00:53 -0400 Subject: [PATCH 10/28] Reorganized installation docs --- docs/getting-started.md | 500 ------------------ .../docker.md} | 15 +- docs/installation/netbox.md | 180 +++++++ docs/installation/postgresql.md | 42 ++ docs/installation/upgrading.md | 63 +++ docs/installation/web-server.md | 132 +++++ mkdocs.yml | 11 +- 7 files changed, 433 insertions(+), 510 deletions(-) delete mode 100644 docs/getting-started.md rename docs/{getting-started-docker.md => installation/docker.md} (58%) create mode 100644 docs/installation/netbox.md create mode 100644 docs/installation/postgresql.md create mode 100644 docs/installation/upgrading.md create mode 100644 docs/installation/web-server.md diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index cda1d4cd875..00000000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,500 +0,0 @@ -This guide documents the process of installing NetBox on an Ubuntu 14.04 server with [nginx](https://www.nginx.com/) and [gunicorn](http://gunicorn.org/). - -[TOC] - -# PostgreSQL - -## Installation - -The following packages are needed to install PostgreSQL: - -* postgresql -* libpq-dev -* python-psycopg2 - -``` -# sudo apt-get install -y postgresql libpq-dev python-psycopg2 -``` - -## Configuration - -At a minimum, we need to create a database for NetBox and assign it a username and password for authentication. This is done with the following commands. - -DO NOT USE THE PASSWORD FROM THE EXAMPLE. - -``` -# sudo -u postgres psql -psql (9.3.13) -Type "help" for help. - -postgres=# CREATE DATABASE netbox; -CREATE DATABASE -postgres=# CREATE USER netbox WITH PASSWORD 'J5brHrAXFLQSif0K'; -CREATE ROLE -postgres=# GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox; -GRANT -postgres=# \q -``` - -You can verify that authentication works using the following command: - -``` -# psql -U netbox -h localhost -W -``` - ---- - -# NetBox - -## Installation - -NetBox requires following dependencies: - -* python2.7 -* python-dev -* python-pip -* libxml2-dev -* libxslt1-dev -* libffi-dev -* graphviz - -``` -# sudo apt-get install -y python2.7 python-dev git python-pip libxml2-dev libxslt1-dev libffi-dev graphviz -``` - -You may opt to install NetBox either from a numbered release or by cloning the master branch of its repository on GitHub. - -### Option A: Download a Release - -Download the [latest stable release](https://github.com/digitalocean/netbox/releases) from GitHub as a tarball or ZIP archive. Extract it to your desired path. In this example, we'll use `/opt/netbox`. - -``` -# wget https://github.com/digitalocean/netbox/archive/vX.Y.Z.tar.gz -# tar -xzf vX.Y.Z.tar.gz -C /opt -# cd /opt/ -# ln -s netbox-1.0.4/ netbox -# cd /opt/netbox/ -``` - -### Option B: Clone the Git Repository - -Create the base directory for the NetBox installation. For this guide, we'll use `/opt/netbox`. - -``` -# mkdir -p /opt/netbox/ -# cd /opt/netbox/ -``` - -If `git` is not already installed, install it: - -``` -# sudo apt-get install -y git -``` - -Next, clone the **master** branch of the NetBox GitHub repository into the current directory: - -``` -# git clone -b master https://github.com/digitalocean/netbox.git . -Cloning into '.'... -remote: Counting objects: 1994, done. -remote: Compressing objects: 100% (150/150), done. -remote: Total 1994 (delta 80), reused 0 (delta 0), pack-reused 1842 -Receiving objects: 100% (1994/1994), 472.36 KiB | 0 bytes/s, done. -Resolving deltas: 100% (1495/1495), done. -Checking connectivity... done. -``` - -### Install Python Packages - -Install the necessary Python packages using pip. (If you encounter any compilation errors during this step, ensure that you've installed all of the required dependencies.) - -``` -# sudo pip install -r requirements.txt -``` - -## Configuration - -Move into the NetBox configuration directory and make a copy of `configuration.example.py` named `configuration.py`. - -``` -# cd netbox/netbox/ -# cp configuration.example.py configuration.py -``` - -Open `configuration.py` with your preferred editor and set the following variables: - -* ALLOWED_HOSTS -* DATABASE -* SECRET_KEY - -### ALLOWED_HOSTS - -This is a list of the valid hostnames by which this server can be reached. You must specify at least one name or IP address. - -Example: - -``` -ALLOWED_HOSTS = ['netbox.example.com', '192.0.2.123'] -``` - -### DATABASE - -This parameter holds the database configuration details. You must define the username and password used when you configured PostgreSQL. If the service is running on a remote host, replace `localhost` with its address. - -Example: - -``` -DATABASE = { - 'NAME': 'netbox', # Database name - 'USER': 'netbox', # PostgreSQL username - 'PASSWORD': 'J5brHrAXFLQSif0K', # PostgreSQL password - 'HOST': 'localhost', # Database server - 'PORT': '', # Database port (leave blank for default) -} -``` - -### SECRET_KEY - -Generate a random secret key of at least 50 alphanumeric characters. This key must be unique to this installation and must not be shared outside the local system. - -You may use the script located at `netbox/generate_secret_key.py` to generate a suitable key. - -## Run Migrations - -Before NetBox can run, we need to install the database schema. This is done by running `./manage.py migrate` from the `netbox` directory (`/opt/netbox/netbox/` in our example): - -``` -# cd /opt/netbox/netbox/ -# ./manage.py migrate -Operations to perform: - Apply all migrations: dcim, sessions, admin, ipam, utilities, auth, circuits, contenttypes, extras, secrets, users -Running migrations: - Rendering model states... DONE - Applying contenttypes.0001_initial... OK - Applying auth.0001_initial... OK - Applying admin.0001_initial... OK - ... -``` - -If this step results in a PostgreSQL authentication error, ensure that the username and password created in the database match what has been specified in `configuration.py` - -## Create a Super User - -NetBox does not come with any predefined user accounts. You'll need to create a super user to be able to log into NetBox: - -``` -# ./manage.py createsuperuser -Username: admin -Email address: admin@example.com -Password: -Password (again): -Superuser created successfully. -``` - -## Collect Static Files - -``` -# ./manage.py collectstatic - -You have requested to collect static files at the destination -location as specified in your settings: - - /opt/netbox/netbox/static - -This will overwrite existing files! -Are you sure you want to do this? - -Type 'yes' to continue, or 'no' to cancel: yes -``` - -## Test the Application - -At this point, NetBox should be able to run. We can verify this by starting a development instance: - -``` -# ./manage.py runserver 0.0.0.0:8000 --insecure -Performing system checks... - -System check identified no issues (0 silenced). -June 17, 2016 - 16:17:36 -Django version 1.9.7, using settings 'netbox.settings' -Starting development server at http://0.0.0.0:8000/ -Quit the server with CONTROL-C. -``` - -Now if we navigate to the name or IP of the server (as defined in `ALLOWED_HOSTS`) we should be greeted with the NetBox home page. Note that this built-in web service is for development and testing purposes only. It is not suited for production use. - -If the test service does not run, or you cannot reach the NetBox home page, something has gone wrong. Do not proceed with the rest of this guide until the installation has been corrected. - -# Web Server and gunicorn - -## Installation - -We'll set up a simple HTTP front end using [gunicorn](http://gunicorn.org/) for the purposes of this guide. For web servers, we provide example configurations for both [nginx](https://www.nginx.com/resources/wiki/) and [Apache](http://httpd.apache.org/docs/2.4). (You are of course free to use whichever combination of HTTP and WSGI services you'd like.) We'll also use [supervisord](http://supervisord.org/) for service persistence. - -``` -# sudo apt-get install -y gunicorn supervisor -``` - -## nginx Configuration - -The following will serve as a minimal nginx configuration. Be sure to modify your server name and installation path appropriately. - -``` -# sudo apt-get install -y nginx -``` - -Once nginx is installed, proceed with the following configuration: - -``` -server { - listen 80; - - server_name netbox.example.com; - - access_log off; - - location /static/ { - alias /opt/netbox/netbox/static/; - } - - location / { - proxy_pass http://127.0.0.1:8001; - proxy_set_header X-Forwarded-Host $server_name; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; - } -} -``` - -Save this configuration to `/etc/nginx/sites-available/netbox`. Then, delete `/etc/nginx/sites-enabled/default` and create a symlink in the `sites-enabled` directory to the configuration file you just created. - -``` -# cd /etc/nginx/sites-enabled/ -# rm default -# ln -s /etc/nginx/sites-available/netbox -``` - -Restart the nginx service to use the new configuration. - -``` -# service nginx restart - * Restarting nginx nginx -``` -## Apache Configuration - -``` -# sudo apt-get install -y apache2 -``` - -Once Apache is installed, proceed with the following configuration (Be sure to modify the `ServerName` appropriately): - -``` - - ProxyPreserveHost On - - ServerName netbox.example.com - - Alias /static /opt/netbox/netbox/static - - - Options Indexes FollowSymLinks MultiViews - AllowOverride None - Require all granted - - - - ProxyPass ! - - - ProxyPass / http://127.0.0.1:8001/ - ProxyPassReverse / http://127.0.0.1:8001/ - -``` - -Save the contents of the above example in `/etc/apache2/sites-available/netbox.conf`, enable the `proxy` and `proxy_http` modules, and reload Apache: - -``` -# a2enmod proxy -# a2enmod proxy_http -# a2ensite netbox -# service apache2 restart -``` - -## gunicorn Configuration - -Save the following configuration file in the root netbox installation path (in this example, `/opt/netbox/`) as `gunicorn_config.py`. Be sure to verify the location of the gunicorn executable (e.g. `which gunicorn`) and to update the `pythonpath` variable if needed. - -``` -command = '/usr/bin/gunicorn' -pythonpath = '/opt/netbox/netbox' -bind = '127.0.0.1:8001' -workers = 3 -user = 'www-data' -``` - -## supervisord Configuration - -Save the following as `/etc/supervisor/conf.d/netbox.conf`. Update the `command` and `directory` paths as needed. - -``` -[program:netbox] -command = gunicorn -c /opt/netbox/gunicorn_config.py netbox.wsgi -directory = /opt/netbox/netbox/ -user = www-data -``` - -Finally, restart the supervisor service to detect and run the gunicorn service: - -``` -# service supervisor restart -``` - -At this point, you should be able to connect to the nginx HTTP service at the server name or IP address you provided. If you are unable to connect, check that the nginx service is running and properly configured. If you receive a 502 (bad gateway) error, this indicates that gunicorn is misconfigured or not running. - -Please keep in mind that the configurations provided here are bare minimums required to get NetBox up and running. You will almost certainly want to make some changes to better suit your production environment. - -## Let's Encrypt SSL + nginx - -To add SSL support to the installation we'll start by installing the arbitrary precision calculator language. - -``` -# sudo apt-get install -y bc -``` - -Next we'll clone Let's Encrypt into /opt/: - -``` -# sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt -``` - -To ensure Let's Encrypt can publicly access the directory it needs for certificate validation you'll need to edit `/etc/nginx/sites-available/netbox` and add: - -``` - location /.well-known/ { - alias /opt/netbox/netbox/.well-known/; - allow all; - } -``` - -Then restart nginix: - -``` -# sudo services nginx restart -``` - -To create the certificate use the following commands ensuring to change `netbox.example.com` to the domain name of the server: - -``` -# cd /opt/letsencrypt -# ./letsencrypt-auto certonly -a webroot --webroot-path=/opt/netbox/netbox/ -d netbox.example.com -``` - -If you wish to add support for the `www` prefix you'd use: - -``` -# cd /opt/letsencrypt -# ./letsencrypt-auto certonly -a webroot --webroot-path=/opt/netbox/netbox/ -d netbox.example.com -d www.netbox.example.com -``` - -Make sure you have DNS records setup for the hostnames you use and that they resolve back the netbox server. - -You will be prompted for your email address to receive notifications about your SSL and then asked to accept the subscriber agreement. - -If successful you'll now have four files in `/etc/letsencrypt/live/netbox.example.com` (remember, your hostname is different) - -``` -cert.pem -chain.pem -fullchain.pem -privkey.pem -``` - -Now edit your nginx configuration `/etc/nginx/sites-available/netbox` and at the top edit to the following: - -``` - #listen 80; - #listen [::]80; - listen 443; - listen [::]443; - - ssl on; - ssl_certificate /etc/letsencrypt/live/netbox.example.com/cert.pem; - ssl_certificate_key /etc/letsencrypt/live/netbox.example.com/privkey.pem; -``` - -If you are not using IPv6 then you do not need `listen [::]443;` The two commented lines are for non-SSL for both IPv4 and IPv6. - -Lastly, restart nginx: - -``` -# sudo services nginx restart -``` - -You should now have netbox running on a SSL protected connection. - -# Upgrading - -## Installation of Upgrade - -As with the initial installation, you can upgrade NetBox by either downloading the latest release package or by cloning the `master` branch of the git repository. - -### Option A: Download a Release - -Download the [latest stable release](https://github.com/digitalocean/netbox/releases) from GitHub as a tarball or ZIP archive. Extract it to your desired path. In this example, we'll use `/opt/netbox`. For this guide we are using 1.0.4 as the old version and 1.0.7 as the new version. - -Download & extract latest version: -``` -# wget https://github.com/digitalocean/netbox/archive/vX.Y.Z.tar.gz -# tar -xzf vX.Y.Z.tar.gz -C /opt -# cd /opt/ -# ln -sf netbox-1.0.7/ netbox -``` - -Copy the 'configuration.py' you created when first installing to the new version: -``` -# cp /opt/netbox-1.0.4/configuration.py /opt/netbox/configuration.py -``` - -### Option B: Clone the Git Repository (latest master release) - -For this guide, we'll use `/opt/netbox`. - -Check that your git branch is up to date & is set to master: -``` -# cd /opt/netbox -# git status -``` - -If not on branch master, set it and verify status: -``` -# git checkout master -# git status -``` - -Pull down the set branch from git status above: -``` -# git pull -``` - - -## Upgrade Script & Netbox Restart - -Once the new code is in place, run the upgrade script (which may need to be run as root depending on how your environment is configured). - -``` -# ./upgrade.sh -``` - -This script: - -* Installs or upgrades any new required Python packages -* Applies any database migrations that were included in the release -* Collects all static files to be served by the HTTP service - -Finally, restart the WSGI service to run the new code. If you followed this guide for the initial installation, this is done using `supervisorctl`: - -``` -# sudo supervisorctl restart netbox -``` diff --git a/docs/getting-started-docker.md b/docs/installation/docker.md similarity index 58% rename from docs/getting-started-docker.md rename to docs/installation/docker.md index c5de5bbf1eb..efc9685a91d 100644 --- a/docs/getting-started-docker.md +++ b/docs/installation/docker.md @@ -1,13 +1,11 @@ -

Getting Started with NetBox and Docker

- -This guide assumes that the latest versions of [Docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/) are already installed in your host. +This guide demonstrates how to build and run NetBox as a Docker container. It assumes that the latest versions of [Docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/) are already installed in your host. # Quickstart To get NetBox up and running: ``` -git clone https://github.com/digitalocean/netbox.git +git clone -b master https://github.com/digitalocean/netbox.git cd netbox docker-compose up -d ``` @@ -15,13 +13,13 @@ docker-compose up -d The application will be available on http://localhost/ after a few minutes. Default credentials: -* user: admin -* password: admin + +* Username: **admin** +* Password: **admin** # Configuration -You can configure the app at runtime using variables (see docker-compose.yml). -Possible environment variables: +You can configure the app at runtime using variables (see `docker-compose.yml`). Possible environment variables include: * SUPERUSER_NAME * SUPERUSER_EMAIL @@ -51,4 +49,3 @@ Possible environment variables: * SHORT_TIME_FORMAT * DATETIME_FORMAT * SHORT_DATETIME_FORMAT - diff --git a/docs/installation/netbox.md b/docs/installation/netbox.md new file mode 100644 index 00000000000..96692af1845 --- /dev/null +++ b/docs/installation/netbox.md @@ -0,0 +1,180 @@ +# Installation + +NetBox requires following system dependencies: + +* python2.7 +* python-dev +* python-pip +* libxml2-dev +* libxslt1-dev +* libffi-dev +* graphviz + +``` +# sudo apt-get install -y python2.7 python-dev git python-pip libxml2-dev libxslt1-dev libffi-dev graphviz +``` + +You may opt to install NetBox either from a numbered release or by cloning the master branch of its repository on GitHub. + +## Option A: Download a Release + +Download the [latest stable release](https://github.com/digitalocean/netbox/releases) from GitHub as a tarball or ZIP archive and extract it to your desired path. In this example, we'll use `/opt/netbox`. + +``` +# wget https://github.com/digitalocean/netbox/archive/vX.Y.Z.tar.gz +# tar -xzf vX.Y.Z.tar.gz -C /opt +# cd /opt/ +# ln -s netbox-X.Y.Z/ netbox +# cd /opt/netbox/ +``` + +## Option B: Clone the Git Repository + +Create the base directory for the NetBox installation. For this guide, we'll use `/opt/netbox`. + +``` +# mkdir -p /opt/netbox/ +# cd /opt/netbox/ +``` + +If `git` is not already installed, install it: + +``` +# sudo apt-get install -y git +``` + +Next, clone the **master** branch of the NetBox GitHub repository into the current directory: + +``` +# git clone -b master https://github.com/digitalocean/netbox.git . +Cloning into '.'... +remote: Counting objects: 1994, done. +remote: Compressing objects: 100% (150/150), done. +remote: Total 1994 (delta 80), reused 0 (delta 0), pack-reused 1842 +Receiving objects: 100% (1994/1994), 472.36 KiB | 0 bytes/s, done. +Resolving deltas: 100% (1495/1495), done. +Checking connectivity... done. +``` + +## Install Python Packages + +Install the required Python packages using pip. (If you encounter any compilation errors during this step, ensure that you've installed all of the system dependencies listed above.) + +``` +# sudo pip install -r requirements.txt +``` + +# Configuration + +Move into the NetBox configuration directory and make a copy of `configuration.example.py` named `configuration.py`. + +``` +# cd netbox/netbox/ +# cp configuration.example.py configuration.py +``` + +Open `configuration.py` with your preferred editor and set the following variables: + +* ALLOWED_HOSTS +* DATABASE +* SECRET_KEY + +## ALLOWED_HOSTS + +This is a list of the valid hostnames by which this server can be reached. You must specify at least one name or IP address. + +Example: + +``` +ALLOWED_HOSTS = ['netbox.example.com', '192.0.2.123'] +``` + +## DATABASE + +This parameter holds the database configuration details. You must define the username and password used when you configured PostgreSQL. If the service is running on a remote host, replace `localhost` with its address. + +Example: + +``` +DATABASE = { + 'NAME': 'netbox', # Database name + 'USER': 'netbox', # PostgreSQL username + 'PASSWORD': 'J5brHrAXFLQSif0K', # PostgreSQL password + 'HOST': 'localhost', # Database server + 'PORT': '', # Database port (leave blank for default) +} +``` + +## SECRET_KEY + +Generate a random secret key of at least 50 alphanumeric characters. This key must be unique to this installation and must not be shared outside the local system. + +You may use the script located at `netbox/generate_secret_key.py` to generate a suitable key. + +# Run Database Migrations + +Before NetBox can run, we need to install the database schema. This is done by running `./manage.py migrate` from the `netbox` directory (`/opt/netbox/netbox/` in our example): + +``` +# cd /opt/netbox/netbox/ +# ./manage.py migrate +Operations to perform: + Apply all migrations: dcim, sessions, admin, ipam, utilities, auth, circuits, contenttypes, extras, secrets, users +Running migrations: + Rendering model states... DONE + Applying contenttypes.0001_initial... OK + Applying auth.0001_initial... OK + Applying admin.0001_initial... OK + ... +``` + +If this step results in a PostgreSQL authentication error, ensure that the username and password created in the database match what has been specified in `configuration.py` + +# Create a Super User + +NetBox does not come with any predefined user accounts. You'll need to create a super user to be able to log into NetBox: + +``` +# ./manage.py createsuperuser +Username: admin +Email address: admin@example.com +Password: +Password (again): +Superuser created successfully. +``` + +# Collect Static Files + +``` +# ./manage.py collectstatic + +You have requested to collect static files at the destination +location as specified in your settings: + + /opt/netbox/netbox/static + +This will overwrite existing files! +Are you sure you want to do this? + +Type 'yes' to continue, or 'no' to cancel: yes +``` + +# Test the Application + +At this point, NetBox should be able to run. We can verify this by starting a development instance: + +``` +# ./manage.py runserver 0.0.0.0:8000 --insecure +Performing system checks... + +System check identified no issues (0 silenced). +June 17, 2016 - 16:17:36 +Django version 1.9.7, using settings 'netbox.settings' +Starting development server at http://0.0.0.0:8000/ +Quit the server with CONTROL-C. +``` + +Now if we navigate to the name or IP of the server (as defined in `ALLOWED_HOSTS`) we should be greeted with the NetBox home page. Note that this built-in web service is for development and testing purposes only. It is not suited for production use. + +!!! warning + If the test service does not run, or you cannot reach the NetBox home page, something has gone wrong. Do not proceed with the rest of this guide until the installation has been corrected. diff --git a/docs/installation/postgresql.md b/docs/installation/postgresql.md new file mode 100644 index 00000000000..c4ad03b6a18 --- /dev/null +++ b/docs/installation/postgresql.md @@ -0,0 +1,42 @@ +NetBox requires a PostgreSQL database to store data. MySQL is not supported, as NetBox leverage's PostgreSQL's built-in [network address types](https://www.postgresql.org/docs/9.1/static/datatype-net-types.html). + +# Installation + +The following packages are needed to install PostgreSQL with Python support: + +* postgresql +* libpq-dev +* python-psycopg2 + +``` +# sudo apt-get install -y postgresql libpq-dev python-psycopg2 +``` + +# Configuration + +At a minimum, we need to create a database for NetBox and assign it a username and password for authentication. This is done with the following commands. + +!!! danger + DO NOT USE THE PASSWORD FROM THE EXAMPLE. + +``` +# sudo -u postgres psql +psql (9.3.13) +Type "help" for help. + +postgres=# CREATE DATABASE netbox; +CREATE DATABASE +postgres=# CREATE USER netbox WITH PASSWORD 'J5brHrAXFLQSif0K'; +CREATE ROLE +postgres=# GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox; +GRANT +postgres=# \q +``` + +You can verify that authentication works issuing the following command and providing the configured password: + +``` +# psql -U netbox -h localhost -W +``` + +If successful, you will enter a `postgres` prompt. Type `\q` to exit. diff --git a/docs/installation/upgrading.md b/docs/installation/upgrading.md new file mode 100644 index 00000000000..55353b77a0f --- /dev/null +++ b/docs/installation/upgrading.md @@ -0,0 +1,63 @@ +# Install the Latest Code + +As with the initial installation, you can upgrade NetBox by either downloading the latest release package or by cloning the `master` branch of the git repository. + +## Option A: Download a Release + +Download the [latest stable release](https://github.com/digitalocean/netbox/releases) from GitHub as a tarball or ZIP archive. Extract it to your desired path. In this example, we'll use `/opt/netbox`. For this guide we are using 1.0.4 as the old version and 1.0.7 as the new version. + +Download & extract latest version: +``` +# wget https://github.com/digitalocean/netbox/archive/vX.Y.Z.tar.gz +# tar -xzf vX.Y.Z.tar.gz -C /opt +# cd /opt/ +# ln -sf netbox-1.0.7/ netbox +``` + +Copy the 'configuration.py' you created when first installing to the new version: +``` +# cp /opt/netbox-1.0.4/configuration.py /opt/netbox/configuration.py +``` + +## Option B: Clone the Git Repository (latest master release) + +For this guide, we'll use `/opt/netbox`. + +Check that your git branch is up to date & is set to master: +``` +# cd /opt/netbox +# git status +``` + +If not on branch master, set it and verify status: +``` +# git checkout master +# git status +``` + +Pull down the set branch from git status above: +``` +# git pull +``` + +# Run the Upgrade Script + +Once the new code is in place, run the upgrade script (which may need to be run as root depending on how your environment is configured). + +``` +# ./upgrade.sh +``` + +This script: + +* Installs or upgrades any new required Python packages +* Applies any database migrations that were included in the release +* Collects all static files to be served by the HTTP service + +# Restart the WSGI Service + +Finally, restart the WSGI service to run the new code. If you followed this guide for the initial installation, this is done using `supervisorctl`: + +``` +# sudo supervisorctl restart netbox +``` diff --git a/docs/installation/web-server.md b/docs/installation/web-server.md new file mode 100644 index 00000000000..b30e2659c0a --- /dev/null +++ b/docs/installation/web-server.md @@ -0,0 +1,132 @@ +# Web Server Installation + +We'll set up a simple WSGI front end using [gunicorn](http://gunicorn.org/) for the purposes of this guide. For web servers, we provide example configurations for both [nginx](https://www.nginx.com/resources/wiki/) and [Apache](http://httpd.apache.org/docs/2.4). (You are of course free to use whichever combination of HTTP and WSGI services you'd like.) We'll also use [supervisord](http://supervisord.org/) to enable service persistence. + +``` +# sudo apt-get install -y gunicorn supervisor +``` + +## Option A: nginx + +The following will serve as a minimal nginx configuration. Be sure to modify your server name and installation path appropriately. + +``` +# sudo apt-get install -y nginx +``` + +Once nginx is installed, proceed with the following configuration: + +``` +server { + listen 80; + + server_name netbox.example.com; + + access_log off; + + location /static/ { + alias /opt/netbox/netbox/static/; + } + + location / { + proxy_pass http://127.0.0.1:8001; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; + } +} +``` + +Save this configuration to `/etc/nginx/sites-available/netbox`. Then, delete `/etc/nginx/sites-enabled/default` and create a symlink in the `sites-enabled` directory to the configuration file you just created. + +``` +# cd /etc/nginx/sites-enabled/ +# rm default +# ln -s /etc/nginx/sites-available/netbox +``` + +Restart the nginx service to use the new configuration. + +``` +# service nginx restart + * Restarting nginx nginx +``` + +To enable SSL, consider this guide on [securing nginx with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-14-04). + +## Option B: Apache + +``` +# sudo apt-get install -y apache2 +``` + +Once Apache is installed, proceed with the following configuration (Be sure to modify the `ServerName` appropriately): + +``` + + ProxyPreserveHost On + + ServerName netbox.example.com + + Alias /static /opt/netbox/netbox/static + + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Require all granted + + + + ProxyPass ! + + + ProxyPass / http://127.0.0.1:8001/ + ProxyPassReverse / http://127.0.0.1:8001/ + +``` + +Save the contents of the above example in `/etc/apache2/sites-available/netbox.conf`, enable the `proxy` and `proxy_http` modules, and reload Apache: + +``` +# a2enmod proxy +# a2enmod proxy_http +# a2ensite netbox +# service apache2 restart +``` + +To enable SSL, consider this guide on [securing Apache with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-14-04). + +# gunicorn Installation + +Save the following configuration file in the root netbox installation path (in this example, `/opt/netbox/`) as `gunicorn_config.py`. Be sure to verify the location of the gunicorn executable (e.g. `which gunicorn`) and to update the `pythonpath` variable if needed. + +``` +command = '/usr/bin/gunicorn' +pythonpath = '/opt/netbox/netbox' +bind = '127.0.0.1:8001' +workers = 3 +user = 'www-data' +``` + +# supervisord Installation + +Save the following as `/etc/supervisor/conf.d/netbox.conf`. Update the `command` and `directory` paths as needed. + +``` +[program:netbox] +command = gunicorn -c /opt/netbox/gunicorn_config.py netbox.wsgi +directory = /opt/netbox/netbox/ +user = www-data +``` + +Finally, restart the supervisor service to detect and run the gunicorn service: + +``` +# service supervisor restart +``` + +At this point, you should be able to connect to the nginx HTTP service at the server name or IP address you provided. If you are unable to connect, check that the nginx service is running and properly configured. If you receive a 502 (bad gateway) error, this indicates that gunicorn is misconfigured or not running. + +!!! info + Please keep in mind that the configurations provided here are bare minimums required to get NetBox up and running. You will almost certainly want to make some changes to better suit your production environment. diff --git a/mkdocs.yml b/mkdocs.yml index a3fb91b376d..8fe5678d403 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,13 @@ site_name: NetBox + pages: - 'Introduction': 'index.md' - - 'Getting Started': 'getting-started.md' + - 'Installation': + - 'PostgreSQL': 'installation/postgresql.md' + - 'NetBox': 'installation/netbox.md' + - 'Web Server': 'installation/web-server.md' + - 'Upgrading': 'installation/upgrading.md' + - 'Alternate Install: Docker': 'installation/docker.md' - 'Configuration': 'configuration.md' - 'Data Model': - 'Circuits': 'data-model/circuits.md' @@ -10,3 +16,6 @@ pages: - 'Secrets': 'data-model/secrets.md' - 'Extras': 'data-model/extras.md' - 'API Integration': 'api-integration.md' + +markdown_extensions: + - admonition: From c94868237048452ed32d9b6c876019eb4669d287 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 16:05:14 -0400 Subject: [PATCH 11/28] Removed TOC elements --- docs/data-model/circuits.md | 2 -- docs/data-model/dcim.md | 2 -- docs/data-model/extras.md | 2 -- docs/data-model/ipam.md | 2 -- docs/data-model/secrets.md | 2 -- 5 files changed, 10 deletions(-) diff --git a/docs/data-model/circuits.md b/docs/data-model/circuits.md index 9246add300a..563e5df7c6d 100644 --- a/docs/data-model/circuits.md +++ b/docs/data-model/circuits.md @@ -1,7 +1,5 @@ The circuits component of NetBox deals with the management of long-haul Internet and private transit links and providers. -[TOC] - # Providers A provider is any entity which provides some form of connectivity. This obviously includes carriers which offer Internet and private transit service. However, it might also include Internet exchange (IX) points and even organizations with whom you peer directly. diff --git a/docs/data-model/dcim.md b/docs/data-model/dcim.md index 3595b09af9b..6512995eab4 100644 --- a/docs/data-model/dcim.md +++ b/docs/data-model/dcim.md @@ -1,7 +1,5 @@ Data center infrastructure management (DCIM) entails all physical assets: sites, racks, devices, cabling, etc. -[TOC] - # Sites How you define sites will depend on the nature of your organization, but typically a site will equate a building or campus. For example, a chain of banks might create a site to represent each of its branches, a site for its corporate headquarters, and two additional sites for its presence in two colocation facilities. diff --git a/docs/data-model/extras.md b/docs/data-model/extras.md index 6ad9589af58..f9fc82e18f1 100644 --- a/docs/data-model/extras.md +++ b/docs/data-model/extras.md @@ -1,7 +1,5 @@ This section entails features of NetBox which are not crucial to its primary functions, but that provide additional value. -[TOC] - # Export Templates NetBox allows users to define custom templates that can be used when exporting objects. To create an export template, navigate to Extras > Export Templates under the admin interface. diff --git a/docs/data-model/ipam.md b/docs/data-model/ipam.md index 2313eeb99cd..c6da1d657f9 100644 --- a/docs/data-model/ipam.md +++ b/docs/data-model/ipam.md @@ -1,7 +1,5 @@ IP address management (IPAM) entails the allocation of IP networks, addresses, and related numeric resources. -[TOC] - # VRFs A VRF object in NetBox represents a virtual routing and forwarding (VRF) domain within a network. Each VRF is essentially a separate routing table: the same IP prefix or address can exist in multiple VRFs. VRFs are commonly used to isolate customers or organizations from one another within a network. diff --git a/docs/data-model/secrets.md b/docs/data-model/secrets.md index 323b623b5e4..ef82c196baa 100644 --- a/docs/data-model/secrets.md +++ b/docs/data-model/secrets.md @@ -1,7 +1,5 @@ "Secrets" are small amounts of data that must be kept confidential; for example, passwords and SNMP community strings. NetBox provides encrypted storage of secret data. -[TOC] - # Secrets A secret represents a single credential or other string which must be stored securely. Each secret is assigned to a device within NetBox. The plaintext value of a secret is encrypted to a ciphertext immediately prior to storage within the database using a 256-bit AES master key. A SHA256 hash of the plaintext is also stored along with each ciphertext to validate the decrypted plaintext. From 129415e15f56b48b74dd7bf20bc5a359b4952798 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 16:09:05 -0400 Subject: [PATCH 12/28] Remove obsolete docs.html template --- netbox/templates/docs.html | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 netbox/templates/docs.html diff --git a/netbox/templates/docs.html b/netbox/templates/docs.html deleted file mode 100644 index c72557b4e1d..00000000000 --- a/netbox/templates/docs.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends '_base.html' %} -{% load render_table from django_tables2 %} - -{% block title %}Documentation{% endblock %} - -{% block content %} -
-
-
-
- Documentation -
- -
-
-
- {{ content }} -
-
-{% endblock %} From b8c5366c3ecd72023ce029bda656162ba5d1943b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 16:25:34 -0400 Subject: [PATCH 13/28] Split configuration doc into two sections --- docs/configuration/mandatory-settings.md | 45 +++++++++++ .../optional-settings.md} | 78 +++---------------- mkdocs.yml | 5 +- 3 files changed, 60 insertions(+), 68 deletions(-) create mode 100644 docs/configuration/mandatory-settings.md rename docs/{configuration.md => configuration/optional-settings.md} (50%) diff --git a/docs/configuration/mandatory-settings.md b/docs/configuration/mandatory-settings.md new file mode 100644 index 00000000000..07a6d8ede48 --- /dev/null +++ b/docs/configuration/mandatory-settings.md @@ -0,0 +1,45 @@ +NetBox's local configuration is held in `netbox/netbox/configuration.py`. An example configuration is provided at `netbox/netbox/configuration.example.py`. You may copy or rename the example configuration and make changes as appropriate. NetBox will not run without a configuration file. + +## ALLOWED_HOSTS + +This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. + +Example: + +``` +ALLOWED_HOSTS = ['netbox.example.com', '192.0.2.123'] +``` + +--- + +## DATABASE + +NetBox requires access to a PostgreSQL database service to store data. This service can run locally or on a remote system. The following parameters must be defined within the `DATABASE` dictionary: + +* NAME - Database name +* USER - PostgreSQL username +* PASSWORD - PostgreSQL password +* HOST - Name or IP address of the database server (use `localhost` if running locally) +* PORT - TCP port of the PostgreSQL service; leave blank for default port (5432) + +Example: + +``` +DATABASE = { + 'NAME': 'netbox', # Database name + 'USER': 'netbox', # PostgreSQL username + 'PASSWORD': 'J5brHrAXFLQSif0K', # PostgreSQL password + 'HOST': 'localhost', # Database server + 'PORT': '', # Database port (leave blank for default) +} +``` + +--- + +## SECRET_KEY + +This is a secret cryptographic key is used to improve the security of cookies and password resets. The key defined here should not be shared outside of the configuration file. `SECRET_KEY` can be changed at any time, however be aware that doing so will invalidate all existing sessions. + +Please note that this key is **not** used for hashing user passwords or for the encrypted storage of secret data in NetBox. + +`SECRET_KEY` should be at least 50 characters in length and contain a random mix of letters, digits, and symbols. The script located at `netbox/generate_secret_key.py` may be used to generate a suitable key. diff --git a/docs/configuration.md b/docs/configuration/optional-settings.md similarity index 50% rename from docs/configuration.md rename to docs/configuration/optional-settings.md index bd4706e6ff7..0aa59a1967d 100644 --- a/docs/configuration.md +++ b/docs/configuration/optional-settings.md @@ -1,62 +1,6 @@ -

Configuration

+The following are optional settings which may be declared in `netbox/netbox/configuration.py`. -NetBox's local configuration is held in `netbox/netbox/configuration.py`. An example configuration is provided at `netbox/netbox/configuration.example.py`. You may copy or rename the example configuration and make changes as appropriate. NetBox will not run without a configuration file. - -[TOC] - -# Mandatory Settings - ---- - -#### ALLOWED_HOSTS - -This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. - -Example: - -``` -ALLOWED_HOSTS = ['netbox.example.com', '192.0.2.123'] -``` - ---- - -#### DATABASE - -NetBox requires access to a PostgreSQL database service to store data. This service can run locally or on a remote system. The following parameters must be defined within the `DATABASE` dictionary: - -* NAME - Database name -* USER - PostgreSQL username -* PASSWORD - PostgreSQL password -* HOST - Name or IP address of the database server (use `localhost` if running locally) -* PORT - TCP port of the PostgreSQL service; leave blank for default port (5432) - -Example: - -``` -DATABASE = { - 'NAME': 'netbox', # Database name - 'USER': 'netbox', # PostgreSQL username - 'PASSWORD': 'J5brHrAXFLQSif0K', # PostgreSQL password - 'HOST': 'localhost', # Database server - 'PORT': '', # Database port (leave blank for default) -} -``` - ---- - -#### SECRET_KEY - -This is a secret cryptographic key is used to improve the security of cookies and password resets. The key defined here should not be shared outside of the configuration file. `SECRET_KEY` can be changed at any time, however be aware that doing so will invalidate all existing sessions. - -Please note that this key is **not** used for hashing user passwords or for the encrypted storage of secret data in NetBox. - -`SECRET_KEY` should be at least 50 characters in length and contain a random mix of letters, digits, and symbols. The script located at `netbox/generate_secret_key.py` may be used to generate a suitable key. - -# Optional Settings - ---- - -#### ADMINS +## ADMINS NetBox will email details about critical errors to the administrators listed here. This should be a list of (name, email) tuples. For example: @@ -69,7 +13,7 @@ ADMINS = [ --- -#### DEBUG +## DEBUG Default: False @@ -77,7 +21,7 @@ This setting enables debugging. This should be done only during development or t --- -#### EMAIL +## EMAIL In order to send email, NetBox needs an email server configured. The following items can be defined within the `EMAIL` setting: @@ -90,7 +34,7 @@ In order to send email, NetBox needs an email server configured. The following i --- -#### LOGIN_REQUIRED +## LOGIN_REQUIRED Default: False, @@ -98,7 +42,7 @@ Setting this to True will permit only authenticated users to access any part of --- -#### MAINTENANCE_MODE +## MAINTENANCE_MODE Default: False @@ -106,15 +50,15 @@ Setting this to True will display a "maintenance mode" banner at the top of ever --- -#### NETBOX_USERNAME +## NETBOX_USERNAME -#### NETBOX_PASSWORD +## NETBOX_PASSWORD If provided, NetBox will use these credentials to authenticate against devices when collecting data. --- -#### PAGINATE_COUNT +## PAGINATE_COUNT Default: 50 @@ -122,7 +66,7 @@ Determine how many objects to display per page within each list of objects. --- -#### TIME_ZONE +## TIME_ZONE Default: UTC @@ -130,7 +74,7 @@ The time zone NetBox will use when dealing with dates and times. It is recommend --- -#### Date and Time Formatting +## Date and Time Formatting You may define custom formatting for date and times. For detailed instructions on writing format strings, please see [the Django documentation](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date). diff --git a/mkdocs.yml b/mkdocs.yml index 8fe5678d403..d0bcb1ba382 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,9 +6,12 @@ pages: - 'PostgreSQL': 'installation/postgresql.md' - 'NetBox': 'installation/netbox.md' - 'Web Server': 'installation/web-server.md' + - 'LDAP (Optional)': 'installation/ldap.md' - 'Upgrading': 'installation/upgrading.md' - 'Alternate Install: Docker': 'installation/docker.md' - - 'Configuration': 'configuration.md' + - 'Configuration': + - 'Mandatory Settings': 'configuration/mandatory-settings.md' + - 'Optional Settings': 'configuration/optional-settings.md' - 'Data Model': - 'Circuits': 'data-model/circuits.md' - 'DCIM': 'data-model/dcim.md' From 4c354277ecd5a09f049391daccfc2f5aecffa4fb Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 17:09:35 -0400 Subject: [PATCH 14/28] Enabled LDAP authentication --- docs/installation/ldap.md | 101 +++++++++++++++++++++++++++++++ docs/ldap.md | 123 -------------------------------------- netbox/netbox/settings.py | 29 +++++++++ 3 files changed, 130 insertions(+), 123 deletions(-) create mode 100644 docs/installation/ldap.md delete mode 100644 docs/ldap.md diff --git a/docs/installation/ldap.md b/docs/installation/ldap.md new file mode 100644 index 00000000000..5a90ec5e315 --- /dev/null +++ b/docs/installation/ldap.md @@ -0,0 +1,101 @@ +This guide explains how to implement LDAP authentication using an external server. User authentication will fall back to +built-in Django users in the event of a failure. + +# Requirements + +## Install openldap-devel + +On Ubuntu: + +``` +sudo apt-get install -y python-dev libldap2-dev libsasl2-dev libssl-dev +``` + +On CentOS: + +``` +sudo yum install -y python-devel openldap-devel +``` + +## Install django-auth-ldap + +``` +sudo pip install django-auth-ldap +``` + +# Configuration + +Create a file in the same directory as `configuration.py` (typically `netbox/netbox/`) named `ldap_config.py`. Define all of the parameters required below in `ldap_config.py`. + +## General Server Configuration + +```python +import ldap + +# Server URI +AUTH_LDAP_SERVER_URI = "ldaps://ad.example.com" + +# The following may be needed if you are binding to Active Directory. +AUTH_LDAP_CONNECTION_OPTIONS = { + ldap.OPT_REFERRALS: 0 +} + +# Set the DN and password for the NetBox service account. +AUTH_LDAP_BIND_DN = "CN=NETBOXSA, OU=Service Accounts,DC=example,DC=com" +AUTH_LDAP_BIND_PASSWORD = "demo" + +# Include this setting if you want to ignore certificate errors. This might be needed to accept a self-signed cert. +# Note that this is a NetBox-specific setting which sets: +# ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) +LDAP_IGNORE_CERT_ERRORS = True +``` + +## User Authentication + +```python +from django_auth_ldap.config import LDAPSearch + +# This search matches users with the sAMAccountName equal to the provided username. This is required if the user's +# username is not in their DN (Active Directory). +AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Users,dc=example,dc=com", + ldap.SCOPE_SUBTREE, + "(sAMAccountName=%(user)s)") + +# If a user's DN is producible from their username, we don't need to search. +AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com" + +# You can map user attributes to Django attributes as so. +AUTH_LDAP_USER_ATTR_MAP = { + "first_name": "givenName", + "last_name": "sn" +} +``` + +# User Groups for Permissions + +```python +from django_auth_ldap.config import LDAPSearch, GroupOfNamesType + +# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group +# heirarchy. +AUTH_LDAP_GROUP_SEARCH = LDAPSearch("dc=example,dc=com", ldap.SCOPE_SUBTREE, + "(objectClass=group)") +AUTH_LDAP_GROUP_TYPE = GroupOfNamesType() + +# Define a group required to login. +AUTH_LDAP_REQUIRE_GROUP = "CN=NETBOX_USERS,DC=example,DC=com" + +# Define special user types using groups. Exercise great caution when assigning superuser status. +AUTH_LDAP_USER_FLAGS_BY_GROUP = { + "is_active": "cn=active,ou=groups,dc=example,dc=com", + "is_staff": "cn=staff,ou=groups,dc=example,dc=com", + "is_superuser": "cn=superuser,ou=groups,dc=example,dc=com" +} + +# For more granular permissions, we can map LDAP groups to Django groups. +AUTH_LDAP_FIND_GROUP_PERMS = True + +# Cache groups for one hour to reduce LDAP traffic +AUTH_LDAP_CACHE_GROUPS = True +AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600 +``` diff --git a/docs/ldap.md b/docs/ldap.md deleted file mode 100644 index dc1130ca5ed..00000000000 --- a/docs/ldap.md +++ /dev/null @@ -1,123 +0,0 @@ - -

LDAP Authentication

- -This section details configuration of alternatives to standard django authentication, specifically LDAP and Active Directory. - -[TOC] - -# Requirements - -**Install openldap-devel** - -On Ubuntu: -``` -sudo apt-get install -y python-dev libldap2-dev libsasl2-dev libssl-dev -``` -or on CentOS: -``` -sudo yum install -y python-devel openldap-devel -``` - -**Install django-auth-ldap** -``` -sudo pip install django-auth-ldap -``` - -# General Configuration -In this guide, all shown configuration ought to be appended to the `settings.py` file. - -# Basic Setup -The following configuration adds the LDAP Authentication backend to your netbox site: -```python -AUTHENTICATION_BACKENDS = ( - 'django_auth_ldap.backend.LDAPBackend', - 'django.contrib.auth.backends.ModelBackend', -) -``` - -# General Server Configuration -```python -# Set the server -AUTH_LDAP_SERVER_URI = "ldaps://ad.example.com" - -# The following may be needed if you are binding to active directory -import ldap -AUTH_LDAP_CONNECTION_OPTIONS = { - ldap.OPT_REFERRALS: 0 -} - -# Set the DN and password for the netbox service account -AUTH_LDAP_BIND_DN = "CN=NETBOXSA, OU=Service Accounts,DC=example,DC=com" -AUTH_LDAP_BIND_PASSWORD = "demo" -``` - -# User Authentication -```python -from django_auth_ldap.config import LDAPSearch -# Search for a users DN. - -# This search matches users with the sAMAccountName equal to the inputed username. -# This is required if the user's username is not in their DN. (Active Directory) -AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Users,dc=example,dc=com", - ldap.SCOPE_SUBTREE, - "(sAMAccountName=%(user)s)") - -# If a users dn is producable from their username, we don't need to search -AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com" - -# You can map user attributes to django attributes as so. -AUTH_LDAP_USER_ATTR_MAP = { - "first_name": "givenName", - "last_name": "sn" -} -``` - -# User Groups for permissions -```python -from django_auth_ldap.config import LDAPSearch, GroupOfNamesType - -# This search ought to return all groups that a user may be part of. -# django_auth_ldap uses this to determine group heirarchy -AUTH_LDAP_GROUP_SEARCH = LDAPSearch("dc=example,dc=com", ldap.SCOPE_SUBTREE, - "(objectClass=group)") -AUTH_LDAP_GROUP_TYPE = GroupOfNamesType() - -# Define a group required to login -AUTH_LDAP_REQUIRE_GROUP = "CN=NETBOX_USERS,DC=example,DC=com" - -# Define user type using groups -AUTH_LDAP_USER_FLAGS_BY_GROUP = { - "is_active": "cn=active,ou=groups,dc=example,dc=com", - "is_staff": "cn=staff,ou=groups,dc=example,dc=com", - "is_superuser": "cn=superuser,ou=groups,dc=example,dc=com" -} - -# For more granular permissions, we can map ldap groups to django groups -AUTH_LDAP_FIND_GROUP_PERMS = True - -# Cache groups for one hour to reduce ldap traffic -AUTH_LDAP_CACHE_GROUPS = True -AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600 -``` - -# Certificate Checking -```python -# If your certificate is valid and trusted, you probably don't need to do anything -# Otherwise, see the solutions below: - -# Don't check the ldap server's certificate as much -ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW) - -# Don't check the cert at all -ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) -``` - -# Logging -If authentication isn't working, you can add the following to your `settings.py`. -```python -import logging - -logger = logging.getLogger('django_auth_ldap') -logger.addHandler(logging.StreamHandler()) -logger.setLevel(logging.DEBUG) -``` diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 273ed3ab424..301e295101b 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -1,3 +1,4 @@ +import logging import os import socket @@ -39,6 +40,34 @@ SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS +# Attempt to import LDAP configuration if it has been defined +LDAP_IGNORE_CERT_ERRORS = False +try: + from ldap_config import * + LDAP_CONFIGURED = True +except ImportError: + LDAP_CONFIGURED = False + +# LDAP configuration (optional) +if LDAP_CONFIGURED: + try: + import ldap, django_auth_ldap + # Prepend LDAPBackend to the default ModelBackend + AUTHENTICATION_BACKENDS = [ + 'django_auth_ldap.backend.LDAPBackend', + 'django.contrib.auth.backends.ModelBackend', + ] + # Optionally disable strict certificate checking + if LDAP_IGNORE_CERT_ERRORS: + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) + # Enable logging for django_auth_ldap + logger = logging.getLogger('django_auth_ldap') + logger.addHandler(logging.StreamHandler()) + logger.setLevel(logging.DEBUG) + except ImportError: + raise ImproperlyConfigured("LDAP authentication has been configured, but django-auth-ldap is not installed. " + "You can remove netbox/ldap.py to disable LDAP.") + BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Database From 8dd6112a4b5009fba1f77e31a997b84f23fab748 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Jul 2016 17:49:20 -0400 Subject: [PATCH 15/28] Corrected detection of private_key --- netbox/secrets/api/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/secrets/api/views.py b/netbox/secrets/api/views.py index 869739e3205..21a71e22fc7 100644 --- a/netbox/secrets/api/views.py +++ b/netbox/secrets/api/views.py @@ -52,7 +52,7 @@ def get(self, request, private_key=None): queryset = self.filter_queryset(self.get_queryset()) # Attempt to decrypt each Secret if a private key was provided. - if private_key is not None: + if private_key: try: uk = UserKey.objects.get(user=request.user) except UserKey.DoesNotExist: @@ -96,7 +96,7 @@ def get(self, request, pk, private_key=None): secret = get_object_or_404(Secret, pk=pk) # Attempt to decrypt the Secret if a private key was provided. - if private_key is not None: + if private_key: try: uk = UserKey.objects.get(user=request.user) except UserKey.DoesNotExist: From cbd6370889b80bb64ec075b47cab7c599e4b2b9f Mon Sep 17 00:00:00 2001 From: bellwood Date: Fri, 8 Jul 2016 20:43:58 -0400 Subject: [PATCH 16/28] Update login.html --- netbox/templates/login.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/templates/login.html b/netbox/templates/login.html index 13c41d682e5..07b10bfcc07 100644 --- a/netbox/templates/login.html +++ b/netbox/templates/login.html @@ -3,7 +3,7 @@ {% block content %}
-
+
{% if form.non_field_errors %}
Errors
From 1cdf70da0bd47e97b01e8bedc869d85b86b9b101 Mon Sep 17 00:00:00 2001 From: bellwood Date: Fri, 8 Jul 2016 20:45:27 -0400 Subject: [PATCH 17/28] Update _base.html --- netbox/templates/_base.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 064aaff94bb..438ffdff593 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -244,13 +244,13 @@

Maintenance Mode