网站系统安全配置(Nginx)防止网站被恶意GJ。网站如DDos,CC等。他们之间都原理都一样,即发送大量的请求数据到服务器。
- Nginx主动防御方法
Nginx中有 2 个模块用于控制访问用户连接的“数量”和“速度”。分别是
HttpLimitZoneModule:限制同时并发连接数访问控制
HttpLimitReqModule:限制访问数据,每秒最多多少次的请求
以上两个模块配置比较容易影响系统业务的正常访问,每秒最多的访问次数,同时的并发访问控制,不能设置太死,要不然都杀无赦,统统将正常客户请求挡在外面。 -
Nginx普通配置
http模块中配置# 用户的 IP 地址 $binary_remote_addr 作为 Key,每个 IP 地址最多有 50 个并发连接 # 你想开几千个连接 刷死我? 超过 50 个连接,直接返回 503 错误给你,根本不处理你的请求了 # limit single IP 50 concurrent control limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:20m ; limit_conn TotalConnLimitZone 50; limit_conn_log_level notice; # 用户的 IP 地址 $binary_remote_addr 作为 Key,每个 IP 地址每秒处理 20 个请求 # 你想用程序每秒几百次的刷我,没戏,再快了就不处理了,直接返回 503 错误给你 # limit single IP/s 20 Request limit_req_zone $binary_remote_addr zone=ConnLimitZone:20m rate=20r/s; limit_req_log_level notice;
其中“limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:20m ;”表示定义一个名称为TotalConnLimitZone的存储区域,大小20M。 “limit_req_log_level notice;”为定义log级别。
其中“limit_req_zone $binary_remote_addr zone=ConnLimitZone:20m rate=25r/s;”表示定义一个名称为ConnLimitZone的存储区域,ConnLimitZone内容为远程IP地址,ConnLimitZone大小20M,ConnLimitZone中的平均请求速率为每秒20个; “limit_req_log_level notice;”为定义log级别。
以上配置应用于server模块... location /abc/ { limit_req zone=ConnLimitZone burst=5 nodelay; proxy_pass http://abc_pool/; } ...
其中“zone=ConnLimitZone”设置使用哪个配置区域来做限制,与上面limit_req_zone的name对应;burst=5,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区,当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内,所以,总的每秒处理请求是上面的20 + 5个排队;nodelay,如果设置,超过访问频次并且缓冲区也满了,会直接返回503,如果没有设置,则所有请求会等待排队。
-
Nginx高级一点的配置
上面是简单的服务器安全限制访问配置,是在比较简单的客户端浏览器 —–> 系统服务器的访问结构,中间是没有各种网络加速(CDN)的情况下配置。
很多情况下,是普通用户浏览器 —–> 360网站卫士加速(CDN,360防CC,DOS) ——> 阿里云加速服务器(我们自己建的CDN,阿里云盾) ——> 源服务器(PHP 程序部署在这里,iptables,nginx 安全配置)。
网站中间经历了好几层透明加速和安全过滤, 这种情况下,就不能用上面的“普通配置”。“源IP”地址不再是普通用户的IP,而是中间网络加速服务器的IP地址了。
所以,要获取真实客户端IP,就需
X-Forwarded-For : 用户IP,代理服务器IP...
经过多层代理之后,用户的真实IP 在第一个位置,后面会跟一串中间代理服务器的IP地址,从这里取到用户真实的IP地址,针对这个IP 地址做限制就可以了。
Nginx配置:#这里取得原始用户的IP地址 map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr; } # limit single IP 50 concurrent control,这里的$binary_remote_addr变成$clientRealIp,$clientRealIp为Key limit_conn_zone $clientRealIp zone=TotalConnLimitZone:20m ; limit_conn TotalConnLimitZone 50; limit_conn_log_level notice; # limit single IP/s 20 Request,这里的$binary_remote_addr变成$clientRealIp,$clientRealIp为Key limit_req_zone $clientRealIp zone=ConnLimitZone:20m rate=20r/s; limit_req_log_level notice; # 具体服务器配置 server { listen 80; location ~ \.php$ { limit_req zone=ConnLimitZone burst=5 nodelay; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; } }
-
测试
Nginx配置怎么测试,使用Echo模块。查看本地的Nginx是否有此模块,输入nginx -V命令查看,如果没有,需额外下载该模块进行编译安装。
这里直接展示nginx配置server { listen 80; server_name www.aaa.com; ## 当用户访问 /nginx-test 的时候,我们输出 $clientRealIp 变量,看看这个变量, 用户源IP 地址 location /nginx-test { echo $clientRealIp; } }
访问网址接nginx-test,下载后用文本编译器打开,即可看到用户端通过多层CDN 之后,$clientRealIp仍然是有效的原始用户IP地址。