Files
wecom_it_smart_desk/deploy-server/nginx/nginx.conf
T

219 lines
9.7 KiB
Nginx Configuration File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# 企微智能IT支持服务台 — Nginx 配置(公司内网服务器版)
# =============================================================================
# 适用场景:独立域名 itsupport.servyou.com.cn,公司内网 DNS 解析
# 与 NAS 版的区别:
# 1. 移除 Cloudflare 相关头(X-Forwarded-Proto https 等)
# 2. server_name 改为正式域名
# 3. 真实 IP 直接从 $remote_addr 获取(无 CF 代理层)
# 4. 预留 HTTPS 配置注释(如公司有统一 SSL 终端)
# =============================================================================
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# ------------------------------------------------------------------
# 日志格式
# ------------------------------------------------------------------
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# ------------------------------------------------------------------
# 真实 IP 还原(2026-06-15 v0.5.1 修复)
# ------------------------------------------------------------------
set_real_ip_from 10.0.0.0/8; # 内网 A 类(代理/WAF 出口)
set_real_ip_from 172.16.0.0/12; # 内网 B 类
set_real_ip_from 192.168.0.0/16; # 内网 C 类
set_real_ip_from 10.212.0.0/16; # VPN 网段
real_ip_header X-Forwarded-For; # 从 X-Forwarded-For 取最后一个非信任 IP
real_ip_recursive on; # 递归剥离已信任代理 IP
# ------------------------------------------------------------------
# 基础配置
# ------------------------------------------------------------------
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 50m;
# ------------------------------------------------------------------
# Gzip 压缩(前端静态资源)
# ------------------------------------------------------------------
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/xml+rss
application/json application/ld+json;
# =================================================================
# 上游服务定义(Docker 内部网络)
# =================================================================
upstream backend_api {
server backend:8000;
}
# =================================================================
# HTTP 服务(监听 80 端口)
# =================================================================
server {
listen 80;
server_name itsupport.servyou.com.cn;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
# H5 静态文件服务
location /h5/ {
root /usr/share/nginx/html;
index index.html;
try_files $uri /h5/index.html;
}
# H5 API 反向代理
location /h5/api/ {
proxy_pass http://backend:8000/;
proxy_http_version 1.1;
proxy_redirect off;
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 $scheme;
proxy_set_header Connection "";
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
location / {
return 301 https://$host$request_uri;
}
}
# =================================================================
# HTTPS — 443 端口(主服务)
# =================================================================
server {
listen 443 ssl;
http2 on;
server_name itsupport.servyou.com.cn;
ssl_certificate /etc/nginx/ssl/itsupport.servyou.com.cn.crt;
ssl_certificate_key /etc/nginx/ssl/itsupport.servyou.com.cn.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://res.wx.qq.com; style-src 'self' 'unsafe-inline' https://res.wx.qq.com https://at.alicdn.com; connect-src 'self' wss://itsupport.servyou.com.cn https://itsupport.servyou.com.cn https://qyapi.weixin.qq.com; img-src 'self' data: https://res.wx.qq.com; font-src 'self' data: https://at.alicdn.com;" always;
# 修复:microphone=() 完全禁用麦克风,导致坐席端 Web Speech API 无法使用
# 改为 microphone=(self) 允许同源页面使用麦克风(浏览器仍会弹窗询问用户)
add_header Permissions-Policy "camera=(), microphone=(self), geolocation=(), payment=()" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
# 修复:COEP require-corp 阻止加载企微 JS-SDK 跨域脚本(res.wx.qq.com 不发 CORP 头)
# 本应用不使用 SharedArrayBuffer / cross-origin isolation,移除 COEP 不影响功能
# add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
server_tokens off;
location = /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 员工端:/itdesk/ -> 重定向到 /h5/H5 员工端)
location /itdesk/ {
return 301 /h5/;
}
location /itagent/ {
alias /usr/share/nginx/html/itagent/;
index index.html;
try_files $uri $uri/ /itagent/index.html;
}
location /itadmin/ {
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
allow 10.212.0.0/16;
allow 10.240.0.0/16;
allow 117.147.35.138;
allow 218.75.34.87;
allow 43.174.152.34;
#deny all;
alias /usr/share/nginx/html/itadmin/;
index index.html;
try_files $uri /itadmin/index.html;
}
location /itportal/ {
alias /usr/share/nginx/html/itportal/;
index index.html;
try_files $uri /itportal/index.html;
}
location /api/ {
location ~ ^/api/admin/ {
# 修复:剥离 /api/ 前缀,使后端收到 /admin/... 而非 /api/admin/...
rewrite ^/api/(.*)$ /$1 break;
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
allow 10.212.0.0/16;
#deny all;
proxy_pass http://backend_api;
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 $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
proxy_pass http://backend_api/;
proxy_http_version 1.1;
proxy_redirect off;
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 $scheme;
proxy_set_header Connection "";
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
location /ws/ {
access_log off;
proxy_pass http://backend_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 86400s;
}
# H5 静态文件服务
location /h5/ {
root /usr/share/nginx/html;
index index.html;
try_files $uri /h5/index.html;
}
# H5 API 反向代理
location /h5/api/ {
proxy_pass http://backend:8000/;
proxy_http_version 1.1;
proxy_redirect off;
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 $scheme;
proxy_set_header Connection "";
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
location = / {
return 302 /itagent/;
}
}
}