在使用某算力平台的过程中,我有一个需求,我不希望在访问我自己的服务的时候,使用我内网穿透服务器中转流量,这成本太高,我希望使用我现有的 EasyTier 虚拟网络来访问,这样走的是 P2P。
但是这个平台提供的是容器,存在以下限制:
- 无法使用
TUN实现透明代理 - 无法使用
iptables劫持 DNS 流量
因此需要一些手段。
使用 EasyTier + Mihomo 提供访问其他节点的能力
首先完成 EasyTier 组网,并使用以下配置让 EasyTier 启用 SOCK5 代理。
socks5_proxy = "socks5://127.0.0.1:1080"
这将允许其他应用通过 EasyTier 访问其他节点。
接下来,在 Mihomo 的配置中添加一个节点和代理组:
proxies:
- name: EasyTier SOCKS5
type: socks5
server: 127.0.0.1
port: 1080
udp: true
proxy-groups:
- name: EasyTier
type: select
proxies:
- EasyTier SOCKS5
然后添加规则:
rules:
- IP-CIDR,192.168.6.0/24,EasyTier SOCKS5,no-resolve
其中 192.168.6.0/24 是我 EasyTier 代理的子网。
经过以上操作,就能实现仅将代理的子网网段转发到 EasyTier 了。
最后设置环境变量 ALL_PROXY 设置为 Mihomo 的代理端口即可。
本地 DNS 解析
我这里使用的是 MosDNS,可以智能转发 DNS 请求,主要配置思路就是将我的域名直接返回固定的内网 IP,其他域名转发到 Mihomo 的 DNS 服务,当 Mihomo 不可用时 fallback 到上游 DNS。具体如何配置请参阅 MosDNS 官方文档。
接下来是使用 socat 将本地 53 端口转发到 MosDNS(安装 socat:apt install socat):
socat UDP-LISTEN:53,fork UDP:127.0.0.1:15353 # 我这里 MosDNS 配置的监听 15353 端口
最后修改 /etc/resolv.conf:
nameserver 127.0.0.1
search .
这种方法虽然仍可能出现 DNS 泄漏,但大多数情况已经能正确应对了。
SSH 配置
经过以上配置,环境已经具备了劫持指定域名、使用 P2P 访问其他节点的能力了,但是 SSH 似乎并不会使用本地 DNS,而是直接使用了上游 DNS,因此还需要对 SSH 进行配置。
首先安装 nc:
sudo apt install netcat-openbsd
然后创建脚本 ~/local/bin/ssh-sock5:
#!/usr/bin/env sh
host="$1"
port="$2"
# ===== 本地 DNS 解析 =====
ip=$(getent ahostsv4 "$host" | awk 'NR==1{print $1}')
[ -z "$ip" ] && exit 1
# ===== 判断是否有 ALL_PROXY =====
if [ -n "$ALL_PROXY" ]; then
proxy="${ALL_PROXY#*://}"
proxy="${proxy#*@}"
proxy_host="${proxy%%:*}"
proxy_port="${proxy##*:}"
exec nc -x "$proxy_host:$proxy_port" "$ip" "$port"
else
exec nc "$ip" "$port"
fi
这段脚本的能力就是,先使用本地 DNS 解析域名,然后根据是否配置了 ALL_PROXY 选择是否使用代理完成请求。
最后在 ~/.ssh/config 的最前面添加 ProxyCommand 使用这个脚本。
Host *
ProxyCommand ~/local/bin/ssh-sock5 %h %p
改完即刻生效,经实测 git 使用 SSH 时已不再使用中转服务器,而是使用 EasyTier 的隧道。