0%

Nginx优化

Nginx 安全优化

隐藏Nginx版本号

1
2
3
4
http
{
server_tokens off;
}

Nginx更改默认用户

nginx配置中指定用户启动

1
2
$ vim /etc/nginx/nginx.conf
user nginx; # 指定用户启动nginx

优化Nginx服务性能

Nginx指定进程数

worker_processes语法:

1
2
3
syntax:         worker_processes number;    #此行为参数语法,number为数量
default: worker_processes 1; #此行意思是不匹配该参数,软件默认情况数量为1
context: main; #此行为worker_processes参数可以放置的位置

优化Nginx进程个数的策略:
worker进程数最开始的设置可以等于CPU的核数,且worker进程数要多一些,这样起始提供服务时就不会出现因为访问量快速增加而临时启动新进程提供服务的问题,缩短了系统的瞬时开销和提供服务的时间,提升了服务用户的速度。高流量高并发场合也可以考虑将进程数提高至CPU核数*2,具体情况要根据实际的业务来选择,因为这个参数除了要和CPU核数匹配外,也和硬盘存储的数据及系统的负载有关,设置为CPU的核数是一个好的起始配置,这也是官方的建议。

Nginx 进程优化

默认情况下,Nginx的多个进程有可能跑在某一个CPU或CPU的某一核上,导致Nginx进程使用硬件的资源不均,本节的优化是尽可能地分配不同的Nginx进程给不同的CPU处理,达到充分有效利用硬件的多CPU多核资源的目的。

在优化不同的Nginx进程对应不同的CPU配置时,四核CPU服务器的参数配置参考如下:

1
2
3
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
# worker_cpu_affinity就是配置Nginx进程与CPU亲和力的参数,即把不同的进程分给不同的CPU处理。这里0001 0010 0100 1000是掩码,分别代表第1,2,3,4核CPU,由于worker_processes进程数为4,因此,上述配置会把每个进程分配一核CPU处理,默认情况下进程不会绑定任何CPU,参数位置为main段。

四核和八核CPU服务器的参数配置参考如下:

1
2
3
4
5
# 八核掩码
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
# 四核掩码
worker_cpu_affinity 0001 0010 0100 1000;
# worker_cpu_affinity 的作用是绑定不同的worker进程数到一组CPU上。通过设置bitmask控制进程允许使用的CPU,默认worker进程不会绑定到任何CPU(自动平均分配。)

下面是绑定的实例配置:

1
2
3
4
5
6
7
8
worker_processes  4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_processes 2;
worker_cpu_affinity 0101 1010;

# 最佳方式绑定方式
worker_processes auto;
worker_cpu_affinity auto;

Nginx 事件模型优化

Nginx的连接处理机制在不同的操作系统会采用不同的I/O模型,在Linux下,Nginx使用epoll的I/O多路复用模型,在Freebsd中使用kqueue的I/O多路复用模型,在Solaris中使用/dev/poll方式的I/O多路复用模型,在Windows中使用的是icop,等等。要根据系统类型选择不同的事件处理模型,可供使用的选择有“use [kqueue|rtsig|epoll|/dev/poll|select|poll];”。

事件模型语法:

1
2
3
synstax:  use method;  # 络模型配置,method选择模型之一
default: -- # 默认没有设置
context: events # 网络模型配置放置events区块内

实践修改Nginx配置:

1
2
3
4
5
$ vi /etc/nginx/nginx.conf
# events 区块是一个用来设置连接进程的区块,例如:设置Nginx的网络I/O模型,以及连接数等。
events {
use epoll;
}

根据Nginx官方文档建议,也可以不指定事件处理模型,Nginx会自动选择最佳的事件处理模型服务。

Nginx 最大连接数

调整Nginx单个进程允许的客户端最大连接数,这个控制连接数的参数为work_connections,worker_connections的值要根据具体服务器性能和程序的内存使用量来指定(一个进程启动使用的内存根据程序确定)

worker_connections语法:

1
2
3
synstax: worker_connections number
default: worker_connections 512
context: events

实践修改Nginx配置:

