Nginx 配置:安全
可以用来检测自己部署的网站安全性情况,本文介绍一些 Nginx 常用的安全防护手段
全局 TLS 加密
这一点就不用说了,如果没套上 TLS 也不用谈什么安全了
证书的选择上我倾向于基于 secp384r1
椭圆曲线的 ec-384
证书,申请也很简单,可以参考我之前写的 Nginx 配置:证书
server 在 80 端口强制重写 HTTPS
80 端口其实是个假端口,仅负责将所有合法 HTTP 请求转发至 443 端口并拒绝所有不可接受的请求
1 | server { |
将可以接受的域名重写为HTTPS,交给Stream进行分流
我不允许任何 HTTP 流量请求,没人喜欢裸奔
隐藏一些路径
这里隐藏了开头是点的路径,注意返回 404 而不是 403,以免引起攻击者注意
1 | server { |
开启 HSTS
HTTP Strict Transport Security (HSTS) is a policy mechanism that helps to protect websites against man-in-the-middle attacks such as protocol downgrade attacks[1] and cookie hijacking. It allows web servers to declare that web browsers (or other complying user agents) should automatically interact with it using only HTTPS connections, which provide Transport Layer Security (TLS/SSL), unlike the insecure HTTP used alone. HSTS is an IETF standards track protocol and is specified in RFC 6797.
Wikipedia
添加 HSTS Header 防止 301 劫持,这一行也可以加到 http 全局配置里面
1 | server { |
拒绝 TLS 握手
显然 Nginx 可以通过配置来实现域名白名单访问,也就是说只有我配置的域名可以访问到我的服务
那么,如果知道 IP 能不能反查出域名呢?
一个常见的配置错误
我在 Nginx 配置:基于 SNI 的分流 这篇文章中提到可以使用 Nginx 的 ngx_stream_module
实现基于 SNI 的分流,同时拒绝非法访问
那么如果不使用 stream 模块,按照传统 HTTP 配置 server_name
进行分流会怎么样?
看下面的示例:
1 |
|
当我仅知道 IP 时,我访问 https://IP
,这时 Nginx 的行为是与配置第一个 server 尝试 TLS 握手
TLSv1.2
过程如下:
- 经过 TCP 握手,建立 TCP 连接
- Client 发送 Hello
- Server 发送 Hello 和证书(其中包含了主机名 api.myserver.com)
随后 TLS 握手失败
此时我便得知 api.myserver.com
是该 IP 的一个合法域名
更加安全的方法
预读 SNI,非法请求直接拒绝握手
1 | stream { |
合理选择加密协议与套件
ssl_protocols
所有现代浏览器和软件都已经支持 TLSv1.3
,如果需要兼容几年前的老浏览器,推荐加上 TLSv1.2
1 | http { |
ssl_ciphers
推荐开启使用 server 端 cipher 顺序
1 | http { |
一些请求头
1 | http { |