作者:mobiledu2502939211 | 来源:互联网 | 2023-10-13 09:25
nginx作为一款流行的web服务器,很多时候作为网站访问入口暴露在公网环境上,为了保护我们的资产,安全加固必不可少。1.禁用server_tokens指令,不暴露版本号。以上是n
nginx作为一款流行的web服务器,很多时候作为网站访问入口暴露在公网环境上,为了保护我们的资产,安全加固必不可少。
1. 禁用server_tokens指令,不暴露版本号
# 建议配置在http 全局
Server_tokens off;
2. 禁用不需要的HTTP方法
# 一般的网站和应用程序,你应该只允许GET,POST,和HEAD并禁用其他
# http 444 代表无响应
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 444;
}
3. 设置缓冲区大小限制
# 为了防止对您的Nginx Web服务器的缓冲区溢出攻击,坐落在一个单独的文件以下指令(创建的文件名为/etc/nginx/conf.d/buffer.conf为例)
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
# 包含此配置
include /etc/nginx/conf.d/*.conf;
4. 设置access error日志
# nginx.conf配置文件中,error_log、access_log前的#去掉
# 示例如下:
log_format nsfocus '$remote_addr - $remote_user [$time_local] '
' "$request" $status $body_bytes_sent "$http_referer" '
' "$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log nsfocus;
error_log logs/error.log nsfocus;
# nsfocus是设置配置文件格式的名称
5. 反向代理隐藏主机信息
# 建议配置在http
proxy_hide_header X-Application-Context;
或者
proxy_hide_header X-Powered-By; proxy_hide_header Server;
6. SSL安全加固
ssl_protocols 协议版本指定为TLSv1.2 TLSv1.3;
# 指定加密模式 禁用弱加密模式
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!3DES:!ADH:!RC4:!DH:!DHE;
7. header安全加固
# X-Frame-Options 同源策略
# 该响应头用于是否允许浏览器加载 frame、 iframe、 object 等属性。可以使用该功能来避免 点击劫持
add_header X-Frame-Options SAMEORIGIN;
该指令用三个可用的配置
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM https://example.com/
当设置为 DENY 时,站点禁止任何页面被嵌入。
当设置为 SAMEORIGIN 时,只允许加载同源的 fram/iframe/object。
当设置为 ALLOW-FROM 时,只允许加载指定的源。
---------------------------------
# Content-Security-Policy CSP防护
# 该响应头主要用于规定页面可以加载那些资源(css/js/img 等)
# 定义所有资源文件的默认加载规则为self,表示允许相同来源的内容(相同的协议、域名和端口)
add_header Content-Security-Policy "default-src 'self';";
或
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline';font-src 'self' data:; img-src 'self' data: 'unsafe-inline' https:; style-src 'self' 'unsafe-inline';frame-ancestors 'self'; frame-src 'self';connect-src https:";
-----------------------------------------------
# X-XSS-Protection 开启XSS防护
# 该响应头是用于防范及过滤 XSS 的
add_header X-XSS-Protection "1; mode=block";
# 可选参数
X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=
说明
0,禁用 XSS 过滤
1,开启 XSS 过滤
1; mode=block,开启 XSS 过滤,并且若检查到 XSS 攻击,停止渲染页面。
X-XSS-Protection: 1; report=,开启 XSS 过滤,并且若检查到 XSS 攻击,将使用指导的 url 来发送报告
--------------------------------------------------
# X-Content-Type-Options资源解析
# 用来指定浏览器对未指定或错误指定 Content-Type 资源真正类型的猜测行为,nosniff 表示不允许任何猜测
# 在我们通常的请求响应中,浏览器会根据 HTTP 响应的 Content-Type 来分辨响应的类型。如 text/html 代表 html 文档。 但当响应类型未指定或错误指定时,浏览会尝试启用 MIME-sniffing 来猜测资源的响应类型。
# 如通过精心制作一个图像文件,并在其中嵌入可以被浏览器所展示和执行的 HTML 和 Javascript 代码。由于未关闭资源的类型猜测,浏览器将直接执行嵌入的 Javascript 代码,而不是显示图片。
add_header X-Content-Type-Options nosniff;
# 这个响应头的值只能是 nosniff,可用于 IE8+ 和 Chrome
----------------------------------------------------------
# Strict-Transport-Security HSTS防护
#
'''
Strict-Transport-Security,简称 HSTS。该响应头用于标识浏览器用 HTTPS 替代 HTTP 的方式去访问目标站点。
我们知道 HTTPS 相对于 HTTP 有更好的安全性,而很多 HTTPS 网站,也可以通过 HTTP 来访问。开发人员的失误或者用户主动输入地址,都有可能导致用户以 HTTP 访问网站,降低了安全性。一般,我们会通过 Web Server 发送 301/302 重定向来解决这个问题。 (Jerry Qu)
我们可以使用下面方式启用 HSTH
'''
add_header strict-transport-security "max-age=16070400; includeSubDomains;";
'''
当用户第一次访问后,将返回一个包含了 strict-transport-security 响应头的字段。他将告诉浏览器,在接下来的 16070400 秒内,当前网站的所有请求都强制使用 HTTPS 的方式访问。即使用户手动输入 http://,浏览器也会强制使用 HTTPS 方式访问。
参数 includeSubDomains 是可选的,当指定了该参数,所有子域名将采用同样的 HSTS 规则。
可以看到 HSTS 可以很好的解决 HTTPS 降级攻击,但是对于 HSTS 生效前的首次 HTTP 请求,依然无法避免被劫持。浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:内置一份可以定期更新的列表,对于列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议
'''
-----------------------------------------------
# CSRF跨站伪请求防护
# CSRF的一般防护策略:
# 1. 限制referer请求来源
location /iot/ {
valid_referers none blocked 192.168.0.41; #现在referer源
if ($invalid_referer) {
return 403;
}
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:5005/iot/;
}
# 2. 增加字段token验证
# 3. 在程序中增加filter,获取referer之后,进行判断
String verifyRefererStr=“http://localhost:8889/,http://localhost:8090/,http://localhost:80/”;
HttpServletRequest req = (HttpServletRequest) servletRequest;
String referer=req.getHeader(“referer”);
System.out.println(“referer:”+referer);
String[] verifyReferer = verifyRefererStr.split(",");
boolean csrfFlag=false;
for (String vReferer : verifyReferer) {
if (referer == null || referer.trim().startsWith(vReferer)) {
csrfFlag = true;
break;
}
}
if (!csrfFlag) {
System.out.println(“疑似CSRF攻击,referer:” + referer);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
8. 限制并发、访问速率和流量
# 使用的模块
(1)limit_conn_zone 模块 - 限制同一 IP 地址并发连接数;
(2)limit_request 模块 - 限制同一 IP 某段时间的访问量;
(3)core 模块提供 - limit_rate 限制同一 IP 流量。
# 示例
#定义链接数限制内存块,以ip地址为key,内存块名叫my_limit_zone,大小10MB
limit_conn_zone $remote_addr zOne=my_limit_zone:10m;
#声明限制单IP限制10个连接
limit_conn my_limit_zone 10;
#声明限制请求传输速率在超过500KB后启用
limit_rate_after 500K;
#声明每个请求会被限速为100K的网速
limit_rate 100K;
#限制每秒请求数(超出的可以丢弃或者排队,排队里也可以定义队列长度,超出的丢弃),首先定义请求数限制的内存块,key为二进制的IP地址,内存块名叫normal_req_limit,大小10M,速率20r/s就是20个request请求每秒
limit_req_zone $binary_remote_addr zOne=normal_req_limit:10m rate=20r/s;
#声明限制请求速率,使用上面这个内存块来记录,超过速率的给一个可容纳100个请求的队列,排队处理,nodelay,无推迟,意思是队列满了之后超过的直接丢弃不处理了
limit_req zOne=normal_req_limit burst=100 nodelay;
9. 防盗链设置
location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
valid_referers none blocked server_names *.nsfocus.com http://localhost baidu.com;
if ($invalid_referer) {
rewrite ^/ [img]http://www.XXX.com/images/default/logo.gif[/img];
# return 403;
}
}
以上是nginx安全加固的一些建议,仅供参考。