用dnsmasq和ss 实现VPS出站流量分流

此智能分流方案 依赖 iptables/dnsmasq/sslocal.

安装依赖

安装 dnsmasq(版本需 >= 2.66), ipset
apt update; apt install -y dnsmasq ipset

安装 sslocal

# 透明代理 使用新版的 sslocal 来代替 旧版的 ss-redir 
wget https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.13.2/shadowsocks-v1.13.2.x86_64-unknown-linux-gnu.tar.xz
tar xJf shadowsocks-*.xz && rm -rf shadowsocks-*.xz*; mv ./ssserver ./sslocal ./ssurl ./ssmanager ./ssservice /usr/bin/;

开启透明代理

本例子用 sslocal 连另一个VPS的ss ("your-vps.com:31000")
本地 用1080端口 开启透明代理(给iptables转发使用)
测试可以直接一行命令:
sslocal --protocol redir -s "your-vps.com:31000" -m "aes-256-gcm" -k "your-vps-password" -b "0.0.0.0:10801" -v
或者 新建 ssredir.conf 文件, 执行 sslocal -c ssredir.conf
这里就不介绍 做成自启动服务了

{
  "protocol": "redir",
  "server": "your-vps.com",
  "server_port": 31000,
  "password": "your-vps-password",
  "method": "aes-256-gcm",
  "local_address": "0.0.0.0",
  "local_port": 1080,
  "mode": "tcp_only"
}

添加 iptables 规则

# 创建 ipset表
`ipset create outwall hash:ip`

# 转发局域网内 TCP 流量
# 创建 iptables 链
iptables -t nat -N SHADOWSOCKS
iptables -t nat -A SHADOWSOCKS -m set ! --match-set outwall dst -j RETURN
# 限制最多32个连接(一般正常足够了)
iptables -t nat -A SHADOWSOCKS -p tcp --syn -m connlimit --connlimit-above 32 -j RETURN
# 忽略的IP 地址(不经过shadowsocks代理), 忽略局域网中的IP
# 执行: ip address | grep -w "inet" | awk '{print $2}' 可以列出
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
# TCP流量转发至 shadowsocks 的本地端口
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1080
# 应用 规则
iptables -t nat -A PREROUTING -j SHADOWSOCKS
# 启用VPS本机流量转发 TCP流量按规则, 智能分流
iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS
# 启用VPS本机 ICMP协议 的流量转发 (一般用不上)
# iptables -t nat -A OUTPUT -p icmp -j SHADOWSOCKS
# 查看 iptables 规则
# iptables -t nat -nvL

配置dnsmasq

修改默认的DNS解析, vi /etc/dnsmasq.conf, 新增如下内容

no-resolv
server=8.8.8.8
server=8.8.4.4
ipset=/ip.sb/outwall # 测试使用
ipset=/youtube.com/outwall # 需要分流的每行1个

重启dnsmasq服务, 使配置生效 service dnsmasq restart

增加 使用本机的dns解析
vi /etc/resolv.conf 最上面加上1行 nameserver 127.0.0.1
请求域名时, dnsmasq自动把ipset规则里的域名的IP 更新到ipset表.

测试效果

curl ip.sb 可以看到 IP地址 为 另一台VPS的 IP了 (sslocal 连接的).

其他说明

删除 iptables 设置: iptables -t nat -F; iptables -t nat -X SHADOWSOCKS
查看ipset表的所有IP记录 ipset list outwall
手动添加 要代理的IP ipset add outwall x.x.x.x
手动删除 要代理的IP ipset del outwall x.x.x.x

总结

分流还是基于了 dnsmasq的域名解析, 方案还算方便.
但缺点就是不能根据域名或IP分流到多个VPS.。。。。

Comments

No comments yet. Why don’t you start the discussion?

发表回复