1
2
3
4
$ vi /etc/nginx/nginx.conf
events {
worker_connections 20480;
}

说明:
worker_connections用来设置一个worker process支持的最大并发连接数,这个连接数包括了所有链接,例如:代理服务器的连接,客户端的连接等,实际的并发连接数除了受worker_connections参数控制外,还和最大打开文件数worker_rlimit_nofile有关(见下文),Nginx总并发连接=worker数量*worker_connections。

参考资料:http://nginx.org/en/docs/ngx_core_module.html

Nginx 文件描述符

调整配置Nginx worker进程的最大打开文件数,这个控制连接数的参数为worker_rlimit_nofile。

worker_rlimit_nofile语法:

1
2
3
synstax: worker_rlimit_nofile number
default: 无
context: main

实践修改Nginx配置:

1
2
3
$ vi /etc/nginx/nginx.conf
# 最大打开文件数,可设置为系统优化后的ulimit-HSn的结果
worker_rlimit_nofile 65535;

Nginx高效传输

设置参数:sendfile on;

sendfile参数用于开启文件的高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率。

参数作用:激活或禁用sendfile()功能功能。sendfile()是作用于两个文件描述符之间的数据拷贝函数,这个拷贝操作是在内核之中的,被称为“零拷贝”,sendfile()比read和write函数要高效很多,因为,read和write函数要把数据拷贝到应用层再进行操作。相关控制参数还有sendfile_max_chunk。

参考资料:http://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile

设置参数:tcp_nopush on;

提高网络的“传输效率”

参数作用:激活或禁用Linux上的TCP_CORK socket选项,此选项仅仅当开启sendfile时才生效,激活这个tcp_nopush参数,数据包不会马上转发出去,而是等数据包最大时,一次性转发出去,有效解决网络堵塞。

参考资料:http://nginx.org/en/docs/http/ngx_http_core_module.html

设置参数:tcp_nodelay on;

在keeplive连接下,提高网络的传输“实时性”
用于激活tcp_ondelay功能,提高I/O性能。

参数作用:默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高I/O性能。但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay功能能够让数据包立刻转发出去。

参数生效条件:
激活或禁用TCP_NODELAY选项,当一个连接进入keep-alive状态时生效。

参考资料:http://nginx.org/en/docs/http/ngx_http_core_module.html

Nginx连接参数优化

keepalive_timeout

用于设置客户端连接保持会话的超时时间为60秒。超过这个时间,服务器会关闭该连接,此数值为参考值。

参数作用:keep-alive可以使客户端到服务器端已经建立的连接一直工作不退出,当服务器有持续请求时,keep-alive会使用已经建立的连接提供服务,从而避免服务器重新建立新连接处理请求。

此参数设置一个keep-alive(客户端连接在服务器端保持多久后退出),其单位是秒,和HTTP响应header域的“Keep-Alive:timeout=time”参数有关,这些header信息也会被客户端浏览器识别并处理,不过有些客户端并不能按照服务器端的设置来处理,例如:MSIE大约60秒后会关闭keep-alive连接。

参考资料:http://nginx.org/en/docs/http/ngx_http_core_module.html

client_header_timeout

用于设置读取客户端请求头数据的超时时间。此处的数值15,其单位是秒,为经验参考值。

参数作用:设置读取客户端请求头数据的超时时间。如果超过这个时间,客户端还没有发送完整的header数据,服务器端将返回“Request time out (408)”错误,可指定一个超时时间,防止客户端利用http协议进行攻击。

参考资料:http://nginx.org/en/docs/http/ngx_http_core_module.html

client_body_timeout

用于设置读取客户端请求主体的超时时间,默认值60

参数作用:设置读取客户端请求主体的超时时间。这个超时仅仅为两次成功的读取操作之间的一个超时,非请求整个主体数据的超时时间,如果在这个超时时间内,客户端没有发送任何数据,Nginx将返回“Request time out(408)”错误,默认值60,

send_timeout 25

用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动或者Nginx数据没有发送完,Nginx都将会关闭连接,默认值为60秒,可以改为参考值25秒。

