Using Oauth2-Proxy with Nginx Subdomains

Akash Rajvanshi
DevOps Dudes
Published in
4 min readFeb 27, 2023
oauth2-proxy

Introduction

When it comes to securing web applications or APIs, one of the most widely used methods is OAuth 2.0. OAuth 2.0 is an authorization framework that provides a way for users to grant access to resources without sharing their credentials. This is done by using access tokens, which are issued by an authorization server after the user grants permission to a client application. One popular tool for implementing OAuth 2.0 in a web server environment is oauth2-proxy. In this blog post, we will explore how to setup oauth2-proxy with docker and use with nginx subdomains, in order to add an extra layer of security to our web applications.

Before moving forward select your authentication provider first, oauth2-proxy support below providers for authentication:

I’m using GitHub as an authentication provider with GitHub users, so only provided GitHub users can authenticate to applications.

The oauth2-proxy configuration file must contain the necessary information to connect to the authentication provider, such as the client ID and secret. We also need to specify the redirect URL, which is the URL to which the authentication provider should redirect the user after authentication. To create these, follow the below steps:

  1. Create a new project: https://github.com/settings/developers
  2. Homepage URL: https://auth.yourdomain.com
  3. Under Authorization callback URL enter the correct url ie https://auth.yourdomain.com/oauth2/callback

Setting up Oauth2-Proxy on Docker

# Create Cookie Secret

# using python
python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())'
fLIblJsthbMhgELnmpqrCbWQD9P1vyDfI5SAs8BUG6c=

# using bash
dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo
---docker-compose.yml

version: '3.3'

services:
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy
container_name: oauth2-proxy
restart: always
networks:
- proxy
command:
- --http-address
- 0.0.0.0:4180
- --cookie-domain
- yourdomain.com
- --whitelist-domain=*.yourdomain.com
environment:
- OAUTH2_PROXY_COOKIE_SECRET=fLIblJsthbMhgELnmpqrCbWQD9P1vyDfI5SAs8BUG6c=
- OAUTH2_PROXY_CLIENT_ID=
- OAUTH2_PROXY_CLIENT_SECRET=
- OAUTH2_PROXY_PROVIDER=github
- OAUTH2_PROXY_EMAIL_DOMAINS=*
- OAUTH2_PROXY_GITHUB_USER="github_username"
- OAUTH2_PROXY_REDIRECT_URL=https://auth.yourdomain.com/oauth2/callback
- OAUTH2_PROXY_HTTP_ADDRESS=0.0.0.0:4180
- OAUTH2_PROXY_COOKIE_DOMAINS=yourdomain.com
- OAUTH2_PROXY_SESSION_STORE_TYPE=cookie
- OAUTH2_PROXY_COOKIE_SAMESITE=lax
- OAUTH2_PROXY_REVERSE_PROXY=true
- OAUTH2_PROXY_COOKIE_CSRF_PER_REQUEST=true
- OAUTH2_PROXY_COOKIE_CSRF_EXPIRE=5m
- OAUTH2_PROXY_SCOPE=user:email
- OAUTH2_PROXY_SKIP_PROVIDER_BUTTON=false
- OAUTH2_PROXY_PASS_USER_HEADERS=true
- OAUTH2_PROXY_SET_XAUTHREQUEST=true
ports:
- 4180:4180
- 8080:8080
networks:
proxy:
external: true
---

# start the stack
# docker compose up -d

Setup Demo Applications

For this demo we are setting up two cool self-hosted applications

  • Linkding — A simple Bookmark Manager
  • Cyber-Chef — The Cyber Swiss Army Knife — a web app for encryption, encoding, compression and data analysis

# 1. Linkding
---
version: '3.3'

services:
linkding:
image: sissbruecker/linkding
container_name: linkding
restart: always
networks:
- proxy
volumes:
- /home/user/homelab/linkding/data:/etc/linkding/data
ports:
- 5500:9090

networks:
proxy:
external: true
---


# 2. Cyberchef
---
version: '3.3'
services:
cyberchef:
image: mpepping/cyberchef
container_name: cyberchef
restart: always
networks:
- proxy
ports:
- 5000:8000

networks:
proxy:
external: true
---

# docker compose -f linkding.yaml -f cyberchef.yaml up -d
# Cyberchef: PORT - 5000
# Linkding: PORT - 5500

Setup Nginx As Reverse Proxy

# install nginx
sudo apt install nginx

# setup these A records for your domain first
A @ SERVER_IP
A auth SERVER_IP
A cyberchef SERVER_IP
A linkding SERVER_IP
cname www yourdomain.com

# install certbot
sudo apt install certbot python3-certbot-nginx

# request for wildcard ssl cert or request certs for few subdomains like below:
sudo certbot certonly --nginx -d yourdomain.com -d www.yourdomain.com -d cyberchef.yourdomain.com -d linkding.yourdomain.com -d auth.yourdomain.com

Create a nginx conf files for oauth2-proxy and demo applications

----/etc/nginx/conf.d/oauth2.conf

server {
listen 443 ssl http2;
server_name auth.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

location /oauth2/ {
proxy_pass http://Internal_IP: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 $scheme://$host$request_uri;
}

location /oauth2/auth {
proxy_pass http://Internal_IP:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}

location / {
try_files $uri $uri/ =404;
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in?rd=https://$host$request_uri;
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;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
}
}
---

---/etc/nginx/conf.d/linkding.conf
server {

listen 443 ssl http2;
server_name linkding.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

location / {
proxy_pass http://Internal_IP:5500;
proxy_set_header Host $host;
#proxy_redirect off;
#proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Auth-Request-Redirect $request_uri;

auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in?rd=https://$host$request_uri;
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;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
}

location /oauth2/ {
proxy_pass http://Internal_IP: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;
}
}

server {
listen 80;
server_name linkding.yourdomain.com;
return 301 https://$host$request_uri;
}
---


---/etc/nginx/conf.d/cyberchef.conf
server {
listen 443 ssl http2;
server_name cyberchef.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

location / {
proxy_pass http://Internal_IP:5000;
proxy_set_header Host $host;
#proxy_redirect off;
#proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Auth-Request-Redirect $request_uri;

auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in?rd=https://$host$request_uri;
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;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
}


location /oauth2/ {
proxy_pass http://Internal_IP: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;
}
}

server {
listen 80;
server_name cyberchef.yourdomain.com;
return 301 https://$host$request_uri;
}
---
sudo systemctl enable nginx
sudo nginx -s reload

Now test your applications on https://linkding.yourdomain.com & https://cyberchef.yourdomain.com

Conclusion

Using oauth2-proxy with Nginx subdomains is a powerful way to add an extra layer of security to your web applications. By requiring authentication for all requests, you can ensure that only authorized users have access to your resources. Additionally, oauth2-proxy provides a simple and easy-to-use interface for working with OAuth 2.0 in a web server environment. If you are looking to secure your web applications, consider using oauth2-proxy.

Find something useful? Hold down the 👏 to support and help others find this article. Thanks for reading!!

Follow me on Twitter @akash_Rajvanshi

--

--