OAuth2 Proxy allows you to set up an OAuth login in front of your existing web services providing you with a secure means of user authentication.

I had previously setup all my web applications to be accessed through Linux Server’s Let’s Encrypt NGINX reverse proxy container. This gave me security in the form of SSL and nice URL’s to access my services with but I still wanted a better and more reliable solution to login to said services. I trust OAuth a lot more than I trust the included login forms with my services such as Radarr and Sonarr.

OAuth2 Proxy works with several authentication services such as GitHub and Facebook, however, in this tutorial, I will be focusing on using google. These instructions, however, can be mostly followed with a couple changes if you wish to use a different authenticator. More details about OAuth2 Proxy and its authenticators can be found on it’s GitHub page.

My NGINX reverse proxy is currently set up to use a subdomain for each service I use. For example, I can get to Sonarr at sonarr.domain.com and Plex at plex.domain.com. If your proxy is not set up this way then you may need to make some changes with the NGINX configs I use but the premise should be similar. Final note, although this tutorial is tailored for use with unRAID, you should be able to follow most instructions with slight tweaks for other systems. Now to get started.

Get your NGINX reverse proxy setup. There are plenty of tutorials online to show you how to do this. I may write one in the future but as of now, I have not.

Head to the community apps tab in the unRAID GUI.

Search for OAuth2 Proxy and click install.

At this stage, you shouldn’t need to change any settings. You can change the location to store the app data if you wish. You can also change the port if you have a clash, however, take note of what you change it to as you will need to apply this in the OAuth2 config as well.

Once you are happy with the settings, click Apply.

The container will install and once complete you can click Done.

You will probably now notice that the container is not running. This is normal. The configuration file has not be completed and thus the container will not start.

Now it’s time to setup your OAuth configuration with Google. Other auth providers are available but I'm not covering them in these instructions.

Google Oauth Setup

  1. Create a new project here: https://console.developers.google.com/project

  2. Make sure the project is selected in the drop-down menu next to the Google Cloud Platform logo in the top bar.

  3. In the project Dashboard centre pane (found here), choose “API Manager“

  4. In the left Nav pane, choose “Credentials“

  5. In the centre pane, choose the “OAuth consent screen” tab. Fill in “Product name shown to users” (it doesn’t matter what it is) and hit save.

  6. In the centre pane, choose “Credentials” tab.

    • Open the “New credentials” drop down
    • Choose “OAuth client ID”
    • Choose “Web application”
    • Application name is freeform, choose something appropriate
    • Authorized JavaScript origins is your domain ex: https://internal.yourcompany.com
    • Authorized redirect URIs is the location of oauth2/callback ex: https://internal.yourcompany.com/oauth2/callback

    You will need one JavaScript origin and one redirect URI for each service you plan to authenticate with OAuth. It will look something like this, but mine is already setup so ymmv!

2019-01-26-19_13_23-OAuth-client---oauth2-proxy---Google-API-Console

  1. Take note of the Client ID and Client Secret
    Now its time to go back and configure the OAuth2 Proxy

OAuth2 Proxy Setup

  1. Open up the folder for the OAuth2 app data. By default its appdata\oauth2
  2. Create a file named oauth2_proxy.cfg and open it in your favorite text editor, Notepad++ 😉, and paste the following in it:
## OAuth2 Proxy Config File
## https://github.com/cheesemarathon/oAuth2-Proxy-Docker-Container

## <addr>:<port> to listen on for HTTP/HTTPS clients
http_address = "0.0.0.0:4180"

## the http url(s) of the upstream endpoint. If multiple, routing is based on path
upstreams = [
     "http://127.0.0.1:4180/oauth2/login"
]

## Log requests to stdout
request_logging = true

## The OAuth Client ID, Secret
client_id = ""
client_secret = ""

## Authenticated Email Addresses File (one email per line)
authenticated_emails_file = "/etc/oauth2/emails.cfg"

