详解nginx服务器中的安全配置
本篇文章详细的讲诉了nginx服务器中的安全配置,具体如下:
一、关闭SELinux
安全增强型Linux(SELinux)的是一个Linux内核的功能,它提供支持访问控制的安全政策保护机制。
但是,SELinux带来的附加安全性和使用复杂性上不成比例,性价比不高
sed-i/SELINUX=enforcing/SELINUX=disabled//etc/selinux/config /usr/sbin/sestatus-v#查看状态
二、通过分区挂载允许最少特权
服务器上nginx目录单独分区。例如,新建一个分区/dev/sda5(第一逻辑分区),并且挂载在/nginx。确保/nginx是以noexec,nodevandnosetuid的权限挂载
以下是我的/etc/fstab的挂载/nginx的信息:LABEL=/nginx/nginxext3defaults,nosuid,noexec,nodev12
注意:你需要使用fdisk和mkfs.ext3命令创建一个新分区。
三、配置/etc/sysctl.conf强化Linux安全
你可以通过编辑/etc/sysctl.conf来控制和配置Linux内核、网络设置
#Avoidasmurfattack net.ipv4.icmp_echo_ignore_broadcasts=1 #Turnonprotectionforbadicmperrormessages net.ipv4.icmp_ignore_bogus_error_responses=1 #TurnonsyncookiesforSYNfloodattackprotection net.ipv4.tcp_syncookies=1 #Turnonandlogspoofed,sourcerouted,andredirectpackets net.ipv4.conf.all.log_martians=1 net.ipv4.conf.default.log_martians=1 #Nosourceroutedpacketshere net.ipv4.conf.all.accept_source_route=0 net.ipv4.conf.default.accept_source_route=0 #Turnonreversepathfiltering net.ipv4.conf.all.rp_filter=1 net.ipv4.conf.default.rp_filter=1 #Makesurenoonecanaltertheroutingtables 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 #Don'tactasarouter net.ipv4.ip_forward=0 net.ipv4.conf.all.send_redirects=0 net.ipv4.conf.default.send_redirects=0 #Turnonexecshild kernel.exec-shield=1 kernel.randomize_va_space=1 #TuenIPv6 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 #OptimizationforportuseforLBs #Increasesystemfiledescriptorlimit fs.file-max=65535 #AllowformorePIDs(toreducerolloverproblems);maybreaksomeprograms32768 kernel.pid_max=65536 #IncreasesystemIPportlimits net.ipv4.ip_local_port_range=200065000 #IncreaseTCPmaxbuffersizesetableusingsetsockopt() net.ipv4.tcp_rmem=4096873808388608 net.ipv4.tcp_wmem=4096873808388608 #IncreaseLinuxautotuningTCPbufferlimits #min,default,andmaxnumberofbytestouse #setmaxtoatleast4MB,orhigherifyouuseveryhighBDPpaths #TcpWindowsetc net.core.rmem_max=8388608 net.core.wmem_max=8388608 net.core.netdev_max_backlog=5000 net.ipv4.tcp_window_scaling=1
四、删除所有不需要的Nginx模块
你需要直接通过编译Nginx源代码使模块数量最少化。通过限制只允许web服务器访问模块把风险降到最低。你可以只配置安装nginx你所需要的模块。例如,禁用SSL和autoindex模块你可以执行以下命令:
./configure–without-http_autoindex_module–without-http_ssi_module make&&makeinstall
更改nginx版本名称、编辑文件/http/ngx_http_header_filter_module.c:
vimsrc/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版本号的显示
server_tokensoff
五、基于Iptables防火墙的限制
下面的防火墙脚本阻止任何除了允许:
- 来自HTTP(TCP端口80)的请求
- 来自ICMPping的请求
- ntp(端口123)的请求输出
- smtp(TCP端口25)的请求输出
六、控制缓冲区溢出攻击
编辑和设置所有客户端缓冲区的大小限制如下:
client_body_buffer_size1K; client_header_buffer_size1k; client_max_body_size1k; large_client_header_buffers21k;
- client_body_buffer_size1k(默认8k或16k)这个指令可以指定连接请求实体的缓冲区大小。如果连接请求超过缓存区指定的值,那么这些请求实体的整体或部分将尝试写入一个临时文件。
- client_header_buffer_size1k-指令指定客户端请求头部的缓冲区大小。绝大多数情况下一个请求头不会大于1k,不过如果有来自于wap客户端的较大的cookie它可能会大于1k,Nginx将分配给它一个更大的缓冲区,这个值可以在large_client_header_buffers里面设置。
- client_max_body_size1k-指令指定允许客户端连接的最大请求实体大小,它出现在请求头部的Content-Length字段。如果请求大于指定的值,客户端将收到一个”RequestEntityTooLarge”(413)错误。记住,浏览器并不知道怎样显示这个错误。
- large_client_header_buffers-指定客户端一些比较大的请求头使用的缓冲区数量和大小。请求字段不能大于一个缓冲区大小,如果客户端发送一个比较大的头,nginx将返回”RequestURItoolarge”(414)
- 同样,请求的头部最长字段不能大于一个缓冲区,否则服务器将返回”Badrequest”(400)。缓冲区只在需求时分开。默认一个缓冲区大小为操作系统中分页文件大小,通常是4k或8k,如果一个连接请求最终将状态转换为keep-alive,它所占用的缓冲区将被释放。
你还需要控制超时来提高服务器性能并与客户端断开连接。按照如下编辑:
client_body_timeout10; client_header_timeout10; keepalive_timeout55; send_timeout10;
- client_body_timeout10;-指令指定读取请求实体的超时时间。这里的超时是指一个请求实体没有进入读取步骤,如果连接超过这个时间而客户端没有任何响应,Nginx将返回一个”Requesttimeout”(408)错误。
- client_header_timeout10;-指令指定读取客户端请求头标题的超时时间。这里的超时是指一个请求头没有进入读取步骤,如果连接超过这个时间而客户端没有任何响应,Nginx将返回一个”Requesttimeout”(408)错误。
- keepalive_timeout55;–参数的第一个值指定了客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接。参数的第二个值(可选)指定了应答头中Keep-Alive:timeout=time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,如果不指定这个参数,nginx不会在应答头中发送Keep-Alive信息。(但这并不是指怎样将一个连接“Keep-Alive”)参数的这两个值可以不相同。
- send_timeout10;指令指定了发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,如果超过这个时间客户端没有任何响应,nginx将关闭连接。
七、控制并发连接
你可以使用NginxHttpLimitZone模块来限制指定的会话或者一个IP地址的特殊情况下的并发连接。编辑nginx.conf:
###Directivedescribesthezone,inwhichthesessionstatesarestoredi.e.storeinslimits.### ###1mcanhandle32000sessionswith32bytes/session,setto5mx32000session### limit_zoneslimits$binary_remote_addr5m; ###Controlmaximumnumberofsimultaneousconnectionsforonesessioni.e.### ###restrictstheamountofconnectionsfromasingleipaddress### limit_connslimits5;
上面表示限制每个远程IP地址的客户端同时打开连接不能超过5个。
八、只允许我们的域名的访问
如果机器人只是随机扫描服务器的所有域名,那拒绝这个请求。你必须允许配置的虚拟域或反向代理请求。你不必使用IP地址来拒绝。
if($host!~^(test.in|www.test.in|images.test.in)$){ return444; }
九、限制可用的请求方法
GET和POST是互联网上最常用的方法。Web服务器的方法被定义在RFC2616。如果Web服务器不要求启用所有可用的方法,它们应该被禁用。下面的指令将过滤只允许GET,HEAD和POST方法:
##Onlyallowtheserequestmethods## if($request_method!~^(GET|HEAD|POST)$){ return444; } ##DonotacceptDELETE,SEARCHandothermethods##
更多关于HTTP方法的介绍
- GET方法是用来请求,如文件http://www.moqifei.com/index.php。
- HEAD方法是一样的,除非该服务器的GET请求无法返回消息体。
- POST方法可能涉及到很多东西,如储存或更新数据,或订购产品,或通过提交表单发送电子邮件。这通常是使用服务器端处理,如PHP,Perl和Python等脚本。如果你要上传的文件和在服务器处理数据,你必须使用这个方法。
十、如何拒绝一些User-Agents?
你可以很容易地阻止User-Agents,如扫描器,机器人以及滥用你服务器的垃圾邮件发送者。
##Blockdownloadagents## if($http_user_agent~*LWP::Simple|BBBike|wget){ return403; }
阻止Soso和有道的机器人:
##Blocksomerobots## if($http_user_agent~*Sosospider|YodaoBot){ return403; }
十一、防止图片盗链
图片或HTML盗链的意思是有人直接用你网站的图片地址来显示在他的网站上。最终的结果,你需要支付额外的宽带费用。这通常是在论坛和博客。我强烈建议您封锁,并阻止盗链行为。
#Stopdeeplinkingorhotlinking location/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 }
十二、目录限制
你可以对指定的目录设置访问权限。所有的网站目录应该一一的配置,只允许必须的目录访问权限。
通过IP地址限制访问
你可以通过IP地址来限制访问目录/admin/:
location/docs/{ ##blockoneworkstation deny192.168.1.1; ##allowanyonein192.168.1.0/24 allow192.168.1.0/24; ##droprestoftheworld denyall; }
通过密码保护目录,首先创建密码文件并增加“user”用户
mkdir/usr/local/nginx/conf/.htpasswd/ htpasswd-c/usr/local/nginx/conf/.htpasswd/passwduser
编辑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
十三、NginxSSL配置
HTTP是一个纯文本协议,它是开放的被动监测。你应该使用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与PHP安全建议
PHP是流行的服务器端脚本语言之一。如下编辑/etc/php.ini文件:
#Disallowdangerousfunctions disable_functions=phpinfo,system,mail,exec ##Trytolimitresources## #Maximumexecutiontimeofeachscript,inseconds max_execution_time=30 #Maximumamountoftimeeachscriptmayspendparsingrequestdata max_input_time=60 #Maximumamountofmemoryascriptmayconsume(8MB) memory_limit=8M #MaximumsizeofPOSTdatathatPHPwillaccept. post_max_size=8M #WhethertoallowHTTPfileuploads. file_uploads=Off #Maximumallowedsizeforuploadedfiles. upload_max_filesize=2M #DonotexposePHPerrormessagestoexternalusers display_errors=Off #Turnonsafemode safe_mode=On #Onlyallowaccesstoexecutablesinisolateddirectory safe_mode_exec_dir=php-required-executables-path #LimitexternalaccesstoPHPenvironment safe_mode_allowed_env_vars=PHP_ #RestrictPHPinformationleakage expose_php=Off #Logallerrors log_errors=On #Donotregisterglobalsforinputdata register_globals=Off #MinimizeallowablePHPpostsize post_max_size=1K #EnsurePHPredirectsappropriately cgi.force_redirect=0 #Disallowuploadingunlessnecessary #EnableSQLsafemode sql.safe_mode=On #AvoidOpeningremotefiles allow_url_fopen=Off
十五、如果可能让Nginx运行在一个chroot监狱
把nginx放在一个chroot监狱以减小潜在的非法进入其它目录。你可以使用传统的与nginx一起安装的chroot。如果可能,那使用FreeBSDjails,Xen,OpenVZ虚拟化的容器概念。
十六、在防火墙级限制每个IP的连接数
网络服务器必须监视连接和每秒连接限制。PF和Iptales都能够在进入你的nginx服务器之前阻止最终用户的访问。
LinuxIptables:限制每次Nginx连接数
下面的例子会阻止来自一个IP的60秒钟内超过15个连接端口80的连接数。
/sbin/iptables-AINPUT-ptcp–dport80-ieth0-mstate–stateNEW-mrecent–set /sbin/iptables-AINPUT-ptcp–dport80-ieth0-mstate–stateNEW-mrecent–update–seconds60–hitcount15-jDROP serviceiptablessave
请根据你的具体情况来设置限制的连接数。
十七、配置操作系统保护Web服务器
像以上介绍的启动SELinux.正确设置/nginx文档根目录的权限。Nginx以用户nginx运行。但是根目录(/nginx或者/usr/local/nginx/html)不应该设置属于用户nginx或对用户nginx可写。找出错误权限的文件可以使用如下命令:
find/nginx-usernginx find/usr/local/nginx/html-usernginx
确保你更所有权为root或其它用户,一个典型的权限设置/usr/local/nginx/html/
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选项来删除这些文件。
十八、限制Nginx连接传出
黑客会使用工具如wget下载你服务器本地的文件。使用Iptables从nginx用户来阻止传出连接。ipt_owner模块试图匹配本地产生的数据包的创建者。下面的例子中只允许user用户在外面使用80连接。
/sbin/iptables-AOUTPUT-oeth0-mowner–uid-ownervivek-ptcp–dport80-mstate–stateNEW,ESTABLISHED-jACCEPT
通过以上的配置,你的nginx服务器已经非常安全了并可以发布网页。可是,你还应该根据你网站程序查找更多的安全设置资料。例如,wordpress或者第三方程序。