参数作用:设置服务器端发送HTTP响应信息到客户端的超时时间,这个超时仅仅为两次成功握手后的一个超时,非请求整个响应数据的超时时间,如在这个超时时间内,客户端没有接收任何数据,连接将被关闭。

Nginx上传文件大小限制

参数作用:设置最大的允许的客户端请求主体大小,在请求头域有“Content-Length”,如果超过了此配置值,客户端会受到413错误,意思是请求的条目过大,有可能浏览器不能正确显示。设置为0表示禁止检查客户端请求主体大小。此参数对提高服务器端的安全性有一定作用。

FastCGI调优

FastCGI参数是配合Nginx向后请求PHP动态引擎服务的相关参数。
FastCGI常见参数的Nginx配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ cat /etc/nginx/nginx.conf
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 65535;
user nginx;
events {
use epoll;
worker_connections 10240;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
tcp_nodelay on;
client_header_timeout 15;
client_body_timeout 15;
send_timeout 15;
server_tokens off;
fastcgi_connect_timeout 30s; #Nginx允许fcgi连接超时时间
fastcgi_send_timeout 30s; #Nginx允许fcgi返回数据的超时时间
fastcgi_read_timeout 30s; #Nginx读取fcgi响应信息的超时时间
fastcgi_buffer_size 64k; #Nginx读取响应信息的缓冲区大小
fastcgi_buffers 4 64k; #指定Nginx缓冲区的数量和大小
fastcgi_busy_buffers_size 128k; #当系统繁忙时buffer的大小
fastcgi_temp_file_write_size 128k; #Nginx临时文件的大小
fastcgi_temp_path /data/ngx_fcgi_tmp; #指定Nginx临时文件放置路径
fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:10m inactive=1d; #指定Nginx缓存放置路径

server {
listen 80;
location ~ .*\.(php|php5)?$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_cache ngx_fcgi_cache; #开启fcgi缓存并起名叫ngx_fcgi_cache,很重要,有效降低CPU负载,并且防止502错误发生。
fastcgi_cache_valid 200 302 1h; #指定应答代码的缓存时间,1h=1小时
fastcgi_cache_valid 301 1d; #1d=1天
fastcgi_cache_valid any 1m; #and 1m:将其他应答缓存1分钟
fastcgi_cache_min_uses 1; #待缓存内容至少要被用户请求过1次
fastcgi_cache_use_stale error timeout invalid_header http_500; #当遇到error,timeout,或者返回码500时,启用过期缓存返回用户(返回过期也比返回错误强)
# fastcgi_cache_key http://$host$request_uri;

}
}

Nginx gzip

Nginx gzip压缩模块提供了压缩文件内容的功能,用户请求的内容在发送到用户客户端之前,Nginx服务器会根据一些具体的策略实施压缩,以节约网站出口带宽,同时加快数据传输效率,来提升用户访问体验。

Nginx gzip压缩的优点
1.提升网站用户体验:发送给用户的内容小了,用户访问单位大小的页面就加快了,用户体验提升了,网站口碑就好了。
2.节约网站带宽成本:数据是压缩传输的,因此节省了网站的带宽流量成本,不过压缩时会稍微消耗一些CPU资源,这个一般可以忽略。

对应的压缩参数说明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#压缩配置
gzip on;
#<==开启gzip压缩功能

gzip_min_length 1k;
#<==设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值0,表示不管页面多大都进行压缩。建议设置成大于1K,如果小于1K可能会越压越大。

gzip_buffers 4 16K;
#<==压缩缓冲区大小。表示申请4个单位为16K的内存作为压缩结果流缓冲,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。

gzip_http_version 1.1;
#<==压缩版本(默认1.1,前端为squid2.5时使用1.0),用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可。

gzip_comp_level 2;
#<==压缩比率。用来指定gzip压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源。

gzip_types text/plain text/css application/x-javascript application/xml application/javascript application/javascript image/jpeg image/jpg image/png;
#<==用来指定压缩的类型,“text/html”类型总是会被压缩,这个就是HTTP原理部分讲的媒体类型。压缩类型可以在../conf/mime.types文件中查看

