在Nginx子域中使用Oauth2-Proxy

简介
当涉及到保护网络应用程序或API的安全时,最广泛使用的方法之一是OAuth 2.0。OAuth 2.0是一个授权框架,为用户提供了一种无需分享他们的凭证就能授权访问资源的方法。这是通过使用访问令牌来实现的,访问令牌是由授权服务器在用户授予客户端应用程序权限后发出的。在Web服务器环境中实现OAuth 2.0的一个流行工具是oauth2-proxy。在这篇博文中,我们将探讨如何用docker设置oauth2-proxy,并与nginx子域一起使用,以便为我们的Web应用增加一个额外的安全层。
在前进之前,首先选择你的认证供应商,oauth2-proxy支持以下认证供应商。
- 谷歌
- 蔚蓝
- ADFS
- 脸书
- GitHub
- 钥匙环
- 淘宝网
- ǞǞǞ
- 微软Azure AD
- OpenID连接
- login.gov
- 翌云
- 数字海洋(DigitalOcean)
- 淘宝网上有一个叫Bitbucket的网站。
- 吉蒂亚
我使用GitHub作为认证提供者,有GitHub的用户,所以只有提供的GitHub用户可以认证应用程序。
oauth2-proxy配置文件必须包含连接到认证提供者的必要信息,如客户端ID和秘密。我们还需要指定重定向URL,即认证提供者在认证后应将用户重定向到的URL。要创建这些,请遵循以下步骤。
- 创建一个新项目:https://github.com/settings/developers
- 主页网址:https://auth.yourdomain.com
- 在授权回调URL下输入正确的URL,即https://auth.yourdomain.com/oauth2/callback。
在Docker上设置Oauth2-Proxy
# 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
设置演示应用程序
在这个演示中,我们将设置两个很酷的自我托管的应用程序
- Linkding - 一个简单的书签管理器
- Cyber-Chef - 网络瑞士军刀 - 一个用于加密、编码、压缩和数据分析的网络应用程序
# 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
设置Nginx作为反向代理
# 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
为oauth2-proxy和演示应用程序创建一个nginx conf文件
----/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
现在在
https://linkding.yourdomain.com &
https://cyberchef.yourdomain.com 上测试你的应用程序。
总结
在Nginx子域中使用oauth2-proxy是一种强大的方式,可以为你的网络应用添加额外的安全层。通过要求对所有的请求进行认证,你可以确保只有授权用户才能访问你的资源。此外,oauth2-proxy提供了一个简单和易于使用的界面,用于在Web服务器环境中使用OAuth 2.0。如果你想保护你的网络应用,可以考虑使用oauth2-proxy。