20个Nginx Web服务器最佳安全实践
Nginx是一个轻量级,高性能的Web服务器/反向代理和电子邮件代理(IMAP/POP3),它可以运行在UNIX,GNU/Linux,BSD变种,MACOSX,Solaris和MicrosoftWindows上。根据Netcraft的调查数据显示,互联网上6%的域名都使用了NginxWeb服务器。Nginx是解决C10K问题的服务器之一,与传统服务器不一样,Nginx不依赖于线程处理请求,相反,它使用了一个更具扩展性的事件驱动(异步)架构。Nginx在很多高流量网站上得到了应用,如WordPress,Hulu,Github和SourceForge。
本文的主要目是介绍如何提高运行在Linux或UNIX类操作系统上的NginxWeb服务器的安全性。
Nginx默认配置文件和默认端口
◆/usr/local/nginx/conf/-Nginx服务器配置目录,/usr/local/nginx/conf/nginx.conf是主配置文件
◆/usr/local/nginx/html/-默认文档位置
◆/usr/local/nginx/logs/-默认日志文件位置
◆NginxHTTP默认端口:TCP80
◆NginxHTTPS默认端口:TCP443
可以使用下面的命令测试Nginx的配置是否正确:
#/usr/local/nginx/sbin/nginx–t
输出示例:
theconfigurationfile/usr/local/nginx/conf/nginx.confsyntaxisokconfigurationfile/usr/local/nginx/conf/nginx.conftestissuccessful
要让修改后的配置生效,执行下面的命令:
#/usr/local/nginx/sbin/nginx-sreload
如果要停止服务器,运行:
#/usr/local/nginx/sbin/nginx-sstop
1、开启SELinux
SELinux(安全增强的Linux)是一个Linux内核功能,它提供了一个机制支持访问控制安全策略,提供了巨大的安全保护能力,它可以防止大多数系统root级攻击,请参考“如何在CentOS/RedHat系统上开启SELinux”(http://www.cyberciti.biz/faq/rhel-fedora-redhat-selinux-protection/)。
运行getsebool–a命令查看SELinux设置项:
getsebool-a|lessgetsebool-a|grepoffgetsebool-a|grepo
然后使用setsebool命令开启需要的配置项,注意:开启SELinux后,在RHEL或CentOS上通常会增加2-8%的系统开销。
2、通过mount参数提供最低权限
为你的/html/php文件创建独立的分区,例如,创建一个/dev/sda5分区挂载在/ngnix上,确定/ngnix使用了noexec,nodev和nosetuid权限挂载。下面是我的一个挂载实例:
LABEL=/nginx/nginxext3defaults,nosuid,noexec,nodev12
注意你需要使用fdisk和mkfs.ext3命令创建一个新分区。
3、通过/etc/sysctl.conf加固
可以通过/etc/sysctl.conf控制和配置Linux内核及网络设置。
另外,请参考:
#避免放大攻击net.ipv4.icmp_echo_ignore_broadcasts=1#开启恶意icmp错误消息保护net.ipv4.icmp_ignore_bogus_error_responses=1#开启SYN洪水攻击保护net.ipv4.tcp_syncookies=1#开启并记录欺骗,源路由和重定向包net.ipv4.conf.all.log_martians=1net.ipv4.conf.default.log_martians=1#处理无源路由的包net.ipv4.conf.all.accept_source_route=0net.ipv4.conf.default.accept_source_route=0#开启反向路径过滤net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
#确保无人能修改路由表
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
#不充当路由器
net.ipv4.ip_forward=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
#开启execshild
kernel.exec-shield=1
kernel.randomize_va_space=1
#IPv6设置
net.ipv6.conf.default.router_solicitations=0
net.ipv6.conf.default.accept_ra_rtr_pref=0
net.ipv6.conf.default.accept_ra_pinfo=0
net.ipv6.conf.default.accept_ra_defrtr=0
net.ipv6.conf.default.autoconf=0
net.ipv6.conf.default.dad_transmits=0
net.ipv6.conf.default.max_addresses=1
#优化LB使用的端口
#增加系统文件描述符限制
fs.file-max=65535
#允许更多的PIDs(减少滚动翻转问题);maybreaksomeprograms32768
kernel.pid_max=65536
#增加系统IP端口限制
net.ipv4.ip_local_port_range=200065000
#增加TCP最大缓冲区大小
net.ipv4.tcp_rmem=4096873808388608
net.ipv4.tcp_wmem=4096873808388608
#增加Linux自动调整TCP缓冲区限制
#最小,默认和最大可使用的字节数
#最大值不低于4MB,如果你使用非常高的BDP路径可以设置得更高
#Tcp窗口等
net.core.rmem_max=8388608
net.core.wmem_max=8388608
net.core.netdev_max_backlog=5000
net.ipv4.tcp_window_scaling=1
◆LinuxVM调优(内存)子系统(http://www.cyberciti.biz/faq/linux-kernel-tuning-virtual-memory-subsystem/)
◆Linux网络堆栈调优(缓冲区大小)提高网络性能(http://www.cyberciti.biz/faq/linux-tcp-tuning/)
4、移除所有不需要的Nginx模块
你需要最大限度地将Nginx加载的模块最小化,我的意思是满足Web服务器需要就可以了,多余的模块一个不留,例如,禁用SSI和autoindex模块的命令如下:
#./configure--without-http_autoindex_module--without-http_ssi_module#make#makeinstall
在编译Nginx服务器时,使用下面的命令查看哪些模块应该启用,哪些模块应该禁用:
#./configure--help|less
禁用你不需要的Nginx模块。
修改Nginx版本头信息(可选),编辑src/http/ngx_http_header_filter_module.c:
#vi+48src/http/ngx_http_header_filter_module.c
找到下面两行:
staticcharngx_http_server_string[]="Server:nginx"CRLF;staticcharngx_http_server_full_string[]="Server:"NGINX_VERCRLF;
将其修改为:
staticcharngx_http_server_string[]="Server:NinjaWebServer"CRLF;staticcharngx_http_server_full_string[]="Server:NinjaWebServer"CRLF;
保存并关闭文件。现在可以开始编译服务器了,将下面的配置代码添加到nginx.conf中,禁止在所有自动产生的错误页面中显示Nginx版本号:
server_tokensoff
5、使用mod_security(仅适用于后端Apache服务器)
Mod_security为Apache提供了一个应用程序级防火墙,为所有后端ApacheWeb服务器安装mod_security模块,可以阻止许多注入攻击。
6、配置SELinux策略加固Nginx
默认情况下,SELinux没有保护NginxWeb服务器,可以手动配置进行保护,首先安装SELinux编译时需要的支持包:
#yum-yinstallselinux-policy-targetedselinux-policy-devel
从项目主页(http://sourceforge.net/projects/selinuxnginx/)下载SELinux策略:
#cd/opt#wget'http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc'
解压:
#tar-zxvfse-ngix_1_0_10.tar.gz
编译:
#cdse-ngix_1_0_10/nginx#make
输出示例:
Compilingtargetednginxmodule/usr/bin/checkmodule:loadingpolicyconfigurationfromtmp/nginx.tmp/usr/bin/checkmodule:policyconfigurationloaded/usr/bin/checkmodule:writingbinaryrepresentation(version6)totmp/nginx.modCreatingtargetednginx.pppolicypackagermtmp/nginx.mod.fctmp/nginx.mod
安装生成的nginx.ppSELinux模块:
#/usr/sbin/semodule-inginx.pp
7、通过iptables防火墙设置限制
下面的防火墙脚本可以阻止一切请求,只允许:
◆入站HTTP请求(TCP80端口)
◆入站ICMPping请求
◆出站NTP请求(端口123)
◆出站SMTP请求(TCP端口25)
#!/bin/bashIPT="/sbin/iptables"####IPS#######获得服务器公共IPSERVER_IP=$(ifconfigeth0|grep'inetaddr:'|awk-F'inetaddr:''{print$2}'|awk'{print$1}')LB1_IP="204.54.1.1"LB2_IP="204.54.1.2"#实现某些智能逻辑,以便我们可以在LB2上使用damm脚本OTHER_LB=""SERVER_IP=""[["$SERVER_IP"=="$LB1_IP"]]&&OTHER_LB="$LB2_IP"||OTHER_LB="$LB1_IP"[["$OTHER_LB"=="$LB2_IP"]]&&OPP_LB="$LB1_IP"||OPP_LB="$LB2_IP"###IPs###PUB_SSH_ONLY="122.xx.yy.zz/29"####文件#####BLOCKED_IP_TDB=/root/.fw/blocked.ip.txt
SPOOFIP="127.0.0.0/8192.168.0.0/16172.16.0.0/1210.0.0.0/8169.254.0.0/160.0.0.0/8240.0.0.0/4255.255.255.255/32168.254.0.0/16224.0.0.0/4240.0.0.0/5248.0.0.0/5192.0.2.0/24"
BADIPS=$([[-f${BLOCKED_IP_TDB}]]&&egrep-v"^#|^$"${BLOCKED_IP_TDB})
###接口###
PUB_IF="eth0"#publicinterface
LO_IF="lo"#loopback
VPN_IF="eth1"#vpn/privatenet
###启动防火墙###
echo"SettingLB1$(hostname)Firewall..."
#删除和关闭一切
$IPT-PINPUTDROP
$IPT-POUTPUTDROP
$IPT-PFORWARDDROP
#不受限制的lo访问
$IPT-AINPUT-i${LO_IF}-jACCEPT
$IPT-AOUTPUT-o${LO_IF}-jACCEPT
#不受限制的vpn/pnet访问
$IPT-AINPUT-i${VPN_IF}-jACCEPT
$IPT-AOUTPUT-o${VPN_IF}-jACCEPT
#删除sync
$IPT-AINPUT-i${PUB_IF}-ptcp!--syn-mstate--stateNEW-jDROP
#删除碎片
$IPT-AINPUT-i${PUB_IF}-f-jDROP
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsALLFIN,URG,PSH-jDROP
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsALLALL-jDROP
#删除空包
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsALLNONE-mlimit--limit5/m--limit-burst7-jLOG--log-prefix"NULLPackets"
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsALLNONE-jDROP
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsSYN,RSTSYN,RST-jDROP
#删除XMAS
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsSYN,FINSYN,FIN-mlimit--limit5/m--limit-burst7-jLOG--log-prefix"XMASPackets"
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsSYN,FINSYN,FIN-jDROP
#删除FIN包扫描
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsFIN,ACKFIN-mlimit--limit5/m--limit-burst7-jLOG--log-prefix"FinPacketsScan"
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsFIN,ACKFIN-jDROP
$IPT-AINPUT-i${PUB_IF}-ptcp--tcp-flagsALLSYN,RST,ACK,FIN,URG-jDROP
#记录并放弃广播/多播和无效数据包
$IPT-AINPUT-i${PUB_IF}-mpkttype--pkt-typebroadcast-jLOG--log-prefix"Broadcast"
$IPT-AINPUT-i${PUB_IF}-mpkttype--pkt-typebroadcast-jDROP
$IPT-AINPUT-i${PUB_IF}-mpkttype--pkt-typemulticast-jLOG--log-prefix"Multicast"
$IPT-AINPUT-i${PUB_IF}-mpkttype--pkt-typemulticast-jDROP
$IPT-AINPUT-i${PUB_IF}-mstate--stateINVALID-jLOG--log-prefix"Invalid"
$IPT-AINPUT-i${PUB_IF}-mstate--stateINVALID-jDROP
#记录和阻止欺骗IP
$IPT-Nspooflist
foripblockin$SPOOFIP
do
$IPT-Aspooflist-i${PUB_IF}-s$ipblock-jLOG--log-prefix"SPOOFListBlock"
$IPT-Aspooflist-i${PUB_IF}-s$ipblock-jDROP
done
$IPT-IINPUT-jspooflist
$IPT-IOUTPUT-jspooflist
$IPT-IFORWARD-jspooflist
#只允许从选定的公共IP使用SSH
foripin${PUB_SSH_ONLY}
do$IPT-AINPUT-i${PUB_IF}-s${ip}-ptcp-d${SERVER_IP}--destination-port22-jACCEPT
$IPT-AOUTPUT-o${PUB_IF}-d${ip}-ptcp-s${SERVER_IP}--sport22-jACCEPT
done
#允许入站ICMPping
$IPT-AINPUT-i${PUB_IF}-picmp--icmp-type8-s0/0-mstate--stateNEW,ESTABLISHED,RELATED-mlimit--limit30/sec-jACCEPT
$IPT-AOUTPUT-o${PUB_IF}-picmp--icmp-type0-d0/0-mstate--stateESTABLISHED,RELATED-jACCEPT
#允许入站HTTP端口80
$IPT-AINPUT-i${PUB_IF}-ptcp-s0/0--sport1024:65535--dport80-mstate--stateNEW,ESTABLISHED-jACCEPT
$IPT-AOUTPUT-o${PUB_IF}-ptcp--sport80-d0/0--dport1024:65535-mstate--stateESTABLISHED-jACCEPT
#允许出站NTP
$IPT-AOUTPUT-o${PUB_IF}-pudp--dport123-mstate--stateNEW,ESTABLISHED-jACCEPT
$IPT-AINPUT-i${PUB_IF}-pudp--sport123-mstate--stateESTABLISHED-jACCEPT
#允许出站SMTP
$IPT-AOUTPUT-o${PUB_IF}-ptcp--dport25-mstate--stateNEW,ESTABLISHED-jACCEPT
$IPT-AINPUT-i${PUB_IF}-ptcp--sport25-mstate--stateESTABLISHED-jACCEPT
###在这里添加其他规则####
#######################
#删除并记录其它数据包
$IPT-AINPUT-mlimit--limit5/m--limit-burst7-jLOG--log-prefix"DEFAULTDROP"
$IPT-AINPUT-jDROP
exit0
8、控制缓冲区溢出攻击
编辑nginx.conf设置所有客户端可用的缓冲区大小限制:
#vi/usr/local/nginx/conf/nginx.conf
具体设置如下:
##Start:SizeLimits&BufferOverflows##client_body_buffer_size1K;client_header_buffer_size1k;client_max_body_size1k;large_client_header_buffers21k;##END:SizeLimits&BufferOverflows##
说明:
client_body_buffer_size1k:默认是8k或16k,指定客户端请求主体缓冲区大小。
client_header_buffer_size1k:指定来自客户端请求头的headerbuffer大小,对于大多数请求,1k的缓冲区大小已经足够,如果你自定义了消息头或有更大的Cookie,你可以增加其大小。
client_max_body_size1k:客户端请求中可接受的主体最大大小,由请求头中的Content-Length表示,如果大小大于给定的尺寸,客户端将会收到一条“RequestEntityTooLarge(413)”的错误,如果你要通过POST方法上传文件,可以将该值设大一些。
large_client_header_buffers21k:为客户端请求中较大的消息头指定的缓存最大数量和大小,默认情况下,一个缓冲区的大小等于页面的大小,根据平台的不同可能是4K或8K,如果在请求连接的末尾状态转换为保持活动(keep-alive),这些缓冲区就被释放,2x1K将可以接收2KB数据的URI,这样有助于打击机器人攻击和DoS攻击。
另外,你还需要控制超时时间,提高服务器性能,降低客户端的等待时间,做如下修改:
##Start:Timeouts##client_body_timeout10;client_header_timeout10;keepalive_timeout55;send_timeout10;##End:Timeouts##
client_body_timeout10:设置客户端请求主体读取超时时间,如果在这个时间后客户端还没有发送任何数据,Nginx返回“Requesttimeout(408)”错误,默认值是60。
client_header_timeout10:设置客户端请求头读取超时时间,如果在这个时间后客户端还没有发送任何数据,Nginx返回“Requesttimeout(408)”错误。
keepalive_timeout55:第一个参数指定客户端连接保持活动的超时时间,在这个时间之后,服务器会关掉连接,第二个参数是可选的,它指定了消息头保持活动的有效时间,即响应中的timeout=time,它可以告诉某些浏览器关闭连接,因此服务器就不必关闭连接了,如果没有这个参数,Nginx不会发送Keep-Alive头。
send_timeout10:指定响应客户端的超时时间,这个超时仅限于两个阅读活动之间的时间,如果这个时间后客户端没有任何活动,Nginx将会关闭连接。
9、控制并发连接
你可以使用NginxHttpLimitZone模块限制指定会话,或某个IP的并发连接数,编辑nginx.conf:
###Directivedescribesthezone,inwhichthesessionstatesarestoredi.e.storeinslimits.###1mcanhandle32000sessionswith32bytes/session,setto5mx32000session###limit_zoneslimits$binary_remote_addr5m;###Controlmaximumnumberofsimultaneousconnectionsforonesessioni.e.######restrictstheamountofconnectionsfromasingleipaddress###
limit_connslimits5;
上述设置可以限制远程客户端每IP地址不能超过5个同时打开的连接。
10、只允许访问指定的域名
如果有机器人程序在随机扫描所有域,那就阻止它访问,你必须配置只允许虚拟域或反向代理请求。
##OnlyrequeststoourHostareallowedi.e.nixcraft.in,images.nixcraft.inandwww.nixcraft.inif($host!~^(nixcraft.in|www.nixcraft.in|images.nixcraft.in)$){return444;}##
11、限制可用的方法
GET和POST是互联网上最常用的方法,RFC2616定义了Web服务器可用的方法,如果一个Web服务器不要求实现所有方法,那些方法就应该被禁止掉,下面的代码将过滤所有方法,只允许GET,HEAD和POST方法:
##Onlyallowtheserequestmethods##if($request_method!~^(GET|HEAD|POST)$){return444;}##DonotacceptDELETE,SEARCHandothermethods##
关于HTTP方法的更多信息:
GET方法用于请求文档,如http://www.cyberciti.biz/index.php。
HEAD方法与GET相同,但服务器不会在响应中只返回消息主体。
POST方法功能就多了,如通过表单存储或更新数据,订购一个产品,发送电子邮件等,通常使用服务器端脚本(如PHP,Perl,Python等)处理,如果你要上传文件或在服务器上处理表单就必须用它。
12a、如何阻止某些用户代理(User-Agents)?
你可以轻松阻止用户代理,如扫描器,机器人和垃圾邮件,它们可能会滥用你的服务器。
##Blockdownloadagents##if($http_user_agent~*LWP::Simple|BBBike|wget){return403;}##
阻止msnbot和scrapbot机器人:
##Blocksomerobots##if($http_user_agent~*msnbot|scrapbot){return403;}
12b、如何阻止被提名的垃圾邮件
被提名的垃圾邮件都很危险,它们可能会损害你的SEO排名,可以使用下面的代码阻止访问垃圾邮件发送者:
##DenycertainReferers###if($http_referer~*(babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen)){#return404;return403;}##
13、如何停止图片热链
图片或HTML热链是指有人在他们的网站上引用了你网站的图片,你必须为其它网站的流量支付贷款费用,有点象是网站jiechi,通常这种情况发生在博
客和论坛中,我强烈建议你在服务器级停止并阻止图片热链。
#Stopdeeplinkingorhotlinkinglocation/images/{valid_referersnoneblockedwww.example.comexample.com;if($invalid_referer){return403;}}
例子:重写并显示禁令图片:
valid_referersblockedwww.example.comexample.com;if($invalid_referer){rewrite^/images/uploads.*\.(gif|jpg|jpeg|png)$http://www.examples.com/banned.jpglast}
另外,请参考“How-to:使用Nginx映射阻止图片热链”(http://nginx.org/pipermail/nginx/2007-June/001082.html)。
14、目录限制
你可以为特定目录设置访问控制,所有网页目录都应配置为按需访问。
通过IP地址限制访问,你可以限制访问/docs/目录的IP地址:
location/docs/{##blockoneworkstationdeny192.168.1.1;##allowanyonein192.168.1.0/24allow192.168.1.0/24;
##droprestoftheworlddenyall;
}
通过密码保护目录,首先创建一个密码文件,再添加一个用户vivek:
#mkdir/usr/local/nginx/conf/.htpasswd/#htpasswd-c/usr/local/nginx/conf/.htpasswd/passwdvivek
编辑nginx.conf添加需要保护的目录:
###PasswordProtect/personal-images/and/delta/directories###location~/(personal-images/.*|delta/.*){auth_basic"Restricted";auth_basic_user_file/usr/local/nginx/conf/.htpasswd/passwd;}
创建好密码文件后,后面的用户可以使用下面的命令进行追加:
#htpasswd-s/usr/local/nginx/conf/.htpasswd/passwduserName
15、NginxSSL配置
HTTP是一个纯文本协议,很容易被qieting,你应该使用SSL加密传输的信息。
首先需要创建一个SSL证书,输入下面的命令:
#cd/usr/local/nginx/conf#opensslgenrsa-des3-outserver.key1024#opensslreq-new-keyserver.key-outserver.csr#cpserver.keyserver.key.org#opensslrsa-inserver.key.org-outserver.key#opensslx509-req-days365-inserver.csr-signkeyserver.key-outserver.crt
编辑nginx.conf,找到对应位置,做如下修改:
server{server_nameexample.com;listen443;sslon;ssl_certificate/usr/local/nginx/conf/server.crt;ssl_certificate_key/usr/local/nginx/conf/server.key;access_log/usr/local/nginx/logs/ssl.access.log;error_log/usr/local/nginx/logs/ssl.error.log;
重启Nginx:
#/usr/local/nginx/sbin/nginx-sreload
另外,请参考NginxSSL文档(http://wiki.nginx.org/NginxHttpSslModule)。
16、Nginx和PHP安全技巧
PHP是流行的服务器端脚本语言,对/etc/php.ini做如下修改:
#禁用危险的函数disable_functions=phpinfo,system,mail,exec##限制资源###每个脚本的最大执行时间,单位秒max_execution_time=30#每个脚本解析请求数据的最大时间max_input_time=60#每个脚本可以消耗的最大内存(8MB)memory_limit=8M#PHP要接收的POST数据最大大小post_max_size=8M#是否允许HTTP文件上传file_uploads=Off#允许上传的最大文件大小upload_max_filesize=2M#不将PHP错误消息暴露给外部用户display_errors=Off#启用安全模式safe_mode=On#只允许访问隔离目录中的可执行文件safe_mode_exec_dir=php-required-executables-path#限制外部访问PHP资源safe_mode_allowed_env_vars=PHP_#限制泄露PHP信息expose_php=Off#记录所有错误log_errors=On#不为输入数据注册全局register_globals=Off#最小化允许的phppost大小post_max_size=1K#确保PHP重定向正确cgi.force_redirect=0#禁止上传,除非必要file_uploads=Off#启用SQL安全模式sql.safe_mode=On#避免打开远程文件allow_url_fopen=Off
另外,请参考“PHP安全:限制脚本使用的资源”(http://www.cyberciti.biz/faq/php-resources-limits/),“PHP.INI:禁用exec,shell_exec,system,popen和其它功能提高安全”(http://www.cyberciti.biz/faq/linux-unix-apache-lighttpd-phpini-disable-functions/)。
17、尽可能在ChrootJail(容器)中运行Nginx
将Nginx放入ChrootJail可以最大限度地减少被攻击的危险,它将Web服务器隔离到文件系统的专用区域,注意你不能使用传统的chroot方法设置Nginx,但你可以使用FreeBSDjails,Xen或OpenVZ虚拟化,它们也使用了容器的概念。
18、在防火墙级限制每个IP的连接
Web服务器必须时刻关注连接和每秒的连接限制,pf和iptables都可以在访问Nginx服务器之前卡住最终用户。
Linuxiptables:每秒卡住的Nginx连接
下面的例子表示如果某个IP在60秒尝试连接到80端口的次数超过了15,iptables将会丢掉来自它的入站连接:
/sbin/iptables-AINPUT-ptcp--dport80-ieth0-mstate--stateNEW-mrecent--set/sbin/iptables-AINPUT-ptcp--dport80-ieth0-mstate--stateNEW-mrecent--update--seconds60--hitcount15-jDROPserviceiptablessave
BSDPF:每秒卡住的Nginx连接
编辑/etc/pf.conf,做如下更新,下面的命令限制了每个来源的最大连接数为100,15/5指定某时间跨度内的连接数限制,这里就是5秒内的最大连接数为
15,如果有人违背这条规则,将被加入到abusive_ips表,那么他以后就不能再连接了。最后刷新所有状态。
ebserver_ip="202.54.1.1"tablepersistblockinquickfrompassinon$ext_ifprototcpto$webserver_ipportwwwflagsS/SAkeepstate(max-src-conn100,max-src-conn-rate15/5,overloadflush)
请根据你的需要和通信流量调整所有的值(浏览器可能会打开多个连接)。
另外,请参考“PF防火墙脚本示例”(http://bash.cyberciti.biz/firewall/pf-firewall-script/),“iptables防火墙脚本示例”(http://bash.cyberciti.biz/firewall/linux-iptables-firewall-shell-script-for-standalone-server/)。
19、配置操作系统保护Web服务器
除了开启SELinux外,还要给/nginx目录设置正确的权限,运行Nginx的系统用户名是nginx,但在DocumentRoot(/nginx或/usr/local/nginx/html)中的文件不应该
属于该用户,他也不能进行修改。使用下面的命令找出权限设置不当的文件:
#find/nginx-usernginx#find/usr/local/nginx/html-usernginx
请确保将文件的所有者修改为root或其它用户,一个典型的权限设置如下:
#ls-l/usr/local/nginx/html/
输出示例:
-rw-r--r--1rootroot925Jan300:50error4xx.html-rw-r--r--1rootroot52Jan310:00error5xx.html-rw-r--r--1rootroot134Jan300:52index.html
另外,你必须删除由vi或其它文本编辑器创建的不必要的备份文件:
#find/nginx-name'.?*'-not-name.ht*-or-name'*~'-or-name'*.bak*'-or-name'*.old*'#find/usr/local/nginx/html/-name'.?*'-not-name.ht*-or-name'*~'-or-name'*.bak*'-or-name'*.old*'
给find命令传递-delete参数,它就会自动删除这些文件。
20、限制出站Nginx连接
攻击者可能要在你的Web服务器上使用如wget等工具下载文件,使用iptables阻止来自Nginx用户的出站连接,ipt_owner模块可以匹配各种包创建者的特征,只有在OUTPUT链中的才有效,在这里,允许vivek用户使用80端口连接外部资源(对RHN访问或通过仓库抓取CentOS更新特别有用)。
/sbin/iptables-AOUTPUT-oeth0-mowner--uid-ownervivek-ptcp--dport80-mstate--stateNEW,ESTABLISHED-jACCEPT
将上述规则添加到你的iptables基础shell脚本中,不允许nginxWeb服务器用户连接外部资源。
附送技巧:观察日志和审核
检查日志文件,可以从中找到攻击者的一些行踪和攻击手段。
#grep"/login.php??"/usr/local/nginx/logs/access_log#grep"...etc/passwd"/usr/local/nginx/logs/access_log#egrep-i"denied|error|warn"/usr/local/nginx/logs/error_log
Auditd服务提供了系统审核功能,启动SELinux事件,认证事件,文件修改,帐户修改等的审核服务,象往常一样首先关闭所有服务,然后打开我在“Linux服务器加固”(http://www.cyberciti.biz/tips/linux-security.html)一文中指出的服务。
总结
通过这些设置,你的Nginx服务器就可以对外提供服务了,但你应该根据应用程序安全需要进一步查看另外的资源。例如,WordPress或其它第三方程序都有其自身的安全要求。