如何实现“仅特定域名(或 IP)走 OpenVPN

这在 OpenVPN 中称为 “Split Tunneling(分流隧道)”

你希望:

  • C 服务器通过 OpenVPN 连接到 A(10.8.0.0/24 网段)
  • 只有访问 oss.abc.com(即 A 的 Master)时走 VPN
  • 其他所有流量(如访问公网、CDN、数据库等)直连,不经过 VPN

实现原理

OpenVPN 默认会推送 redirect-gateway 指令,强制所有流量走 VPN
要实现分流,你需要:

  1. 禁用全流量重定向
  2. 只推送特定路由(如 10.8.0.0/24 或 A 的公网 IP)
  3. 在 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.com10.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'

Comments

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

发表回复