## Templates
## optional directory with custom sign_in.html and error.html
# custom_templates_dir = "/etc/oauth2/templates/"

## Cookie Settings
## Name     - the cookie name
## Secret   - the seed string for secure cookies; should be 16, 24, or 32 bytes
##            for use with an AES cipher when cookie_refresh or pass_access_token
##            is set
## Domain   - (optional) cookie domain to force cookies to (ie: .yourcompany.com)
## Expire   - (duration) expire timeframe for cookie
## Refresh  - (duration) refresh the cookie when duration has elapsed after cookie was initially set.
##            Should be less than cookie_expire; set to 0 to disable.
##            On refresh, OAuth token is re-validated. 
##            (ie: 1h means tokens are refreshed on request 1hr+ after it was set)
## Secure   - secure cookies are only sent by the browser of a HTTPS connection (recommended)
## HttpOnly - httponly cookies are not readable by javascript (recommended)
cookie_name = "_oauth2_proxy"
cookie_secret = ""
cookie_domain = ""
cookie_expire = "168h"
cookie_refresh = "1h"
cookie_secure = true
cookie_httponly = true
  1. First you want to fill in lines 16 and 17 with your client ID and secret respectively, that you generated at the Google Cloud Platform site.
  2. Next, go to this encryption key generator and create a 128-bit encryption key and copy it.
  3. Paste this between the quotation makes on line 36 of the config file
  4. On the line below, enter your domain name e.g. domain.com
  5. Save and close this file
  6. Now in the same folder create a file named emails.cfg and open it
  7. Enter the email addresses associated with the Google accounts you want to be able to log in. One email per line.
  8. Save and close this file
  9. Start the container

The final step is to configure NGINX. All you need to edit is the site conf for each domain you wish to authenticate. I have one file per subdomain I use to make management easier, however, this is not compulsory. All you need to do is take the config below and change the listen domain and the proxy address. Any special settings you have for a service may need to be copied over as well.

server {
 
listen 80;
 
# Change this to the URL (no HTTP part) of your service
 
server_name service.domain.com;
 
return 301 https://$server_name$request_uri;
 
}
 
 
 
server {
 
listen 443 ssl;
 
# Change this to the URL (no http part) of your service
 
server_name service.domain.com;
 
 
 
ssl on;
 
ssl_certificate /config/keys/letsencrypt/fullchain.pem;
 
ssl_certificate_key /config/keys/letsencrypt/privkey.pem;
 
ssl_prefer_server_ciphers on;
 
add_header Strict-Transport-Security max-age=2592000;
 
 
 
location /oauth2/ {
 
proxy_pass       http://unRAIDip:4180;
 
proxy_set_header Host                    $host;
 
proxy_set_header X-Real-IP               $remote_addr;
 
proxy_set_header X-Scheme                $scheme;
 
proxy_set_header X-Auth-Request-Redirect $request_uri;
 
}
 
location = /oauth2/auth {
 
proxy_pass       http://unRAIDip:4180;
 
proxy_set_header Host             $host;
 
proxy_set_header X-Real-IP        $remote_addr;
 
proxy_set_header X-Scheme         $scheme;
 
# nginx auth_request includes headers but not body
 
proxy_set_header Content-Length   "";
 
proxy_pass_request_body           off;
 
}
 
 
 
location / {
 
auth_request /oauth2/auth;
 
error_page 401 = /oauth2/sign_in;
 
 
 
# pass information via X-User and X-Email headers to backend,
 
# requires running with --set-xauthrequest flag
 
auth_request_set $user   $upstream_http_x_auth_request_user;
 
auth_request_set $email  $upstream_http_x_auth_request_email;
 
proxy_set_header X-User  $user;
 
proxy_set_header X-Email $email;
 
 
 
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
 
auth_request_set $auth_cookie $upstream_http_set_cookie;
 
add_header Set-Cookie $auth_cookie;
 
 
 
# Change this to the internal IP and port of your service
 
proxy_pass http://0.0.0.0:9999/;
 
}
 
}