gzip_vary on;
#<==vary header支持。该选项可以让前端的缓存服务器缓存经过gzip压缩的页面,例如用Squid缓存经过Nginx压缩的数据。

Nginx Expires 缓存

简单说,Nginx expires的功能就是为用户访问的网站内容设定一个过期时间,当用户第一次访问这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及以后继续访问该网站时,浏览器会检查加载已经缓存在用户浏览器本地的内容,就不会去服务器请求了,当缓存的内容过期了会向源服务器发送请求,检查缓存内容是否被修改。

更深入的理解:
expires的功能就是允许通过Nginx配置文件控制HTTP的“Expires”和“Cache-Control”响应头部内容,告诉客户端浏览器是否缓存和缓存多久以内访问的内容。这个expires模块控制Nginx服务器应答时的expires头内容和Cache-Control头的max-age指令。缓存的有效期可以设置为相对于源文件的最后修改时刻或客户端的访问时刻。
这些HTTP头向客户端表明了额内容的有效性和持久性。如果客户端本地有内容缓存,则内容就可以从缓存而不是从服务器中读取,然后客户端会检查缓存中的副本,看其是否过期或失效,以决定是否重新从服务器获得内容更新。

Nginx expires配置详解

根据文件扩展名进行判断,添加expires功能范例

1
2
3
4
5
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 3650d;
}
#该范例的意思是当用户访问网站URL结尾的文件扩展名为上述指定类型的图片时,设置缓存3650天,即10年。
1
2
3
4
5
location ~ .*\.(js|css)$
{
expires 30d;
}
#该范例的意思是当用户访问网站URL结尾的文件扩展名为js,css类型的元素时,设置缓存30天,即1个月。

根据URL中的路径(目录)进行判断,添加expires功能范例

1
2
3
4
5
location ~ ^/(images|javascript|js|css|flash|media|static)/
{
expires 360d;
}
#该范例的意思是当用过户访问网站URL中包含上述路径(例:images,js,css,这些在服务器端是程序目录)时,把访问的内容设置缓存360天,即1年。

注意事项:expires只能在web节点上的nginx的配置文件里生效,如果配置在nginx方向代理的话,expires是不生效的

Nginx 日志文件安全

不记录特定的访问日志

在实际工作中,对于负载均衡器健康节点检查或某些特定文件(比如图片,JS,CSS)的日志,一般不需要记录下来,因为在统计PV时是按照页面计算的,而且日志写入太频繁会消耗大量磁盘I/O,降低服务的性能。

1
2
3
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ {
access_log off;
}

访问日志的权限设置

假如日志目录为/app/logs,则授权方法如下:

1
2
chown -R root.root /app/logs
chmod -R 600 /app/logs

不需要在日志目录上给Nginx用户读或写许可,但很多网友都没注意这个问题,他们把该权限直接给了Nginx或Apache用户,这就成为了安全隐患。

Nginx 访问控制

根据扩展名限制程序和文件访问

1
2
3
4
5
6
7
8
9
10
location ~ ^/images/.*\.(php|php5|sh|pl|py)$ {
deny all;
}

location ~ ^/static/.*\.(php|php5|sh|pl|py)$ {
deny all;
}
location ~* ^/data/(attachment|avatar)/.*\.(php|php5)$ {
deny all;
}

对上述目录的限制必须写在Nginx处理PHP服务配置的前面,如下:

1
2
3
4
5
6
location ~ .*\.(php|php5)$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

Nginx下配置禁止访问.txt和.doc文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
location ~* \.(txt|doc)$
{
if (-f $request_filename)
{
root /data/www/www;
#rewrite ...可以重定向到某个URL
break;
}
}
location ~* \.(txt|doc)$
{
root /data/www/www;
deny all;
}

禁止访问指定的目录

1
2
3
4
5
6
7
8
9
#禁止访问单个目录的命令如下:
location ~ ^/static {
deny all;
}

