[nginx]优化和安全设置 - 迁

安全设置

Http(7层)

#拒绝特定的User Agent的访问(除非改下UA)

set $block_user_agents 0;
if ($http_user_agent ~ "Wget|ApacheBench|WebBench|TurnitinBot|libwww-perl")
{
set $block_user_agents 1;
}

if ($block_user_agents = 1)
{
return 403;
}

  

#拒绝访问特定后缀的文件(比如 一个全备份的tar包)

location ~* "\.(sql|bak|inc|old|sh|zip|tgz|gz|tar)$"
{
return 403;
}

1.8.3 #防止SQL注入 匹配 union select from (
set $block_sql_injections 0;
if ($query_string ~ "union.*select.*\(|union.*all.*select.*")
{
set $block_sql_injections 1;
}
if ($block_sql_injections = 1)
{
return 403;
}

 

# 隐去版本号

server_tag off;
server_info off;
#
server_tokens off;

  

    

# ip白名单

最方便的办法是引入配置文件,但是修改white_ip.conf后需要reload服务

方式1

http {
   .......
   include conf/white_ip.conf  
}
////////////////////
white_ip.conf:
allow 58.xxxxxx; 
allow 10.0.0.0/8; 
allow 122.224.125.111; #yimei
deny all;

 

方式2

# 配置whiteiplist.conf 
geo $remote_addr $whitelist {
 default 0;
 127.0.0.1 1;
 10.0.0.0/8 1;
 192.168.0.0/16 1;
 106.75.248.0/24 1;
}

# 在nginx.conf中include进来
include /usr/local/openresty/nginx/conf/whiteiplist.conf;

# 在vhosts中的location部分加上
       if ( $whitelist != 1 ) {
            return 403;
        }

这样可以做到部分限制,部分不限制,更可以和黑名单功能叠加上去

  

TCP(4层)

IP过白

方式1(官方):

stream {
    #...
    server {
        listen 12345;
        deny   192.168.1.2;
        allow  192.168.1.1/24;
        allow  2001:0db8::/32;
        deny   all;
    }
}

  

方式2:

stream {
   upstream prod_backend {
      server 192.168.137.129:23;
   }

   # white ip addr
   map $remote_addr $backend_svr {
      192.168.23.45 "prod_backend";
      default "not_exist";
   }

   server {
      listen 23;
      proxy pass $backend_svr;
   }
}

  

限速

# 根据ip地址限制并发连接量
stream {
    #...
    limit_conn_zone $binary_remote_addr zone=ip_addr:10m;

    server {
        #...
        limit_conn ip_addr 1;
    }
}

# 限制每个server的流量
stream {
       #...
    server {
        #...
        proxy_download_rate 100k;
        proxy_upload_rate   50k;
    }
}

     

限速限流

 

 

HttpLimitReqModule 限制ip访问频率

http{
        limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
       #定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
       #以$binary_remote_addr 为key,限制平均每秒的请求为20个,
       #1M能存储16000个状态,rate的值必须为整数,
       #如果限制两秒钟一个请求,可以设置成30r/m

    server {
        location {
            limit_req zone=allips burst=5 nodelay;
            #限制每ip每秒不超过20个请求,漏桶数burst为5
            #brust的意思就是,如果第1秒 2,3,4秒请求为19个,
            #第5秒的请求为25个是被允许的。
            #但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。
            #nodelay,如果不设置该选项,严格使用平均速率限制请求数,
            #第1秒25个请求时,5个请求放到第2秒执行,
            #设置nodelay,25个请求将在第1秒执行。不严格执行限制
        }
    }
}

  

HttpLimitZoneModule 限制并发连接数 

limit_zone只能定义在http作用域,limit_conn可以定义在http server location作用域

