当前位置:   article > 正文

cdn背后nginx 设置获取真实IP及安全配置

cdn背后nginx 设置获取真实IP及安全配置

1、获取cdn下用户的真实ip

  1. http
  2. {
  3. set_real_ip_from 0.0.0.0/0;
  4. real_ip_header X-Forwarded-For;
  5. real_ip_recursive on;
  6. }

2、Nginx默认是不允许列出整个目录的,可以增加配置

  1. http
  2. {
  3. autoindex off;
  4. }

3、nginx默认是会在返回的数据包中显示版本号,隐藏ng版本号

  1. http
  2. {
  3. server_tokens off;
  4. }

4、限制访问请求参数

  1. http {
  2. #设置客户端请求头读取超时时间,超过这个时间还没有发送任何数据,Nginx将返回“Request time out(408)”错误
  3. client_header_timeout 15;
  4. #设置客户端请求主体读取超时时间,超过这个时间还没有发送任何数据,Nginx将返回“Request time out(408)”错误
  5. client_body_timeout 15;  
  6. #上传文件大小限制
  7. client_max_body_size 100m;
  8. #指定响应客户端的超时时间。这个超过仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。
  9. send_timeout    600;
  10. #设置客户端连接保持会话的超时时间,超过这个时间,服务器会关闭该连接。
  11. keepalive_timeout 60;
  12. }

5、限制访问个别目录或文件后缀名。

  1. #在访问uploads、images目录时,访问php|php5|jsp后缀的文件会返回403代码,也就是不给执行代码了。
  2. location ~ ^/(uploads|images)/.*\.(php|php5|jsp)$ {
  3. return 403;
  4. }
  5. #禁止访问所有目录下的sql|log|txt|jar|war|sh|py后缀的文件,这些是什么文件就不详细说了。
  6. location ~.*\.(sql|log|txt|jar|war|sh|py) {
  7. deny all;
  8. }
  9. #有时候,有些访问记录不想保存到日志里面,例如静态图片
  10. location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF|png)$ {
  11. access_log off;
  12. }

6、 限制IP的访问频率

防御DDOS是一个系统工程,攻击花样多,防御的成本高瓶颈多,防御起来即被动又无奈。DDOS的特点是分布式,针对带宽和服务攻击,也就 是四层流量攻击和七层应用攻击,相应的防御瓶颈四层在带宽,七层的多在架构的吞吐量。对于七层的应用攻击,我们还是可以做一些配置来防御的,例如前端是 Nginx,主要使用nginx的http_limit_conn和http_limit_req模块来防御。 ngx_http_limit_conn_module 可以限制单个IP的连接数,ngx_http_limit_req_module 可以限制单个IP每秒请求数,通过限制连接数和请求数能相对有效的防御CC攻击。

ngx_http_limit_req_module模块通过漏桶原理来限制单位时间内的请求数,一旦单位时间内请求数超过限制,就会返回503错误。配置需要在两个地方设置:
1、nginx.conf的http段内定义触发条件,可以有多个条件;
2、在location内定义达到触发条件时nginx所要执行的动作;

要先在http层定义,然后在 location, server, http上下文中作限制,他们用的是限制单ip访问的漏桶算法,超过定义的限制会报503错误,当然,有些时候可能是某个公司同一个ip有几十人一起访问网站,这是有可能被误伤的,做好503报错回调是很有必要的。

  1. http {
  2. limit_req_zone $binary_remote_addr zone=iplimit:10m rate=20r/s;
  3. # zone=iplimit:10m 表示生成一个大小为10M的名字为iplimit的内存区域来存储访问频次信息,1M大约可以存16000个ip会话,看你访问量有多少就设多少
  4. # rate=20r/s 表示允许相同标识的客户端访问频次 每秒20次,依据你的访问量来设置
  5. server{
  6. location ~ ^/api {
  7. proxy_pass http:#127.0.0.1:8000;
  8. # 对访问以/api的请求,限制每个ip每秒不超过20个请求,漏桶数burst为5,brust的意思就是,如果第1,2,3,4秒请求为19个,第5秒的请求为25个是被允许的。但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。nodelay,如果不设置该选项,第125个请求时,5个请求放到第2秒执行,设置nodelay,25个请求将在第1秒执行。
  9. limit_req zone=ipmlimit burst=5 nodelay;
  10. limit_req_status 503;
  11. # burst 缓冲区大小 
  12. # nodelay 超过访问频次而且缓冲区也满的时候返回503
  13. # limit_req_status指定自定义错误码, 默认503
  14. }
  15. }
  16. # 指定503错误页面:
  17. error_page 503 /errpage/503.html;
  18. }

 7、Nginx 限制IP的并发

