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或其它第三方程序都有其自身的安全要求。

相关推荐