提及网络***,可能不少人只知道大名鼎鼎的DDOS***,这种***廉价且效果出众,直接经过第四层网络协议用他的带宽把你的带宽顶掉,形成网路阻塞,防不胜防,就连腾讯这种大鳄公司也被大流量DDOS搞过焦头烂额。暂时的解决方法只有三种,第一种就是你要够有钱,买强大的高级防火墙,或者使用的带宽足够大,无视这些网络流量。第二种是技术足够强,例如个别有技术的大牛公司(阿里),用类如DPDK的高效数据包处理驱动,开发出流量清洗服务,把垃圾网络包过滤掉,不过同时也会影响正常的网络包,增长延时。第三种就是钱很少的公司多数使用的方案,换ip(废话)。不过,如今有不少公司推出本身的流量清洗服务,细化到按小时收费,也是至关灵活了,按需购买。javascript
不过还有一种网络***其实比起DDOS更频繁出现,就是CC(Challenge Collapsar)***,通常来讲是利用网站代码漏洞,不停地发大量数据包请求,形成对方服务器回应这些请求致使资源耗尽,一直到宕机崩溃。这种***属于第七层的网络协议,一方面在服务器层面是正常的请求,因此这种状况想根本解决问题,只能从代码入手。可是另外一方面,也就能够用其余来限制他访问,例如nginx的配置上也是能稍微防一下。php
nginx基本安全配置css
先说一些基本安全设置,由开始发展到如今,其实nginx的安全作得比之前已经好很多,不过有些仍是要强调一下。html
Nginx默认是不容许列出整个目录的,不过,咱们为了安全,最好仍是确认这个真的关闭了,否则代码被拉走了就悲剧了。java
http { autoindex off; }
nginx默认是会在返回的数据包中显示版本号,本来这个并非大问题,可是被别有用心的人专门***这个版本的话,那就很差了,因此,咱们仍是隐藏好一点。node
http { server_tokens off; }
其余限制访问请求参数nginx
http { #设置客户端请求头读取超时时间,超过这个时间尚未发送任何数据,Nginx将返回“Request time out(408)”错误 client_header_timeout 15; #设置客户端请求主体读取超时时间,超过这个时间尚未发送任何数据,Nginx将返回“Request time out(408)”错误 client_body_timeout 15; #上传文件大小限制 client_max_body_size 100m; #指定响应客户端的超时时间。这个超过仅限于两个链接活动之间的时间,若是超过这个时间,客户端没有任何活动,Nginx将会关闭链接。 send_timeout 600; #设置客户端链接保持会话的超时时间,超过这个时间,服务器会关闭该链接。 keepalive_timeout 60; }
毫无疑问,nginx是能够作访问限制的,allow就是容许访问的ip和ip段,deny就是禁止访问的ip和ip段,不过这个须要看你网站的需求,如今满天飞的家用宽带IP,谁敢说IP一直是那一个。web
#设置网站根目录的访问权限 location / { allow 192.168.1.1/24; allow 120.76.147.159; deny 119.23.19.240; deny 192.168.3.1/24; deny all; }
因此,咱们再细化一点,限制访问个别目录或文件后缀名。算法
#在访问uploads、p_w_picpaths目录时,访问php|php5|jsp后缀的文件会返回403代码,也就是不给执行代码了 location ~ ^/(uploads|p_w_picpaths)/.*\.(php|php5|jsp)$ { allow 192.168.1.1/24; return 403; } #禁止访问全部目录下的sql|log|txt|jar|war|sh|py后缀的文件,这些是什么文件就不详细说了。 location ~.*\.(sql|log|txt|jar|war|sh|py) { deny all; } #有时候,有些访问记录不想保存到日志里面,例如静态图片 location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF|png)$ { access_log off; } #若是想用户体验好一点,能够创建一个报错页面,而后让这个页面跳转到其余页面 error_page 403 http://www.example.com/errorfile/404.html;
再高级一点,判断特定条件,而后拒绝服务sql
#判断当http_user_agent返回的结果中包含UNAVAILABLE关键字,则返回403错误。 location / { if ($http_user_agent ~ UNAVAILABLE) { return 403; } }
再次强调,这些要跟网站实际状况相结合,要否则影响范围被扩大,形成一些莫名其妙的事,那可不是好事,不过通常403都是本身控制,比较好判断,因此最好别直接deny all。
nginx高级安全配置
访问权限控制:
想更精准控制访问权限,其实还有auth_basic指令,用户必须输入有效的用户名和密码才能访问站点。而用户名和密码应该列在 auth_basic_user_file指令设置的文件中。
server { ... auth_basic "closed website"; auth_basic_user_file conf/htpasswd; }
auth_basic的off参数能够取消验证,好比对于一些公共资源,则能够取消验证。
server { ... auth_basic "closed website"; auth_basic_user_file conf/htpasswd; location /public/ { auth_basic off; } }
咱们还需使用satisfy指令来组合来使用IP访问和Http验证。 其默认设置为all,即IP访问和HTTP验证同时经过时才容许用户访问,若设置为any,即IP访问和HTTP验证其一经过就容许用户访问
location / { satisfy any; allow 192.168.1.0/24; deny all; auth_basic "closed site"; auth_basic_user_file conf/htpasswd; }
这样弄好像变得有点复杂,因此仍是得看需求。
---------------------------------------------------------------------------------
链接权限控制:
实际上nginx的最大链接数是worker_processes乘以worker_connections的总数。
也就是说,下面的这个配置,就是4X65535,通常来讲,咱们会强调worker_processes设置成和核数相等,worker_connections并无要求。可是同时这个设置其实给了***者空间,***者是能够同时发起这么多个链接,把你服务器搞跨。因此,咱们应该更合理的配置这两个参数。
user www; worker_processes 4; error_log /data/logs/nginx_error.log crit; pid /usr/local/nginx/nginx.pid; events { use epoll; worker_connections 65535; }
不过,也不是彻底没有办法限制,在nginx0.7开始,出了两个新的模块:
HttpLimitReqModul: 限制单个 IP 每秒请求数
HttpLimitZoneModule: 限制单个 IP 的链接数
这两个模块,要先在http层定义,而后在 location, server, http上下文中做限制,他们用的是限制单ip访问的漏桶算法,也就是说超过定义的限制会报503错误,这样爆发的cc***就所有被限制住了。固然,有些时候多是某个公司同一个ip有几十人一块儿访问网站,这是有可能被误伤的,作好503报错回调是颇有必要的。
先看HttpLimitReqModul:
http { limit_req_zone $binary_remote_addr zone=test_req:10m rate=20r/s; … server { … location /download/ { limit_req zone=test_req burst=5 nodelay; } } }
上面http层的就是定义,这是一个名为test_req的limit_req_zone空间,用来存储session数据,大小是10M内存,1M大约能够存16000个ip回话,看你访问量有多少就设多少。以$binary_remote_addr 为key,这个定义是客户端IP,能够改为$server_name等其余,限制平均每秒的请求为20个,写成20r/m就是每分钟了,也是看你访问量。
下面location层就是应用这个限制了,对应上面的定义,对访问download文件夹的请求,限制每一个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秒执行。
就这个限制定义而言,把每一个IP限制了请求数,对于海量的cc请求***,效果明显,例如限制到1r/s每秒一次请求,那就更明显了,不过也正如开头所说,对于大公司多人统一IP同时访问,不免出现误伤,因此仍是得多考虑。
而后再看HttpLimitZoneModule:
http { limit_conn_zone test_zone $binary_remote_addr 10m; server { location /download/ { limit_conn test_zone 10; limit_rate 500k; } } }
和上面的相似,上面http层就是总定义,这是一个名为test_zone的limit_conn_zone空间,大小也是10M,key仍是客户端IP地址,不过这个没有限制次数,改下面定义去了。
下面location层就是真正定义了,由于key定义是客户端ip,因此limit_conn就是一个IP限制了10个链接,若是是$server_name,那就是一个域名10个链接。而后下面limit_rate就是限制一个链接的带宽,若是一个ip两个链接,就是500x2k,这里是10,那就是最多能够有5000K速度给到这个ip了。
-----------------------------------------------------------------------
嫌弃503用户体验很差,也能够加个返回页面:
error_page 503 /errpage/503.html;
503页面的源代码:
<html> <head> <title>页面即将载入….</title> <meta http-equiv=content-type c> <META NAME=”ROBOTS” C> </head> <body bgcolor=”#FFFFFF”> <table cellpadding=”0″ cellspacing=”0″ border=”0″ width=”700″ align=”center” height=”85%”> <tr align=”center” valign=”middle”> <td> <table cellpadding=”10″ cellspacing=”0″ border=”0″ width=”80%” align=”center” style=”font-family: Verdana, Tahoma; color: #666666; font-size: 11px”> <tr> <td valign=”middle” align=”center” bgcolor=”#EBEBEB”> <br /><b style=”font-size: 16px”>页面即将载入</b> <br /><br />你刷新页面的速度过快。请少安毋躁,页面即将载入… <br /><br />[<a href="JavaScript:window.location.reload();"><font color=#666666>当即从新载入</font></a>] <br /><br /> </td> </tr> </table> </td> </tr> </table> </body> </html> <SCRIPT language=javascript> function update() { window.location.reload(); } setTimeout(“update()”,2000); </script>
-----------------------------------------------------------------------
上述的配置,是全网通用得,有时候不免有误伤,那怎么办呢,能够设置白名单制度。
#geo指令定义了一个白名单$whiteiplist变量,默认值为1, #若是客户端ip在上面的范围内,$whiteiplist的值为0。 geo $whiteiplist { default 1; 10.11.15.161 0; 127.0.0.1/32 0; } #使用map指令映射上面geo匹配的客户端的ip为空串,若是不是就显示自己真实的ip, #这样匹配的ip就不能存到limit_req_zone内存session中,因此不会被限制访问 map $whiteiplist $limit { 1 $binary_remote_addr; 0 ""; } #而后再制定这个$limit变量来设置规则,白名单制度就创建起来了 limit_req_zone $limit zone=one:10m rate=10r/s; limit_conn_zone $limit zone=addr:10m;