Skip to content

Files

Latest commit

38aab90 · Feb 22, 2019

History

History
234 lines (174 loc) · 9.02 KB

README_SAML.md

File metadata and controls

234 lines (174 loc) · 9.02 KB

SAML 2.0 for NetBox

The original form of this doc can be found here: https://github.com/explody/netbox/blob/basic_saml_support/README_SAML.md

Overview

This doc covers only the most basic setup of a SAML Service Provider (SP, e.g. netbox) and a basic example of Identity Provider (IDP, e.g. Okta, OneLogin, etc.) settings. The config.py used for SAML configuration has been simplified and should work, given a few simple modifications to suit your environment. However, SAML is a large and complicated subject and some IDPs may require specific settings. Should this not work with the basic configuration, we encourage you to refer to the pysaml2 and djangosaml2 documentation for its much greater detail on SAML options and settings.

Installation

SAML authentication support is provided via djangosaml2 and pysaml2.

To set up basic SAML support for NetBox, begin by installing pysaml2, djangosaml2 and xmlsec1

# cd /path/to/netbox
# pip3 install -r requirements_saml.txt

Or manually install the dependencies:

# pip3 install pysaml2 djangosaml2

Then, install the xmlsec1 program. The package proivding this program is different depending on your OS/distribution.

Ubuntu/Debian

# sudo apt-get install xmlsec1

OSX+Homebrew

# brew install libxmlsec1

Configuration

Once the dependencies are installed, copy the sample config to the config.py.

# cd /path/to/netbox
# cp netbox/netbox/saml/config.example.py netbox/netbox/saml/config.py

At minimum, you must modify the "Basic Settings" at the top of this file to match your environment. However, the full pysaml2 configuration is available via the SAML_CONFIG dictionary. Please refer to the djangosaml2 and pysaml2 docs for full detail on configuration options.

Basic Settings
# Set to true to enable SAML login
SAML_ENABLED = False

# Set to true to require SAML login. Use with LOGIN_REQUIRED to require SAML login for all access.
SAML_REQUIRED = False

# The base URL of your NetBox installation.
NETBOX_BASE = "http://localhost:8080"

SAML_IDP_ENTITY_ID = 'http://idp.domain.com/metadata'     # Commonly the URL for the IDP metadata
SAML_IDP_SSO_SERVICE = 'https://idp.domain.com/sso/saml'  # The SSO URL for your IDP

# Don't change this unless you know what you're doing. Defaults to the directory this file is in.
SAML_DIR = path.dirname(path.abspath(__file__))

# Set this to the URL of the page where users should be redirected, upon logout
# Only relevant if SAML is enabled and login is required.
# Otherwise, users will be sent to the netbox root page.
SAML_ON_LOGOUT_URL = 'https://idp.domain.com/'
Recommended Additional Settings

In the SAML_CONFIG dictionary, it's recommended that you also configure the contact and organization information so your metadata is prettier, or at least more accurate.

    # own metadata settings
    'contact_person': [
        {'given_name': 'Lorenzo',
         'sur_name': 'Gil',
         'company': 'Yaco Sistemas',
         'email_address': '[email protected]',
         'contact_type': 'technical'},
        {'given_name': 'Angel',
         'sur_name': 'Fernandez',
         'company': 'Yaco Sistemas',
         'email_address': '[email protected]',
         'contact_type': 'administrative'},
    ],
    # you can set multilanguage information here
    'organization': {
        'name': [('Yaco Sistemas', 'es'), ('Yaco Systems', 'en')],
        'display_name': [('Yaco', 'es'), ('Yaco', 'en')],
        'url': [('http://www.yaco.es', 'es'), ('http://www.yaco.com', 'en')],
    },
Set Up Certificates

SAML assertion signing works fine with a self-signed SSL certificate. Alternately, you can also use custom, privately signed or commercial certificates. In all cases, the paths to the certificate and key must be configured in config.py. By default, the config expects both files to be in the same directory as itself:

    # For assertion signing. This can be a self-signed pair.
    'key_file': path.join(SAML_DIR, 'key.pem'),  # private part
    'cert_file': path.join(SAML_DIR, 'cert.pem'),  # public part

