网站系统安全配置(Nginx)防止网站被恶意被攻,网站如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=20r/s;”:针对突发流量访问频率。表示定义一个名称为ConnLimitZone的存储区域,ConnLimitZone内容为远程客户端IP地址,ConnLimitZone大小20M,ConnLimitZone中的平均请求速率为每秒20个; “limit_req_log_level notice;”为定义log级别。 语法:limit_req_zone key zone rate key :定义限流对象,$binary_remote_addr 是一种key,表示基于 remote_addr(客户端IP) 来做限流,binary 的目的是压缩内存占用量。 zone:定义共享内存区来存储访问信息, ConnLimitZone:20m 表示一个大小为20M,叫 ConnLimitZone 的内存区域。1M能存储16000 IP地址的访问信息,10M可以存储16W IP地址访问信息。 rate:用于设置最大访问速率,rate=10r/s 表示每秒最多处理10个请求。Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续100毫秒内又有请求到达,将拒绝处理该请求。 以上配置应用于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地址。