在 Nginx上配置 HSTS、CSP 等安全策略

配置 HSTS(HTTP Strict-Transport-Security头缺失或不安全)

HSTS是一种 安全策略,即— HTTP Strict Transport Security,HTTP严格传输安全。假设TLS连接没有错误,兼容的浏览器将会在 max-age 参数指定的保留期内激活HSTS。它告诉浏览器:“只能用HTTPS来访问我的网站,不要用HTTP哦!”这样,即使有人尝试用不安全的方式(HTTP)来访问网站,浏览器也会自动切换到安全的方式(HTTPS)。

一旦站点启用了HSTS,用户的后续访问就会直接进入443端口,然而你还需要确保那些访问到80端口的用户能被重定向到正确的地址。为了支持这个重定向,而且由于在明文响应中HSTS响应头是不被允许的。

需要配置重定向

HTTP响应中包含 Strict-Transport-Security 头实现网站HSTS,像下面这样配置,就实现了HSTS:

登录后复制
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • 1.
Nginx配置HSTS的示例代码:
登录后复制
server {  
    listen 80;  
    server_name example.com;  
  
    # 重定向所有HTTP请求到HTTPS  
    return 301 https://$host$request_uri;  
}  
  
server {  
    listen 443 ssl;  
    server_name example.com;  
  
    # SSL证书和其他SSL配置...  
  
    # 添加HSTS头部  
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always ;
  
    # 其他配置...  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

要注意 add_header 这个指令的继承方式,如果一个子配置块中设置了add_header 指令,那么在上层配置块中的 add_header 指令是不会被继承的。如果你需要在子配置中添加额外的add_header 指令,那么有关HSTS那部分要复制到子配置中。

 https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header

这个配置做了什么呢?
  1. 重定向HTTP请求到HTTPS:在第一个server块中,我们监听HTTP 80端口,然后使用return 301 指令将所有HTTP请求重定向到HTTPS。
  2. 添加HSTS头部:在第二个server块中,我们监听HTTPS 443端口,并使用add_header指令添加一个名为Strict-Transport-Security的头部。这个头部告诉浏览器:“在接下来的31536000秒(也就是1年)内,只能用HTTPS来访问这个网站,而且也包括它的所有子域名。另外,如果你支持的话,请把这个策略预加载到你的缓存里。”
Strict-Transport-Security头部的参数解释:
  • max-age=31536000:表示这个HSTS策略的有效期是31536000(单位是秒,31536000/3600*24 = 365天 =1年)。在这段时间内,浏览器会自动使用HTTPS来访问网站。
  • includeSubDomains:表示这个HSTS策略也适用于网站的所有子域名。
  • preload:是一个可选的参数,是一个为了解决第一次访问的用户,无法预先得知HSTS设置而创建的。它告诉浏览器:“如果你支持的话,请把这个HSTS策略预加载到你的缓存里。”这样,即使用户第一次访问网站时没有用HTTPS,浏览器也会知道应该使用HTTPS。
  • always:表示无论哪种请求都将HSTS的头发送给客户端,也包括错误响应。默认情况404等是不发送HSTS头的。

在 Nginx上配置 HSTS、CSP 等安全策略_安全

配置 CSP(Content-Security-Policy)

HTTP Content-Security-Policy 响应头允许网站运营者能够控制遵循CSP的用户代理(通常是浏览器)可以为特定页面加载的资源,通过控制要启用哪些功能,以及从哪里下载内容,可以减少网站的***面。除了少数例外,策略主要涉及指定服务器来源和脚本终端节点。这有助于防范跨站点脚本G击 (  Cross-site_scripting )。

 CSP的主要目的是,用于检测并削弱某些特定类型的G击,包括跨站脚本(cross-ste scripting, XSS)和数据注入G击等。无论是数据盗取、网站内容污染还是恶*软件分发,这些G击都是主要的手段。例如,CSP可以完全禁止内联的JavaScript,并且控制外部代码从哪里加载。它也可以禁止动态代码执行。禁用了所有的这些源,XSS变得更加困难。一个网站通过设置 Content-Security-Policy 响应头启用所需的CSP策略。

为使 CSP 可用,你需要配置你的网络服务器返回  Content-Security-Policy HTTP 标头(有时你会看到 X-Content-Security-Policy 标头,但那是旧版本,并且你无须再如此指定它)。

 句法

 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy

登录后复制
Content-Security-Policy: <policy-directive>; <policy-directive>
  • 1.

其中<policy-directive>由以下部分组成: <directive> <value>没有内部标点符号。

 Fetch directives 通过获取指令来控制某些可能被加载的确切的资源类型的位置。

具体指令:

  • default-src:默认策略
  • script-src:限制 JavaScript 的源地址。
  • style-src:样式,限制层叠样式表文件源。
  • img-src:限制图片和图标的源地址。
  • connect-src:链接,限制能通过脚本接口加载的 URL。
  • font-src:字体,设置允许通过 @font-face 加载的字体源地址。
  • object-src:插件<object>, <embed> 或者<applet>等
  • media-src:多媒体<audio>,<video>之类
  • frame-src:设置允许通过类似 <frame> 和 <iframe> 标签加载的内嵌内容的源地址。
  • sandbox:类似 <iframe> sandbox 属性,为请求的资源启用沙盒。
  • Referrer-Policy:用来指定会离开当前页面的跳转链接的 referer header 信息。

可取值与含义:

  • *: 任意来源
  • none: 任何来源的都不加载
  • self: 同源,与请求同源的资源可以加载
  • https: 要求来源是https协议的
  • https://xxx.com: 要求来源是https协议的某个站点
  • css.test.com: 要求来源是某个站点
  • *.test.com: 要求来源是某个站点及其所有的子站点
  • blob: 允许加载 Blob 资源,通常用于 Web 应用的文件处理或视频流。
  • data: 允许使用 data: 协议加载数据 URI(如内嵌图片或字体)。但这也可能被用于 XSS G击,通常建议限制使用。
  • unsafe-inline: 行内代码可以执行'unsafe-eval':允许动态代码执行,例如 JavaScript的 eval()方法
  • unsafe-eval: 控制多种脚本执行方法,这些方法可根据字符串创建代码。

CSP 被设计成完全向后兼容(除 CSP2 在向后兼容有明确提及的不一致; 更多细节查看 这里 章节 1.1)。不支持 CSP 的浏览器也能与实现了 CSP 的服务器正常工作,反之亦然:不支持 CSP 的浏览器只会忽略它,如常运行,默认为网页内容使用标准的同源策略。如果网站不提供 CSP 标头,浏览器也使用标准的 同源策略

Nginx配置CSP的示例代码

这里  script-src 放开了允许内联js 'unsafe-inline',其实这里并不是很安全,但公司项目的前端架构已经成型改动代码工作量太大,先跟着指定的ip或域名访问这样配置着。后面有时间在出动态生成 nonce属性值的文档。

登录后复制
#使用 CSP
add_header Content-Security-Policy "default-src 'self' *.demo.com(该地址按需修改); script-src 'self' 'unsafe-inline' *.demo.com(该地址按需修改); connect-src 'self'; img-src * data: blob:; style-src 'self' 'unsafe-inline' 'unsafe-eval' *.demo.com(该地址按需修改) https:; frame-ancestors 'self'; font-src * https: data:";
  • 1.
  • 2.

页面结果:

在 Nginx上配置 HSTS、CSP 等安全策略_HSTS_02

参考文献:

更多Nginx配置安全策略总结

“X-Content-Type-Options”头缺失或不安全
登录后复制
# 禁止服务器自动解析资源类型,防止浏览器对内容类型进行猜测,提升安全性
add_header X-Content-Type-Options nosniff;
  • 1.
  • 2.

nosniff 是禁止嗅探 ,服务器提示客户端一定按照 Content-Type 首部中的 MIME 类型来解析,而不能对其进行修改。

禁用了客户端的 MIME 类型嗅探行为,防止**代码的注入。开启 X-Content-Type-Options 要注意,要保证所传输的内容都要有正确 Content-Type 属性,要是没有这个属性,可能会造成加载不成功和无法运行;因为关闭了浏览器自动识别这一项。有些浏览器 如 IE9 ,IE11 在无法获得类型时,就不加载内容。

“X-XSS-Protection”头缺失或不安全
登录后复制
# 防止XSS跨站脚本G击
add_header X-Xss-Protection "1; mode=block";
  • 1.
  • 2.

XSS***:跨站脚本***:

X-Xss-Protection:4个选项值:

  • 0: 不开启XSS保护
  • 1: 开启保护(浏览器中一般默认),检测到跨站点脚本***,浏览器将删除不安全的部分。
  • 1; mode=block 检测到***,浏览器将阻止页面的呈现
  • 1; report=<reporting-uri> 检测到跨站点脚本***,浏览器将清理页面并报告违规行为。这使用CSP report-uri功能发送报告;只有chrome支持发送报告。
X-Frame-Options响应头防点击劫持
登录后复制
# 防止嵌入 到frame 中;避免点击劫持***
add_header X-Frame-Options  DENY ;
  • 1.
  • 2.

X-Frame-Options 3个选项值:

  • DENY: 拒绝一个页以frame方式加载
  • SAMEORIGIN: 同源域名下的页面,可以用frame方式加载
  • ALLOW-FROM: 允许指定的域名以frame形式加载

点击劫持,是在某个自身不安全站点的某个页面上有一个iframe加载了你的网站的某个页面,***者可以篡改这个iframe,诱使用户去点击,所以最好还是禁止iframe去加载你的页面;或者是同源和个别指定站点可以以frame形式加载你的页面。

发现可高速缓存的SSL页面
登录后复制
# “Cache-Control: no-store”和“Pragma: no-cache”或“Cache-Control: no-cache”
add_header Cache-Control max-age=3600;
  • 1.
  • 2.
检测到SHA-1密码套件
登录后复制
ssl_ciphers ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE:!SHA-1;
ssl_prefer_server_ciphers on;
  • 1.
  • 2.
检测到隐藏目录
登录后复制
location ^~ /(html|static|img) {
 	deny all;
}
location ^~ /地址名称/对应的目录/ {
 	deny all;
}
error_page 403 =404 /404.html;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
检测到支持较老的TLS版本
登录后复制
# TLSv1.2 以上版本即可
ssl_protocols TLSv1.2 TLSv1.3;
  • 1.
  • 2.
未实施加密
登录后复制
set $open_http 0;
if ($scheme = http) {
     set $open_http "${open_http}1";
 }
 if ($scheme = https) { 
     set $open_http "${open_http}0";
 }
 if ($request_uri ~* "/地址名称/ajax/libs/") {
     set $open_http "${open_http}0";
 }
 if ($request_uri ~* "/地址名称/js/") {
     set $open_http "${open_http}0";
 }

 if ($open_http = "010") {
     return 403;
 }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
启用了不安全的“OPTIONS”HTTP 方法
登录后复制
server {
    ...
    # 如果我们在服务器环境中,最好使用这样的结构:
    add_header Allow "GET, HEAD, POST" always;
    
    if ($request_method !~ ^(GET|HEAD|POST)$) {
      # 您还可以在“if”上下文中使用“add_header”:
      # add_header Allow "GET, HEAD, POST" always;
      return 405;
    
    }
    ...
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑、在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值