1、nginx平滑升级
平滑升级:升级过程中用户的访问不断开
简单粗暴的方法:
1、备份现有的ngx命令
2、用新的版本的ngx命令替换原有的命令
3、重启nginx
需求:不重启nginx且升级nginx
平滑升级:
平滑更新步骤 | 说明 |
---|---|
1、准备好新的nginx命令(已经测试的可用的) | |
2、检查旧版本的ngx是否运行,如果没有则运行 | |
3、把当前环境的nginx命令备份,使用新的命令替换 | 把当前运行nginx的pid文件改个名 |
4、通过kill命令向当前运行的nginx发出信息,准备被替代-USR2 pid | 使用新的nginx命令启动nginx进程 |
5、测试调试,关闭旧的nginx进程即可(kill即可) |
1.1 环境准备
web01中操作
1、准备nginx1.24.0
2、准备新版本的nginx,比如放在/tmp/目录,比如使用tengine2.3.3
3、备份原有的ngx命令
1.2 具体操作
第一步:准备新版的nginx命令
假设,lb01的nginx命令是最新版的,把lb01的 nginx命令发送到web01的/tmp目录中
[root@lb01 ~]#scp /sbin/nginx 192.168.10.7:/tmp
第二步:备份原有的nginx命令
web01中,备份原有的nginx命令
[root@web01 ~]#mv /sbin/nginx /sbin/nginx-1.24.0
第三步:用新的nginx命令替换
新的nginx命令已经放在/tmp目录中,将它复制到/sbin/目录中即可
[root@web01 ~]#cp /tmp/nginx /sbin/
第四步:使用kill命令启动新的ngx
注意不能使用systemctl restart重启nginx
查看旧版本的ngx运行的pid
[root@web01 ~]#cat /var/run/nginx.pid*
22786
[root@web01 ~]#ps -ef | grep 22786
root 22786 1 0 20:48 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
www 22787 22786 0 20:48 ? 00:00:02 nginx: worker process
root 24103 1726 9 21:12 pts/0 00:00:00 grep --color=auto 22786
[root@web01 ~]#
使用kill -USR2 pid号结束进程:
[root@web01 ~]#kill -USR2 `cat /var/run/nginx.pid`
查看nginx的pid
[root@web01 ~]#ll /var/run/nginx.pid*
-rw-r--r-- 1 root root 6 Jul 1 21:15 /var/run/nginx.pid
-rw-r--r-- 1 root root 6 Jul 1 20:48 /var/run/nginx.pid.oldbin
[root@web01 ~]#
此时有2个pid,一个是正在运行的,一个是旧的
第五步:结束旧的进程
[root@web01 ~]#kill `cat /var/run/nginx.pid.oldbin`
2、rewrite功能
2.1 nginx重定向概述
重定向:也叫URL重定向,也叫URL改写
通过模块指令实现对url、uri改变
未来的需求:
1、网站是http(80)--->https(443)URL重定向
例如:用户访问:http://www.baidu.com --->https://www.baidu.com
2、根据客户端访问类型进行跳转
希望根据用户客户端类型进行判断,例如:
使用手机访问,则访问m.baidu.com
否则默认访问www.baidu.com
3、新老域名跳转,例如:www.360buy.com ---> jd.com
4、需要我们调整URL格式:伪静态(搜索引擎收入),例如:
https://doc.qq.com/desklg/Rfklvv1124gg11
2.2 模块与指令
rewrite模块
相关指令 | 说明 |
---|---|
return | 实现对url的改写,一般与nginx变量一起使用 返回指定的状态码 |
rewrite | 实现对url的改写,使用正则匹配uri,进行改写,还有各种标记 |
set | 创建或修改nginx变量 |
if | 判断,一般与nginx变量一起使用 |
1)return指令
格式 | 说明 |
---|---|
格式1 | return code URL;返回状态码+新的url地址 |
格式2 | return code;返回状态码 |
放哪 | server,location,if |
案例01:如果用户访问/admin/页面,返回403
[root@web01 ~]#vim /etc/nginx/conf.d/rewrite.test.conf
server {
listen 80;
server_name rewrite.test.com;
root /app/code/rewrite;
location / {
index index.html;
}
location /admin/ {
return 403;
}
案例02:域名跳转
用户访问rewrite.test.com 跳转到:www.badu.com
server {
listen 80;
server_name rewrite.test.com;
root /app/code/rewrite;
return 302 https://www.baidu.com;
}
302:临时跳转
301:永久跳转
本地做hosts解析,浏览器打开即可看到跳转效果
谷歌浏览器安装Redirect-Path_v2.2.2插件,可以看到跳转的过程信息:
命令行访问:
[root@web01 ~]#curl -Lv -H Host:rewrite.test.com http://192.168.10.7/
-L:–location,跟踪跳转,响应是301、302跳转的时候使用
案例03:http跳转到https
server {
listen 80;
server_name rewrite.test.com;
return 302 https://rewrite.test.com$request_uri;
}
server {
listen 443 ssl;
server_name rewrite.test.com;
root /app/code/rewrite;
私钥;
公钥(证书);
location / {
index index.html;
}
}
这里只演示格式写法,由于没有公钥、私钥,所以,无法正式运行
2)if判断
if指令可以在server、location中使用,if在nginx中不能嵌套使用
1、一般与nginx内置变量或自定义变量一起使用
2、与location使用的符号类似,如:
~、~*、!~、!~*、=、!=、
3、常用\*、!
4、nginx中取反、排除,只能用if
案例04:前面的rewrite.test.com网站只准许GET、POST、HEAD 3种请求方法,其他的访问禁止
[root@web01 ~]#cat /etc/nginx/conf.d/rewrite.test.conf
server {
listen 80;
server_name rewrite.test.com;
root /app/code/rewrite;
if ($request_method !~ "GET|POST|HEAD") {
return 403;
}
location / {
index index.html;
}
}
可以使用405状态码,405表示使用的请求方法不被网站允许或支持。
重启nginx,测试
[root@web01 ~]#nginx -s reload
#GET
[root@web01 ~]#curl -v -H Host:rewrite.test.com http://192.168.10.7/
#HEAD
[root@web01 ~]#curl -I -v -H Host:rewrite.test.com http://192.168.10.7/
#POST
[root@web01 ~]#curl -X POST -v -H Host:rewrite.test.com http://192.168.10.7/
3)set指令
set:用于创建或修改nginx变量
# shell中的写法
变量名=值
例如:name=zhangsan
echo $name
# nginx中的写法
set $变量 值;
例如:set $name zhangsan;
例如:
[root@web01 ~]#vim /etc/nginx/conf.d/rewrite.test.conf
server {
listen 80;
server_name rewrite.test.com;
set $url $http_host$request_uri;
return 200 $url;
}
重启nginx,测试:
[root@web01 ~]#nginx -s reload
[root@web01 ~]#curl -H Host:rewrite.test.com http://192.168.10.7/
rewrite.test.com/
案例05:设置网站是否为维护状态,如果是:返回503,否则,访问正常
流程:设置标记$flag,默认是0
判断如果$flag的值是1,则返回503
[root@web01 ~]#vim /etc/nginx/conf.d/rewrite.test.conf
server {
listen 80;
server_name rewrite.test.com;
root /app/code/rewrite;
set $flag 1;
if ( $flag = 1 ) {
return 503;
}
error_page 503 /503.html;
location / {
index index.html;
}
}
[root@web01 ~]#echo "503 error" > /app/code/rewrite/503.html
error_page:遇到指定的错误的时候显示指定的页面,需要nginx遇到对应的错误才会生效
把变量独立放在一个文件:
#变量单独在一个文件中定义
[root@web01 ~]#vim /app/code/rewrite/flag.txt
set $flag 1;
[root@web01 ~]#vim /etc/nginx/conf.d/rewrite.test.conf
server {
listen 80;
server_name rewrite.test.com;
root /app/code/rewrite;
include /app/code/rewrite/flag.txt;
if ( $flag = 1 ) {
return 503;
}
error_page 503 /503.html;
location / {
index index.html;
}
}
4)rewrite指令
rewrite正则用于匹配用户请求的uri
命令格式:与sed ‘s###g’类似,实现替换功能,rewrite替换url内容(改写)
rewrite指令 | 说明 |
---|---|
格式 | rewrite 找什么(具体内容、正则、保护分组) 替换成什么(具体内容、后向引用)[标记];标记可以省略,默认使用302 |
放在哪 | server、location、if |
rewrite匹配的内容,匹配uri |
rewrite的301、302标记
301:permanent
302:redirect
案例06:域名跳转
[root@web01 ~]#vim /etc/nginx/conf.d/rewrite.test.conf
server {
listen 80;
server_name rewrite.test.com;
#return 301 http://www.baidu.com$request_uri;
rewrite ^(.*)$ https://www.baidu.com/$1 redirect;
}
^:匹配的是域名(rewrite.test.com)的末尾
$1:第一个分组
redirect:表示302,可以不写,默认是302
案例07:配置phpshe(shop)电商的伪静态规则
假设伪静态之后的url地址(静态):http://192.168.10.7:83/product/1
伪静态之前的url地址(动态):http://192.168.10.7:83/index.php?mod=product&act=1
书写的rewrite目标,把用户访问的静态url地址还原成动态地址,地址通过php处理
rewrite 匹配伪静态请求url 还原成动态url;
rewrite ^/([0-9a-zA-Z]+)/(\d+) http://192.168.10.7:83/index.php?mod=$1&act=$2;
或:rewrite ^/(\w+)/(\d+) http://192.168.10.7:83/index.php?mod=$1&act=$2;
\w:[a-zA-Z0-9_]
\d:数字
直接访问:http://192.168.10.7:83/product/1
则报错:
下面进行rewrite改写:
修改shop的config.php文件,把url_mode改成pathinfo,表示开启伪静态
[root@web01 ~]#vim /app/code/shop/config.php
$pe['url_model'] = 'pathinfo'; //url模式,可选项(pathinfo/pathinfo_safe/php)
书写伪静态欢迎规则
修改站点配置文件
[root@web01 ~]#vim /etc/nginx/conf.d/shop.conf
server {
listen 83;
server_name shop.com;
error_log /var/log/nginx/shop-error.log notice;
access_log /var/log/nginx/shop-access.log main;
rewrite ^/(\w+)/(\d+) http://192.168.10.7:83/index.php?mod=$1&act=$2;
root /app/code/shop;
location / {
index index.php;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
5)rewrite标记
标记 | 说明 | 补充 |
---|---|---|
redirect(默认) | 302,临时。用户访问的时候,收到302提示及新的位置Location(响应头),用户根据Location新的位置进行访问(让用户重新发出http请求) | 新、旧的地址都可以用 |
permanent | 301,永久。用户访问的时候,收到301提示及新的位置Location(响应头),用户根据Location新的位置进行访问(让用户重新发出http请求) | 旧的地址取消了,用不了。只能用新的网站 |
break | 用户的请求匹配到包含break指令或rewrite规则后,即使后面还有location规则,不会继续运行,终止运行 | |
last | 用户请求匹配到包含last标记的rewrite规则后,停止继续执行,nginx会重新发出内部请求,请求与location规则进行匹配 | 开启nginx rewrite_log才能看到 |
案例:
[root@web01 ~]#vim /etc/nginx/conf.d/flag.test.conf
server {
listen 80;
server_name flag.test.com;
root /app/code/flag;
error_log /var/log/nginx/flag-error.log notice;
rewrite_log on; #需要错误日志debug...notice
location / {
rewrite /1.html /2.html;
rewrite /2.heml /3.html;
}
location /2.html {
rewrite /2.html /b.html;
}
location /3.html {
rewrite /3.html /a.html;
}
}
#站点目录及测试文件
[root@web01 ~]#mkdir -p /app/code/flag
[root@web01 ~]#echo 1.html url > /app/code/flag/1.html
[root@web01 ~]#echo 2.html url > /app/code/flag/2.html
[root@web01 ~]#echo 3.html url > /app/code/flag/3.html
[root@web01 ~]#echo a.html url > /app/code/flag/a.html
[root@web01 ~]#echo b.html url > /app/code/flag/b.html
#重启nginx
[root@web01 ~]#systemctl restart nginx
1、访问/1.html显示a.html内容
[root@web01 ~]#curl -H Host:flag.test.com http://192.168.10.7/1.html
a.html url
2、访问/2.html显示b.html内容
[root@web01 ~]#curl -H Host:flag.test.com http://192.168.10.7/2.html
b.html url
3、在rewrite /1.html /2.html加上break标记,即:
server {
listen 80;
server_name flag.test.com;
root /app/code/flag;
error_log /var/log/nginx/flag-error.log notice;
rewrite_log on; #需要错误日志debug...notice
location / {
rewrite /1.html /2.html break;
rewrite /2.heml /3.html;
}
location /2.html {
rewrite /2.html /b.html;
}
location /3.html {
rewrite /3.html /a.html;
}
}
执行完rewrite后直接结束。
此时,访问/1.html显示b.html内容:
[root@web01 ~]#curl -H Host:flag.test.com http://192.168.10.7/1.html
b.html url
4、在rewrite /1.html /2.html加上last标记,即:
server {
listen 80;
server_name flag.test.com;
root /app/code/flag;
error_log /var/log/nginx/flag-error.log notice;
rewrite_log on; #需要错误日志debug...notice
location / {
rewrite /1.html /2.html last;
rewrite /2.heml /3.html;
}
location /2.html {
rewrite /2.html /b.html;
}
location /3.html {
rewrite /3.html /a.html;
}
}
访问/1.html显示b.html内容:
[root@web01 ~]#curl -H Host:flag.test.com http://192.168.10.7/1.html
b.html url
查看日志可以看到跳转情况:
[root@web01 ~]#tail /var/log/nginx/flag-error.log
3、nginx优化
3.1 nginx配置详解
nginx完整配置示例:
user www;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
#load modules
include /etc/nginx/modules-enabled/*.conf;
events {
multi_accept on; #性能优化
worker_connections 65535;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
types_hash_bucket_size 64;
client_max_body_size 16M;
#MTME
include mime.types;
default_type application/octet-stream;
#logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
#limits 安全优化
limit_req_log_devel warn;
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
#ssl 配置https 开始
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
#diffie-hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;
#mozilla intermediate configuration
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;
#OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
#配置HTTPS 结束
#load configs
include /etc/nginx/conf.d/*.conf;
#server部分配置
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name blog.test.com;
set $base /app/code/;
root $base/blog/;
#SSL
ssl_certificate /etc/letsencrypt/live/blog.test.com/fullchain.pem;
ssl_certificate /etc/letsencrypt/live/blog.test.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/blog.test.com/chain.pem;
#security headers
add_header X-XSS-Protection "1;mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http:https:ws:wss:data:blob:'unsafe-inline';frame-ancestors 'self';" always;
add_header Permissions-Policy "interest-cohort=()" always;
add_header Strict-Transport-Security "max-age=31536000;includeSubDomains" always;
# .files 禁止访问
location ~ /\.(?!well-known) {
deny all;
}
# security.txt
location /security.txt {
return 301 /.well-known/security.txt;
}
location = /.well-known/security.txt {
alias ~/security.txt;
}
# index.php
index index.php;
# index.php fallback
location / {
try_files $uri $uri/ /index.php?$query_string;
#测试指定的uri是否存在
#如果不存在,则设置个默认的(最后的那个)
}
# favicon.ico 站点的图标文件
location = /favicon.ico {
log_not_found off;
access_log off;
}
#robots.txt 安全优化
location = /robots.txt {
log_not_found off;
access_log off;
}
# assets,media 性能优化
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|mp4|ogg|midi?|wav|m4a|acc|mov|webm|mpe?g|avi|flv|ogv|wmv)$ {
expires 7d;
access_log on;
}
# svg,fonts 性能优化
location ~* \.(?:scgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin "*";
exprise 7d;
access_log off;
}
# gzip 性能优化
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
#brotli 性能优化
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
# handle .php
location ~ \.php$ {
# fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_pass 127.0.0.1:9000;
#404
try_files $fastcgi_script_name =404;
# default fastcgi_params
include fastcgi_params;
# fastcgi settings
fastcgi_index index.php;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
#fastcgi params
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
}
}
# http redirect
server {
listen 80;
listen [::]:80;
server_name blog.test.com;
# ACME-challenge
location ^~ /.well-know/acme-challenge/ {
root /var/www/_letsencrypt;
}
location / {
return 301 https://blog.test.com$request_uri;
}
}
}
生成环境的配置示例:
#user root;
worker_processes 4;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
#ssi on;
#ssi_silent_errors on
underscores_in_headers on;
log_format main '[$remote_addr] [$remote_port] [$remote_user] [$http_cookie] [$time_local] [$request] [$http_host]'
'[$request_method] [$http_x_forwarded_for] [$status] [$upstream_status] [$body_bytes_sent] [$http_referer]'
'[$http_user_agent] [$ssl_protocol] [$ssl_cipher] [$upstream_addr] [$request_time] [$upstream_response_time]';
##如果需要打印用户真实IP,使用$http_x_forwarded_for代替$remote_addr,
# log_format access '{"appname":"nginx",'
# '"logtime": "$time_local", '
# '"client_ip": "$remote_addr", '
# '"remote_user": "$remote_user", '
# '"http_referer": "$http_referer", '
# '"resp_len": "$body_bytes_sent", '
# '"waster_time": "$request_time", '
# '"status": "$status", '
# '"request_path": "$request", '
# '"request_method": "$request_method", '
# '"request_url": "$http_referer", '
# '"body_bytes_sent":"$body_bytes_sent", '
# '"http_forwarded": "$http_x_forwarded_for", '
# '"user_agent": "$http_user_agent" ,'
# '"upstream": "$upstream_addr",'
# '"upstream_status": "$upstream_status"}';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
server_tag off;
server_info off;
server_tokens off;
fastcgi_intercept_errors on;
keepalive_requests 3000;
keepalive_timeout 120;
check_shm_size 50m;
proxy_ssl_server_name on;
proxy_ssl_verify off;
proxy_intercept_errors on;
gzip on;
#WAF
# lua_shared_dict limit 10m;
# lua_package_path "/servyou/tengine/conf/ngx_lua_waf/?.lua";
# init_by_lua_file "/servyou/tengine/conf/ngx_lua_waf/init.lua";
# access_by_lua_file "/servyou/tengine/conf/ngx_lua_waf/waf.lua";
upstream account-core-web {
server 10.0.0.111:8001;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /account-core-web-service/version HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream bszm-web {
server 10.0.0.111:8002;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /bszm-web/RemoteCallServlet?health=test HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream wszx-web {
server 10.0.0.111:8003;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /wszx-web/RemoteCallServlet?health=test HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream zmpt-web {
server 10.0.0.111:8004;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /zmpt-web/RemoteCallServlet?health=test HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream wlx-svc {
server 10.0.0.111:8005;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /wlzx-svc/RemoteCallServlet?health=test HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream dzzlk {
server 10.0.0.111:8006;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /dzzlk/RemoteCallServlet?health=test HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream zmpt-gld {
server 10.0.0.111:8007;
check interval=5000 rise=2 fall=5 timeout=3000 type=http;
check_http_send "HEAD /zmpt-gld/RemoteCallServlet?health=test HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
# web 层代理
server {
listen 8081;
#server_name localhost;
#charset utf-8;
port_in_redirect off;
proxy_buffer_size 128k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 1024k;
proxy_max_temp_file_size 100M;
large_client_header_buffers 4 128k;
client_max_body_size 100m;
client_body_buffer_size 128k;
proxy_read_timeout 300;
proxy_send_timeout 300;
proxy_connect_timeout 60;
proxy_next_upstream off;
#拦截除以下方式的请求(DELETE PUT)
if ($request_method !~ ^(GET|HEAD|POST)$ ){
return 403;
}
#deny ip;
#nginx访问黑名单
#if ($remote_addr ~* 'ip01|ip02'){
# return 307 https://oldboyedu.com/error;
# }
# 访问根自动跳转至首页
#location = / {
# rewrite ^(.*)$ http://10.0.0.7:8081/wszx-web/bszm/apps/views/beforeLogin/indexBefore/pageIndex.html#/ ;
# }
#前端静态资源
location /nsrymh {
alias /servyou/tengine/nsrymh;
autoindex off;
}
#前端静态资源
location /nsryh5mh {
alias /servyou/tengine/nsryh5mh;
autoindex off;
}
#前端静态资源
location /hndzswj {
alias /servyou/tengine/hndzswj;
autoindex off;
}
#行为日志记录代理
location /burial {
alias /servyou/tengine/burial;
autoindex off;
}
#bszm-web 依赖 login-web下面的字体
location /login-web {
alias /servyou/tengine/login-web;
autoindex off;
}
#纳税人下载的文件
location /download {
alias /servyou/tengine/download;
autoindex off;
}
location /account {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#add_header Access-Control-Allow-Origin http://1.1.1.1; #允许跨域
#add_header X-Frame-Options SAMEORIGIN;
proxy_pass http://account-core-web/account-core-web-service$request_uri;
}
location /yhzx-web {
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_pass http://yhzx-web$request_uri;
}
location /wszx-web {
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_pass http://wszx-web$request_uri;
}
location /zmpt-web {
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_pass http://zmpt-web$request_uri;
}
location /zmpt-gld {
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_pass http://zmpt-gld$request_uri;
}
location /wlzx-svc {
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_pass http://wszx-svc$request_uri;
}
location /dzzlk {
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_pass http://dzzlk$request_uri;
}
location /bszm-web {
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_pass http://bszm-web$request_uri;
}
# location /download {
# alias /filepath1;
# autoindex off;
# }
location ~ /druid {
deny all;
}
#weblogic漏洞挡板
location ~ ^/wls-wsat {
deny all;
}
location ~ ^/uddiexplorer {
deny all;
}
location ~ ^/bea_wls_internal {
deny all;
}
location ~ ^/console {
deny all;
}
location ~ ^/_async {
deny all;
}
location ~ ^/bea_wls_deployment_internal {
deny all;
}
location ~ ^/status{
allow 192.168.0.0/16;
allow 10.0.0.0/8;
deny all;
check_status;
access_log off;
}
location ~ ^/nginx_status {
allow 192.168.0.0/16;
allow 10.0.0.0/8;
deny all;
stub_status on;
access_log off;
}
# set $a 0;
# if ($request_uri ~ hessian){
# set $a 1;
# }
# if ($request_uri ~ RemoteCallServlet){
# set $a 1;
# }
# if ($remote_addr ~* '192.168.2') {
# set $a 0;
# }
# if ($remote_addr ~* '82.17.64') {
# set $a 0;
# }
# if ($a = 1){
# return 403;
# }
location /error {
root html;
}
error_page 501 502 503 504 /51x.html;
location = /51x.html {
root html;
}
error_page 400 401 402 403 404 405 406 407 408 409 410 412 413 414 415 /40x.html;
location = /40x.html {
root html;
}
}
include test.conf;
}
3.2 优化一览表
优化类型 | 优化说明 | 优化方法 |
---|---|---|
安全优化 | 1、隐藏nginx版本信息 | 修改nginx配置文件,设置:server_tokens off; |
安全优化 | 2、修改nginx名称信息 | 修改nginx源码配置文件 nginx-xxx/src/core/nginx.h nginx-xxx/src/http/ngx_http_header_filter_module.c nginx-xxx/src/http/nginx_special_response.c |
安全优化 | 3、修改nginx软件work_processes进程用户信息 | 修改nginx默认用户,利用配置文件参数,例如: user www www; 编译安装采用编译参数实现 |
安全优化 | 4、优化nginx服务上传文件大小限制 | client_max_body_size,设置客户端请求报文主体最大尺寸,默认是1M,用户上传文件大小。可以在http、server、location中设置。超过限制的大小,报413错误 |
安全优化 | 5、配置nginx相关日志操作 | 防止日志过大,进行日志文件轮询切割: 1、yum安装nginx,自动切割(logrotate) 2、编译安装手动切割 部分日志内容不进行记录,节省磁盘空间。 对日志文件进行授权 logrotate 日志切割工具+系统定时任务 kill -USR1 cat /var/run/nginx.pid |
安全优化 | 6、nginx站点目录及文件uri访问控制 | 在动态解析配置前面,设置限制特定目录下扩展名文件、限制指定目录uri信息访问,利用禁止策略和返回错误信息限制用户访问,利用黑名单白名单方式,禁止非域名访问网站等 |
安全优化 | 7、图片及目录防盗链 | 根据HTTP referer实现防盗链。用户从哪里跳转过来的(通过域名) refer 控制 例如:if ( $http_referer !~ “空或www.baidu.com“) { return 403;} |
安全优化 | 8、错误页面的优雅显示 | 对错误代码实行本地页面跳转。优雅显示错误页面放到本地单独目录下。 |
安全优化 | 9、nginx站点目录文件及目录权限优化 | 只将用户上传数据的目录设为755,用户和组使用nginx。其余目录和文件为755/644,用户和组用root。 网站相当于www用户,因此: 1、站点目录,整体文件和目录,文件644,目录755,用户和组均为root 2、用户上传数据的目录和文件,目录755,文件644,用户和组为www |
安全优化 | 10、nginx限制请求访问 | HTTP用户请求方法:GET、POST、PUT、HEAD、DELETE、TRACE、OPTIONS等等 例如: if ($http_mothod !~ “GET|POST|HEAD”) { return 403; #deny all; } |
安全优化 | 11、nginx防爬虫优化 | 利用robots.txt机器人协议防止爬虫。在网站目录下面放robots.txt文件,利用$http_user_agent变量来阻止爬虫代理访问。 |
安全优化 | 12、监牢模式(keep in jail) | 利用nginx -c参数启动nginx多实例。普通用户无法使用1-1024端口。80–转发iptables–>8080 |
安全优化 | 13、限速limit_rate | limit_rate 速度,如:limit_rate 100k |
安全优化 | 14、控制客户端请求nginx的频率 | 访问频率、nginx处理的频率: limit_conn_module:连接频率限制(服务端) limit_req_module:请求频率限制(限制客户端) |
性能优化 | 15、修改nginx软件work process进程数量 | woker_processes 8; 一般和CPU的核心数一致,高并发可以设为 核心数的2倍。 查看cpu核心数:lscpu、nproc 、/proc/cpuinfo、top命令按1 1个核心处理1件事情。Intel超线程技术,1个核心出来2件事情 |
性能优化 | 16、优化nginx服务进程均匀分配到不同CPU处理,即CPU亲和力(工具人进程平均使用cpu核心) | 利用worker_cpu_affinity进行优化(CPU亲和力),让CPU的每个核心平均 4颗cpu优化配置参数为0001 0010 0100 1000 2颗CPU优化配置参数:0101 1010 worker_cpu_affinity 0101 1010; worker_affinity auto; Linux系统设置CPU亲和力为:taskset (15k) Bin 1111 15 0x00000f Taskset -p oxf pid #把进程绑定到对应的cpu核心上 |
性能优化 | 17、优化nginx事件处理模型 | 利用use epoll 参数修改事件模型为epoll。事件模型指定配置参数放置在event区块中。Nginx epoll:处理数据异步;Apache select:处理数据同步 |
性能优化 | 18、优化nginx单进程客户端连接数 | 利用worker_connections连接参数进行调整。用户最大并发连接数=worker进程数*worker连接数 |
性能优化 | 19、优化nginx服务进程打开文件数 | 利用worker_rlimit_nofile参数进行调整(65535) |
性能优化 | 20、优化nginx服务数据高效传输模式 | 利用sendfile on打开高效传输模式。 tcp_nopush on表示将数据积攒到一定的量再进行传输 tcp_nodelay on表示将数据信息进行快速传输 |
性能优化 | 21、优化nginx服务超时信息 | keepalive_timeout优化客户端访问nginx服务端超时时间。Http协议特点:连接断开后会给你保留一段时间 client_header_timeout优化服务端读请求头的超时时间 client_body_timeout优化两个请求主体发动间隔超时时间 send_timeout优化两个响应信息的间隔超时时间 |
性能优化 | 22、优化nginx服务与连接缓存与缓冲信息 | Fastcgi与php连接缓存、缓冲信息。适用于nginx的各种buffer和cache |
性能优化 | 23、配置nginx gzip压缩实现性能优化 | 利用gzip命令进行对数据信息压缩优化 |
性能优化 | 24、brotli压缩(第三方模块) | 与gzip类似,用于https环境 |
性能优化 | 25、expires缓存 | 利用location匹配相应要缓存的信息,利用expires把数据缓存到浏览器中 |
1、修改server_tokens为off,隐藏版本
2、修改web服务名称,比如:nginx改成Tomcat,tengine改成apache
需要修改源码的3个文件:
nginx-xxx/src/core/nginx.h
nginx-xxx/src/http/ngx_http_header_filter_module.c
nginx-xxx/src/http/nginx_special_response.c
修改如下:
#修改一下参数
[root@web03 ~/tengine-2.3.3]#egrep -n "NGINX_(VERSION|VAR)" src/core/nginx.h
13:#define NGINX_VERSION "1.18.0"
14:#define NGINX_VER "nginx/" NGINX_VERSION
29:#define NGINX_VAR "NGINX"
[root@web03 ~/tengine-2.3.3]#
#修改/src/http/ngx_http_header_filter_module.c的参数:
static u_char ngx_http_server_string[] =
#修改src/http/ngx_http_special_response.c的参数:
"<hr><center>nginx</center>" CRLF
3、限制用户上传文件大小
#在http{}中修改client_max_body_size参数
client_max_body_size 50m;
还要修改php
#修改/etc/opt/remi/php74/php.ini文件
post_max_size=50M
upload_max_filesize=50M
4、日志切割
日志切割使用的命令:
logrotate -f /etc/logrotate.d/nginx
默认是系统定时任务调用,可以自定义书写crontab -e
#日志切割的配置格式:
[root@web01 ~]#cat /etc/logrotate.d/nginx
#指定要切割的文件
/var/log/nginx/*.log {
daily #每天切割
missingok #文件不存在不报错
rotate 52 #循环52次,从第53次开始,删除旧的切割
compress #对日志进行压缩
delaycompress #隔天压缩
notifempty #文件为空不切割
create 640 nginx adm #切割后文件的权限、用户、用组
#切割后运行指定的命令,一般是重启的命令
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid` #相当于reload
fi
endscript
}
查看被压缩的日志文件:zcat 日志文件
5、访问控制
例如:
location /admin/ {
return 403;
#deny all;
}
6、防盗链
什么是盗链:网站中盗取其他人网站的资源连接。
防盗链:1、加水印;2、通过referer头判断,用户间接访问就会有这个头部信息;3、配置认证,登录后才能用
if ( $http_referer ~ "img.com") {
return 403;
}
7、错误页面
配置如下:
error_page 501 502 503 504 /50x.html;
location = /50x.html {
root /app/code/error;
}
error_page 400 401 402 403 404 405 406 407 408 409 410 412 413 414 415 /40x.html;
location = /40x.html {
root /app/code/error;
}
#在return如何指定错误提示的页面
set $flage 1;
if ($flage = 1) {
return 503 http://xxx/50x.html;
}
8、nginx站点目录文件及目录权限优化
权限推荐设置:
1、整个网站目录,文件644,目录755,用户和组均为root
2、涉及用户上传数据的目录,文件644,目录755,用户和组为www(中间件运行的用户,比如:nginx、www)
3、时刻盯紧临时目录
4、给网站设置md5sum校验,对于缓存不需要做校验,例如:
[root@web01 ~]#find /app/code/blog/ -type f | xargs md5sum > blog_file.md5 #没有排除缓存文件
校验:
[root@web01 ~]#md5sum -c --quiet blog_file.md5
定时任务定期执行:md5sum -c –quiet blog_file.md5 2>/dev/null | wc -l
然后把结果保存下来传输到备份服务器
检查是否有新增的文件:find /app/code/blog/ -type f | wc -l
研究aide命令
9、利用nginx限制请求访问
HTTP用户请求方法:GET、POST、PUT、HEAD、DELETE、TRACE、OPTIONS等等
例如:
if ($http_mothod !~ "GET|POST|HEAD") {
return 403;
#deny all;
}
10、防爬虫
什么是爬虫?通过命令或软件下载网站的指定的信息。
如何防爬虫?
1、君子协议。robots.txt,文件格式:
User-agent: Baiduspider
Disallow: /baidu
Disallow: /s?
Disallow: /ulink?
Disallow: /link?
Disallow: /home/news/data/
Disallow: /bh
2、在nginx中通过ua变量进行判断,手动屏蔽爬虫,在server中设置,例如:
server {
#这种屏蔽容易误杀一些搜索引擎的爬虫
if ($http_user_agent ~* "spider|bot") {
return 403;
}
}
可以精确写出具体不想要的爬虫,排除法,比如:
if ($http_user_agent !~* "baidu|google|android|ios|windows")
但是,也可能误杀
3、增加登录,认证功能
11、nginx监牢模式
监牢模式:通过普通用户(非虚拟用户)运行与管理指定的服务。
比如,nginx进程运行使用www(虚拟用户),而启动重启操作使用root用户。可不可以统一一个普通用户?
一般是编译安装的软件(可以安装到指定目录,如:–prefix=/app/tools/nginx/)
还可以是二进制软件。
如果是nginx有个坑,1-1024范围的端口是特权端口,只能是root管理。
12、限速(速度,请求频率)
限制下载速度
例如:limit_rate 100k
13、访问频率
访问频率、nginx处理的频率:
limit_conn_module:连接频率限制(服务端)
limit_req_module:请求频率限制(限制客户端)
#木桶原理
测试limit_conn
limit_conn_zone
limit_conn zone number
例如:
http {
#limit_conn_zone 创建木桶
#$binary_remote_addr 根据客户端ip进行限制
#zone=木桶的名字
#10m 木桶的大小为10m
limit_conn_zone $binary_remote_addr zone=conn_zone:10m; #10m大小
server {
limit_conn conn_zone 1; #1个ip地址连接并发数是1
}
}
测试:ab -n 10 -c 2 -H Host:tes.com http://192.168.10.5/
limit_req:
http {
# rate=1r/s,每秒处理1个
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {
limit_req zone=req_zone burst=5;#burst,并发数
}
}
14、优化nginx服务进程打开文件数
Linux文件描述符,用于控制每个进程最多可以打开多少个文件。
这个值分为2个部分:
1、系统的设置
1)修改/etc/security/limits.conf文件:
* soft nofile 65535
* hard nofile 65535
2)命令行:ulimit -n 65535 (临时生效)
2、服务软件的设置,例如:nginx
worker_rlimit_nofile 65535
15、优化nginx服务与连接缓存与缓冲信息
cache缓存区读服务:
fastcgi_cache my_nginx
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
buffer缓冲区写服务:
fastcgi_read_timeout
fastcgi_buffer_size 8k;
fastcgi_buffers 8 8k;
fastcgi_busy_buffers_sizes 16k;
16、配置nginx gzip压缩实现性能优化
gzip on;
gzip_min_length 1k; #设置大于1k的才压缩
gzip_buffers 4 16k; #设置压缩缓存
#gzip_http_version 1.0;
gzip_comp_level 2; #压缩级别,数字越大,压缩率(占用空间)越小,占用cpu越多
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-http-php; #哪些类型的文件需要压缩,这些类型需用mime types媒体类型(/etc/nginx/mime.types)
16、expires缓存
location ~* \.(css|jpeg|html|js|bmp|png)$ {
expires 1d;
}