http{
      limit_conn_zone one $binary_remote_addr 10m; 
     #定义一个名为one的limit_zone,大小10M内存来存储session,
     #以$binary_remote_addr 为key
     #nginx 1.18以后用limit_conn_zone替换了limit_conn
     #且只能放在http作用域
     server{
          location {
               limit_conn one 20; #连接数限制
               #带宽限制,对单个连接限数,如果一个ip两个连接,就是500x2k
               limit_rate 500k;
          }
     }
}
 

 

auth_basic用户基本认证

1 配置nginx密码:nginx可以为网站或目录甚至特定的文件设置密码认证。密码必须是crypt加密的。可以用apache的htpasswd来创建密码。
格式为:htpasswd -b -c site_pass username password
location / { 
    auth_basic "Restricted"; 
    #你的nginx密码文件地址 注意此模块不能存在 if {} 内
    auth_basic_user_file /usr/local/nginx/conf/site_pass; 
}
# 测试
curl http://ftbd.jczj123.com/ -u kkyunying:xxxx

  

  

图片防盗链

location /images/ {
		valid_referers none blocked www.caihongshop.com;  
		if ($invalid_referer) {
    	             return 403;
		}
}



-- 测试:
curl http://127.0.0.1:9991/images/ggg -I --referer http://test.ops.com
HTTP/1.1 403 Forbidden
Server: openresty/1.13.6.1
Date: Thu, 06 Jun 2019 02:03:24 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 175
Connection: keep-alive

curl http://127.0.0.1:9991/images/ggg -I --referer http://www.caihongshop.com
HTTP/1.1 200 OK
Server: openresty/1.13.6.1
Date: Thu, 06 Jun 2019 02:03:34 GMT
Content-Type: application/octet-stream
Content-Length: 39
Last-Modified: Thu, 06 Jun 2019 01:56:21 GMT
Connection: keep-alive
ETag: "5cf872c5-27"
Accept-Ranges: bytes

  

 

性能优化

基本方法

更换更高效的协议:
    http2 websocket
压缩
    js image; 静态, 动态
keepalive

    长连接

cpu亲和性

    worker_cpu_affinity auto;

# 查看进程绑定在哪个cpu上
ps -eo pid,args,psr|grep nginx 

  

worker之间的负载均衡

  

关闭accept_mutex

关闭后低负载情况下,有惊群的现象

events { 
       accept_mutex off; 
} 

  

端口重用

原版和openresty

listen 80 resueport;  

  

tengine配置在events里面

events {
	use epoll;
	multi_accept off;
	reuse_port on;
	worker_connections  1048576;
}

  

keepalive长连接 

1w个idle连接只需要消耗 2.5MB内存 

http {
    keepalive_timeout 10; 
}

  

优化连接数和用户数

最终的结论:

http 1.1协议下,由于浏览器默认使用两个并发连接,因此计算方法:

   nginx作为http服务器的时候:

max_clients = worker_processes * worker_connections/2​

   nginx作为反向代理服务器的时候:

max_clients = worker_processes * worker_connections/4

 

gzip 压缩   

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";​

第1行:开启Gzip

第2行:不压缩临界值,大于1K的才压缩,一般不用改

第3行:buffer,就是,嗯,算了不解释了,不用改

第4行:用了反向代理的话,末端通信是HTTP/1.0,有需求的应该也不用看我这科普文了;有这句的话注释了就行了,默认是HTTP/1.1

第5行:压缩级别,1-10,数字越大压缩的越好,时间也越长,看心情随便改吧

第6行:进行压缩的文件类型,缺啥补啥就行了,JavaScript有两种写法,最好都写上吧,总有人抱怨js文件没有压缩,其实多写一种格式就行了

第7行:跟Squid等缓存服务有关,on的话会在Header里增加"Vary: Accept-Encoding",开启对客户端浏览器进行是否支持gzip功能进行判断,若不支持则不开启gzip功能

第8行:IE6对Gzip不怎么友好,不给它Gzip了

 

内核解析

 

 

 

 

 

 

 

posted @ 2019-12-26 11:09  richardzgt  阅读(312)  评论(0编辑  收藏  举报