Skip to content

Merging oidc branch with master #753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from

Conversation

joe307bad
Copy link

This PR merges the changes introduced in the oidc branch into the master branch. These changes add the ability to specify an OIDC provider for authentication.

Subv and others added 15 commits June 2, 2020 21:42
There is a Knex issue ( knex/knex#2649 ) that prevents .defaultTo from working for text columns.
… enabling/disabling oidc.

If this is not triggered and the OIDC toggle is enabled, the "disabled" property will be removed from the restricted user list input, causing an error when trying to submit the form without it.
Add the ability to secure proxy hosts with OpenID Connect
@jc21
Copy link
Member

jc21 commented Dec 2, 2020

Docker Image for build 1 is available on DockerHub as jc21/nginx-proxy-manager:github-pr-753

@joe307bad
Copy link
Author

This works!

Here are the steps I used to get this working on my internal network using NPM, Keycloak, and Docker. I was able to secure my home server's instance of Tautulli with Keycloak's identity management framework.

Setting up Keycloak:

(based off of this guide)

  1. Spin up a Keycloak environment (I ran the main Keycloak container (quay.io/keycloak/keycloak:latest) and a postgres container for data persistence)
  2. Create a realm (explained in the guide linked above)
  3. On the realm's General settings tab, take note of the OpenID Endpoint Configuration link beside Endpoints. Mine was:

    https://<keycloak instance>/auth/realms/<realm name>/.well-known/openid-configuration

  4. Save realm.
  5. Create and save a user in your realm as described in the linked guide above.
  6. Your new realm will come with prebuilt clients. From the sidebar, select Clients and go into the settings for the "account" client.
  7. In this client's settings, you want to add a new Valid Redirect URI. For my case, I added: https://<tautulli instance>/redirect_uri. As far as I know, this is just the accessible to-be-secured instance (IP address, domain, etc.) + some arbitrary, unused path. /redirect_uri has no significance here other than https://<tautulli instance>/ does not use it.
  8. Save the client.
  9. Select the Credentials tab of this client's settings. Take note of the client secret. Mine looked like a GUID.

Setting up NPM:

(the orginal PR also has good technical info)

  1. Set up a proxy_host and navigate to the OpenID Connect settings tab.
  2. The Redirect URI is the new URI we added in step 7 of setting up Keycloak.
  3. The Well-known discovery endpoint is the endpoint we found in step 3 of setting up Keycloak.
  4. The Token endpoint auth method should be client_secret_post.
  5. Client ID will be "account".
  6. Client secret is the secret we found in step of setting up Keycloak.

That should be it! Navigating to https://<tautulli instance>/ should send you into an OAuth2 authorization flow where you can login as the user we created in step 5 of setting up Keycloak.

One issue I ran into was my container for NPM was not resolving <tautulli instance> correctly. Since the info you enter in the "Setting up NPM" part of this guide has to use the "source"/actual domain of the proxy host, not the internal Docker container names (e.g. https://tautulli:8181 does not work in OpenID Connect settings of a proxy host), and for my internal network I am running a bind DNS server to resolve custom TLD names, I needed to figure out a way of resolving these custom TLD's within my NPM instance. I ended up having to add --dns arg when running the NPM container and also forcing the NPM container to trust the root CA for my internal network's URLs. Then everything works great!

We should merge this PR :) 🚀

@adrianzech
Copy link

I've been running this image since over 2 weeks now and it's working flawlessly so far.
I hope this gets merged soon. 👍

@joe307bad
Copy link
Author

@adrianzech just curious, what does your set up look like in regards to this container? Are you using keycloak like I describe or some other oidc provider? Are you using it in production or on a home network? Thanks!

@adrianzech
Copy link

I use Keycloak together with FreeIPA for user managment. Other than that my configuration looks pretty similar to yours, except that I didn't use docker for Keycloak.
I'm using it in my home network

@lividpro
Copy link

Hi Am trying to set Open ID with Azure AD.
My Site is working publicly and I get normal responses in the log files.

[29/Dec/2020:12:29:34 +0000] - - 000 - GET https sonarqube.conet.info "/" [Client 172.19.0.1] [Length 0] [Gzip -] [Sent-to ] "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-"

in the error log I get this message
2020/12/29 12:29:34 [warn] 6878#6878: *2246 using uninitialized "server" variable while logging request, client: 172.19.0.1, server: sonarqube.conet.info, host: "sonarqube.conet.info"

Did I make a configuration mistake? Can you point me in the right direction?

I will try to setup Keycloak to make sure nothing else is wrong.

To make sure there weren't any db issues I have started a new instance of the DB and APP docker. So all new clean setup.

@joe307bad
Copy link
Author

@lividpro

  • What error does your browser show you when you try to open the site?
  • What does the generated nginx/proxy_host conf file look like for the proxy you want to hook up to OIDC?

Here is what my conf file looks like and it works for me:

# ------------------------------------------------------------
# <tautulli instance>
# ------------------------------------------------------------

server {
  set $forward_scheme http;
  set $server         "tautulli";
  set $port           8181;

  listen 80;
  listen [::]:80;

  listen 443 ssl http2;
  listen [::]:443;
  server_name <tautulli instance>;

  # Custom SSL
  ssl_certificate /data/custom_ssl/npm-5/fullchain.pem;
  ssl_certificate_key /data/custom_ssl/npm-5/privkey.pem;
  access_log /data/logs/proxy_host-5.log proxy;

  location / {
   access_by_lua_block {
            local openidc = require("resty.openidc")
            local opts = {
            redirect_uri = "https://<tautulli instance>/redirect_uri",
            discovery = "https://<keycloak instance>/auth/realms/<keycloak realm>/.well-known/openid-configuration",
            token_endpoint_auth_method = "client_secret_post",
            client_id = "account",
            client_secret = "<client secret>",
            scope = "openid email profile"
        }

        local res, err = openidc.authenticate(opts)

        if err then
            ngx.status = 500
            ngx.say(err)
            ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
        end

        ngx.req.set_header("X-OIDC-SUB", res.id_token.sub)
        ngx.req.set_header("X-OIDC-EMAIL", res.id_token.email)
        ngx.req.set_header("X-OIDC-NAME", res.id_token.name)
    }

    # Force SSL
    include conf.d/include/force-ssl.conf;

    # Proxy!
    include conf.d/include/proxy.conf;
  }

  # Custom
  include /data/nginx/custom/server_proxy[.]conf;
}

@cierzniak
Copy link

Any idea how to connect Gitlab OIDC provider? I cant setup any valid redirect url - gitlab itself won't redirect to previous page, this page shows network error. (all domains are redacted)

Gitlab redirect page

config result
image image

Self redirect page

config result
image image

Gitlab has also callback url, w/e means and it's configured like:
image

@joe307bad
Copy link
Author

@cierzniak did you allow the redirect URI in gitlab? Something similar to my step 7 in "Setting up keycloak" ?

@lividpro
Copy link

lividpro commented Dec 30, 2020

@joe307bad Hi Joe,

Mine is almost the same

`server {
set $forward_scheme https;
set $server "192.168.10.175";
set $port 443;

listen 80;
#listen [::]:80;

listen 443 ssl http2;
#listen [::]:443;

server_name sonarqube.conet.info;

Custom SSL

ssl_certificate /data/custom_ssl/npm-2/fullchain.pem;
ssl_certificate_key /data/custom_ssl/npm-2/privkey.pem;

access_log /data/logs/proxy_host-2.log proxy;

location / {

access_by_lua_block {
local openidc = require("resty.openidc")
local opts = {
redirect_uri = "https://sonarqube.conet.info/redirect_uri",
discovery = "https://login.microsoftonline.com/af4f3a2c-f5d7-408e-89f2-7e11f3c2cfd2/v2.0/.well-known/openid-configuration",
token_endpoint_auth_method = "client_secret_post",
client_id = "*",
client_secret = "
",
scope = "openid email profile"
}

    local res, err = openidc.authenticate(opts)

    if err then
        ngx.status = 500
        ngx.say(err)
        ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    end

    ngx.req.set_header("X-OIDC-SUB", res.id_token.sub)
    ngx.req.set_header("X-OIDC-EMAIL", res.id_token.email)
    ngx.req.set_header("X-OIDC-NAME", res.id_token.name)
}

# Proxy!
include conf.d/include/proxy.conf;

}

Custom

include /data/nginx/custom/server_proxy[.]conf;
}`

The browser give an net::ERR_CONNECTION_CLOSED
the http code is 000
[30/Dec/2020:14:04:30 +0000] - - 000 - GET https sonarqube.conet.info "/" [Client 172.19.0.1] [Length 0] [Gzip -] [Sent-to ] "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66" "https://login.microsoftonline.com/"

@adrianzech
Copy link

I've noticed that I am getting "Cross-Origin Request Blocked" messages after a short period of time using one of my sites.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://keycloak.example.com/auth/realms/REALM/protocol/openid-connect/auth?scope=openid%20email%20profile&client_id=account&state=e2deee143931461158131fcaca9c26f8&nonce=385b96d234594d23907c07e9fea53f35&redirect_uri=https%3A%2F%2Fsub.example.com%2Fredirect&response_type=code. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

I've tried adding add_header "Access-Control-Allow-Origin" "*"; to my site in nginx proxy manager under advanced and added "*" to the Web Origins field in Keycloak. But with no luck.

Has anyone experienced the same issue?

@cierzniak
Copy link

cierzniak commented Dec 30, 2020

@joe307bad Ok, give it another try:

Gitlab config:
image

NPM config:
image

image

And after entering http://secured.domain/ it makes redirection to gitlab (oidc auth) and back to http://secured.domain/redirect_url?code=b5b0a7f6379...&state=43d299238af8b33dc6781e3cb150b060 but response from NPM is 502 Bad Gateway and no entry in NPM logs (logs shows next 302).

==> proxy_host-5.log <==
[30/Dec/2020:22:43:47 +0000] - - 302 - GET http secured.domain "/" [Client //ip//] [Length 142] [Gzip -] [Sent-to secured_app] "//client//" "-"
[30/Dec/2020:22:43:48 +0000] - - 302 - GET http secured.domain "/redirect_url?code=b5b0a7f6379...&state=43d299238af8b33dc6781e3cb150b060" [Client //ip//] [Length 142] [Gzip -] [Sent-to secured_app] "//client//" "-"

OMG, after refresh page is something more - 500 Internal Server Error

==> error.log <==
2020/12/30 22:53:23 [error] 747#747: *24336 [lua] openidc.lua:1089: authenticate(): state from argument: 43d299238af8b33dc6781e3cb150b060 does not match state restored from session: 48208b9d991046398447a33cc749660b, client: //ip//, server: secured.domain, request: "GET /redirect_url?code=b5b0a7f6379...&state=43d299238af8b33dc6781e3cb150b060 HTTP/1.0", host: "secured.domain"

==> proxy_host-5.log <==
[30/Dec/2020:22:53:23 +0000] - - 500 - GET http secured.domain "/redirect_url?code=b5b0a7f6379...&state=43d299238af8b33dc6781e3cb150b060" [Client //ip//] [Length 63] [Gzip -] [Sent-to secured_app] "//client//" "-"

I have 2 TLDs, gitlab is gitlab.doman1.com (and SSLed) and secured site is secured.domain2.com (without SSL), should I turn off SAMEORIGIN or change another value inside NPM to begin it working? When I want to use Google or any other OAuth provider same happens, two different domains. No SSL shouldn't be problem anyway, I use Portainer or SonarQube in local network without SSL and same Gitlab instance is OAuth provider for both.

@jc21 jc21 changed the base branch from master to develop January 3, 2021 02:13
@jc21
Copy link
Member

jc21 commented Jan 3, 2021

The reason I had not merged this branch yet is because during my own testing of my production sites, I've found that reloading nginx with at least one OIDC auth enabled host increased the reload time for each host by 300ms. Since I had more than 100 hosts, this reload time was ridiculous. We never got around to investigating it any deeper than a single configuration line I found (and had to be included for oidc to work) so I left the branch there to see if others had similar problems too. Actually I recall it might be trying to fetch something from the auth server for each host defined even if it's not using the auth server in it's configuration.

The other thing I was waiting for, openresty updates that might help resolve that.

I'm interested to see if anyone who has a large number of hosts, with mixed configurations, letsencrypt certs etc.

@jc21
Copy link
Member

jc21 commented Jan 3, 2021

Docker Image for build 2 is available on DockerHub as jc21/nginx-proxy-manager:github-pr-753

@GlibTongue GlibTongue mentioned this pull request Jan 10, 2021
@Secarius
Copy link

Secarius commented Feb 4, 2021

Hi how can i install it with docker-compose?
What is the image i have to put in the docker-compose.yml?

Thank you very much

@adrianzech
Copy link

Hi how can i install it with docker-compose?
What is the image i have to put in the docker-compose.yml?

Thank you very much

Replace image: 'jc21/nginx-proxy-manager:latest' with image: 'jc21/nginx-proxy-manager:github-pr-753

@Secarius
Copy link

Secarius commented Feb 5, 2021

@adrianzech thank you very much it worked.

I have a suggestion: additional to the "Allow only these user emails" it would be very nice to have the ability to define
Allow only Users with these Roles:"

image

Is this the right place to place a suggestion?

Kind regards
Felix

@jc21
Copy link
Member

jc21 commented Feb 8, 2021

I have a suggestion: additional to the "Allow only these user emails" it would be very nice to have the ability to define
Allow only Users with these Roles:"
Is this the right place to place a suggestion?

No I think this setup is part of your third party authentication service. This project is only responsible for passing off authentication to that service, it doesn't have any more control than that.

@coltonshipley
Copy link

I have tried playing with this. I'm trying to use Auth0 as the provider. I get taken to the auth0 loginform, and i get redirected back. but then i just get 'too many redirects' on chrome and if i try to use ie (yeah.. i know) it just loads forever. Any insight to what is going on?

image

image

I do use cloudflare for my nameserver and the subdomains are proxied via cloudflare. i'm using origin SSL certs with full/strict mode.

Any help or insight would be appreciated.

Also, because I don't know. How does this work trying to protect applications that have their own auth but can't be disabled. Like Radarr can be disabled. but some other services cannot.

I'm also open to another provider other than Auth0 if it is easier to implement.

@jc21
Copy link
Member

jc21 commented Mar 10, 2021

Docker Image for build 3 is available on DockerHub as jc21/nginx-proxy-manager:github-pr-753

@fabiopedrosa
Copy link

@jc21 won't this be merged?

@arod20832
Copy link

IMHO this is a very desirable feature. I think it should be merged with a warning regarding impact to large scale deployments.

@h3rbst
Copy link

h3rbst commented Apr 17, 2021

Is this possible with just Google OAuth aswell? Can't get it working, I just get 404 after the Login Page with Google. Redirect URL is not resolved to the correct Host

@Secarius
Copy link

any update on when this will be pushed into the master?

@Rob-Powell
Copy link

Rob-Powell commented May 17, 2021

Docker Image for build 3 is available on DockerHub as jc21/nginx-proxy-manager:github-pr-753

Can we get this merged soon @jc21? Do you need more help testing it or something?

@sash2222
Copy link

Please merge!

@jozefKruszynski
Copy link

I'm really not sure that this is ready to be merged. There are many errors in the logs when running this and the behaviour of the redirect is not stable.
I honestly think more work on this is needed.

@jc21 jc21 added the requires-verification Waiting for one or more people to confirm the fix label May 30, 2021
@natoleet
Copy link

natoleet commented Jun 7, 2021

What is stopping this from being merged and what are the errors?

@micudaj
Copy link

micudaj commented Jul 23, 2021

I would also like to use this feature in order to switch from apache to nginx-proxy-manager.
When I try to change my running latest version 2.9.5 to jc21/nginx-proxy-manager:github-pr-753 it does not work, probably because it is based on 2.8.0.

@micudaj
Copy link

micudaj commented Jul 23, 2021

in case anyone wants to try this on latest version 2.9.5. I merged it into tag 2.9.5 and created a docker image out of it. you can find it here: https://hub.docker.com/repository/docker/knitze/nginx-proxy-manager
Version on login screen shows version 0.0.0, but it is 2.9.5. Maybe someone can tell me how change this.
One thing to note: If you are upgrading an existing database, you get an internal error when adding additional hosts. I fixed it by setting the default value for the new openid_* fields in the table proxy_host to empty string.

@jc21
Copy link
Member

jc21 commented Sep 8, 2021

Closing this PR in favour of #1388, using branches from this project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
requires-verification Waiting for one or more people to confirm the fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.