在Nginx子域中使用Oauth2-Proxy

100人浏览   2024-08-15 12:17:19

简介

当涉及到保护网络应用程序或API的安全时,最广泛使用的方法之一是OAuth 2.0。OAuth 2.0是一个授权框架,为用户提供了一种无需分享他们的凭证就能授权访问资源的方法。这是通过使用访问令牌来实现的,访问令牌是由授权服务器在用户授予客户端应用程序权限后发出的。在Web服务器环境中实现OAuth 2.0的一个流行工具是oauth2-proxy。在这篇博文中,我们将探讨如何用docker设置oauth2-proxy,并与nginx子域一起使用,以便为我们的Web应用增加一个额外的安全层。

在前进之前,首先选择你的认证供应商,oauth2-proxy支持以下认证供应商。

  1. 谷歌
  2. 蔚蓝
  3. ADFS
  4. 脸书
  5. GitHub
  6. 钥匙环
  7. 淘宝网
  8. ǞǞǞ
  9. 微软Azure AD
  10. OpenID连接
  11. login.gov
  12. 翌云
  13. 数字海洋(DigitalOcean)
  14. 淘宝网上有一个叫Bitbucket的网站。
  15. 吉蒂亚

我使用GitHub作为认证提供者,有GitHub的用户,所以只有提供的GitHub用户可以认证应用程序。

oauth2-proxy配置文件必须包含连接到认证提供者的必要信息,如客户端ID和秘密。我们还需要指定重定向URL,即认证提供者在认证后应将用户重定向到的URL。要创建这些,请遵循以下步骤。

  1. 创建一个新项目:https://github.com/settings/developers
  2. 主页网址:https://auth.yourdomain.com
  3. 在授权回调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

设置演示应用程序

在这个演示中,我们将设置两个很酷的自我托管的应用程序

  1. Linkding - 一个简单的书签管理器
  2. 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。

相关推荐