保姆级教程:利用 Dnsmasq + SNIproxy 实现香港 VPS 流量分流
手里蹲着几台香港 VPS,线路虽然不错,但直连国内的时候偶尔还是会“抽风”,或者访问某些被屏蔽的站点时特别头疼。这时候如果能让 VPS 自己“聪明”一点,自动把流量分流,是不是能省去很多折腾代理的麻烦?
今天就跟大家聊聊一个非常经典的分流方案:Dnsmasq + SNIproxy。这组搭档可以帮你实现 DNS 分流和透明代理,让你的 VPS 能根据域名自动选择直连还是转发,尤其适合不想在每台设备上都配置繁琐代理规则的小伙伴。
什么是分流?为什么要这么做?
简单来说,分流就是“指路”。当你在 VPS 上发起请求时,系统会判断你要访问的目标是谁。
- 国内/友好站点:直接走 VPS 的原生线路出去,速度快、延迟低。
- 被墙/国外慢速站点:通过 SNIproxy 转发出去,绕过限制。
这样做的好处显而易见:你不需要在客户端(手机、电脑)做任何特殊设置,只要把 DNS 指向这台 VPS,或者把这台 VPS 作为网关,就能享受到丝滑的上网体验。
准备工作
在开始之前,你需要准备:
流量分流示意图:左侧显示国内站点直接连接,右侧显示被墙站点通过代理转发
- 一台 Linux VPS(本教程以香港 VPS 为例,系统推荐 Debian 或 Ubuntu)。
- Root 权限。
- 一颗耐折腾的心。
第一步:安装 Dnsmasq
Dnsmasq 是一个轻量级的 DNS 转发器和 DHCP 服务器,我们主要利用它的 DNS 转发功能。
在终端中运行以下命令安装:
apt update
apt install dnsmasq -y
安装完成后,我们需要编辑配置文件 /etc/dnsmasq.conf。为了不把配置弄乱,建议先备份原文件:
cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak
vim /etc/dnsmasq.conf
写入以下基础配置(这里只列核心部分):
# 监听接口,建议填你的内网 IP 或者 0.0.0.0(监听所有)
listen-address=127.0.0.1
listen-address=<你的VPS内网IP>
# 上游 DNS 服务器,建议使用国内DNS解析国内域名,国外DNS解析国外域名
server=223.5.5.5 # 阿里 DNS
server=119.29.29.29 # 腾讯 DNS
server=8.8.8.8 # Google DNS

