Nginx技术指北


学计算机的同学都知道,TCP/IP协议簇中的HTTP就是访问网站使用的协议,Nginx就是HTTP的服务器。

一、重定向

域名重定向

if ($host ~* !^www.) {
    return 301 https://www.替换你的域名.com$request_uri;
    break;
}

状态码重定向

error_page 404 https://www.替换你的域名.com$request_uri; #响应302状态码

二、UA防盗链

对于个人或小型网站来说,我不希望国外蜘蛛来访问我的网站,特别是个别垃圾蜘蛛,它们访问特别频繁。这些垃圾流量多了之后,严重浪费服务器的带宽和资源。通过判断user agent,在nginx中禁用这些蜘蛛可以节省一些流量,也可以防止一些恶意的访问。

if ($http_user_agent ~* (Scrapy|Curl|HttpClient|Hacker|Creaker)) {
    return 403;
}

三、Referer防盗链

背景说明:为了避免他人获取服务器资源,只能让本服务器能正常访问服务器资源,使用refer做防止其他网站或直接获取服务器资源,在nginx中配置如下:

location ~ /uploads/mail/201 {
    valid_referers blocked www.pinlucky.com www.pinlucky.cn;
    #valid_referers blocked $server_name;
    if ($invalid_referer) {
        rewrite ^/ /static/img/openRedBG.png;
        return 403;
    }
    #rewrite ^/ /static/img/openRedBG.png;
}

四、设置过期时间

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)\$
{
    expires      30d;
}

生成头部为

Accept-Ranges: bytes
Cache-Control: max-age=2592000
Content-Length: 1428235
Content-Type: image/jpeg
Date: Fri, 04 Jun 2021 08:11:58 GMT
ETag: "60b9e02f-15cb0b"
Expires: Sun, 04 Jul 2021 08:11:58 GMT
Last-Modified: Fri, 04 Jun 2021 08:11:27 GMT

五、IP黑(白)名单

IP白名单

allow 1.1.1.1; 
allow 1.1.1.2;
deny 1.1.2.0/24;
deny all;

IP黑名单

deny 1.1.1.2;

六、限速管理

limit_conn perip 5;
limit_rate_after 500k;
limit_rate 20k;

上面这两个limit的意思是:单个IP最大允许5个连接,单个连接带宽为20K,若下载器一次可以发起5个请求(5个连接数),那么这个下载器最大下载速度为100K;

七、防攻击

CC防攻击

https://www.centos.bz/2012/12/openresty-nginx-block-cc-attack-deploy/

异常攻击

185.153.197.165 - - [01/Aug/2021:06:38:08 +0800] "\x03\x00\x00/*\xE0\x00\x00\x00\x00\x00Cookie: mstshash=Administr" 400 150 "-" "-"

解决办法

add_header Allow "GET, POST, HEAD, DELETE, OPTIONS" always; 
if ($request_method !~ ^(GET|POST|HEAD|OPTIONS|DELETE|PUT)$) { 
    return 405; 
}

屏蔽异常IP

cat *.log |grep '\"\\x' |awk '{print "deny",$1";"}'|sort|uniq > /usr/local/nginx/conf/block.conf
# 在Nginx中引入
include block*.conf

八、URL重写

普通重写

rewrite ^(.*)$ /index.php?s=$1 last;

PHP后缀改为html后缀(未测试)

rewrite ^(.*)\.php(.*)$ /$1\.html$2 last;

忽略html扩展名

location / {
    try_files $uri.html $uri $uri/ =404;
}

九、过滤请求

if ($request_method ~* GET|get) {
    rewrite  ^(.*)$  /notice  last;
}

十、反向代理

upstream tornado {
    server 127.0.0.1:5010;
}
server
{
    listen 80;
    server_name tornado.com;
    location = / {
        proxy_pass http://tornado;
        root   html;
    }
    access_log  /home/wwwlogs/tornado.log;
}

十一、代理Websocket