#禁止访问多个目录的命令如下:
location ~ ^/(static|js) {
deny all;
}
1
2
3
4
5
6
7
8
9
10
#禁止访问目录并返回指定的HTTP状态码
server {
listen 80;
server_name www.youngboy.com youngboy.com;
root /data/www/www;
index index.html index.htm;
access_log logs/www_access.log commonlog;
location /admin/ {return 404;}
location /tmplates/ {return 403;}
}

Nginx 限制来源IP访问

使用ngx_http_access_module限制网站来源IP访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 禁止某目录让外界访问,但允许某IP访问该目录,且支持PHP解析,命令如下:
location ~ ^/yunjisuan/ {
allow 202.111.12.211;
deny all;
}

location ~ .*\.(php|php5)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}

# 限制指定IP或IP段访问
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
}

Nginx做反向代理的时候可以限制客户端IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#方法一:使用if来控制,命令如下:
if ($remote_addr = 10.0.0.7) {
return 403;
}

if ($remote_addr = 218.247.17.130) {
set $allow_access_root 'ture';
}

#方法二:利用deny和allow只允许IP访问,命令如下:
location / {
root html/blog;
index index.php index.html index.htm;
allow 10.0.0.7;
deny all;
}

#方法三:只拒绝某些IP访问,命令如下:
location / {
root html/blog;
index index.php index.html index.htm;
deny 10.0.0.7;
allow all;
}

注意事项:
1.deny一定要加一个IP,否则会直接跳转到403,不再往下执行了,如果403默认页是在同一域名下,会造成死循环访问。
2.对于allow的IP段,从允许访问的段位从小到大排列,如127.0.0.0/24的下面才能是10.10.0.0/16,其中:
1)24表示子网掩码:255.255.255.0
2)16表示子网掩码:255.255.0.0
3)8表示子网掩码:255.0.0.0
3.以deny all:结尾,表示除了上面允许的,其他的都禁止。如:
1)deny 192.168.1.1;
2)allow 127.0.0.0/24;
3)allow 192.168.0.0/16;
4)allow 10.10.0.0/16;
5)deny all;

Nginx 禁止非法域名解析

Nginx如何防止用户IP访问网站(恶意域名解析,也相当于是直接IP访问企业网站)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 方法一
# 让使用IP访问网站的用户,或者恶意解析域名的用过户,收到501错误
# 直接用新的server标签
server {
listen 80 default_server;
server_name _;
return 501;
}
# 说明:直接报501错误,从用户体验上不是很好

# 方法二
# 通过301跳转到主页
# 当输入IP地址访问的时候会自动跳转到域名
server {
listen 80 default_server;
server_name _;
rewrite ^(.*) http://xxx.com/$1 permanent;
}

# 方法三
# 发现某域名恶意解析到公司的服务器IP,在server标签里添加以下代码即可,若有多个server则要多处添加
if ($host !~ ^xxx.com$) {
rewrite ^(.*) http://xxx.com/$1 permanent;
}
# 说明:代码含义为如果header信息的host主机名字非xxx.com,就301跳转到xxx.com

Nginx 防爬虫

我们可以根据客户端的user-agents信息,轻松地阻止指定的爬虫爬取我们的网站。下面来看几个案例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 阻止下载协议代理
# Block download agents##
if ($http_user_agent ~* LWP:Simple|BBBike|wget) {
return 403;
}
#如果用户匹配了if后面的客户端(例如wget),就返回403.
#这里根据$http_user_agent获取客户端agent,然后判断是否允许或返回指定错误码。

# 添加内容防止N多爬虫代理访问网站
#这些爬虫代理使用“|”分隔,具体要处理的爬虫可以根据需求增加或减少,添加的内容如下:
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot-Modile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! SSlurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot"){
return 403;
}

# 测试禁止不同的浏览器软件访问
if ($http_user_agent ~* "Firefox|MSIE") {
rewrite ^(.*) http://xxx.com/$1 permanent;
}
#如果浏览器为Firefox或IE,就会跳转到http://xxx.com

Nginx 限制HTTP请求方法

