NGINX 的常用配置
柳铃
撰写于 2022年 08月 17 日

常用的响应头

X-Content-Type-Options HTTP 响应头(防MIME类型混淆攻击)

互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如: text/html 代表 html 文档, image/png 是PNG图片, text/css 是CSS样式文档。然而,有些资源的 Content-Type 是错的或者未定义的。这时,某些浏览器就会启用 MIME-sniffing 来猜测该资源的类型,解析内容并执行。
X-Content-Type-Options HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定,而不能对其进行修改。这就禁用了客户端的 MIME 类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。

介绍

  该消息头最初是由微软在 IE 8 浏览器中引入的,在此之后,其他浏览器也相继引入了这个消息头,虽然其它浏览器比 IE8 什么的更先进。

  例如,我们即使给一个 html 文档指定 Content-Typetext/plain ,在 IE8 中这个文档依然会被当做 html 来解析。利用浏览器的这个特性,攻击者甚至可以让原本应该解析为图片的请求被解析为 JavaScript ,他们可以利用这种方式执行跨站点脚本攻击,使用精心制作的图像来窃取受害者在当前访问的服务器上的身份验证 cookie ,然后以受害者的身份登录到那个服务器。

  而服务器如果发送响应头 “X-Content-Type-Options: nosniff”,则 “script” 和 “styleSheet” 元素会拒绝包含错误的 MIME 类型的响应。这是一种安全功能,有助于防止基于 MIME 类型混淆的攻击。(注意: nosniff 只应用于 "script" 和 "style" 两种类型。事实证明,将其应用于图片类型的文件会导致与现有的站点冲突。也就是说,当图片的响应头带有它时,部分浏览器会出现拦截这个图片的情况,但是现在几乎都没有这个没有这个问题了。)

nginx

# 此标头只有 nosniff 一个值。

add_header 'X-Content-Type-Options'  'nosniff';

其它

  浏览器兼容性上,支持几乎所有的浏览器。
X-Content-Type-Options标头兼容性示意图

X-Content-Type-Options标头兼容性示意图

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/X-Content-Type-Options


Content-Security-Policy HTTP 响应头(防止点击劫持,跨站脚本攻击)

提示
Content-Security-Policy HTTP 响应头有一个 frame-ancestors 指令,支持这一指令的浏览器已经废弃了 X-Frame-Options 响应头

HTTP 响应头 Content-Security-Policy 允许站点管理者控制用户代理能够为指定的页面加载哪些资源。除了少数例外情况,设置的政策主要涉及指定服务器的源和脚本结束点。这将帮助防止跨站脚本攻击(XSS)。

  使用这个标头,将可以限制能通过脚本接口加载的 URL;设置允许通过 CSS的 @font-face 加载的字体源地址;设置允许通过类似 <frame> 标签加载的内嵌内容的源地址;限制图片和图标的源地址;限制应用声明文件的源地址;限制通过 <audio><video><track> 标签加载的媒体文件的源地址;限制 <object><embed><applet> 标签的源地址等等。

  使用它,可以防止点击劫持 (ClickJacking) 之类的攻击。

语法&指令

# 语法
Content-Security-Policy: <policy-directive>; <policy-directive>

# 指令
connect-src:限制能通过脚本接口加载的 URL。
default-src:为其他取指令提供备用服务 fetch directives。
font-src:设置允许通过 @font-face 加载的字体源地址。
frame-src:设置允许通过类似 <frame> 和 <iframe> 标签加载的内嵌内容的源地址。
img-src:限制图片和图标的源地址。
manifest-src:限制应用声明文件的源地址。
media-src:限制通过 <audio>、<video> 或 <track> 标签加载的媒体文件的源地址。
object-src:限制 <object>、<embed> 或 <applet> 标签的源地址。(注意:由 object-src 控制的元素可能恰巧被认为是旧版 HTML 元素,并且没有接收新的标准化功能(例如安全属性沙箱或允许 <iframe>)。因此,建议限制此获取指令(例如,如果可能,显式设置 object-src 'none')。)
script-src:限制 JavaScript 的源地址。
style-src:限制层叠样式表文件源。
form-action:限制能被用来作为给定上下文的表单提交的目标 URL(说白了,就是限制 form 的 action 属性的链接地址)