location /websocket {
    proxy_pass http://127.0.0.1:9501;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 600;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

十二、头部操作

添加响应头部

这样在浏览器的Response Headers就能看到客户端的IP了,注意放到location里面,还可能被其他location覆盖导致获取不到。

add_header yourip $remote_addr;

添加请求头(代理时):

location /proxypass {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

获取自定义头部

比如我们自定义header为X-Real-IP,通过nginx获取该header时需要这样:$http_x_real_ip; (一律采用小写,而且前面多了个http_)

curl http://127.0.0.1/nginx -H "A-B-C:a-B-c" -v
127.0.0.1 - a-B-c
location /nginx {
	default_type text/html;
	return 200 '$remote_addr - $http_a_b_c';
}

if ( $http_a_b_c != "abcdef00" ) {
	return 403 '访问被禁止,访问该请求需要特定的头部';
}

十三、使用Nginx作文件服务

location /dir {
    charset utf-8;
    autoindex on;
    autoindex_localtime on;
    autoindex_exact_size off;
    add_after_body /autoindex.html;
}

其中add_after_body /autoindex.html可自定义加在html后面的内容,设置自定义样式,页面优化可访问 https://phus.lu/

十四、泛域名+泛网站

类似于Git Pages网站,将该域名的所有子域名解析到同一个IP,每个子域名访问到自己的目录上。即a.gitee.io访问到目录./a.gitee.io/b.gitee.io访问到目录./b.gitee.io/

server {
    listen 80;
    server_name *.gitee.io;
    index index.html;
    root D:/Pro/phpEnv/www/$host;
    error_page 404 /404.html;
    access_log logs/gitee.io.access.log;
    error_log logs/gitee.io.error.log;
}

十五、日志记录

日志自定义格式配置

http {
    log_format main_json '{
            "@timestamp":"$time_local",
            "client_ip":"$remote_addr",
            "request":"$request",
            "status":"$status",
            "bytes":"$body_bytes_sent",
            "x_forwarded":"$http_x_forwarded_for",
            "referer":"$http_referer"}';
    log_format simple "$remote_addr - $remote_user";
    # ...
    server {
        # ...
        access_log logs/access_json.log main_json;
    }
}
log_format格式变量:
    $remote_addr  #记录访问网站的客户端地址
    $remote_user  #远程客户端用户名
    $time_local  #记录访问时间与时区
    $request  #用户的http请求起始行信息
    $status  #http状态码,记录请求返回的状态码,例如:200、301、404等
    $body_bytes_sent  #服务器发送给客户端的响应body字节数
    $http_referer  #记录此次请求是从哪个连接访问过来的,可以根据该参数进行防盗链设置。
    $http_user_agent  #记录客户端访问信息,例如:浏览器、手机客户端等
    $http_x_forwarded_for  #当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器也要进行相关的x_forwarded_for设置

十六、日志切割

/home/wwwlogs/*.log {
    su root root
    daily
    dateext
    compress
    rotate 10
    notifempty
    sharedscripts
    postrotate
        kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
    endscript
}

十七、Nginx日志分析

都用哪些安卓版本

cat ssl_xinxi.club.log|awk -F '"' '{print $6}'|egrep -o "Android [0-9.]+;"|sort|uniq -c

1 Android 4.0.4;
1 Android 4.4.2;
7 Android 4.4.4;
7 Android 5.0.2;
12 Android 5.1;
24 Android 5.1.1;
18 Android 6.0;
20 Android 6.0.1;
6 Android 7.0;
30 Android 7.1.1;
87 Android 7.1.2;
63 Android 8.0;
79 Android 8.1;
2 Android 8.1.0;

500状态码URL统计

cat *.log|grep " 500 "|awk '{print $7}'|sort|uniq -c |sort -nr

14 /admin/Sports/event_list.html
5 /rest/yard/index

404状态码的IP统计

cat *.log|grep " 404 "|awk '{print $1}'|sort|uniq -c |sort -nr|head

十八、带宽限制

location /download
{
    limit_rate 20k;
    limit_rate_after 500k;
    #limit_rate_after 512; 发送头部之后立即限制
    #limit_conn   limitconnbyaddr  1; 限制1个IP只能有1个连接
}

十九、更改响应状态码

允许POST请求json文件

location ~ (.*\.json)
{
    error_page 405 =200 $1;
}