通过 limit_conn_zone 模块来达到限制用户的连接数的目的,即限制同一用户 IP 地址的并发连接数。

通过配置,设定/api 这个location,每个IP,同一时刻只存在一个连接。

注意:并发的概念并不是说 每秒多少连接。

  1. http {
  2. limit_conn_zone $binary_remote_addr zone=connlimit:10m;
  3. # zone=iplimit:10m 表示生成一个大小为10M的名字为iplimit的内存区域来存储访问频次信息,1M大约可以存16000个ip会话,看你访问量有多少就设多少
  4. server{
  5. location ~ ^/api {
  6. proxy_pass http:#127.0.0.1:8000;
  7. # 配置的并发请求为 1, 依据你的实际情况来设置
  8. limit_conn connlimit 1;
  9. # limit_conn_status 指定自定义错误码, 默认503
  10. limit_conn_status 503;
  11. }
  12. }
  13. # 指定503错误页面:
  14. error_page 503 /errpage/503.html;
  15. }

 8、Nginx 限制IP的流量

通过limit_rate模块来进行流量控制, 对于提供下载的网站,肯定是要进行流量控制的。Nginx 通过 core模块的 limit_rate 等指令可以做到限流的目的。

如果要进行限速,可以和 limit_conn_zone 模块配合进行使用

  1. http {
  2. server{
  3. location ~ ^/download{
  4. # 以最大的速度下载 size大小后,在进行 limit_rate speed 限速,例如:limit_rate_after 3m 解释为:以最大的速度下载3m后,再进行限速。
  5. limit_rate_after 3m;
  6. # 向客户端传输数据的速度,速度的单位是每秒传输的字节数。注意:该限制只是针对一个连接的设定,也就是说,如果同时有2个连接,那么它的速度将会是该指令设置的两倍。
  7. limit_rate 512k;
  8. }
  9. }
  10. }

9、禁止不安全的HTTP方法

默认情况下,Nginx支持多种HTTP方法,包括GET、POST、OPTIONS等。然而,某些HTTP方法可能存在安全风险,例如TRACE方法可以被用于跨站脚本(XSS)攻击。我们可以使用Nginx的"limit_except"指令来限制某些HTTP方法的访问。
示例代码:

  1. location / {
  2. limit_except GET POST {
  3. deny all;
  4. }
  5. }
