nginx 安全配置文档
1.配置文档中有多处明确写出了nginx的配置文件路径,该路径是测试环境中的路径,线上系统的nginx配置文件与文档中所写的路径可能不一样,在进行相关配置时,应以线上配置文件的实际路径为准。
线上系统nginx的安装目录在:/usr/local/nginx,默认配置文件在/usr/local/nginx/conf/nginx.conf,此外也引用了/usr/local/nginx/conf/conf.d目录下的配置文件。
2.本文档仅包括了用于提升安全的配置方法。
3.在遵从本文档的方法进行配置前,请做好相关配置文件的备份,以便在配置失败时可以回退到变更前状态。
1.新安装,选用安全稳定版本
编号: |
Nginx_Sec_001 |
适用: |
LINUX下新安装或者升级nginx服务器 |
配置要求: |
1.安装包要求从nginx官方网站获取,官方网站地址:http://nginx.org/。 2.安装包优先选用稳定版(stable)最新版,如果要跨大版本升级nginx,则要求在测试环境测试不存在兼容性问题后才在生产环境进行部署。 3.要求对下载的源码安装包文件进行完整性验证。
具体方法参考“备注”处的方法。 |
安全增强说明: |
1.从官方网站下载安装包及对安装包进行指纹验证可以最大程度确保安装文件未被篡改; 2.使用最新版本,最大避免旧版版中已发现安全漏洞的威胁,使用稳定版可以确保功能稳定。 |
备注: |
完整性验证方法: (1)每个nginx源码包都有一个签名文件,从官网访问下载nginx源码包的同时也下载该源码包的签名文件到同一目录,该签名文件是nginx官方使用pgp私钥对源码包进行签名得到,该文件后缀.为.asc,获取pgp签名文件方法:
(2)nginx源码包使用的是pgp签名,进行签名验证时需要到GnuPG程序,如果没有安装该工具,可以使用yum install gnupg进行安装。 (3)获取pgp签名文件的公钥ID,执行:# sudo gpg --verify nginx-1.11.3.tar.gz.asc gpg: Signature made Tue 26 Jul 2016 09:59:49 PM CST using RSA key ID A1C052F8 gpg: Can't check signature: No public key (4)根据ID号从公钥服务器中下载公钥,如下: #sudo gpg --keyserver hkp://keys.gnupg.net --recv-keys A1C052F8 gpg: requesting key A1C052F8 from hkp server keys.gnupg.net gpg: /root/.gnupg/trustdb.gpg: trustdb created gpg: key A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported gpg: key A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported gpg: no ultimately trusted keys found gpg: Total number processed: 2 gpg: imported: 2 (RSA: 2) (5)利用公钥验证nginx源码包和签名文件,如下,说明文件没有被篡改: # sudo gpg --verify nginx-1.11.3.tar.gz.asc gpg: Signature made Tue 26 Jul 2016 09:59:49 PM CST using RSA key ID A1C052F8 gpg: Good signature from "Maxim Dounin <mdounin@mdounin.ru>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: B0F4 2533 73F8 F6F5 10D4 2178 520A 9993 A1C0 52F8 |
2.使用普通账号运行nginx服务
编号: |
Nginx_Sec_002 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置要求: |
nginx服务器的work进程不能使用root账号运行,要求以普通账号运行,具体方法参考“备注”处的方法。 |
安全增强说明: |
防范或降低攻击者通过上传webshell来获取到的执行权限 |
备注: |
配置普通账号运行nginx服务方法: 1.nginx(worker进程)默认以nobody运行,创建普通账号nginx,使用nginx账号来运行 # sudo groupadd -g 1001 nginx #创建nginx组 # sudo useradd -s /sbin/nologin -M -g nginx -u 1001 nginx #创建nginx用户并加入到nginx组,不创建家目录,不允许nginx账号登录。 说明:GID和UID定义为1000,避免与nis系统上的账号的ID冲突。 2.以普通账号nginx来运行Nginx,两个方法: 方法1:如果是新安装nginx,编译时添加--user=nginx --group=nginx参数; 方法2:已完成nginx的安装,通过修该配置文件来指定,如下: 1)# sudo vim /usr/local/nginx/conf/nginx.conf 2)将#user nobody;改成user nginx nginx; 3)测试配置文件是否正确,执行命令# sudo /usr/local/nginx/sbin/nginx –t 4)在3)步骤测试配置无错误后重启Nginx服务器,执行命令# sudo /usr/local/nginx/sbin/nginx -s reload 5)查看work进程账号,确认该进程账号为nginx,执行命令# sudo ps -aux |grep nginx Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 30153 0.0 0.1 17976 1604 ? Ss 22:53 0:00 nginx: master process /usr/local/nginx/sbin/nginx nginx 30245 0.0 0.1 18404 1528 ? S 23:05 0:00 nginx: worker process 3.修改nginx根目录的用户与用户组: 1)chown –R ngin.nginx nginx根目录
注意:设置nginx根目录的用户和用户组为nginx后,且安全加固中将umask设置成027后,nginx安装目录的权限为750,普通用户无法访问该目录,此时需要nginx的安装目录的权限应该是755。 |
3.隐藏nginx的版本信息
编号: |
Nginx_Sec_003 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置要求: |
要求隐藏nginx的版本信息, 具体方法参考“备注”处的方法。 |
安全增强说明: |
绝大多数漏洞扫描工具通过获取目标web服务器的版本号来判断该web服务器是否存在安全漏洞,隐藏版本号后可以最大减少恶意攻击者通过漏扫工具来收集漏洞信息。 |
备注: |
隐藏nginx版本信息方法: 1.编辑nginx配置文件,在http块中添加 server_tokens off; 2.重启nginx服务即可。 |
4.禁止目录列表
编号: |
Nginx_Sec_004 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置要求: |
要求禁止nginx服务器目录列表功能,默认已禁止目录列表功能。具体方法参考“备注”处的方法。 |
安全增强说明: |
1.当目标web服务器允许目录时,只要访问目标web服务器的目录,如果该目录下没有设置默认访问的文件,则会同时将该目录的所有文件列出来,如下:
2.禁止目录列表功能可以避免因暴露目标网站的目录结构和敏感文件,最终造成敏感信息丢失。 |
备注: |
在nginx配置文件的location,server 或 http块中都允许设置autoindex on;确认nginx没有启用目录列表功能,即同时检查这几个地方没有配置参数autoindex on; 说明: 禁止目录列表后,url访问目录应该是403错误,如下:
|
5.日志规范
编号: |
Nginx_Sec_005 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置要求: |
要求nginx服务器同时启用访问日志和错误日志的记录,具体方法参考“备注”处的方法。 |
安全增强说明: |
nginx访问日志记录了客户端的请求行为,通过对访问日志的分析能够发现潜在的攻击行为;nginx的错误日志反映了nginx 服务器的健康状况,通过分析或者监控nginx的报错信息能够及时发现nginx存在故障问题。 |
备注: |
1.设置访问日志(access_log),日志的格式定义如下: log_format access '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for'; 各个变量的说明: $remote_user :用来记录客户端用户名称; $time_local :用来记录访问时间与时区; $request :用来记录请求的url与http协议; $status :用来记录请求状态;成功是200, $body_bytes_sent:记录发送给客户端文件主体内容大小; $http_referer :用来记录从那个页面链接访问过来的; $http_user_agent:记录客户端浏览器的相关信息; $http_x_forwarded_for:用以记录原始客户端IP地址,如果原始客户端原始请求发送到nginx前没有经过任何代理,则该变量的值为-。 2.生成的访问日志格式如下: 效果: 192.168.12.92 - - [12/Aug/2016:20:14:41 +0800] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0" – 3.错误日志的级别要求定义为warn,如下 error_log logs/error.log warn; 注意:如果更改日志文件的默认路径,则nginx运行账号需要具有新路劲下日志文件的读写权限。
说明:错误日志级别包括: debug, info, notice, warn, error, crit, alert, or emerg.默认是error级别. 当前3.0系统线上环境nginx编译时将access日志和error日志存在/var/log/nginx目录下。 |
6.限制不安全请求方法
编号: |
Nginx_Sec_006 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置建议: |
建议拒绝接受除POST和GET,HEAD以外的请求方法,具体方法参考“备注”处的方法。 |
安全增强说明: |
http定义了8种请求方法,其中PUT、DELETE等请求方法是不安全的,限制不安全的请求方法降低目标网站文件被恶意篡改的风险。 |
备注: |
配置拒绝除get,head和post方法以外的请求方法: 编辑Nginx配置文件如下: server{ ... ... if ($request_method !~ ^(GET|HEAD|POST)$) { return 444; } ... ... 注:非标准的444错误代码可以强制关闭服务器与客户端的连接而不返回任何响应信息给客户端。
http的8种请求方式: GET:当浏览器要从服务器读取指定文档。Get方法要求服务器将URL定位的资源放在响应报文的正文中,回传给浏览器。 HEAD:使用post方法,浏览器只读取请求文件的头部信息,而不是文件的正文; POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。 PUT:从客户端传送的数据取代(替换)指定文件的内容; DELETE:请求服务器删除指定文件; TRACE:回显服务器收到的请求,主要用于测试或诊断; OPTIONS:1)获取服务器支持的HTTP请求方法;2)用来检查服务器的性能; CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
7.禁用SSL/TSL不安全协议和弱加密算法
编号: |
Tomcat_Sec_007 |
适用: |
使用提供HTTPS方式访问的Tomcat服务器 |
配置要求: |
当nginx使用到https访问时,要求禁止使用SSLV1.0、SSLV2.0,SSLV3.0不安全协议,建议也不要使用TLSv1.0协议,要求禁止使用以下不安全加密算法:
具体配置方法参考“备注”处的方法。 |
安全增强说明: |
降低由于使用不安全协议和弱加密导致被中间人攻击,最终造成敏感信息泄露的风险。 |
备注: |
在nginx配置文件中的ssl_protocols和ssl_ciphers做如下配置: ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH:!kEDH:!kECDH; ssl_prefer_server_ciphers on; 保存配置文件并重启nginx服务即可。
最终支持的加密协议和加密套件如下:
优先使用说明: 加密协议 优先使用顺序TLSv1.2,TLSv1.1,TLS1.0。其中TLS1.0也被认为是不安全协议,建议不使用。 加密套件: 密钥交换算法,优先使用顺序:ECDHE(支持正向安全,2048位,防止中间人攻击),DHE,RSA(无法防止中间人攻击),不要使用1024位的DH。 认证算法,优先使用RSA, ECDSA 对称加密算法,优先使用AES_256_GCM,AES_128_GCM,AES_256_CBC,AES_128_CBC,3DES_EDE_CBC 散列算法,优先使用顺序SHA_256,SHA1 |
8.自定义缓冲区
编号: |
Nginx_Sec_008 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置建议: |
此方法可用于在遭受攻击时用于减轻攻击的防范手段,平时不强制要求配置,如要配置,相关参数则需要根据实际情况来定,具体配置方法如下: http{ ... ... server{ ... ... client_body_buffer_size 16K; client_header_buffer_size 1k; large_client_header_buffers 4 8k; client_max_body_size 1m; |
安全增强说明: |
主要用于防范或者减轻缓冲区溢出攻击。 |
备注: |
语法: client_body_buffer_size size; 默认: client_body_buffer_size 8k|16k; 上下文: http, server, location 参数使用说明: 设置缓冲区(buffer)大小,用于存放所读取客户端的请求体,在请求体(request body)大于buffer,那么整个请求体或者请求体的一部分会写到临时文件(a temporary file)。默认情况下:buffer大小等于两个内存页,在 x86, other 32-bit platforms, and x86-64这些平台它的大小是8K,64-bit平台通常是16k. -------------------------------------------------------------------------------------------------- 语法: client_header_buffer_size size; 默认: client_header_buffer_size 1k; 上下文: http, server 参数使用说明: 设置缓冲区(buffer)大小,用于存放所读取客户端的请求头,在大多数的请求中1k大小的buffer已经足够。但是,如果一个请求头包括很长的cookies或者来自WAP客户端,配置1k可能是不适合的,如果分配的buffer无法容纳 request_line/request_header ,那么则根据large_client_header_buffers配置的参数来分配large_buffer。 ------------------------------------------------------------------------------------------------------------------ 语法: large_client_header_buffers number size; 默认: large_client_header_buffers 4 8k; 上下文: http, server 参数使用说明: 设置单个buffers的大小以及buffers最大个数用于存放所读取客户端的大请求头(reading large client request header),先根据client_header_buffer_size配置的值分配一个buffer,如果分配的buffer无法容纳 request_line/request_header,那么就会再次根据large_client_header_buffers配置的参数分配large_buffer,如果large_buffer还是无法容纳,那么就会返回414(处理request_line)/400(处理request_header)错误。 ------------------------------------------------------------------------------------------------------------------ 语法: client_max_body_size size; 默认: client_max_body_size 1m; 上下文: http, server, location 参数使用说明: Sets the maximum allowed size of the client request body(请求体), specified in the “Content-Length” request header field(请求体的大小在请求头Content-Length字体写明,单位字节). If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client(如果请求体大小大于该设定值,则给客户端返回413错误). Please be aware that browsers cannot correctly display this error(但浏览器不能正确显示该错误). Setting size to 0 disables checking of client request body size.(设置值为0时,不限制请求体大小) 该参数用于设置nginx允许客户端请求体的最大值,请求体的大小在请求头Content-Length字体写明,单位字节。如果亲请求体的大小超过了配置的值,则向客户端返回413错误,但需要注意的是浏览器不能正确显示该错误,如果该参数值设置0,则不限制请求体大小。 |
9.设置连接超时时间
编号: |
Nginx_Sec_009 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置建议: |
此方法可用于在遭受攻击时用于减轻攻击的防范手段,平时不强制要求配置,如要配置,相关参数则需要根据实际情况来定,具体配置方法如下:
http { ... ... client_body_timeout 10; client_header_timeout 30; keepalive_timeout 30 30; send_timeout 10; |
安全增强说明: |
主要用于防范或者减轻慢连接攻击。 |
备注: |
语法: client_body_timeout time; 默认: client_body_timeout 60s; 上下文: http, server, location 参数使用说明: 设置读取客户端的请求体(request body.)超时时间,该超时时间为在两个连续的读取操作间的超时时间,而不是整个请求体的传输超时时间。如果在这个时间内客户端没有响应(transmit anything),nginx将向客户端返回408请求超时错误。
注意:只有请求体需要被1次以上读取时,该超时时间才会被设置。 --------------------------------------------------------------------------------------------------- 语法: client_header_timeout time; 默认: client_header_timeout 60s; 上下文: http, server 参数使用说明: 设置读取客户端请求头的超时时间,如果在该时间内客户端没有传输完整个请求头(the entire header),nginx将返回408(请求超时)错误。 ------------------------------------------------------------------------------------------------------------------- 语法: keepalive_timeout timeout [header_timeout]; 上下文:http, server, location 参数使用说明: 第一个参数的值指定了客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接。值为0时,关闭客户端的会话保持连接,(即关闭长连接). 第二个参数的值(可选)指定了应答头中Keep-Alive: timeout=time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,如果不指定这个参数,nginx不会在应答头中发送Keep-Alive信息。 ---------------------------------------------------------------------------------------------------------------- 语法: send_timeout time; 默认: send_timeout 60s; 上下文: http, server, location 参数使用说明: 该指令指定了发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,如果超过这个时间客户端没有任何响应,nginx将关闭连接。 |
10.限制并发连接
编号: |
Nginx_Sec_010 |
适用: |
LINUX下新安装部署或已上线nginx服务器 |
配置建议: |
此方法可用于在遭受攻击时用于减轻攻击的防范手段,平时不强制要求配置,如要配置,相关参数则需要根据实际情况来定,具体配置方法如下: 1.在nginx.conf里的http{}里加上如下代码: limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; 2.在需要限制并发数和下载带宽的网站配置server{}里加上如下代码: #每IP最大并发为2。 limit_conn perip 2; 限制单一虚拟服务器,最大只接受20个并发 limit_conn perserver 20; limit_rate 100k; |
安全增强说明: |
主要用以防范或者减轻DDOS攻击。 |
备注: |
语法: limit_conn_zone key zone=name:size; 默认: — 上下文: http 参数使用说明: 定义一个用于存放key变量,大小为szie名称为name的zone,key的值可以是特定变量的任何非空值(空值将不会被考虑)。 例如: limit_conn_zone $binary_remote_addr zone=perip:10m; 定义一个大小为10m字节,名称为perip的zone,该zone用于二进制来储存客户端的IP地址; Ipv4地址对应的 $binary_remote_addr 变量的大小为 4 bytes ,IPv6 地址对应的是16字节。. -------------------------------------------------------------------------------------------------- 语法: limit_conn zone number; 默认: — 上下文: http, server, location 使用参数说明: Zone变量是一个需要引起的zone,zone在前面的limit_conn_zone命令中已经定义好,使用limit_conn_zone名义中定义的zone名称即可引用,number参数用于定义一个数字,并应用到该zone,说明对该zone做并发连接数限制,最大并发连接数为number定义的值,如果客户端并发连接请求大于该值,则向客户端返回503错误(服务暂时不可用)。 例如: limit_conn_zone $binary_remote_addr zone=addr:10m; server { location /download/ { limit_conn addr 1; }
在同一时间(at a time),一个IP仅允许一个连接。 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 语法: limit_rate rate; 默认: limit_rate 0; 上下文: http, server, location, if in location 参数使用说明 限制响应传输给客户端的速率(下载速度),rate指定多少字节每秒,值为0时不限速。注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate×2。 |
转载于:https://www.cnblogs.com/heaven-xi/p/9961357.html
=====================================================================================================================
隐藏版本号
http {
server_tokens off;
}
经常会有针对某个版本的nginx安全漏洞出现,隐藏nginx版本号就成了主要的安全优化手段之一,当然最重要的是及时升级修复漏洞
开启HTTPS
server {
listen 443;
server_name ops-coffee.cn;
ssl on;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
}
ssl on: 开启https
ssl_certificate: 配置nginx ssl证书的路径
ssl_certificate_key: 配置nginx ssl证书key的路径
ssl_protocols: 指定客户端建立连接时使用的ssl协议版本,如果不需要兼容TSLv1,直接去掉即可
ssl_ciphers: 指定客户端连接时所使用的加密算法,你可以再这里配置更高安全的算法
添加黑白名单
白名单配置
location /admin/ {
allow 192.168.1.0/24;
deny all;
}
上边表示只允许192.168.1.0/24网段的主机访问,拒绝其他所有
也可以写成黑名单的方式禁止某些地址访问,允许其他所有,例如
location /ops-coffee/ {
deny 192.168.1.0/24;
allow all;
}
更多的时候客户端请求会经过层层代理,我们需要通过$http_x_forwarded_for
来进行限制,可以这样写
set $allow false;
if ($http_x_forwarded_for = "211.144.204.2") { set $allow true; }
if ($http_x_forwarded_for ~ "108.2.66.[89]") { set $allow true; }
if ($allow = false) { return 404; }
添加账号认证
server {
location / {
auth_basic "please input user&passwd";
auth_basic_user_file key/auth.key;
}
}
关于账号认证《Nginx的几个常用配置和技巧》文章中已有详细介绍,这里不赘述
限制请求方法
if ($request_method !~ ^(GET|POST)$ ) {
return 405;
}
$request_method
能够获取到请求nginx的method
配置只允许GET\POST方法访问,其他的method返回405
拒绝User-Agent
if ($http_user_agent ~* LWP::Simple|BBBike|wget|curl) {
return 444;
}
可能有一些不法者会利用wget/curl等工具扫描我们的网站,我们可以通过禁止相应的user-agent来简单的防范
Nginx的444状态比较特殊,如果返回444那么客户端将不会收到服务端返回的信息,就像是网站无法连接一样
图片防盗链
location /images/ {
valid_referers none blocked www.ops-coffee.cn ops-coffee.cn;
if ($invalid_referer) {
return 403;
}
}
valid_referers: 验证referer,其中none
允许referer为空,blocked
允许不带协议的请求,除了以上两类外仅允许referer为www.ops-coffee.cn或ops-coffee.cn时访问images下的图片资源,否则返回403
当然你也可以给不符合referer规则的请求重定向到一个默认的图片,比如下边这样
location /images/ {
valid_referers blocked www.ops-coffee.cn ops-coffee.cn
if ($invalid_referer) {
rewrite ^/images/.*\.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last;
}
}
控制并发连接数
可以通过ngx_http_limit_conn_module
模块限制一个IP的并发连接数
http {
limit_conn_zone $binary_remote_addr zone=ops:10m;
server {
listen 80;
server_name ops-coffee.cn;
root /home/project/webapp;
index index.html;
location / {
limit_conn ops 10;
}
access_log /tmp/nginx_access.log main;
}
}
limit_conn_zone: 设定保存各个键(例如$binary_remote_addr
)状态的共享内存空间的参数,zone=空间名字:大小
大小的计算与变量有关,例如$binary_remote_addr
变量的大小对于记录IPV4地址是固定的4 bytes,而记录IPV6地址时固定的16 bytes,存储状态在32位平台中占用32或者64 bytes,在64位平台中占用64 bytes。1m的共享内存空间可以保存大约3.2万个32位的状态,1.6万个64位的状态
limit_conn: 指定一块已经设定的共享内存空间(例如name为ops
的空间),以及每个给定键值的最大连接数
上边的例子表示同一IP同一时间只允许10个连接
当有多个limit_conn
指令被配置时,所有的连接数限制都会生效
http {
limit_conn_zone $binary_remote_addr zone=ops:10m;
limit_conn_zone $server_name zone=coffee:10m;
server {
listen 80;
server_name ops-coffee.cn;
root /home/project/webapp;
index index.html;
location / {
limit_conn ops 10;
limit_conn coffee 2000;
}
}
}
上边的配置不仅会限制单一IP来源的连接数为10,同时也会限制单一虚拟服务器的总连接数为2000
缓冲区溢出攻击
缓冲区溢出攻击 是通过将数据写入缓冲区并超出缓冲区边界和重写内存片段来实现的,限制缓冲区大小可有效防止
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
client_body_buffer_size: 默认8k或16k,表示客户端请求body占用缓冲区大小。如果连接请求超过缓存区指定的值,那么这些请求实体的整体或部分将尝试写入一个临时文件。
client_header_buffer_size: 表示客户端请求头部的缓冲区大小。绝大多数情况下一个请求头不会大于1k,不过如果有来自于wap客户端的较大的cookie它可能会大于 1k,Nginx将分配给它一个更大的缓冲区,这个值可以在large_client_header_buffers
里面设置
client_max_body_size: 表示客户端请求的最大可接受body大小,它出现在请求头部的Content-Length字段, 如果请求大于指定的值,客户端将收到一个"Request Entity Too Large" (413)错误,通常在上传文件到服务器时会受到限制
large_client_header_buffers 表示一些比较大的请求头使用的缓冲区数量和大小,默认一个缓冲区大小为操作系统中分页文件大小,通常是4k或8k,请求字段不能大于一个缓冲区大小,如果客户端发送一个比较大的头,nginx将返回"Request URI too large" (414),请求的头部最长字段不能大于一个缓冲区,否则服务器将返回"Bad request" (400)
同时需要修改几个超时时间的配置
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
client_body_timeout: 表示读取请求body的超时时间,如果连接超过这个时间而客户端没有任何响应,Nginx将返回"Request time out" (408)错误
client_header_timeout: 表示读取客户端请求头的超时时间,如果连接超过这个时间而客户端没有任何响应,Nginx将返回"Request time out" (408)错误
keepalive_timeout: 参数的第一个值表示客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接,可选的第二个参数参数表示Response头中Keep-Alive: timeout=time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,如果不指定这个参数,nginx不会在应Response头中发送Keep-Alive信息
send_timeout: 表示发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,如果超过这个时间客户端没有任何响应,nginx将关闭连接
Header头设置
通过以下设置可有效防止XSS攻击
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
X-Frame-Options: 响应头表示是否允许浏览器加载frame等属性,有三个配置DENY
禁止任何网页被嵌入,SAMEORIGIN
只允许本网站的嵌套,ALLOW-FROM
允许指定地址的嵌套
X-XSS-Protection: 表示启用XSS过滤(禁用过滤为X-XSS-Protection: 0
),mode=block
表示若检查到XSS攻击则停止渲染页面
X-Content-Type-Options: 响应头用来指定浏览器对未指定或错误指定Content-Type
资源真正类型的猜测行为,nosniff 表示不允许任何猜测
在通常的请求响应中,浏览器会根据Content-Type
来分辨响应的类型,但当响应类型未指定或错误指定时,浏览会尝试启用MIME-sniffing来猜测资源的响应类型,这是非常危险的
例如一个.jpg的图片文件被恶意嵌入了可执行的js代码,在开启资源类型猜测的情况下,浏览器将执行嵌入的js代码,可能会有意想不到的后果
另外还有几个关于请求头的安全配置需要注意
Content-Security-Policy: 定义页面可以加载哪些资源,
add_header Content-Security-Policy "default-src 'self'";
上边的配置会限制所有的外部资源,都只能从当前域名加载,其中default-src
定义针对所有类型资源的默认加载策略,self
允许来自相同来源的内容
Strict-Transport-Security: 会告诉浏览器用HTTPS协议代替HTTP来访问目标站点
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
上边的配置表示当用户第一次访问后,会返回一个包含了Strict-Transport-Security
响应头的字段,这个字段会告诉浏览器,在接下来的31536000秒内,当前网站的所有请求都使用https协议访问,参数includeSubDomains
是可选的,表示所有子域名也将采用同样的规则
=============================================================================================================================================
本期带来一篇最近在阿里云服务器上折腾nginx配置网站的教程。
1 nginx简介
nginx是一个轻量级的web服务器,我的认知,这东西跟负载平衡不分家。这里抄下度娘简介。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。——百度百科
接下来给出官网。
2 阿里云安装nginx
这里就不多说阿里云服务器的相关内容了,笔者长期有租用一台用于数据处理等工作。系统是Ubuntu 14.02,这里选用Xshell连接服务器进行一系列操作,并用Xftp来上传下载文件。这里安装nginx有两种方式,一种是apt-get的安装,但是这种安装一般不是最新版本。如果想要最新版本,就推荐下载源码,自行编译安装。这里我们就不使用最新版本了。至于编译安装的可以在网上搜索教程,关键就是先安装几个关键依赖库openssl,zlib,pcre,同时编译安装也比较自由,可以在自己定义的路径里安装。
apt-get update
apt-get install nginx
如果apt-get报错如图的话。并且无法安装任何软件包的话,就必须执行第一行update的命令行。
执行完update命令行,如图。
接着执行安装语句。键盘敲入y即可安装。
安装成功后,可以键入如下命令检测。
nginx -v
说起来这版本确实旧。目前官网最新版本为1.17。
3 配置nginx
我们首先了解下nginx的目录,默认安装的目录主要在/etc文件夹下。
这个时候,只需要在命令行里敲入nginx,即运行了nginx。
nginx
由于我的阿里云之前只打开了22端口用于Xshell连接,这里就多打开默认的80端口访问网站。打开阿里云官网,登录账户,点击云服务器ECS,如图点击安全组。
接着在主面板点击配置规则。
然后点击添加安全组规则,按如图所示填写页面的80端口。0.0.0.0/0表示任意ip可以访问。
接下来把服务器ip地址放到浏览器中,即可发现跳转到nginx的欢迎页面。
接下来只需要把网页放到服务器中的指定位置即可,再针对配置文件做修改。有域名的条件下,可以把域名和自己服务器关联起来做解析。
这个版本的nginx的文件配置不是nginx目录下的nginx.conf,而是site-available文件夹下的default。这里给出一个测试的配置。
root是网站的路径。这里采用二级域名来控制,所以还得去配置域名。具体的教程可以看后面的参考链接。这里就不赘述了。
4 基本命令以及错误
这里的一些命令主要是开启nginx,关闭,重启,关闭所有nginx。
# 关闭
nginx -s stop
# 查询80端口占用
netstat -ntpl | grep 80
# 杀死所有nginx进程
killall nginx
详细的命令可以参考后面的链接。
另外我在启动nginx时报了两次80端口占用的信息。
这个应该是多启动了一次nginx(猜想)。此外网上也有不少人遇到第二个端口ipv6占用问题,真正的措施并不是kill掉所有nginx,而是配置文件中的修改。这些参考链接我一并列出,有需要者自行取用。
参考链接:
3.[nginx - nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)](https://stackoverflow.com/questions/14972792/nginx-nginx-emerg-bind-to-80-failed-98-address-already-in-use)
5.[解决nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)](https://blog.csdn.net/yusiguyuan/article/details/20565337)