最常用的HTTP方法为GET,POST,我们可以通过Nginx限制HTTP请求的方法来达到提升服务器安全的目的,例如,让HTTP只能使用GET,HEAD和POST方法的配置如下:

1
2
3
4
5
6
7
#Only allow these request methods
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 501;
}

#命令解释:
($request_method !~ ^(GET|HEAD|POST)$) #<==如果匹配的http请求方法不是get|head|post就拒绝掉

当上传服务器上传数据到存储服务器时,用户上传写入的目录就不得不给Nginx对应的用户相关权限,这样一旦程序有漏洞,木马就有可能被上传到服务器挂载的对应存储服务器的目录里,虽然我们也做了禁止PHP,SH,PL,PY等扩展名的解析限制,但还是会遗漏一些想不到的可执行文件。对于这样情况,该怎么办呢?事实上,还可以通过限制上传服务器的Web服务(可以具体到文件)使用GET方法,防止用户通过上传服务器访问存储内容,让访问存储渠道只能从静态或图片服务器入口进入。

例如,在上传服务器上限制HTTP的GET方法的配置如下:

1
2
3
4
5
#Only deny GET request methods ##
if ($request_method ~* ^(GET)$) {
return 501;
}
#还可以加一层location,更具体地限制文件名

Nginx 连接限制

连接频率限制 limit_conn_module
请求频率限制 limit_req_module

Nginx连接限制配置

具体配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
http {  #http段配置连接限制, 同⼀时刻只允许⼀个客户端IP连接 
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;

...

server {

...

location / {
#同⼀时刻只允许⼀个客户端IP连接
limit_conn conn_zone 1;
}

#压⼒测试 yum install -y httpd-tools ab -n 50 -c 20 http://127.0.0.1/index.html

Nginx 请求限制配置

具体配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
http {  ##http段配置请求限制, rate限制速率,限制⼀秒钟最多⼀个IP请求 
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;

...

server {

...

location / {
#1r/s只接收⼀个请求,其余请求拒绝处理并返回错误码给客户端

limit_req zone=req_zone;
#请求超过1r/s,剩下的将被延迟处理,请求数超过burst定义的数量, 多余的请求返回503

#limit_req zone=req_zone burst=3 nodelay; }

#压⼒测试 yum install -y httpd-tools ab -n 50 -c 20 http://127.0.0.1/index.html

Nginx SSL HTTPS

开启 HTTP/2

HTTP/2最初是在Nginx版本1.9.5中实现的,以取代spdy。在Nginx上启用HTTP/2模块很简单。

原先的配置:

1
listen 443 ssl;

修改为:

1
listen 443 ssl http2;

可以通过curl来验证:

1
curl --http2 -I https://domain.com/

开启 SSL session 缓存

启用 SSL Session 缓存可以减少 TLS 的反复验证,减少 TLS 握手。 1M 的内存就可以缓存 4000 个连接,非常划算,现在内存便宜,尽量开启。

1
2
ssl_session_cache shared:SSL:50m; # 1m 4000个,
ssl_session_timeout 1h; # 1小时过期 1 hour during which sessions can be re-used.

禁用 SSL session tickets

由于Nginx中尚未实现SSL session tickets,可以关闭。

1
ssl_session_tickets off;

禁用 TLS version 1.0

1
ssl_protocols TLSv1.2 TLSv1.3;

启用OCSP Stapling

如果不启用 OCSP Stapling 的话,在用户连接你的服务器的时候,需要去验证证书,这个验证证书的时间不可控,我们开启OCSP Stapling后,可以省掉这一步。

1
2
3
4
5
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/full_chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

减小ssl buffer size

ssl_buffer_size 控制在发送数据时的 buffer 大小,默认情况下,缓冲区设置为16k,为了最大程度地减少TTFB(至第一个字节的时间),最好使用较小的值,这样TTFB可以节省大约30 – 50ms。

1
ssl_buffer_size 4k;

调整 Cipher 优先级

更新更快的 Cipher放前面,这样延迟更小。

1
2
3
# 手动启用 cipher 列表
ssl_prefer_server_ciphers on; # prefer a list of ciphers to prevent old and slow ciphers
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';