Nginx容器配置

大约 4 分钟

Nginx容器配置

作 者: Luke

日 期: 2022-10-14

背景

承接资源对外映射的入口,安全性、稳定性、功能要求下的典型使用范例记录

更多配置参见: Nginx官网open in new window

安全防护配置

防止使用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;
}
上次编辑于:
贡献者: lu_feng,luke