If you have your own cert+key, simply copy them into the same directory as config.py, to cert.pem and key.pem respectively. If you'd like to generate a self-signed certificate, you can do so as follows:

# cd /path/to/netbox
# cd netbox/netbox/saml
# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

Please note: *This generates a self-signed cert that is valid for one year, and without a passphrase.

Set Up Metadata

Once you have modified your config.py, you'll need to fetch your IDP's metadata and generate your own. Download your IDP metadata and copy it to netbox/netbox/saml/idp.xml.

Next, you'll need to generate your metadata. Luckily, pysaml2 comes with a utility for this.

# cd /path/to/netbox
# cd netbox/netbox/saml
# make_metadata.py config.py > sp.xml

IDP Configuration

The defaults as given were confiured against Okta. Covering all the possible IDP settings is beyond the scope of this README, but we can offer the generic settings that work for Okta, and should be generally translatable to other IDPs

# IDP's commonly use the same URL for all three of these
Single Sign On URL: http://localhost:8080/saml2/acs/
Recipient URL: http://localhost:8080/saml2/acs/
Destination URL: http://localhost:8080/saml2/acs/

# This should be the SP entityID. If in doubt, use the URL to the SP metadata
Audience Restriction: http://localhost:8080/saml2/metadata/

# This is the path to which the IDP will redirect a client following auth.
# We experienced issues using the full URL, so instead set it to the relative
# URL, i.e. the relative path to the netbox root
Default Relay State: /

# Ensure the name ID format is set to "unspecified" unless you specifically need something else
Name ID Format: Unspecified

# These were defaults for Okta. YMMV
Response: Signed
Assertion Signature: Signed
Signature Algorithm: RSA_SHA256
Digest Algorithm: SHA256
Assertion Encryption: Unencrypted
SAML Single Logout: Disabled
authnContextClassRef: PasswordProtectedTransport
Honor Force Authentication: Yes
SAML Issuer ID: http://www.okta.com/${org.externalKey}

Instructions for DUO Access Gateway (DAG)

Once your DAG is setup you will need to setup a DUO application via your Dashboard on duo.com. This requires that you have a paid account to access the SAML applications. After logging into your dashboard do the following:

  • Click on 'Applications'
  • Click 'Protect an Application'
  • Search for 'SAML - Service Provider'
  • Fill in the following fields:
Field Value from netbox config
Service Provider Name a unique name for your instance
Entity ID https://<netbox_host>/saml2/metadata/
Assertion Consumer Service https://<netbox_host>/saml2/acs/
Single Logout URL https://<netbox_host>/logout
Service Provider Login URL https://<netbox_host>/saml2/login
  • Save your changes
  • At the top of your page click 'Download your configuration file' (this will be used on your DAG)

Now go back to the DAG you created earlier, and do the following:

  • Click on 'Applications'
  • Under 'Add Application' heading you should see a 'choose file' button click this and select the 'configuration file' file you generated in the steps above
  • Click 'Upload' and your application should be added
  • You should see a 'Metadata' section at the bottom of this page. Use this information to populate the following on your netbox SAML conf.py:
DUO Field Netbox Variable
Entity ID SAML_IDP_ENTITY_ID
SSO URL SAML_IDP_SSO_SERVICE
Logout URL SAML_ON_LOGOUT_URL
  • Also in this section, you should click 'Download XML metadata' and copy this to netbox/netbox/saml/idp.xml

Usage

Once you have configured your SAML settings, generated metadata and certificates, you can adjust the authentication behavior of netbox with a combination of settings.

If you want netbox to be public, but also to support SAML and username+password auth:

netbox/netbox/configuration.py:
	LOGIN_REQUIRED = False
netbox/netbox/saml/config.py:
	SAML_ENABLED = True
	SAML_REQUIRED = False

If you would like to completely protect netbox behind SAML auth:

netbox/netbox/configuration.py:
	LOGIN_REQUIRED = True
netbox/netbox/saml/config.py:
	SAML_ENABLED = True
	SAML_REQUIRED = True

Lastly, perhaps obviously, if you'd like to enforce login but accept both SAML and username+password

netbox/netbox/configuration.py:
	LOGIN_REQUIRED = True
netbox/netbox/saml/config.py:
	SAML_ENABLED = True
	SAML_REQUIRED = False