Browse Source

Enabled LDAP authentication

Jeremy Stretch 8 years ago
parent
commit
4c354277ec
3 changed files with 130 additions and 123 deletions
  1. 101 0
      docs/installation/ldap.md
  2. 0 123
      docs/ldap.md
  3. 29 0
      netbox/netbox/settings.py

+ 101 - 0
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
+```

+ 0 - 123
docs/ldap.md

@@ -1,123 +0,0 @@
-
-<h1>LDAP Authentication</h1>
-
-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)
-```

+ 29 - 0
netbox/netbox/settings.py

@@ -1,3 +1,4 @@
+import logging
 import os
 import socket
 
@@ -39,6 +40,34 @@ 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
 
+# 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