upgrade-insecure-requests:让浏览器把一个网站所有的不安全 URL(通过 HTTP 访问)当做已经被安全的 URL 链接(通过 HTTPS 访问)替代。这个指令是为了哪些有量大不安全的传统 URL 需要被重写时候准备的。
block-all-mixed-content:当使用 HTTPS 加载页面时阻止使用 HTTP 加载任何资源。

除了最后两个,其余的格式均为(以 frame-src 为例) :
Content-Security-Policy: frame-src <source>;
Content-Security-Policy: frame-src <source> <source>;

最后两个,不需要再添加任何网址,原(以 block-all-mixed-content 为例):
Content-Security-Policy: block-all-mixed-content;

这里只是列举了部分命令,更多命令请参阅底下的参考文档。

nginx 限制内嵌内容加载(防止点击劫持 (ClickJacking))

# 可以同时设置一个或多个源。

Content-Security-Policy  'frame-src'  '*.example.com';
Content-Security-Policy  'frame-src'  '*.example.com  example.com';

其它

X-Frame-Options 响应头的介绍(防止点击劫持 (ClickJacking)):

X-Frame-Options HTTP 标头有两个可能的值:

X-Frame-Options: DENY 
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。

X-Frame-Options: SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。规范让浏览器厂商决定此选项是否应用于顶层、父级或整个链,有人认为该选项不是很有用,除非所有的祖先页面都属于同一来源(origin)。

所有浏览器都兼容。
兼容性

  Content-Security-Policy 兼容性不错,除了 IE浏览器 ,大部分都支持。因版面限制,具体兼容性请参考下方的参考文档。

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


X-XSS-Protection 响应头(XSS跨站脚本攻击):

提示
此标头只有 Safari on iOS 浏览器 和 IE 浏览器支持。若网站设置了良好的 Content-Security-Policy 来禁用内联 JavaScript ('unsafe-inline'),现代浏览器不太需要这些保护, 但其仍然可以为尚不支持 CSP 的旧版浏览器的用户提供保护。

顾名思义,这个响应头是用来防范XSS的。最早我是在介绍IE8的文章里看到这个,现在主流浏览器都支持,并且默认都开启了XSS保护,用这个header可以关闭它。它有几种配置:

