DNS解锁使用 docker 简单教程

DNS解锁使用 docker 简单教程

什么是 DNS 解锁

实际上就是一种结合了 DNS 劫持 (DNS Hijacking)SNI 代理 (SNI Proxy) 的流量重定向(Traffic Redirection)架构。其核心是通过一个定制的 分离解析 DNS (Split-horizon DNS) 服务器,对特定域名请求返回代理服务器自身的 IP 地址(A 记录),从而诱导客户端连接。随后,部署在同一台服务器上的 SNI 感知反向代理 (SNI-aware Reverse Proxy) 捕获入站流量,通过解析 TLS 握手中的 服务器名称指示 (Server Name Indication) 头部来识别客户端的真正目标,最终将数据包中继(Relay)到上游的原始服务器,实现透明代理和访问控制。

准备

  • (A)一台 VPS
  • (B)一台解锁漂亮的 VPS (需要有 docker)

步骤1

登录 VPS(B)

1
2
3
git clone https://github.com/0b6/dns.git
cd dns
echo "PUBLIC_IP=$(curl -s ip.sb -4)" > .env

当前的文件树应该是这样的:

.
├── .env
├── .env.save
├── .git
├── .github
├── compose.yml
├── dnsmasq
├── proxy-domains.txt
├── readme.md
└── sniproxy

我们只需要关注 proxy-domains.txt, .env 即可。

  • proxy-domains.txt中是我们需要解锁的域名地址, 你可以随意的更改, 比如你想解锁 gemini,就在其中填入 gemini.google.com.
  • .env 直接收两个变量, 分别是PUBLIC_IPALLOWED_IPS,前者是我们当前VPS的IP地址,后者是我们希望哪个IP可以通过我们进行代理,填入需要被解锁的VPS的IP即可。

之后我们启动容器,先不分离到后台,因为我们需要看一下日志:

1
docker compose up

不如意外的话,控制台会显示错误:

Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint dns-dnsmasq-1 (bb7cd1e4e43f631336d1dc4f9819be2a254d5cf217544075eb51e637cb2a94ae): failed to bind host port for 0.0.0.0:53:172.18.0.3:53/tcp: address already in use

意思其实就是 你的 VPS(B) 上的 53 端口已经被占用了。 dnsmasq 容器需要使用 53 端口(DNS 服务的标准端口),但 VPS(B)已经有另一个程序在占用它。在大多数现代 Linux 系统(如 Ubuntu)上,这个程序几乎肯定是 systemd-resolved,它是系统内置的 DNS 缓存服务。

接下来我们解决它:

1
2
# 检查 53 端口的监听情况
sudo ss -lunp | grep :53

大概率会是以下的情况:

UNCONN 0      0                           127.0.0.54:53         0.0.0.0:*    users:(("systemd-resolve",pid=285,fd=19))
UNCONN 0      0                        127.0.0.53%lo:53         0.0.0.0:*    users:(("systemd-resolve",pid=285,fd=17))

接着去取消它:

1
sudo nano /etc/systemd/resolved.conf

找到 #DNSStubListener=yes 这一行(它可能被注释掉了)。把他修改为:DNSStubListener=no。重启一下 systemd-resolved 服务。

1
sudo systemctl restart systemd-resolved

再次启动 docker 服务:

1
docker compose up

观察一下日志,如果显示以下结果就证明没问题了。:

dnsmasq-1  | 正在使用 proxy-domains.txt 文件更新配置...
dnsmasq-1  | 启动 dnsmasq 服务...

步骤2

现在我们登录 VPS(A),我们只需要修改一下原来的 DNS 为我们VPS(B)的IP地址即可。

1
nano /etc/resolv.conf

把所有 nameserver 行都注释掉,添加:

nameserver 2.2.2.2 # VPS(B) 的IP

最后在VPS(A)上进行一下测试,来测试我们的规则是否已经启用:

1
dig gemini.google.com VPS(A)的IP

之后会返回一个结果:

;; SERVER: x.x.x.x#53(x.x.x.x) (UDP)

如果这个 x.x.x.x 是你的 VPS(B)的地址,那么恭喜你,DNS解锁已经成功了。

updatedupdated2025-11-052025-11-05