mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-11 21:10:29 +01:00
External authentication #1912
Closed
opened 2025-12-29 17:20:19 +01:00 by adam
·
50 comments
No Branch/Tag Specified
main
update-changelog-comments-docs
feature-removal-issue-type
20911-dropdown
20239-plugin-menu-classes-mutable-state
21097-graphql-id-lookups
feature
fix_module_substitution
20923-dcim-templates
20044-elevation-stuck-lightmode
feature-ip-prefix-link
v4.5-beta1-release
20068-import-moduletype-attrs
20766-fix-german-translation-code-literals
20378-del-script
7604-filter-modifiers-v3
circuit-swap
12318-case-insensitive-uniqueness
20637-improve-device-q-filter
20660-script-load
19724-graphql
20614-update-ruff
14884-script
02496-max-page
19720-macaddress-interface-generic-relation
19408-circuit-terminations-export-templates
20203-openapi-check
fix-19669-api-image-download
7604-filter-modifiers
19275-fixes-interface-bulk-edit
fix-17794-get_field_value_return_list
11507-show-aggregate-and-rir-on-api
9583-add_column_specific_search_field_to_tables
v4.5.0
v4.4.10
v4.4.9
v4.5.0-beta1
v4.4.8
v4.4.7
v4.4.6
v4.4.5
v4.4.4
v4.4.3
v4.4.2
v4.4.1
v4.4.0
v4.3.7
v4.4.0-beta1
v4.3.6
v4.3.5
v4.3.4
v4.3.3
v4.3.2
v4.3.1
v4.3.0
v4.2.9
v4.3.0-beta2
v4.2.8
v4.3.0-beta1
v4.2.7
v4.2.6
v4.2.5
v4.2.4
v4.2.3
v4.2.2
v4.2.1
v4.2.0
v4.1.11
v4.1.10
v4.1.9
v4.1.8
v4.2-beta1
v4.1.7
v4.1.6
v4.1.5
v4.1.4
v4.1.3
v4.1.2
v4.1.1
v4.1.0
v4.0.11
v4.0.10
v4.0.9
v4.1-beta1
v4.0.8
v4.0.7
v4.0.6
v4.0.5
v4.0.3
v4.0.2
v4.0.1
v4.0.0
v3.7.8
v3.7.7
v4.0-beta2
v3.7.6
v3.7.5
v4.0-beta1
v3.7.4
v3.7.3
v3.7.2
v3.7.1
v3.7.0
v3.6.9
v3.6.8
v3.6.7
v3.7-beta1
v3.6.6
v3.6.5
v3.6.4
v3.6.3
v3.6.2
v3.6.1
v3.6.0
v3.5.9
v3.6-beta2
v3.5.8
v3.6-beta1
v3.5.7
v3.5.6
v3.5.5
v3.5.4
v3.5.3
v3.5.2
v3.5.1
v3.5.0
v3.4.10
v3.4.9
v3.5-beta2
v3.4.8
v3.5-beta1
v3.4.7
v3.4.6
v3.4.5
v3.4.4
v3.4.3
v3.4.2
v3.4.1
v3.4.0
v3.3.10
v3.3.9
v3.4-beta1
v3.3.8
v3.3.7
v3.3.6
v3.3.5
v3.3.4
v3.3.3
v3.3.2
v3.3.1
v3.3.0
v3.2.9
v3.2.8
v3.3-beta2
v3.2.7
v3.3-beta1
v3.2.6
v3.2.5
v3.2.4
v3.2.3
v3.2.2
v3.2.1
v3.2.0
v3.1.11
v3.1.10
v3.2-beta2
v3.1.9
v3.2-beta1
v3.1.8
v3.1.7
v3.1.6
v3.1.5
v3.1.4
v3.1.3
v3.1.2
v3.1.1
v3.1.0
v3.0.12
v3.0.11
v3.0.10
v3.1-beta1
v3.0.9
v3.0.8
v3.0.7
v3.0.6
v3.0.5
v3.0.4
v3.0.3
v3.0.2
v3.0.1
v3.0.0
v2.11.12
v3.0-beta2
v2.11.11
v2.11.10
v3.0-beta1
v2.11.9
v2.11.8
v2.11.7
v2.11.6
v2.11.5
v2.11.4
v2.11.3
v2.11.2
v2.11.1
v2.11.0
v2.10.10
v2.10.9
v2.11-beta1
v2.10.8
v2.10.7
v2.10.6
v2.10.5
v2.10.4
v2.10.3
v2.10.2
v2.10.1
v2.10.0
v2.9.11
v2.10-beta2
v2.9.10
v2.10-beta1
v2.9.9
v2.9.8
v2.9.7
v2.9.6
v2.9.5
v2.9.4
v2.9.3
v2.9.2
v2.9.1
v2.9.0
v2.9-beta2
v2.8.9
v2.9-beta1
v2.8.8
v2.8.7
v2.8.6
v2.8.5
v2.8.4
v2.8.3
v2.8.2
v2.8.1
v2.8.0
v2.7.12
v2.7.11
v2.7.10
v2.7.9
v2.7.8
v2.7.7
v2.7.6
v2.7.5
v2.7.4
v2.7.3
v2.7.2
v2.7.1
v2.7.0
v2.6.12
v2.6.11
v2.6.10
v2.6.9
v2.7-beta1
Solcon-2020-01-06
v2.6.8
v2.6.7
v2.6.6
v2.6.5
v2.6.4
v2.6.3
v2.6.2
v2.6.1
v2.6.0
v2.5.13
v2.5.12
v2.6-beta1
v2.5.11
v2.5.10
v2.5.9
v2.5.8
v2.5.7
v2.5.6
v2.5.5
v2.5.4
v2.5.3
v2.5.2
v2.5.1
v2.5.0
v2.4.9
v2.5-beta2
v2.4.8
v2.5-beta1
v2.4.7
v2.4.6
v2.4.5
v2.4.4
v2.4.3
v2.4.2
v2.4.1
v2.4.0
v2.3.7
v2.4-beta1
v2.3.6
v2.3.5
v2.3.4
v2.3.3
v2.3.2
v2.3.1
v2.3.0
v2.2.10
v2.3-beta2
v2.2.9
v2.3-beta1
v2.2.8
v2.2.7
v2.2.6
v2.2.5
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.6
v2.2-beta2
v2.1.5
v2.2-beta1
v2.1.4
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.10
v2.1-beta1
v2.0.9
v2.0.8
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v2.0.0
v2.0-beta3
v1.9.6
v1.9.5
v2.0-beta2
v1.9.4-r1
v1.9.3
v2.0-beta1
v1.9.2
v1.9.1
v1.9.0-r1
v1.8.4
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.7.3
v1.7.2-r1
v1.7.1
v1.7.0
v1.6.3
v1.6.2-r1
v1.6.1-r1
1.6.1
v1.6.0
v1.5.2
v1.5.1
v1.5.0
v1.4.2
v1.4.1
v1.4.0
v1.3.2
v1.3.1
v1.3.0
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.7-r1
v1.0.7
v1.0.6
v1.0.5
v1.0.4
v1.0.3-r1
v1.0.3
1.0.0
Labels
Clear labels
beta
breaking change
complexity: high
complexity: low
complexity: medium
needs milestone
netbox
pending closure
plugin candidate
pull-request
severity: high
severity: low
severity: medium
status: accepted
status: backlog
status: blocked
status: duplicate
status: needs owner
status: needs triage
status: revisions needed
status: under review
topic: GraphQL
topic: Internationalization
topic: OpenAPI
topic: UI/UX
topic: cabling
topic: event rules
topic: htmx navigation
topic: industrialization
topic: migrations
topic: plugins
topic: scripts
topic: templating
topic: testing
type: bug
type: deprecation
type: documentation
type: feature
type: housekeeping
type: translation
Mirrored from GitHub Pull Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/netbox#1912
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @awlx on GitHub (Aug 8, 2018).
Originally assigned to: @jeremystretch on GitHub.
Environment
Ability to use external authentication via a proxy (eg. Keycloak-proxy, Nginx, Apache) by setting the appropriate headers. It was already described as a possibility here but I find no documentation or anything about this topic.
Proposed Functionality
It should be possible to pass authentication headers to netbox and either add a user automatically to the local database and make it possible to give the correct permissions in netbox or use the permissions passed via a header.
Use Case
This would be very useful because it wouldn't be necessary to implement and maintain dozens of different authentication mechanisms directly to Netbox but just pass the headers.
There is already an example for this in the wild but it requires some code changes and patching Netbox on every update is in my opinion not a good idea. So it would be really cool if something like this could be implemented in the codebase.
Example:
https://groups.google.com/d/msg/netbox-discuss/BTB8q8CzmrA/2BcnbectAQAJ
@jeremystretch commented on GitHub (Aug 8, 2018):
It sounds like this should be folded into #1989. The idea also needs to be fleshed out a lot more:
@awlx commented on GitHub (Aug 9, 2018):
Yep, sounds like those two could be solved together.
What are the proposed headers?
Most common seem to be REMOTE_USER and Authorization. Maybe it would be useful to have some other headers to pass E-Mail address or something.
Or the way Graylog does it with configurable Headers:
http://docs.graylog.org/en/2.4/pages/users_and_roles/external_auth.html#single-sign-on
How do you handle user creation and deletion?
I would propose to just add any existing user and no automatic deletion process in Netbox itself. Since nobody without external could log into Netbox anyway and a few users shouldn't slow down Netbox.
Other solution is to not create the user at all and just work with the forwarded permissions but I think this needs a bigger code change?
Illustrate how an existing tool would employ this functionality to authenticate a user
Icinga2 and Graylog already have the ability to do so. See here:
https://www.icinga.com/docs/icingaweb2/latest/doc/05-Authentication/#external-authentication
http://docs.graylog.org/en/2.4/pages/users_and_roles/external_auth.html#single-sign-on
Any conflicts between this and the existing UI/API authentication.
That is a good question I cannot answer at the moment. Basically the code needs to skip the login page of the UI when it detects the header and the option to do external auth is enabled in the config. Maybe we should also add a variable to only allow certain hosts to pass these strings otherwise it could add some security issues if we just accept the REMOTE_USER header from everywhere ;).
@rsepulvedacl commented on GitHub (Aug 17, 2018):
Grafana has a very useful way to authenticate users. I'm writing a proxy based in PHP and cURL and it's working very well.
I'm using SimpleSAMLphp to authenticate users when they try to connect to Grafana through this proxy. Once authenticated, the proxy passes some user's data to Grafana through the headers.
You can see some documentation from Grafana here: http://docs.grafana.org/tutorials/authproxy/.
I'd like to see something similar into Netbox. 😃
@cimnine commented on GitHub (Aug 17, 2018):
I think the exact names should be configurable.
Additionally to checking the authentication cookie, Netbox would also need to check for the header.
But I could see problems with the API, as it relies on headers for authentication.
@jeremystretch commented on GitHub (Aug 22, 2018):
The user also needs to be assigned permissions and/or groups in order to have any write access.
A valid user must be created in the database. This is a requirement of the framework and schema.
@awlx commented on GitHub (Aug 23, 2018):
Maybe if the group which is forwarded matches an existing group in Netbox, we could work with those permissions? Otherwise just create the user with a default group (configurable).
@globoudou commented on GitHub (Oct 2, 2018):
I'm on similar project, trying to use MS Kerberos Auth with Netbox. Globally it works with the following configuration :
reverse proxy apache 2.4.6 perform the kerb auth on /login url as follow :
AuthType GSSAPIGssapiCredStore /etc/keytabRequire valid-userRewriteEngine OnRewriteCond %{LA-U:REMOTE_USER} (.+)RewriteRule . - [E=RU:%1]RewriteRule "^(.*)$" "/"RequestHeader set KAUTHUSER "%{RU}e" env=RURequestHeader unset Authorizationadd django RemoteUser in netbox/settings.py :
AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.RemoteUserBackend', ]MIDDLEWARE = ( ... , 'django.contrib.auth.middleware.PersistentRemoteUserMiddleware', ... )change REMOTE_USER with KAUTHUSER in django/contrib/auth/middleware.py :
header = "HTTP_KAUTHUSER"In reverse-proxy configuration we can't deal with REMOTE_USER, because django is looking for a system variable, not an http header. This is the reason why apache rewrite it to KAUTHUSER http header.
Forcing the authentication in Netbox (
LOGIN_REQUIRED = True), it works as expected. The user's samaccountname@REALM must be provisioned in Netbox, and the SSO is working.The problem is when the user try to use the "logout" button. The redirect scheme is :
/logout/ ==302==> / ==302==> /login/?next=/ ==500It failed with error 500 :
_thread._localobject as no attribute changed_objectsin netbox/extras/middleware.py line 28After that I must restart the Netbox instance to log again.
I don't understand what is the problem...
@cimnine commented on GitHub (Oct 2, 2018):
Not sure if typo on Github or in your config, but this should probably be
PersistentRemoteUserMiddleware, as per Documentation (Using Remote User on Login Pages Only).@globoudou commented on GitHub (Oct 2, 2018):
Yes... error on keyboard... it was correct in my conf.
@DanSheps commented on GitHub (Jan 4, 2019):
Just to add on here, I would love if Duo was supported.
@cimnine commented on GitHub (Jan 4, 2019):
You would only be able to do this using a OIDC, OAuth or SAML reverse proxy, for example the Keycloak Security Proxy. That's as far as the proposed implementation would go.
@rsepulvedacl commented on GitHub (Jan 5, 2019):
I could use Shibboleth on Apache, doing the following changes in the NetBox code:
I modified the file
/opt/netbox/netbox/netbox/settings.py, adding the following lines:I also added the following lines at the end of
/opt/netbox/netbox/utilities/middleware.py:In the file
/opt/netbox/netbox/netbox/configuration.py, I changed toFalsethe following line:You can also use another external authentication method, changing the header if necessary, and you can use redirections in Apache for
/loginand/logoutURL's.These changes are based on @globoudou's comment.
@awlx commented on GitHub (Jan 9, 2019):
@rsepulvedacl I tried to reproduce your setup on v2.5.2 but for some reason it is not working at all.
Am I missing a step from your description? I changed everything you mentioned and added the following to my nginx config (for now it's static for tests).
proxy_hide_header Authorization; proxy_set_header HTTP_REMOTE_USER 'netbox';The user netbox exists and is able to login if I change everything back to the previous state.
@rsepulvedacl commented on GitHub (Jan 11, 2019):
@awlx, try it again without the
HTTP_prefix:You could be really passing
HTTP_HTTP_REMOTE_USERto NetBox with your settings. If for some reason, this doesn't work, change the header settings in both: nginx and/opt/netbox/netbox/utilities/middleware.py, but you should preserve theHTTP_prefix in this last file.I only tested this with Apache, using Shibboleth. The setting I used on Apache is the following:
You can also try with or without quotes around the user name. Good luck!
@rsepulvedacl commented on GitHub (Jan 11, 2019):
@awlx, I don't know nginx very well, but I found some settings that could be useful here:
https://developer.okta.com/blog/2018/08/28/nginx-auth-request#bonus-who-logged-in
@aficustree commented on GitHub (Jan 24, 2019):
@awlx , what did you end up getting to work? I need to do something similar but instead use OAUTH2. I was going to use the nginx oauth2 proxy and then make the changes to middleware/settings/configuration.py as above. It looks like that plugin pulls the UPN of the auth'd user to $upstream_http_x_auth_request_user which I'd assume we set as the REMOTE_USER header. Waiting on the app to be enabled by our directory team but curious if you ended up getting your use-case working.
@leoluk commented on GitHub (Jan 24, 2019):
We ended up implementing a custom OAuth provider via social_django by using a custom settings.py file.
If you want to try something similar, maybe this helps:
https://gist.github.com/leoluk/16d91ec22d833945c7ac7ed2b3b05a27
Hoping for a proper upstream hook.
@aficustree commented on GitHub (Jan 24, 2019):
very clean set of monkey patches. well done. almost see how this could indeed be generalized into a proper extensible authentication framework.
@aficustree commented on GitHub (Feb 14, 2019):
@leoluk , curious, followed your gist using the AzureAD social Django backend but how do I actually trigger the backend to fire? I see the custom url as ^oauth/ but the login page doesn't seem to hit it and if I just goto localhost/oauth/ I get a 404 with not matching the pattern
feel like I'm close but just missing something obvious.
my backends are set as follows:
@leoluk commented on GitHub (Feb 14, 2019):
Something like
LOGIN_URL = '/oauth/login/azuread/'should take care of redirecting you to the proper login page (you would have to check the Django Social docs on how exactly the backend is called).@aficustree commented on GitHub (Feb 14, 2019):
ah thanks, that was the tip I needed to look at the social Django code and discovered I should have used
oauth/login/azuread-tenant-oauth2/@aficustree commented on GitHub (Feb 15, 2019):
for some reason the login button doesn't seem to pick up the LOGIN_URL changes. No idea why but it just keeps with the regular login page. It works if I go direct to the URL but not if I click the login button.
@bluikko commented on GitHub (Jun 10, 2019):
Should the modifications in https://github.com/digitalocean/netbox/issues/2328#issuecomment-451677322 work at 2.5.13?
I have authentication at Apache working but Netbox does not seem to do anything with those changes - the user is not with admin rights and the "login" feature works as normal.
@rsepulvedacl commented on GitHub (Jun 10, 2019):
@bluikko, the modifications should work. Please consider that this method won't make any changes to login and logout buttons. You should consider to create a redirection and/or use rewrite on Apache.
It's been a long time since I implemented this, so I don't remember whether users are created automatically or not, but I remember that users won't be administrators automatically, unless you make some more improvements to this monkey patch or decide to make them administrators by hand.
@bluikko commented on GitHub (Jun 11, 2019):
@rsepulvedacl I see. Thanks. Unfortunately it is a problem for me if the user permissions would need to be manually managed.
I hope the developers would consider this enhancement request and integrate it properly with LDAP.
@davidc commented on GitHub (Jul 8, 2019):
I don't think bloating Netbox away from its core functionality is helpful or maintainable or a good use of development time, nor a wise decision as messing up authentication/authorisation is potentially very dangerous.
Leave authentication to the web server front-ends which already have plenty of options available, in a mature state of development.
For example, why on earth would someone devote the huge amount of effort to implementing SAML authentication in Netbox (#1677) instead of simply using e.g. Apache2 with mod_auth_mellon in front (as I do). Same for #118.
The options are countless and, no matter how many are implemented in Netbox, there will always be calls for more, so why even go down this route?
But, Netbox does needs to have better support for already-externally-authorised users:
Respect the headers (that the administrator has explicitly defined in Netbox configuration) for already-authorised users.
A way to automatically create the Netbox internal user when a new already-authorised user is detected. The admin should be able to specify in the config file what Netbox groups such a user will be added to.
If external auth is in use, disable internal login/logout pages and allow customisation of the target URL of login/logout links (or remove the login/logout links entirely at the administrator's option).
Documentation on how to configure this, which should be plainly obvious for anyone looking for "another way to auth to Netbox". And documentation on how to bootstrap this process - i.e. how to create or rename an existing admin user to their SSO username.
I have implemented https://github.com/netbox-community/netbox/issues/2328#issuecomment-451677322 and it works fine for 1, but it should be a configuration option rather than an edit to core files that will be lost on update. Then the "loose ends" 2-4 should be implemented.
@leoluk commented on GitHub (Jul 8, 2019):
The nice thing about Django is that is has a large ecosystem of high quality authentication backends which can easily be used with Netbox, like in the snippet above or my openshift-netbox role: https://github.com/leoluk/openshift-netbox/blob/master/openshift/netbox/openshift_auth.py
These don't belong in the core, but a well-defined set of hooks for users to configure their own authentication would solve most of these use cases. In my particular case, these are the only modifications made:
Overwriting the logout URL such that, in addition to terminating the user session, the user gets logged out of an external IdP (https://github.com/leoluk/openshift-netbox/blob/master/openshift/netbox/openshift_auth.py)
For any login provider which uses callbacks, the callback URL needs to be accessible before the user is logged in. Right now, this requires a modification to LoginRequiredMiddleware and the root URLs (https://github.com/leoluk/openshift-netbox/blob/master/openshift/netbox/openshift_middleware.py and https://github.com/leoluk/openshift-netbox/blob/master/openshift/netbox/openshift_urls.py).
Various extra settings.py configurations to load the provider, enable and configure it (https://github.com/leoluk/openshift-netbox/blob/master/openshift/netbox/settings.py).
I agree with @davidc that HTTP headers are the best approach for "generic" authentication.
@tombastianello commented on GitHub (Sep 13, 2019):
If anyone is interested in being able to use pass-through authentication form an authentication proxy such as pusher/oauth2_proxy, I've created a custom image build here: https://gitlab.com/tom.bastianello/netbox-proxy-auth
The changes are minimal and it captures the email of the user authenticated by the proxy.
@bluikko commented on GitHub (Sep 13, 2019):
@tombastianello I am definitely interested in this. Does your patch require manual creation of users in Netbox (for each REMOTE_USER account) or no additional users are needed in Netbox?
Clicking your link goes to a wrong place.
Edit: just took a look at it. Can the variable be changed? REMOTE_USER is the standard one in my opinion but I'm not familiar with oauth2 and never saw the "PREAUTH_COOKIE" var before.
Also, what is the purpose of the
login.htmlfile? My use case for this is Kerberos/GSSAPI so a login page will never be needed.Respectfully, Netbox should support this out of box. The earlier discussion shows that it might not be that complex at basic level; but maybe it is more complex than a few lines if manually creating the users in Netbox would not be needed. I'd be fine with mapping all preauthenticated users to admin.
@tombastianello commented on GitHub (Sep 13, 2019):
@bluikko The authentication proxy adds a cookie (containing basic user details like their email) for the specified domain the to the client browser, when you are setting up said proxy, you have the option to choose the name of the cookie to use, the PREAUTH_COOKIE environment variable tells the netbox authentication module what cookie to look for.
The
login.htmlfile is only there so that the user gets a message (most of the time very brief) that their credentials are being checked. I didn't want to re-work netbox too much so that it was easy to maintain and little changes had to be made.Lastly, users don't need to be added manually, they are automatically added to netbox with a blank password (no password is technically needed because the application is already hidden behind the authentication proxy).
If you need any more help with running it in kubernetes I can provide an example template for the deployment and service/ingress.
@bluikko commented on GitHub (Sep 13, 2019):
@tombastianello It sounds a lot like what I need.
If I understand correctly
PREAUTH_COOKIEis similar to theREMOTE_USERvariable. That contains the logon name of the preauthenticated user when usingmod_auth_gssapiormod_auth_kerberos. But that variable is not base64-encoded. Example from my use case:I could probably disable the base64-decoding myself and change the variable name.
I will definitely look at testing your code (in the coming weeks when there's time for this). I'm not using Docker for NetBox but it seems straightforward enough.
Thanks.
@tombastianello commented on GitHub (Sep 13, 2019):
@bluikko The base64 encoding/decoding is a valid point, I've just updated the code with a new variable to enable/disable that. Give it a go and if you have any issues let me know and I'll include the changes.
@sdktr commented on GitHub (Oct 15, 2019):
Hi Tom, can you provide the kubernetes based example you’re referring to above? Thanks!
@tombastianello commented on GitHub (Nov 6, 2019):
Hi @sdktr,
Sorry for the delay, example deployment and ingress can be found here:
https://gitlab.com/tom.bastianello/netbox-proxy-auth/tree/master/examples/kubernetes
If anyone needs help adding this to netbox directly, let me know and I'd be happy to help, I can potentially clean up the code and submit a pull request. @jeremystretch
@CrackerJackMack commented on GitHub (Dec 29, 2019):
I have a working docker, kubernetes, nginx+oauth2_proxy and netbox related patches working so it is optionally enabled. How would you like these pull requests? One per feature? All in one? My works are based on v2.6.9 but I'm sure I could port them to develop.
@sdktr commented on GitHub (Dec 30, 2019):
I think only the netbox -part is desired in this repo. A netbox PR including documentation on how to enable/configure it. Maybe a seperate issue in the 'netbox-docker' repo outlining how you did it with your k8s based setup?
@bootc commented on GitHub (Dec 30, 2019):
@CrackerJackMack I'd like to have your K8s components please to integrate into bootc/netbox-chart. This is a setup I would very much like to be able to use and a scenario I'd like to have in the chart.
@jeremystretch commented on GitHub (Jan 16, 2020):
I've been going over the discussion here and in other issues, trying to determine the scope for this change. I think it boils down to two different approaches:
REMOTE-USER) set by a reverse proxy (nginx or Apache) and assign the current user based on its value.django-auth-ldapworks currently).As the second case should be handled by #3351 (plugin support), this issue should focus on the first case: HTTP header-based authentication. Of course, a complete implementation of this feature entails not only user assignment, but user creation and group assignment (for granting of permissions) as well.
There are some good references linked in the chat above, such as Grafana's implementation, but we need to thoroughly define the login/logout workflow before any serious progress can be made.
@jeremystretch commented on GitHub (Feb 18, 2020):
It's surprising this hasn't gotten any more feedback in the past month. We really need to work on scoping this out fully and defining a working model for this to be implemented. Would anyone like to volunteer to take the lead? We need at least a few solid use cases for reference I think.
@kobayashi commented on GitHub (Feb 19, 2020):
If no objection here, I handle this to implement a header for proxy authentication.
@kobayashi commented on GitHub (Feb 19, 2020):
For this issue, agree to focus on the first one to authenticate with a proxy like apache or nginx in front of netbox.
@CrackerJackMack commented on GitHub (Feb 21, 2020):
I don't have time for an official PR (sorry). But I'm are using https://github.com/pusher/oauth2_proxy
with https://github.com/divio/django-simple-ssowith some very minor alterations to netbox.There is also https://github.com/agoragames/nginx-google-oauth as well as https://github.com/cloudflare/nginx-google-oauth which have different headers.
For hosted solutions there is https://teams.cloudflare.com/access/index.html and https://cloud.google.com/iap/
I'll see if I can post a gist of the patch this weekend. Maybe a good starting point for a more generic solution to support more auth proxies.
edit: mispoke about django-simple-sso, this was a previous attempt
@bluikko commented on GitHub (Feb 22, 2020):
@CrackerJackMack maybe I am wrong but at least some of your links seem to do authentication with external sources. I believe that this issue is about using the "preauthentication" headers set by the web server?
For example I am using GSSAPI where the web server sets REMOTE_USER HTTP header and all NetBox would need to do for basic support is to check for presence of that header.
It would be good if NetBox could be told to automatically give administrator rights to the users. Several web apps that I administer can split authentication and authorization so that authentication is done based on the HTTP headers and then authorization is done in the web app, for example by using LDAP to check group memberships of the user in REMOTE_USER.
This would be great but I'd even be happy if just the basic case would be supported.
@CrackerJackMack commented on GitHub (Feb 22, 2020):
@bluikko You are only partially wrong I believe. They specifically exist to auth, and set HTTP headers. All the links I provided act as a trusted reverse proxy which you can trust that authentication and authorization was handled prior to setting and sending the HTTP headers. In the simplest, most crude examples:
Depending on the solution and if it's configurable with that solution, all of them set HTTP headers with we inherently trust. This choice is based entirely on this snippet from https://docs.djangoproject.com/en/3.0/howto/auth-remote-user/
The not-pr-worthy gist I promised. It also includes a more complicated nginx auth_request module setup to defer to oauth2_proxy using a side request.
https://gist.github.com/CrackerJackMack/8f0e84b2d6ca981f4262b5fa5136375c
@sdktr commented on GitHub (Feb 23, 2020):
Hi @CrackerJackMack , shouldn’t the ‘user normalization’ be part of the frontend proxy’s job? I think it opens up a whole can of possible rules that end up beging maintained in Netbox on how to interpret the header?
@CrackerJackMack commented on GitHub (Feb 23, 2020):
@sdktr Funny enough, the proxies would argue that it's the application's problem to clean up things if desired 😆
This is one of those annoying external authentication issues everyone likes to gloss over in their "Have them login with facebook!" blog posts. The issue isn't a issue with external authentication on a technical level, but more so that you have no idea how the login system works externally or what it will return in the headers and/or cookie data.
There are some agreed upon standards to help adoption, but they aren't a hard rule.
First, we have to choose an upstream auth service and see what header is does, or can send back to us. The auth service could do oauth2, SAML, openid connect, LDAP, ... We don't really know how users actually login to the service. Depending on the external authentication the headers could be a combination or just a single set of the following headers
Next problem. Are the username and email forwarded to us usable as is? Well that's really dependent on the downstream application (netbox & administrator). If usernames are intended to be emails then you just use X-Forwarded-Email and ignore -User for example. are the username and email prefixed as to help identify the upstream:
accounts.google.com:username@gsuite.domain.com?I had a 3rd point but I can't recall what it is right now.
@jeremystretch commented on GitHub (Feb 27, 2020):
I think it makes sense to implement this feature by introducing two new abilities.
First, I propose implementing a custom subclass of Django's RemoteUserBackend. We can provide hooks into this class in the form of configuration parameters to control attributes such as:
The configuration parameter for this might look something like:
The remote authentication backend will be enabled only if
REMOTE_AUTH_CONFIGis defined. (The current ViewExemptModelBackend will still be in place as a fallback for local authentication.) This will likely address the majority of use cases for this feature.The second component is to allow the injection of a custom backend class, to be inserted at the beginning of
AUTHENTICATION_BACKENDS. This would take the form of a separate configuration parameter, e.g.REMOTE_AUTH_CONFIGandREMOTE_AUTH_BACKENDwould be mutually exclusive to avoid confusion.I believe this strikes a nice balance between built-in support and custom extensibility, and should be fairly low-effort to maintain long-term.
@jeremystretch commented on GitHub (Feb 28, 2020):
In the interest of moving the conversation along, I've introduced PR #4299. This largely implements what I described, however I opted to use individual configuration parameters rather than a dictionary for easier validation. The following can be used to enable and configure built-in remote user authentication:
This is sufficient to:
If further customization is needed, there is another setting which can be used to swap out the built-in backend with a custom one:
There was some discussion above around manipulating the user name. The backend class does provide a hook for that, but I'm not sure what degree of flexibility would be appropriate. I think at most we can allow the configuration of a regular expression that will match the desired portion of the username passed by the reverse proxy. This would allow us to, for example, strip the username portion from an email address, but anything more complicated than that would require a custom authentication backend.
@chaomodus commented on GitHub (Mar 4, 2020):
All of this sounds very good, I was wondering how feasible it would be to also provide a remote auth header name for groups or some sort of group mapping mechanism (similar to REMOTE_AUTH_HEADER, but like REMOTE_AUTH_GROUPS), or would the standard suggestion would be to use a remote_auth_backend for that?
@bluikko commented on GitHub (Mar 4, 2020):
@chaomodus There are ways to provide list of groups in an HTTP header but in my opinion that would never be as good as separating authorization from authentication: the HTTP header would be authentication and NetBox would do authorization via LDAP for example.
Anyhow it might be good to not try to widen the scope too much at this point - a simple external authentication via HTTP headers would be a good start.