*在 Linux VPS 终端中安装和配置 Dnsmasq 的过程*
# 设置缓存大小,提高解析速度
cache-size=1000
# 关闭 DNSSEC,防止某些解析失败
no-dhcp-interface=
no-resolv
这里的关键在于 server 指令。Dnsmasq 支持根据特定域名指定不同的上游 DNS,但简单的配置中,我们通常让它轮询或使用顺序查询。更精细的做法是指定特定域名走特定 DNS,但这在 SNIproxy 场景下,我们更多是依赖 SNIproxy 的转发规则。
启动服务:
systemctl start dnsmasq
systemctl enable dnsmasq
第二步:安装并配置 SNIproxy
SNIproxy 的作用是作为一个 transparent proxy,它通过 sniffing(嗅探) TLS 握手中的 SNI(Server Name Indication)字段来判断目标域名,然后代替客户端去访问目标服务器。
安装 SNIproxy:
由于官方源可能版本较旧,建议直接编译安装或者添加相关源(Debian/Ubuntu 通常 apt 直接有):
apt install sniproxy -y
配置 SNIproxy:
编辑配置文件 /etc/sniproxy.conf:
vim /etc/sniproxy.conf
``n
一个最基础的有效配置如下:
```conf
user daemon
# 监听地址和端口
listen 80 {
proto http
table https_hosts
# 这里可以根据需求指定来源 IP 段,或者默认 all
access_log /var/log/sniproxy/http_access.log
}
listen 443 {
proto tls
table https_hosts
access_log /var/log/sniproxy/https_access.log
}
# 定义转发表
table https_hosts {
# 语法:域名 目标IP:端口 或 目标域名:端口
# .* 代表匹配所有域名
.* *
}
这个配置的意思是,监听 80 和 443 端口,把所有通过这两个端口进来的 HTTPS/HTTP 流量,根据 SNI 域名转发出去。.* * 表示匹配所有域名并使用目标域名原本的 IP 进行连接(即替你去访问)。
启动 SNIproxy:
systemctl start sniproxy
systemctl enable sniproxy
第三步:设置 iptables 规则(关键步骤)
装好了软件,并不代表流量会自动走过去。我们需要利用 iptables 把流量“劫持”到 SNIproxy 的监听端口上。
假设 SNIproxy 监听的是本机的 80 和 443 端口(注意:如果你的 Web 服务占用了这些端口,需要修改 SNIproxy 的监听端口,或者修改下面的端口)。
如果是想让这台 VPS 作为网关,给其他机器用,配置会比较复杂(涉及 MASQUERADE)。这里最简单的应用场景是:这台 VPS 自己访问网络时,某些域名走代理。但通常 SNIproxy 配合 Dnsmasq 的玩法是把 SNIproxy 当成一个网关服务。
常见玩法修正:
其实更通用的做法是让 SNIproxy 监听一个非标准端口(比如 8443),然后配合 Dnsmasq 的 address 指令。
- 修改
/etc/sniproxy.conf,让 listen 端口改为 8443。 - 修改
/etc/dnsmasq.conf,增加针对特定域名的 IP 指向。
比如,你想让 Google 走代理:
address=/google.com/<你的VPS的IP>
address=/youtube.com/<你的VPS的IP>
但是这样配置,因为目标 IP 变成了 VPS 自己,VPS 需要能处理这些流量。这通常需要更复杂的端口转发 NAT 规则。
简化版的“分流”实操思路:
如果是单机使用,其实更推荐用 redsocks 或者 gost 配合 iptables 的 REDIRECT。但既然我们要玩 SNIproxy,那就得调整好 iptables。
为了避免把问题搞得过于复杂,这里提供一个最基础的思路:利用 SNIproxy 做反向代理。
如果你的目的是让这台 VPS 能够访问被墙的网站,最简单的其实是搭建一个 HTTP/SOCKS5 代理。但如果你需要“分流”,即部分 IP 直连,部分走代理,那么 SNIproxy 的优势在于它可以基于域名。
修正配置策略(推荐):
让 Dnsmasq 的 address 指令把目标域名解析为 127.0.0.1,然后 iptables 把访问 127.0.0.1:443 的流量 REDIRECT 到 SNIproxy 监听的端口(例如 7443)。
- SNIproxy 配置:监听 7443 端口,处理 TLS 请求。
- Dnsmasq 配置:
address=/.google.com/127.0.0.1 address=/.youtube.com/127.0.0.1 - iptables 规则:
将输出到 127.0.0.1 443 端口的流量重定向到 7443。
注意:要把 Dnsmasq 的 server 设置好,防止解析死循环。iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 443 -j REDIRECT --to-ports 7443 iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 7080
验证与排错
配置完成后,修改 VPS 的 /etc/resolv.conf,将 nameserver 指向 127.0.0.1(也就是 Dnsmasq)。
nameserver 127.0.0.1
尝试 curl -v https://www.google.com。如果能看到返回的 HTML 源码,说明分流成功。
常见问题:
- 解析不了:检查 Dnsmasq 是否启动,
/etc/resolv.conf是否正确。 - 连接被拒:检查 iptables 规则是否保存,SNIproxy 是否正在监听对应端口。
- 证书错误:这是 SNIproxy 的特性,它只是一个透传,不会验证证书,如果浏览器报错,通常是客户端配置问题或者目标站点真的挂了。
总结
利用 Dnsmasq 负责指路(DNS 劫持),利用 SNIproxy 负责带路(流量转发),这套组合拳在低配机器上运行非常稳定,资源占用极低。虽然配置过程稍微有点繁琐,特别是 iptables 那一块,但一旦搭建完成,对于手里有多台 VPS 想要做单点突破或者整合网络环境的朋友来说,绝对是值得折腾的干货。
建议大家先在测试机上跑通流程,再应用到生产环境。祝大家折腾愉快!

评论已关闭