防止SQL注入、XSS攻击将下面的Nginx配置文件代码放入到对应站点的.conf配置文件[server]里,然后重启Nginx即可生效。
  1. if ($request_method !~* GET|POST) { return 444; }
  2. #使用444错误代码可以更加减轻服务器负载压力。
  3. #防止SQL注入
  4. if ($query_string ~* (\$|'|--|[+|(%20)]union[+|(%20)]|[+|(%20)]insert[+|(%20)]|[+|(%20)]drop[+|(%20)]|[+|(%20)]truncate[+|(%20)]|[+|(%20)]update[+|(%20)]|[+|(%20)]from[+|(%20)]|[+|(%20)]grant[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]where[+|(%20)]|[+|(%20)]select[+|(%20)]|[+|(%20)]and[+|(%20)]|[+|(%20)]or[+|(%20)]|[+|(%20)]count[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]chr[+|(%20)]|[+|(%20)]mid[+|(%20)]|[+|(%20)]like[+|(%20)]|[+|(%20)]iframe[+|(%20)]|[\<|%3c]script[\>|%3e]|javascript|alert|webscan|dbappsecurity|style|confirm\(|innerhtml|innertext)(.*)$) { return 555; }
  5. if ($uri ~* (/~).*) { return 501; }
  6. if ($uri ~* (\\x.)) { return 501; }
  7. #防止SQL注入
  8. if ($query_string ~* "[;'<>].*") { return 509; }
  9. if ($request_uri ~ " ") { return 509; }
  10. if ($request_uri ~ (\/\.+)) { return 509; }
  11. if ($request_uri ~ (\.+\/)) { return 509; }
  12. #if ($uri ~* (insert|select|delete|update|count|master|truncate|declare|exec|\*|\')(.*)$ ) { return 503; }
  13. #防止SQL注入
  14. if ($request_uri ~* "(cost\()|(concat\()") { return 504; }
  15. if ($request_uri ~* "[+|(%20)]union[+|(%20)]") { return 504; }
  16. if ($request_uri ~* "[+|(%20)]and[+|(%20)]") { return 504; }
  17. if ($request_uri ~* "[+|(%20)]select[+|(%20)]") { return 504; }
  18. if ($request_uri ~* "[+|(%20)]or[+|(%20)]") { return 504; }
  19. if ($request_uri ~* "[+|(%20)]delete[+|(%20)]") { return 504; }
  20. if ($request_uri ~* "[+|(%20)]update[+|(%20)]") { return 504; }
  21. if ($request_uri ~* "[+|(%20)]insert[+|(%20)]") { return 504; }
  22. if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { return 505; }
  23. if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
  24. if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
  25. if ($query_string ~ "proc/self/environ") { return 505; }
  26. if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { return 505; }
  27. if ($query_string ~ "base64_(en|de)code\(.*\)") { return 505; }
  28. if ($query_string ~ "[a-zA-Z0-9_]=http://") { return 506; }
  29. if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { return 506; }
  30. if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { return 506; }
  31. if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { return 507; }
  32. if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") {return 507; }
  33. if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { return 507; }
  34. if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { return 507; }
  35. #这里大家根据自己情况添加删减上述判断参数,cURL、wget这类的屏蔽有点儿极端了,但要“宁可错杀一千,不可放过一个”。
  36. if ($http_user_agent ~* YisouSpider|ApacheBench|WebBench|Jmeter|JoeDog|Havij|GetRight|TurnitinBot|GrabNet|masscan|mail2000|github|wget|curl|Java|python) { return 508; }
  37. #同上,大家根据自己站点实际情况来添加删减下面的屏蔽拦截参数。
  38. if ($http_user_agent ~* "Go-Ahead-Got-It") { return 508; }
  39. if ($http_user_agent ~* "GetWeb!") { return 508; }
  40. if ($http_user_agent ~* "Go!Zilla") { return 508; }
  41. if ($http_user_agent ~* "Download Demon") { return 508; }
  42. if ($http_user_agent ~* "Indy Library") { return 508; }
  43. if ($http_user_agent ~* "libwww-perl") { return 508; }
  44. if ($http_user_agent ~* "Nmap Scripting Engine") { return 508; }
  45. if ($http_user_agent ~* "~17ce.com") { return 508; }
  46. if ($http_user_agent ~* "WebBench*") { return 508; }
  47. if ($http_user_agent ~* "spider") { return 508; } #这个会影响国内某些搜索引擎爬虫,比如:搜狗
  48. #拦截各恶意请求的UA,可以通过分析站点日志文件或者waf日志作为参考配置。
  49. if ($http_referer ~* 17ce.com) { return 509; }
  50. #拦截17ce.com站点测速节点的请求
  51. if ($http_referer ~* WebBench*") { return 509; }
  52. #拦截WebBench或者类似压力测试工具,其他工具只需要更换名称即可。

10、防止恶意请求

恶意请求包括大量的请求、大文件上传、恶意脚本等等,这会导致服务器负载过高。我们可以通过设置请求限制,来防止这种情况发生。
 

  1. http {
  2. limit_req_zone $binary_remote_addr zone=req_limit:10m rate=1r/s;
  3. server {
  4. location / {
  5. limit_req zone=req_limit burst=5 nodelay;
  6. # 其他配置
  7. }
  8. }
  9. }

11、拒绝User-Agent:server、location

可能有一些不法者会利用wget/curl等工具扫描我们的网站,我们可以通过禁止相应的user-agent来简单的防范

Nginx的444状态比较特殊,如果返回444那么客户端将不会收到服务端返回的信息,就像是网站无法连接一样

  1. if ($http_user_agent ~* LWP::Simple|BBBike|wget|curl) {
  2. return 444;
  3. }

 如果经常分析网站日志你会发现,一些奇怪的 UA 总是频繁的来访问网站,而这些 UA 对网站收录毫无意义,反而增加服务器压力,可以直接将其屏蔽。

  1. if ($http_user_agent ~* (SemrushBot|python|MJ12bot|AhrefsBot|AhrefsBot|hubspot|opensiteexplorer|leiki|webmeup)) {
  2. return 444;
  3. }

12、禁止访问目录

  1. #禁止访问多个目录
  2. location ~ ^/(picture|move)/ {
  3. deny all;
  4. break;
  5. }
  6. #禁止访问 htaccess
  7. location ~/\.ht {
  8. deny all;
  9. }
  10. #禁止访问 /data 开头的文件
  11. location ~ ^/data {
  12. deny all;
  13. }
  14. #禁止访问单个目录
  15. location /imxhy/images/ {
  16. deny all;
  17. }

13、Nginx代理安全策略

Strict-Transport-Security(简称为 HSTS)可以告诉浏览器,在指定的 max-age 内,始终通过 HTTPS 访问我的站点。即使用户自己输入 HTTP 的地址,或者点击了 HTTP 链接,浏览器也会在本地替换为 HTTPS 再发送请求。

X-Frame-Options 用来指定此网页是否允许被 iframe 嵌套,deny 就是不允许任何嵌套发生。

X-Content-Type-Options 用来指定浏览器对未指定或错误指定 Content-Type 资源真正类型的猜测行为,nosniff 表示不允许任何猜测。

Content-Security-Policy(简称为 CSP)用来指定页面可以加载哪些资源,主要目的是减少 XSS 的发生。我允许了来自本站、disquscdn 的外链 JS,还允许内联 JS,以及在 JS 中使用 eval;允许来自本站和 google 统计的图片,以及内联图片(Data URI 形式);允许本站外链 CSS 以及内联 CSS;允许 iframe 加载来自 disqus 的页面。对于其他未指定的资源,都会走默认规则 self,也就是只允许加载本站的。关于 CSP 的详细介绍请看这里

  1. server {
  2. listen 28443;
  3. server_tokens off;
  4. location /cas {
  5. proxy_pass http://localhost:28442/cas;
  6. proxy_redirect default;
  7. proxy_read_timeout 600s;
  8. proxy_set_header X-Real-IP $remote_addr;
  9. proxy_set_header Host $host:$server_port;
  10. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  11. # 防止xss
  12. add_header X-XSS-Protection "1; mode=block";
  13. # 防劫持
  14. add_header X-Frame-Options "SAMEORIGIN";
  15. # 防劫持
  16. add_header X-Content-Type-Options "nosniff";
  17. # 防劫持
  18. add_header Content-Security-Policy "frame-ancestors 'self'";
  19. # HSTS
  20. add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
  21. add_header Referrer-Policy origin;
  22. add_header X-Permitted-Cross-Domain-Policies "master-only";
  23. add_header X-Download-Options noopen;
  24. index index.html index.htm;
  25. }
  26. }

14、日志快速查询

  1. #查询访问最频繁的前100个IP
  2. awk '{print $1}' access_temp.log | sort -n|uniq -c | sort -rn | head -n 100
  1. #统计耗时接⼝, 列出传输时间超过 2 秒的接⼝,显示前5条
  2. cat time_temp.log|awk '($NF > 2){print $7}'|sort -n|uniq -c|sort -nr|head -5
  3. 备注:$NF 表示最后⼀列, awk '{print $NF}'

 

awk 是⽂本处理⼯具,默认按照空格切分,
$N 是第切割后第N个,从1开始
sort命令⽤于将⽂本⽂件内容加以排序,-n 按照数值排,-r 按照倒序来排案例的
sort -n 是按照第⼀列的数值⼤⼩进⾏排序,从⼩到⼤,倒序就是 sort -rn
uniq 去除重复出现的⾏列, -c 在每列旁边显示该⾏重复出现的次数。
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/383708
推荐阅读
相关标签
  

闽ICP备14008679号