You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过SSH隧道将OpenVPN服务器的全部客户端流量转发至另一服务器

如何通过SSH隧道将OpenVPN服务器的全部客户端流量转发至另一服务器

先看了你的OpenVPN配置,push "redirect-gateway def1 bypass-dhcp"这条已经设置到位,客户端的所有流量都会路由到Server A上。接下来我会一步步带你把这些流量通过SSH隧道转发到Server B,最终从Server B的公网IP出去。

先明确整个流量路径:

  • OpenVPN客户端 → Server A的OpenVPN tun接口 → Server A与Server B之间的SSH虚拟隧道 → Server B → 公网

第一步:在Server B上开启IP转发

Server B需要具备转发流量的能力,先开启内核IP转发:

  • 临时生效(重启后失效):
echo 1 > /proc/sys/net/ipv4/ip_forward
  • 永久生效:编辑/etc/sysctl.conf,找到net.ipv4.ip_forward一行,修改为:
net.ipv4.ip_forward = 1

执行sysctl -p让配置立即生效。

第二步:在Server B上配置iptables做SNAT

为了让OpenVPN客户端的流量能通过Server B的公网IP访问互联网,需要配置源地址转换:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

⚠️ 注意:把eth0替换成Server B的公网网卡名称,可以用ip addr命令查看。
如果要永久保存iptables规则,Ubuntu系统可以安装iptables-persistent包,然后执行iptables-save > /etc/iptables/rules.v4

第三步:在Server A与Server B之间建立SSH虚拟隧道

我们用SSH的-w选项创建一对点对点虚拟网卡,这种方式比端口转发更稳定,类似小型VPN:

  1. 在Server A上以root身份执行(需要Server B的root权限):
ssh -f -N -w 0:0 root@w.x.y.z

参数解释:

  • -f:后台运行SSH进程
  • -N:仅建立隧道,不执行远程命令
  • -w 0:0:在Server A创建tun0网卡,Server B同步创建tun0网卡,作为点对点连接
  1. 配置虚拟网卡IP:
    • 在Server A上执行:
      ip addr add 192.168.100.1/30 dev tun0
      ip link set tun0 up
      
    • 在Server B上执行:
      ip addr add 192.168.100.2/30 dev tun0
      ip link set tun0 up
      
    测试连通性:在Server A上执行ping 192.168.100.2,能通就说明隧道建立成功。

第四步:在Server A上配置路由规则,引导流量走隧道

我们需要让来自OpenVPN客户端(10.8.0.0/24)的流量单独走SSH隧道,不影响Server A自身的网络:

# 创建单独的路由表(编号100)
echo "100 ssh-tunnel" >> /etc/iproute2/rt_tables
# 添加默认路由到Server B的虚拟网卡IP
ip route add 0.0.0.0/0 via 192.168.100.2 dev tun0 table 100
# 添加规则:来自10.8.0.0/24的流量使用路由表100
ip rule add from 10.8.0.0/24 table 100

第五步:调整Server A的iptables规则

你原来的MASQUERADE规则是让客户端流量从Server A的公网网卡出去,现在需要删除这条规则:

iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -j MASQUERADE

如果原来的规则指定了网卡(比如-o eth0),记得加上对应的参数删除。

第六步:设置SSH隧道开机自启

手动建立的隧道重启后会消失,我们把它做成systemd服务:
在Server A上创建/etc/systemd/system/ssh-tunnel.service文件,内容如下:

[Unit]
Description=SSH Tunnel to Server B for OpenVPN Traffic
After=network.target openvpn-server@server.service

[Service]
Type=forking
User=root
ExecStart=/usr/bin/ssh -f -N -w 0:0 root@w.x.y.z
ExecStartPost=/usr/bin/ip addr add 192.168.100.1/30 dev tun0
ExecStartPost=/usr/bin/ip link set tun0 up
ExecStartPost=/usr/bin/ip route add 0.0.0.0/0 via 192.168.100.2 dev tun0 table 100
ExecStartPost=/usr/bin/ip rule add from 10.8.0.0/24 table 100
ExecStop=/usr/bin/pkill -f "ssh -f -N -w 0:0 root@w.x.y.z"
ExecStopPost=/usr/bin/ip link set tun0 down
ExecStopPost=/usr/bin/ip addr del 192.168.100.1/30 dev tun0
ExecStopPost=/usr/bin/ip rule del from 10.8.0.0/24 table 100
ExecStopPost=/usr/bin/ip route del 0.0.0.0/0 via 192.168.100.2 dev tun0 table 100

[Install]
WantedBy=multi-user.target

然后启用并启动服务:

systemctl daemon-reload
systemctl enable ssh-tunnel.service
systemctl start ssh-tunnel.service

⚠️ 重要前提:确保Server A的root用户可以免密码SSH登录Server B,否则隧道无法自动建立。可以在Server A上执行ssh-copy-id root@w.x.y.z,把Server A的root公钥复制到Server B的~/.ssh/authorized_keys中。

测试配置

连接你的OpenVPN客户端,访问https://ifconfig.me,如果显示Server B的公网IP(w.x.y.z),说明整个转发流程正常工作了。

如果遇到问题,可以从以下几点排查:

  • Server B的net.ipv4.ip_forward是否为1(cat /proc/sys/net/ipv4/ip_forward
  • SSH隧道状态:Server A上执行ip link show tun0,看是否处于UP状态
  • 路由规则:执行ip rule listip route show table 100,确认规则已生效
  • iptables规则:Server B上执行iptables -t nat -L POSTROUTING -v,看是否有匹配的流量

备注:内容来源于stack exchange,提问作者Pejman Ghasemi

火山引擎 最新活动