Authenticate with Netbox via AzureAD
Project description
netbox-plugin-azuread
A plugin for the IPAM tool Netbox to support OAuth2 authentication via Azure Active Directory.
netbox-plugin-azuread
is effectively a light wrapper around Microsoft's own msal
library with the added ability to map AzureAD groups to Django permissions.
Installation
Before installing any plugins, it's worth familiarising yourself with the Netbox documentation.
Regardless of environment, it's always a good idea to pin your dependencies. I haven't done it explicitly in this README but I recommend doing it for your own deployments eg; pip install msal==1.2.3 netbox_plugin_azuread==1.0.0
.
Bare metal
If you're using a non-containerised deployment of Netbox, you'll want to first activate the virtual environment as referenced in the Netbox setup process.
cd /opt/netbox
source venv/bin/activate
Once activated, you'll be able to use pip install netbox-plugin-azuread
by way of its hosted PyPI distribution. We'll also be installing msal
as a dependency. Once done, you'll need to restart Netbox to see your changes.
pip install msal netbox_plugin_azuread
systemctl restart netbox
If you prefer to install this package manually, both a .tar.gz
and .whl
distribution are available under under the releases section of this Github repository.
Once installed, don't forget to add these changes to your requirements.txt
or better yet, store them in their own distinct requirements file from the Netbox base requirements.
Containerisation
If you're looking to use this plugin in conjunction with your own dockerised version of Netbox, or one of the available netbox-docker images, it's a little bit more involved.
At work, we run this plugin within a build of Netbox deployed via Kubernetes but the steps are the same for any Docker deployment.
Here's the simplest possible Dockerfile you could write:
FROM netboxcommunity/netbox:v2.11.12
RUN /opt/netbox/venv/bin/pip install netbox_plugin_azuread msal
As above, msal
is a dependency of this plugin so we need to install it as well. Despite this container being extremely small, the rest of the netbox-docker
build scripts will implicitly execute as we haven't overridden the entrypoint or any other commands.
Usage
In order to use this plugin, you'll need to add it to the PLUGINS_CONFIG portion of your Netbox configuration.
Here's a sample of all of the possible settings you can configure:
PLUGINS = [
'netbox_plugin_azuread' # Note that we use underscores for the plugin internally but the name has dashes
]
PLUGINS_CONFIG = {
'netbox_plugin_azuread': {
'CLIENT_ID': '<YOUR-CLIENT-ID-HERE>', # Available for viewing in the Azure Portal under Azure Active Directory
'CLIENT_SECRET': '<YOUR-CLIENT-SECRET-HERE>',
'AUTHORITY': '<YOUR-CLIENT-AUTHORITY-HERE>',
'LOGIN_URL': '<LOGIN-URL>', # Should be /plugins/azuread/login/ unless you remap it using eg; nginx
'REPLY_URL': '<REPLY_URL>', # Should be /plugins/azuread/complete/ unless you remap it using eg; nginx
'SCOPES': ['https://graph.microsoft.com/.default'],
'AD_GROUP_MAP': {
'STAFF': ['abc123', 'blahblah'],
'SUPERUSER': ['blahadmin'] # Set one or more Azure AD groups and users with this group will receive the superuser or staff flag
},
'AD_GROUP_FILTER': [ # Only import those groups listsm otherwise if empty, import all Azure groups
'abc123',
'blahblah',
'blahadmin'
]
}
}
REMOTE_AUTH_AUTO_CREATE_USER = True
REMOTE_AUTH_BACKEND = 'netbox_plugin_azuread.backends.AzureADRemoteUserBackend'
REMOTE_AUTH_ENABLED = True
Here is a basic breakdown of each one:
Name | Example | Notes | Required |
---|---|---|---|
CLIENT_ID | abc123 |
The client id for your Azure AD service principle | Yes |
CLIENT_SECRET | abc123 |
The client secret for your Azure AD service principle | Yes |
AUTHORITY | https://login.microsoftonline.com/abc123 |
The authority for your Azure AD service principle | Yes |
LOGIN_URL | /plugins/azuread/login/ |
The login URL to display the custom login page under | No |
REPLY_URL | /plugins/azuread/complete/ |
The reply URL to receive Azure AD OAuth callbacks on | No |
SCOPES | ['https://graph.microsoft.com/.default'] |
The scopes to use. The default Graph scope should be fine as it passes through all pre-configured permissions | No |
AD_GROUP_MAP | {'SUPERUSER: ['abc123']} |
A dictionary where keys are privileges and values are lists of groups to inherit those privileges | No |
AD_GROUP_FILTER | ['abc123'] |
A list of groups to be explicitly included so you don't import hundreds of irrelevant AD groups. Leaving it blank will import all groups. | No |
As depicted above, only CLIENT_ID
, CLIENT_SECRET
and AUTHORITY
are explicitly required. LOGIN_URL
, REPLY_URL
and SCOPES
will default to the above URLs. You'll probably want to make use of the AD_GROUP_MAP
and AD_GROUP_FILTER
but they are also optional.
Setting up group claims
Getting groups flowing through can trip up some users so it's important that the Azure Service Principal you're using has the correct permissions.
At present, the bare minimum configuration is a service principal with the Directory.Read.All
permission of type Application
.
Either yourself or someone authorised to view Azure Active Directory should be able to verify this under Enterprise Applications -> your sp -> API Permissions tab. It should look like the following:
You can also read a bit more about this in issue #3.
Redirecting the login page
Out of the box, you'll notice that http://netbox.blah/login
still shows the usual login page. Due to the nature of this being a plugin and not a core part of Netbox, it lives under /plugins/azuread
and can't overwrite Netbox URLs.
One possible solution is to request that Netbox allows updating which route is considered the login page via configuration but in lieu of that, we can work around this. To be clear, you can always just ask users to manually visit /plugins/azuread/login/
each time but that's a pain to remember.
In my own case, I use an nginx instance to write /login/
to point to /plugins/azuread/login/
instead.
Here's an example of how your configuration could look:
worker_processes 1;
pid /tmp/nginx.pid;
error_log /dev/stderr info;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
client_max_body_size 25m;
access_log /dev/stdout;
server {
listen 8000;
server_name _;
access_log off;
location / {
proxy_pass http://localhost:8080/;
}
location /login/ {
proxy_pass http://localhost:8080/plugins/azuread/login/;
}
location /complete/ {
proxy_pass http://localhost:8080/plugins/azuread/complete/;
}
}
}
This may seem a bit overkill just for one plugin but originally, nginx was required regardless to serve static assets. In our case, netbox-docker
has since updated to use nginx unit under the hood so this is no longer relevant to my knowledge.
Questions
While this project is open sourced with no guarantees, feel free to open an issue and I'll attempt to provide support as I can.
Screenshots
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file netbox-plugin-azuread-1.2.0.tar.gz
.
File metadata
- Download URL: netbox-plugin-azuread-1.2.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.5.0 importlib_metadata/4.8.2 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 870e7ddfbda1476fb7f80479cb2374b1f68b771458144ac33003ef29414d390c |
|
MD5 | 746012107822352c9bdd420b01eb90a4 |
|
BLAKE2b-256 | d38e2f06f9bfab5573d100e2ce998c25a878277f69d4a35418d5e62159f79524 |
File details
Details for the file netbox_plugin_azuread-1.2.0-py3-none-any.whl
.
File metadata
- Download URL: netbox_plugin_azuread-1.2.0-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.5.0 importlib_metadata/4.8.2 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ef5d262a15abef40ee8f724e001676b0ef8e32d64efe052a39579f77e5dd6f82 |
|
MD5 | 82634b2327e106829ce7ad4a0b3d4e0d |
|
BLAKE2b-256 | c428f842ecdcaa53a26b35f0d9dbc4d19cde7f19508efaa7b8e85cea54bd63d0 |