Nginx 安全加固参考建议 —— 筑梦之路

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=<reporting-uri>,开启 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安全加固的一些建议,仅供参考。

猜你喜欢

转载自blog.csdn.net/qq_34777982/article/details/128131493