0: 禁止XSS过滤;
1 :启用 XSS 过滤(通常在浏览器中默认):如果检测到跨站点脚本攻击,浏览器将清理页面(删除不安全的部分);
mode = block :启动 XSS 过滤。如果检测到攻击,浏览器将阻止页面的呈现,而不是过滤页面中的XSS内容。启用XSS保护,并在检查到XSS攻击时,停止渲染页面(例如IE8中,检查到攻击时,整个页面会被一个#替换);
report = :(仅限 Chromium)启用 XSS 筛选。如果检测到跨站点脚本攻击,浏览器将清理页面并报告违规行为。这使用 CSP report-uri指令的功能发送报告;

# HTTP X-XSS-Protection 响应头是 Internet Explorer,Chrome 和 Safari 的一个特性,
# 当检测到跨站脚本攻击 (XSS)时,浏览器将停止加载页面。

# X-XSS-Protection响应头的缺失使得目标URL更易遭受跨站脚本攻击。

# 浏览器提供的XSS保护机制并不完美,但是开启后仍然可以提升攻击难度,总之没有特别的理由,不要关闭它。
add_header 'X-XSS-Protection'  0
add_header 'X-XSS-Protection' 1
add_header 'X-XSS-Protection' '1; mode=block'
add_header 'X-XSS-Protection'  '1; report=<reporting-uri>'

headers-more-nginx-module 模块:

此模块允许您添加、设置或清除您指定的任何输出或输入标头。
这是标准标头模块的增强版本,因为它提供了更多实用程序,例如重置或清除“内置标头”,如 、 和 。Content-TypeContent-LengthServer
它还允许您使用该选项指定可选的 HTTP 状态代码条件,并使用该选项指定可选的内容类型条件。

  使用此模块可以删除一些不想要让他显示的标头信息,例如:server: nginx 。地址:headers-more-nginx-module

跨域问题(仅供参考)

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, OPTIONS";

nginx配置文件(对于宝塔面板来说)

.config文件(站点配置文件)

首先在nginx主配置文件的 server 中添加类似的,然后再去每个网站的独立配置文件(宝塔默认就有):

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

limit_conn perserver 1;:网站最多能有多少连接

limit_conn perip 1;:每个请求的IP能有多少连接

limit_rate 4k;:每个连接的最大速度,默认的单位是 bytes/s ,也就是每秒传输的 字节数Bytes 而不是 比特数bits。限速指令的生效范围是根据每个连接确定的,例如前面限定每个连接的速率为4k,也就是当客户端发起两个连接的时候,速率就可以变为8k。


参考:
https://cloud.tencent.com/developer/section/1190033 (X-XSS-Protection 介绍)
https://www.cnblogs.com/you-men/p/13387316.html (Nginx配置各种响应头防止XSS,点击劫持,frame恶意攻击)
http://nginx.org/en/docs/http/ngx_http_headers_module.html (ngx_http_headers_module 模块官方说明 add_header)
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers (HTTP Headers 介绍 火狐MDN Web Docs 社区)

NGINX 的常用配置

常用的响应头

X-Content-Type-Options HTTP 响应头(防MIME类型混淆攻击)

互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如: text/html 代表 html 文档, image/png 是PNG图片, text/css 是CSS样式文档。然而,有些资源的 Content-Type 是错的或者未定义的。这时,某些浏览器就会启用 MIME-sniffing 来猜测该资源的类型,解析内容并执行。
X-Content-Type-Options HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定,而不能对其进行修改。这就禁用了客户端的 MIME 类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。

介绍

  该消息头最初是由微软在 IE 8 浏览器中引入的,在此之后,其他浏览器也相继引入了这个消息头,虽然其它浏览器比 IE8 什么的更先进。

  例如,我们即使给一个 html 文档指定 Content-Typetext/plain ,在 IE8 中这个文档依然会被当做 html 来解析。利用浏览器的这个特性,攻击者甚至可以让原本应该解析为图片的请求被解析为 JavaScript ,他们可以利用这种方式执行跨站点脚本攻击,使用精心制作的图像来窃取受害者在当前访问的服务器上的身份验证 cookie ,然后以受害者的身份登录到那个服务器。

  而服务器如果发送响应头 “X-Content-Type-Options: nosniff”,则 “script” 和 “styleSheet” 元素会拒绝包含错误的 MIME 类型的响应。这是一种安全功能,有助于防止基于 MIME 类型混淆的攻击。(注意: nosniff 只应用于 "script" 和 "style" 两种类型。事实证明,将其应用于图片类型的文件会导致与现有的站点冲突。也就是说,当图片的响应头带有它时,部分浏览器会出现拦截这个图片的情况,但是现在几乎都没有这个没有这个问题了。)

nginx

# 此标头只有 nosniff 一个值。

add_header 'X-Content-Type-Options'  'nosniff';

其它

  浏览器兼容性上,支持几乎所有的浏览器。
X-Content-Type-Options标头兼容性示意图

X-Content-Type-Options标头兼容性示意图

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/X-Content-Type-Options


Content-Security-Policy HTTP 响应头(防止点击劫持,跨站脚本攻击)

提示
Content-Security-Policy HTTP 响应头有一个 frame-ancestors 指令,支持这一指令的浏览器已经废弃了 X-Frame-Options 响应头

HTTP 响应头 Content-Security-Policy 允许站点管理者控制用户代理能够为指定的页面加载哪些资源。除了少数例外情况,设置的政策主要涉及指定服务器的源和脚本结束点。这将帮助防止跨站脚本攻击(XSS)。

  使用这个标头,将可以限制能通过脚本接口加载的 URL;设置允许通过 CSS的 @font-face 加载的字体源地址;设置允许通过类似 <frame> 标签加载的内嵌内容的源地址;限制图片和图标的源地址;限制应用声明文件的源地址;限制通过 <audio><video><track> 标签加载的媒体文件的源地址;限制 <object><embed><applet> 标签的源地址等等。

  使用它,可以防止点击劫持 (ClickJacking) 之类的攻击。

语法&指令

# 语法
Content-Security-Policy: <policy-directive>; <policy-directive>

# 指令
connect-src:限制能通过脚本接口加载的 URL。
default-src:为其他取指令提供备用服务 fetch directives。
font-src:设置允许通过 @font-face 加载的字体源地址。
frame-src:设置允许通过类似 <frame> 和 <iframe> 标签加载的内嵌内容的源地址。
img-src:限制图片和图标的源地址。
manifest-src:限制应用声明文件的源地址。
media-src:限制通过 <audio>、<video> 或 <track> 标签加载的媒体文件的源地址。
object-src:限制 <object>、<embed> 或 <applet> 标签的源地址。(注意:由 object-src 控制的元素可能恰巧被认为是旧版 HTML 元素,并且没有接收新的标准化功能(例如安全属性沙箱或允许 <iframe>)。因此,建议限制此获取指令(例如,如果可能,显式设置 object-src 'none')。)
script-src:限制 JavaScript 的源地址。
style-src:限制层叠样式表文件源。
form-action:限制能被用来作为给定上下文的表单提交的目标 URL(说白了,就是限制 form 的 action 属性的链接地址)

upgrade-insecure-requests:让浏览器把一个网站所有的不安全 URL(通过 HTTP 访问)当做已经被安全的 URL 链接(通过 HTTPS 访问)替代。这个指令是为了哪些有量大不安全的传统 URL 需要被重写时候准备的。
block-all-mixed-content:当使用 HTTPS 加载页面时阻止使用 HTTP 加载任何资源。

除了最后两个,其余的格式均为(以 frame-src 为例) :
Content-Security-Policy: frame-src <source>;
Content-Security-Policy: frame-src <source> <source>;

最后两个,不需要再添加任何网址,原(以 block-all-mixed-content 为例):
Content-Security-Policy: block-all-mixed-content;

这里只是列举了部分命令,更多命令请参阅底下的参考文档。

nginx 限制内嵌内容加载(防止点击劫持 (ClickJacking))

# 可以同时设置一个或多个源。

Content-Security-Policy  'frame-src'  '*.example.com';
Content-Security-Policy  'frame-src'  '*.example.com  example.com';

其它

X-Frame-Options 响应头的介绍(防止点击劫持 (ClickJacking)):

X-Frame-Options HTTP 标头有两个可能的值:

X-Frame-Options: DENY 
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。

X-Frame-Options: SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。规范让浏览器厂商决定此选项是否应用于顶层、父级或整个链,有人认为该选项不是很有用,除非所有的祖先页面都属于同一来源(origin)。

所有浏览器都兼容。
兼容性

  Content-Security-Policy 兼容性不错,除了 IE浏览器 ,大部分都支持。因版面限制,具体兼容性请参考下方的参考文档。

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


X-XSS-Protection 响应头(XSS跨站脚本攻击):

提示
此标头只有 Safari on iOS 浏览器 和 IE 浏览器支持。若网站设置了良好的 Content-Security-Policy 来禁用内联 JavaScript ('unsafe-inline'),现代浏览器不太需要这些保护, 但其仍然可以为尚不支持 CSP 的旧版浏览器的用户提供保护。

顾名思义,这个响应头是用来防范XSS的。最早我是在介绍IE8的文章里看到这个,现在主流浏览器都支持,并且默认都开启了XSS保护,用这个header可以关闭它。它有几种配置:

0: 禁止XSS过滤;
1 :启用 XSS 过滤(通常在浏览器中默认):如果检测到跨站点脚本攻击,浏览器将清理页面(删除不安全的部分);
mode = block :启动 XSS 过滤。如果检测到攻击,浏览器将阻止页面的呈现,而不是过滤页面中的XSS内容。启用XSS保护,并在检查到XSS攻击时,停止渲染页面(例如IE8中,检查到攻击时,整个页面会被一个#替换);
report = :(仅限 Chromium)启用 XSS 筛选。如果检测到跨站点脚本攻击,浏览器将清理页面并报告违规行为。这使用 CSP report-uri指令的功能发送报告;

# HTTP X-XSS-Protection 响应头是 Internet Explorer,Chrome 和 Safari 的一个特性,
# 当检测到跨站脚本攻击 (XSS)时,浏览器将停止加载页面。

# X-XSS-Protection响应头的缺失使得目标URL更易遭受跨站脚本攻击。

# 浏览器提供的XSS保护机制并不完美,但是开启后仍然可以提升攻击难度,总之没有特别的理由,不要关闭它。
add_header 'X-XSS-Protection'  0
add_header 'X-XSS-Protection' 1
add_header 'X-XSS-Protection' '1; mode=block'
add_header 'X-XSS-Protection'  '1; report=<reporting-uri>'

headers-more-nginx-module 模块:

此模块允许您添加、设置或清除您指定的任何输出或输入标头。
这是标准标头模块的增强版本,因为它提供了更多实用程序,例如重置或清除“内置标头”,如 、 和 。Content-TypeContent-LengthServer
它还允许您使用该选项指定可选的 HTTP 状态代码条件,并使用该选项指定可选的内容类型条件。

  使用此模块可以删除一些不想要让他显示的标头信息,例如:server: nginx 。地址:headers-more-nginx-module

跨域问题(仅供参考)

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, OPTIONS";

nginx配置文件(对于宝塔面板来说)

.config文件(站点配置文件)

首先在nginx主配置文件的 server 中添加类似的,然后再去每个网站的独立配置文件(宝塔默认就有):

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

limit_conn perserver 1;:网站最多能有多少连接

limit_conn perip 1;:每个请求的IP能有多少连接

limit_rate 4k;:每个连接的最大速度,默认的单位是 bytes/s ,也就是每秒传输的 字节数Bytes 而不是 比特数bits。限速指令的生效范围是根据每个连接确定的,例如前面限定每个连接的速率为4k,也就是当客户端发起两个连接的时候,速率就可以变为8k。


参考:
https://cloud.tencent.com/developer/section/1190033 (X-XSS-Protection 介绍)
https://www.cnblogs.com/you-men/p/13387316.html (Nginx配置各种响应头防止XSS,点击劫持,frame恶意攻击)
http://nginx.org/en/docs/http/ngx_http_headers_module.html (ngx_http_headers_module 模块官方说明 add_header)
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers (HTTP Headers 介绍 火狐MDN Web Docs 社区)

赞 (2)

评论区(3条评论)

我要评论


哥斯拉
LV1
  

前三点很有用,以前我都没注意到。收藏了。

柳铃
博主
   哥斯拉

其实,除了前三点,其它的都是原创 ╭(°A°`)╮。
看来,我还是要再努力一下下……

回复 0
哥斯拉
LV1
   柳铃

哈哈,不是这个意思。
只是后面的我已经早知道。

回复 1