diff --git a/.gitignore b/.gitignore index 40ddbcd..c1165aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ .DS_Store .claude/ +nginx-local.conf +docker-compose.local.yml +certs/ +conf.d.sso-backup/ diff --git a/conf.d/assets-ai.conf b/conf.d/assets-ai.conf index 908cf17..30d5d46 100644 --- a/conf.d/assets-ai.conf +++ b/conf.d/assets-ai.conf @@ -5,11 +5,45 @@ server { ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem; + # Authelia 认证端点(internal = 仅子请求可访问) + location /authelia-auth { + internal; + proxy_pass http://authelia:9091/api/authz/auth-request; + proxy_set_header Cookie $http_cookie; + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-URI $request_uri; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + } + location / { - proxy_pass http://assets-ai:3000; + auth_request /authelia-auth; + + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + + proxy_set_header X-Remote-User $user; + proxy_set_header X-Remote-Groups $groups; + proxy_set_header X-Auth-Proxy-Key "internal-auth-key-tlyq-2026"; + proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://assets-ai:3000; + } + + error_page 401 =302 https://sso.tlyq.ai/?rd=$scheme://$http_host$request_uri; + error_page 502 503 = @fallback; + + location @fallback { + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://assets-ai:3000; } } diff --git a/conf.d/git-ai.conf b/conf.d/git-ai.conf index 5310b65..5157ac8 100644 --- a/conf.d/git-ai.conf +++ b/conf.d/git-ai.conf @@ -5,6 +5,7 @@ server { ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem; + # Gitea 通过 OIDC 认证,不走 auth_request,只需基本反向代理 location / { proxy_pass http://gitea-ai:3000; proxy_set_header Host $host; diff --git a/conf.d/issue-ai.conf b/conf.d/issue-ai.conf index 452cc2b..e703bd9 100644 --- a/conf.d/issue-ai.conf +++ b/conf.d/issue-ai.conf @@ -5,11 +5,45 @@ server { ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem; + # Authelia 认证端点(internal = 仅子请求可访问) + location /authelia-auth { + internal; + proxy_pass http://authelia:9091/api/authz/auth-request; + proxy_set_header Cookie $http_cookie; + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-URI $request_uri; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + } + location / { - proxy_pass http://issue-ai:3000; + auth_request /authelia-auth; + + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + + proxy_set_header X-Remote-User $user; + proxy_set_header X-Remote-Groups $groups; + proxy_set_header X-Auth-Proxy-Key "internal-auth-key-tlyq-2026"; + proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://issue-ai:3000; + } + + error_page 401 =302 https://sso.tlyq.ai/?rd=$scheme://$http_host$request_uri; + error_page 502 503 = @fallback; + + location @fallback { + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://issue-ai:3000; } } diff --git a/conf.d/sso-ai.conf b/conf.d/sso-ai.conf new file mode 100644 index 0000000..81ef68e --- /dev/null +++ b/conf.d/sso-ai.conf @@ -0,0 +1,23 @@ +server { + listen 443 ssl; + server_name sso.tlyq.ai; + + ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem; + + # 登录接口限流 + location /api/firstfactor { + limit_req zone=sso_login burst=3 nodelay; + proxy_pass http://authelia:9091; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location / { + proxy_pass http://authelia:9091; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + } +} diff --git a/nginx.conf b/nginx.conf index 6914273..62f6da0 100644 --- a/nginx.conf +++ b/nginx.conf @@ -3,6 +3,9 @@ events {} http { include /etc/nginx/conf.d/*.conf; + # SSO 登录限流:按真实客户端 IP(X-Forwarded-For),每分钟 5 次,burst 3 + limit_req_zone $http_x_forwarded_for zone=sso_login:10m rate=5r/m; + # 所有 HTTP 自动跳 HTTPS server { listen 80 default_server;