这在 OpenVPN 中称为 “Split Tunneling(分流隧道)”。
你希望:
- C 服务器通过 OpenVPN 连接到 A(
10.8.0.0/24网段) - 只有访问
oss.abc.com(即 A 的 Master)时走 VPN - 其他所有流量(如访问公网、CDN、数据库等)直连,不经过 VPN
实现原理
OpenVPN 默认会推送 redirect-gateway 指令,强制所有流量走 VPN。
要实现分流,你需要:
- 禁用全流量重定向
- 只推送特定路由(如
10.8.0.0/24或 A 的公网 IP) - 在 C 上配置 DNS 或 hosts,确保
oss.abc.com解析到内网地址(可选但推荐)
配置步骤
第一步:修改 OpenVPN 服务端配置(在 A 上)
编辑 /etc/openvpn/server.conf(或你的配置文件):
# 注释掉或删除这行(禁止全流量走 VPN)
# push "redirect-gateway def1 bypass-dhcp"
# 只推送访问 A 所在网络的路由
push "route 10.8.0.0 255.255.255.0" # 如果 Master 在 10.8.0.1
# 如果你希望 C 通过内网访问 A 的公网服务,也可以加:
# push "route <A的公网IP> 255.255.255.255"
这样,C 只有访问
10.8.0.0/24网段时才走 VPN,其他流量直连。
第二步:在 C 上配置 DNS 或 Hosts(关键!)
因为 oss.abc.com 通常解析到 A 的公网 IP,而你希望 C 通过 内网 IP(10.8.0.1) 访问 Master,所以有两种方式:
方式 A:修改 /etc/hosts(简单可靠)
# 在 C 服务器上
echo "10.8.0.1 oss.abc.com" >> /etc/hosts
优点:强制
oss.abc.com→10.8.0.1(走 VPN)
缺点:如果 A 的内网 IP 变了,需手动更新
方式 B:使用私有 DNS(高级)
- 在 A 上部署内网 DNS(如 CoreDNS)
- 配置 C 的
/etc/resolv.conf优先使用该 DNS - 为
oss.abc.com设置内网 A 记录
适合大规模部署,小规模用 hosts 更简单。
第三步:启动 OpenVPN 客户端(在 C 上)
确保客户端配置 不包含 redirect-gateway:
# client.ovpn
client
dev tun
proto udp
remote <A的公网IP> 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
auth SHA256
key-direction 1
verb 3
# ❌ 不要加这行!
# redirect-gateway def1
启动后,检查路由表:
ip route show table all | grep 10.8.0
# 应看到: 10.8.0.0/24 dev tun0 ...
验证是否生效
1. 测试 oss.abc.com 是否走 VPN
# 应返回 A 的内网服务(Master)
curl -v http://oss.abc.com/dir/status
# 查看连接源 IP(在 A 上抓包或看日志)
# 应显示来源为 10.8.0.6(C 的 VPN IP),而非 C 的公网 IP
2. 测试其他域名是否直连
# 应走公网,不经过 A
curl -v https://google.com
# 查公网出口 IP(应为 C 自己的公网 IP)
curl ifconfig.me
最终效果
| 流量类型 | 路径 |
|---|---|
C → Master (oss.abc.com:9333) | C → (VPN) → A 内网 10.8.0.1 |
客户端 → 文件 (oss.abc.com/<fid>) | 客户端 → C 公网 IP(直连,不走 VPN) |
| C → 其他网站(如 GitHub) | C → 公网(直连) |
🔒 安全 + 性能兼顾:
- 控制面(Master 通信)走加密 VPN
- 数据面(文件下载)走高速公网直连
附:一键检查脚本(在 C 上运行)
#!/bin/bash
echo "=== 当前路由 ==="
ip route get 10.8.0.1
ip route get 8.8.8.8
echo -e "\n=== DNS 解析 ==="
nslookup oss.abc.com
echo -e "\n=== 测试 Master 访问 ==="
curl -s --connect-timeout 5 http://oss.abc.com:9333/cluster/status | jq -r '.Topology.Max'