基于本地NGINX反向代理加速docker pull

详解 SNI、DoH 与本地 Nginx 反向代理实践

本文将详细介绍 SNI(Server Name Indication)、DoH(DNS over HTTPS)相关原理,并通过一个实用的 Nginx 本地反代配置实例,结合自制的 SNI 封锁检测脚本,帮助你理解在严苛网络环境下如何提升访问 DNS 及 Web 资源的可达性和隐私性。


一、SNI(Server Name Indication)是什么?

SNI 是 TLS/SSL 握手时用于指明目标主机名的扩展。客户端在建立 HTTPS 连接时,会在握手的 ClientHello 阶段明文发送欲访问的域名。这样,服务器可以基于域名选择对应的证书,支持一个 IP 托管多个站点。

SNI 特点与风险:

  • SNI 明文传输,易被中间人(如审查防火墙)检测和拦截。
  • 某些网络环境会针对 SNI 字段中的“敏感域名”进行封锁(即“SNI 封锁”),导致即使你有正确 IP,也无法访问目标站点。

二、DoH(DNS over HTTPS)简介

DoH 是一种通过 HTTPS 协议进行 DNS 查询的方式,目的是防止传统明文 DNS 查询被劫持、污染或监控。

DoH 优势:

  • 查询过程加密,难以被中间人监听和篡改。
  • 可防止 DNS 污染、劫持,提升隐私性。
  • 可绕过部分基于 DNS 的封锁手段。

典型 DoH 服务商:


三、Nginx 本地反向代理 DoH 实践

有时直连 DoH 服务(如 cloudflare-dns.com)会遇到 SNI 封锁,或希望统一流量出口、加速 DoH 访问,可以利用 Nginx 本地反代:

1. 反代配置解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
map $host $doh_upstream {
cloudflare-dns.com 104.16.248.249;
}

server {
listen 443 ssl;
server_name cloudflare-dns.com;

ssl_certificate certs/cloudflare-dns.com.pem;
ssl_certificate_key certs/cloudflare-dns.com-key.pem;

location / {
proxy_pass https://$doh_upstream;
proxy_set_header Host cloudflare-dns.com;
}
}

四、SNI 封锁检测脚本详解

结合以上配置,我们可以用下述脚本检测某域名是否遭遇 SNI 封锁,以及本地 DNS 污染等多种网络问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/bin/bash

DOMAIN=$1
PROXY="192.168.1.2:7890"
echo "DOMAIN: $DOMAIN"
echo "=== 1. 本地 dig 查询 IP(可能被污染) ==="
LOCAL_IP=$(dig +short $DOMAIN | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
echo "dig IP: $LOCAL_IP"
echo

echo "=== 2. Cloudflare DoH 查询 IP(防污染) ==="
DOH_IP=$(curl -s "https://cloudflare-dns.com/dns-query?name=$DOMAIN&type=A" \
-H 'accept: application/dns-json' -x $PROXY | grep -oP '"data":"\K[\d.]+' | head -1)
echo "DoH IP: $DOH_IP"
echo

echo "=== 3. Ping 检测 dig IP 是否可达 ==="
if [ -n "$LOCAL_IP" ]; then
if ping -c 4 "$LOCAL_IP" > /dev/null 2>&1; then
echo "Ping $LOCAL_IP 成功,可达。"
else
echo "Ping $LOCAL_IP 失败,不可达。"
fi
else
echo "本地 dig 未查到 IP。"
fi
echo

echo "=== 4. Ping 检测 DoH IP 是否可达 ==="
if [ -n "$DOH_IP" ]; then
if ping -c 4 "$DOH_IP" > /dev/null 2>&1; then
echo "Ping $DOH_IP 成功,可达。"
else
echo "Ping $DOH_IP 失败,不可达。"
fi
else
echo "DoH 查询未查到 IP。"
fi
echo

echo "=== 5. 通过域名不使用代理进行 curl 测试 ==="
curl -I --connect-timeout 8 "https://${DOMAIN}"
echo

echo "=== 6. 用 dig IP 直连 curl(带 Host) ==="
if [ -n "$LOCAL_IP" ]; then
curl -k "https://${LOCAL_IP}/" -H "Host: $DOMAIN" -I --connect-timeout 8
else
echo "DoH 查询无 IP,跳过。"
fi
echo

echo "=== 7. 用 DoH IP 直连 curl(带 Host) ==="
if [ -n "$DOH_IP" ]; then
curl -k "https://${DOH_IP}/" -H "Host: $DOMAIN" -I --connect-timeout 8
else
echo "DoH 查询无 IP,跳过。"
fi
echo

echo "=== 8. 通过代理直连域名(模拟国外环境)==="
curl "https://${DOMAIN}" -x $PROXY -I --connect-timeout 8
echo

echo "=== 流程结束 ==="

五、总结与实践建议

  1. 利用 Nginx 本地反代 可规避 SNI 封锁,让内网设备稳定访问 DoH 服务。
  2. 结合 SNI 检测脚本,可快速定位访问失败的症结,是 DNS 污染、SNI 封锁还是 IP 被墙。
  3. 安全建议:
    • 本地部署 Nginx 时注意证书安全,避免泄露私钥。
    • 可适当定制反代规则,支持多家 DoH 服务切换。
  4. 灵活运用
    • 企业或家庭网络可统一出口 DNS,提升隐私与安全性。
    • 科学上网场景可配合代理使用,进一步绕开封锁。

参考链接:

欢迎根据你的实际需求调整配置,提升网络可用性与安全性!

-------------end-------------