Nginx 拒绝错误 SNI 握手, 防止扫描

这篇文章是 《屏蔽 Censys 扫描器, 及设置仅允许 Cloudflare 回源》的扩展, 有助于更好的保护源站避免被扫描, 且理论上对全部扫描器都有效.

在 Nginx 1.19.4 中, 添加了一个新的特性, 允许使用 ssl_reject_handshake 这个参数来拒绝错误 SNI 请求的握手.

源站 IP 是如何泄漏的

在上一篇博客文章中提到过, Censys 这类的扫描器在不停的扫描互联网空间, 他们获取服务器默认 SNI 的方法之一就是使用 curl, 例如 curl -v -k https://23.92.28.1, 此时服务器会返回的内容如下:

➜ curl -v -k https://23.92.28.1
*   Trying 23.92.28.1:443...
* Connected to 23.92.28.1 (23.92.28.1) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: C=US; ST=California; L=San Jose; O=test.thisdomaindoesnotexist.io P; OU=test.thisdomaindoesnotexist.io; CN=test.thisdomaindoesnotexist.io
*  start date: Aug 11 03:22:00 2023 GMT
*  expire date: Feb  9 15:27:00 2123 GMT
*  issuer:xxxxxx
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: 23.92.28.1]
* h2 [:path: /]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x13f012800)
> GET / HTTP/2
> Host: 23.92.28.1
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/2 200
< server: nginx
< date: Sat, 09 Sep 2023 13:47:07 GMT
< content-type: text/html
< content-length: 635
< last-modified: Thu, 10 Aug 2023 15:52:00 GMT
< etag: "x"xxxxx
< strict-transport-security: max-age=31536000
< accept-ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
* Connection #0 to host 23.92.28.1 left intact
</html>%

可见, 证书会包含在 Server certificate: 字段中, 其中包括 SNI 信息 (已手动替换为不存在的域名, 不用试了)

如何让 Nginx 拒绝错误 SNI 的握手

打开 Nginx 配置文件, 找到 Server 字段, 并且在上方插入一段新的 Server 配置块, 输入以下内容, 注意原先的 listen 443 参数不要删!!

    listen 443 ssl default_server;
    ssl_reject_handshake on;

完整的配置应该是

server {
    listen 443 ssl default_server;
    ssl_reject_handshake on;
}

然后重启 nginx

service nginx restart

此时再尝试 curl -v -k https://23.92.28.1, 你会看到

➜ curl -v -k https://23.92.28.1
*   Trying 23.92.28.1:443...
* Connected to 23.92.28.1 (23.92.28.1) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* LibreSSL/3.3.6: error:1404B458:SSL routines:ST_CONNECT:tlsv1 unrecognized name
* Closing connection 0
curl: (35) LibreSSL/3.3.6: error:1404B458:SSL routines:ST_CONNECT:tlsv1 unrecognized name

此时已经不会显示证书信息

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