Nginx容器配置
大约 4 分钟
Nginx容器配置
作 者: Luke
日 期: 2022-10-14
背景
承接资源对外映射的入口,安全性、稳定性、功能要求下的典型使用范例记录
更多配置参见: Nginx官网
安全防护配置
防止使用IP地址访问,刺探出访问的域名信息
server {
listen 443 default_server;
server_name _;
# 直接拒绝握手, 需要1.19以上版本支持
ssl_reject_handshake on;
}
server {
listen 80 default_server;
server_name _;
# 403 forbidden
return 403;
}
常用配置
server {
listen 80;
keepalive_timeout 300;
server_name your.example.com;
index index.php index.html index.htm default.php default.htm default.html;
root /usr/share/nginx/html;
charset utf-8;
#请求body的最大尺寸
client_max_body_size 100M;
#打开非标Header参数
underscores_in_headers on;
#HTTP_TO_HTTPS_END
listen 443 ssl;
ssl_certificate /usr/share/certs/your.example.com.pem;
ssl_certificate_key /usr/share/certs/your.example.com.key;
#处于安全考虑,最低支持TLS1.2
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
#如果ssl协议支持tlsv1 tls1.1这种老协议,设置为 on ,并配合ssl_ciphers使用
#如果ssl协议只支持tlsv1.2 tlsv1.3新协议,设置为 off (nginx默认为off),因为新协议不再采纳此参数
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
#SSL-END
#拦截根请求,客户端重定向,以status=302返回
rewrite ^/$ https://$host$1/portal permanent;
#拦截匹配Path,客户端重定向,以status=301返回
rewrite ^/admin(.*) https://$host$1/portal redirect;
#拦截匹配Path,客户端重定向,拼接成Hash方式
rewrite ^/portal/tfs/exchange(.*)$ /portal/index.html#/tfs/exchange$1 permanent;
#针对静态资源访问,添加缓存设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
error_log /dev/null;
access_log off;
}
location ~ .*\.(js|css)?$ {
expires 12h;
error_log /dev/null;
access_log off;
}
#面向后端服务,使用代理转发
location /api {
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
#严格模式下,限制站点不允许被其他网站嵌套使用
add_header X-Frame-Options SAMEORIGIN;
#add_header Access-Control-Allow-Origin https://your.example.com;
add_header X-Content-Type-Options nosniff;
#add_header Content-Security-Policy "default-src 'self';";
add_header X-Permitted-Cross-Domain-Policies master-only;
add_header Referrer-Policy same-origin;
#缓存策略忽略
add_header Cache-Control 'no-cache, no-store, must-revalidate';
#透传用户请求域名与IP等信息
proxy_set_header Host $http_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 10s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
#内网服务地址
proxy_pass http://localhost:8081/api;
}
条件转发
# 全局参数设置,根据 referer判断
map $http_referer $is_referer_match {
default 0;
"~KEYWORDS" 1;
}
server {
# 匹配location条件,/cdn/
# 若1, 匹配Refer条件,则,重写地址后,继续执行 其他Location
# 若2, 匹配本地文件,则,直接返回文件内容
# 若3, 以上均失败,则,转发至 Proxy Location
location /cdn/ {
if ($is_referer_match) {
rewrite ^/cdn/(.*)$ /nocache/$1 last;
}
alias /var/www/example.woodare.com/cdn/;
try_files $uri @cdn_fetch;
}
# 其他Location
location /nocache/ {
rewrite ^/nocache/(.*)$ /download?path=$1 break;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://127.0.0.1:8080;
}
# Proxy Location
location @cdn_fetch {
# 重写URL地址,
rewrite ^/cdn/(.*)$ /download?path=$1 break;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://127.0.0.1:8080;
}
# 根据传入参数进行路由分发
location /portal {
# 匹配Get参数后,客户端重定向
if ($args ~ "state=qa_(.*)") {
rewrite ^/portal/exchange(.*)$ https://example.woodare.com/portal/index.html#/qa/exchange$1 permanent;
}
# 默认动作,指向本地新路径
rewrite ^/portal/exchange(.*)$ /portal/index.html#/prod/exchange$1 permanent;
}
}
特殊配置
server {
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md) {
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
#WebSocket映射
location / {
#透传http1.1协议
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#转发配置参照如上
}
#https代理映射
location / {
proxy_ssl_server_name on;
proxy_redirect off;
proxy_pass https://example.com/;
}
#开启history模式,非静态文件指向index.html
location /alias/ {
index index.html index.html;
alias /usr/share/nginx/html/alias;
try_files $uri $uri/ /alias/index.html;
# 针对html请求不返回缓存信息
if ($request_filename ~* .*\.(?:htm|html)$) {
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
}
#过滤静态文件,不存在时指向代理服务
location / {
root /usr/share/nginx/html;
try_files $uri @gofly;
}
location @gofly {
#Set Nginx Cache
add_header Cache-Control no-cache;
add_header X-Cache $upstream_cache_status;
# 内网服务地址
proxy_pass http://127.0.0.1:8081;
}
}
负载均衡
#多节点服务
upstream balance.gfly {
server 192.168.1.100:8080 weight=1;
server 192.168.1.101:8080 weight=1;
#绑定Cookies方式
sticky;
#ip_hash;
}
server {
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
# add_header Content-Security-Policy "default-src 'self';";
add_header X-Permitted-Cross-Domain-Policies master-only;
add_header Referrer-Policy same-origin;
rewrite ^/$ /index.html;
location = /index.html {
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
root /usr/share/nginx/html;
}
location / {
proxy_set_header Host $http_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_intercept_errors on;
proxy_read_timeout 300s;
#指向多节点服务
proxy_pass http://balance.qypy.prod;
}
}
跨域配置
add_header Access-Control-Allow-Origin '$http_origin';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, PATCH, DELETE';
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers '$http_access_control_request_headers';
if ($request_method = OPTIONS) {
return 200;
}
