####### nginx.conf
user www www;
worker_processes auto;
worker_cpu_affinity auto;
error_log /home/wwwlogs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events {
use epoll;
worker_connections 51200;
multi_accept off;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 100m; # 文件上传大小限制
client_body_buffer_size 32k; # 超过时日志 $request_body 将为空,过大占用存储空间
sendfile on;
sendfile_max_chunk 512k;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
server_tokens off; # 关闭版本号
# access_log off; # 关闭日志
# 先定义日志格式,logf 是日志格式的名字
log_format logf '[$time_local] $remote_addr "$request" $status $body_bytes_sent $request_body "$http_referer" "$http_user_agent"';
access_log /package/log/access.log logf;
# 引用配置文件
include vhost/*.conf;
}
####### 日志
http {
# 定义日志格式
log_format main_json escape=json '{'
'"time_local": "$time_local", '
'"remote_addr": "$remote_addr", ' # client IP
'"status": "$status", ' # response status code
'"http_host": "$http_host", ' # request host
'"request_method": "$request_method", ' # request method
'"request_uri": "$request_uri", ' # full path and arguments if the request
'"request_body": "$request_body", ' # request body
'"request_length": "$request_length", ' # request length (including headers and body)
'"body_bytes_sent": "$body_bytes_sent", ' # the number of body bytes exclude headers sent to a client
'"bytes_sent": "$bytes_sent", ' # the number of bytes sent to a client
'"http_referer": "$http_referer", ' # HTTP referer
'"http_user_agent": "$http_user_agent", ' # user agent
'"http_x_forwarded_for": "$http_x_forwarded_for", ' # http_x_forwarded_for
'"request_time": "$request_time", ' # request processing time in seconds with msec resolution
'"upstream_response_time": "$upstream_response_time", ' # time spend receiving upstream body
'"upstream_response_length": "$upstream_response_length", ' # upstream response length
'"ssl_protocol": "$ssl_protocol", ' # TLS protocol
'"ssl_cipher": "$ssl_cipher", ' # TLS cipher
'"scheme": "$scheme", ' # http or https
'"server_protocol": "$server_protocol", ' # request protocol, like HTTP/1.1 or HTTP/2.0
'"gzip_ratio": "$gzip_ratio"'
'}';
access_log /package/access.json main_json; # 存储位置
# 定义日志格式,logf 是日志格式的名字
log_format logf '[$time_local] "$remote_addr" "$host" "$request" '
'$status $body_bytes_sent $request_body "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /package/access.log logf; # 存储位置
# access_log off; # 关闭日志
}
####### 端口转发,322 => 192.168.1.188:22
stream {
server {
listen 322;
proxy_pass 192.168.1.188:22;
}
}
####### HTTP => HTTPS
server {
listen 80;
server_name *.netnr.com;
return 301 https://$host$request_uri;
}
####### HTTP => HTTPS 非默认端口,自动跳转
server {
listen 8080 ssl http2;
listen [::]:8080 ssl http2;
server_name *.netnr.com;
error_page 497 https://$host$request_uri; # http => https 默认 302 临时
error_page 497 =301 https://$host$request_uri; # 301 永久
error_page 497 =307 https://$host$request_uri; # 临时重定向,不改变请求的方法(如post还是post)
}
####### proxy_method 改变到上游的请求方式
location = /path/api/list_post {
proxy_method GET; # 指定到上游的请求方式
proxy_pass http://192.168.7.13:713$request_uri;
}
####### @ => www
server {
listen 80;
server_name netnr.com;
rewrite ^(.*) $scheme://www.$host$1 permanent;
}
####### IPv6
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name netnr.com;
# SSL
ssl_certificate /package/ssl/netnr.com/fullchain.cer;
ssl_certificate_key /package/ssl/netnr.com/private.key;
# ...
}
####### SSL 证书
server {
# add_header Strict-Transport-Security "max-age=31536000";
ssl_certificate /package/ssl/netnr.com/fullchain.cer;
ssl_certificate_key /package/ssl/netnr.com/private.key;
ssl_session_timeout 60m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
}
####### 自定义错误 404 503
server {
proxy_intercept_errors on;
# 错误4
error_page 403 404 408 413 414 /404.html;
location /404.html {
root html;
}
# 错误5
error_page 500 501 503 504 /503.html;
location /503.html {
root html;
}
}
####### 开启 nginx 状态
server {
location /nginx_status {
stub_status on;
access_log off;
}
}
####### upstream 负载均衡,注意:upstream 取名不要下划线_ 与 gzip 冲突
upstream lb-web {
server 192.168.5.100:8080 weight=1 max_fails=2 fail_timeout=20s;
server 192.168.5.101:8080 weight=2 max_fails=2 fail_timeout=20s;
}
location / {
proxy_pass http://lb-web;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
}
####### 上传、下载优化
location / {
# 下载缓冲
proxy_buffering on; # 流式响应需关闭
proxy_buffer_size 4k;
proxy_buffers 8 1M;
proxy_busy_buffers_size 2M;
proxy_max_temp_file_size 0;
# 禁用上传缓冲(大文件上传实时写入上游,超出 client_max_body_size 会报错)
proxy_request_buffering off;
# 上传大小不限制
client_max_body_size 0;
}
####### Header、Cookie 正常
location / {
proxy_redirect http://$host/ http://$http_host/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
# proxy_set_header X-Forwarded-For $remote_addr;
# XFF 是可以被伪造,所以第一层应该是 $remote_addr 后面才是 $proxy_add_x_forwarded_for
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
}
####### CORS 跨域
location / {
proxy_hide_header Access-Control-Allow-Origin; # 可隐藏反代,避免重复添加
add_header Access-Control-Allow-Origin '*' always;
add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,PATCH,OPTIONS' always;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
}
####### FTP
location /ftp/ {
alias /package/;
index _index.html;
autoindex on;
autoindex_exact_size off;
autoindex_localtime off;
}
####### SPA 项目刷新非主页路由出现 404 的问题
location / {
root /package/site/www;
try_files $uri $uri/ /index.html?$args;
}
####### 反代第三方域名
location /third-party/getip {
resolver 114.114.114.114; # dns
proxy_pass https://www.taobao.com/help/getip.php; # 代理目标 URL
proxy_ssl_verify off; # 禁用证书校验
}
####### 默认访问 index.html,忽略 .html
location / {
# 默认访问 index.html
if ( $request_uri = "/" ) {
rewrite ^(.*)$ /$1/index.html last;
}
# 默认访问 .html
if (!-e $request_filename) {
rewrite ^(.*)$ /$1.html last;
break;
}
}
####### 代理上游 https,自签证书:https://www.netnr.com/gist/code/5218147624476006375
location / {
proxy_pass https://10.0.0.5:9951;
proxy_ssl_certificate /package/ssl/local/server.crt;
proxy_ssl_certificate_key /package/ssl/local/server.key;
proxy_ssl_verify off;
proxy_ssl_session_reuse on;
}
####### 禁 IP 访问
server {
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server; # IPv6
listen [::]:443 default_server; # IPv6
server_name _;
charset utf-8;
ssl_certificate /package/ssl/netnr.com/fullchain.cer;
ssl_certificate_key /package/ssl/netnr.com/private.key;
# return 444;
return 500 "Visit https://www.netnr.com";
}
####### 屏蔽
server {
# 屏蔽 HEAD 请求
if ($request_method ~ ^(HEAD)$ ) {
return 404;
}
location / {
# cookie 无关键字字符阻断访问
if ($http_cookie !~ 'access_token') {
return 401;
}
# 白名单 IP 或使用 allow、deny 或使用 geo
if ($remote_addr !~ ^(192.168.1.11|123.123.123.123)) {
return 403 "No Access $remote_addr\n";
}
# 白名单 IP ,根据转发 $http_x_forwarded_for 来配置,注意 XFF 伪造
if ($http_x_forwarded_for !~ ^(192.168.100.100)) {
return 403 "No Access $http_x_forwarded_for\n";
}
}
}
####### 白名单IP,根据 $remote_addr 获取 IP ,不是转发 $http_x_forwarded_for
server {
allow 192.168.100.100;
deny all;
}
location / {
allow 192.168.100.100;
deny all;
}
####### geo 白名单
# 0 allow 1 deny
geo $not_allowed {
192.168.100.100 0;
default 1;
}
server {
location / {
if ($not_allowed) {
return 403 "No Access $remote_addr\n";
}
}
}
####### 直接返回
location /404 {
add_header Content-Type text/html;
return 404 '<!DOCTYPE html><html><head><title>404</title></head><body><h1>404</h1></body></html>';
}
location /ip {
add_header Access-Control-Allow-Origin '*' always;
add_header X-Forwarded-List $http_x_forwarded_for;
add_header X-real-IP $remote_addr;
default_type text/plain;
return 200 "$remote_addr\n";
}
####### 永久缓存 unpkg mirror
location ~* @ {
root /data/mirror_unpkg; # 指定存放目录,需手动创建目录,nginx 进程用户有读写权限
proxy_store on; # 开启本地缓存
proxy_temp_path cache_temp; # 设置反向代理接受的数据临时存储文件的目录,配置生效时候会自动创建
proxy_store_access user:rw group:rw all:r; # 设置缓存的读写规则
proxy_set_header Accept-Encoding ''; # 不返回压缩内容,避免乱码
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
# 不存在则直接从后台web内容服务器调取
if (!-e $request_filename) {
proxy_pass https://unpkg.com;
}
}
####### 1.25.1 变更 http2 配置
server {
# 之前
listen 443 ssl http2;
# 之后
listen 443 ssl;
http2 on;
}
####### www.netnr.com
server {
listen 443 ssl http2;
server_name www.netnr.com;
charset utf-8;
# SSL
#add_header Strict-Transport-Security "max-age=31536000";
ssl_certificate /package/ssl/netnr.com/fullchain.cer;
ssl_certificate_key /package/ssl/netnr.com/private.key;
ssl_session_timeout 60m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# status
location /nginx_status {
stub_status on;
access_log off;
}
location / {
# 跨域
proxy_hide_header Access-Control-Allow-Origin; # 可隐藏反代,避免重复添加
add_header Access-Control-Allow-Origin '*' always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,tenant-id' always;
proxy_redirect http://$host/ http://$http_host/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
proxy_pass http://localhost:51;
# 默认访问.html
if (!-e $request_filename) {
rewrite ^(.*)$ /$1.html last;
break;
}
}
}