![允许在具有活动 OpenVPN 客户端的服务器上使用 SSH](https://linux22.com/image/649807/%E5%85%81%E8%AE%B8%E5%9C%A8%E5%85%B7%E6%9C%89%E6%B4%BB%E5%8A%A8%20OpenVPN%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E4%BD%BF%E7%94%A8%20SSH.png)
我有一个运行 CentOS 7 的 VPS,我使用 SSH 连接到它。我想在 VPS 上运行 OpenVPN 客户端,以便互联网流量通过 VPN 路由,但仍允许我通过 SSH 连接到服务器。当我启动 OpenVPN 时,我的 SSH 会话断开连接,我无法再连接到我的 VPS。如何配置 VPS 以允许传入的 SSH(端口 22)连接在 VPS 的实际 IP(104.167.102.77)上打开,但仍通过 VPN 路由传出的流量(例如来自 VPS 上的 Web 浏览器的流量)?
我使用的 OpenVPN 服务是 PrivateInternetAccess,示例 config.ovpn 文件是:
客户 开发调谐 原始 UDP 远程 nl.privateinternetaccess.com 1194 解析-重试无限 不绑定 持久密钥 坚持-tun ca 证书 tls-客户端 远程证书 TLS 服务器 授权用户密码 康普 动词 1 reneg-sec 0 crl-验证crl.pem
VPS 的 IP 地址:
1:lo:mtu 65536 qdisc 无队列状态未知 链路/环回 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 范围主机 lo valid_lft 永远 preferred_lft 永远 inet6 ::1/128 范围主机 valid_lft 永远 preferred_lft 永远 2:ens33:mtu 1500 qdisc pfifo_fast 状态UP qlen 1000 链接/以太 00:50:56:be:16:f7 brd ff:ff:ff:ff:ff:ff inet 104.167.102.77/24 brd 104.167.102.255 范围全局 ens33 valid_lft 永远 preferred_lft 永远 inet6 fe80::250:56ff:febe:16f7/64 范围链接 valid_lft 永远 preferred_lft 永远 4:tun0:mtu 1500 qdisc pfifo_fast 状态未知 qlen 100 链接/无 inet 10.172.1.6 对等 10.172.1.5/32 范围全局 tun0 valid_lft 永远 preferred_lft 永远
VPS的ip路由:
0.0.0.0/1 通过 10.172.1.5 dev tun0 默认通过 104.167.102.1 dev ens33 proto static metric 1024 10.172.1.1 通过 10.172.1.5 dev tun0 10.172.1.5 dev tun0 proto 内核范围链接 src 10.172.1.6 104.167.102.0/24 dev ens33 proto 内核范围链接 src 104.167.102.77 109.201.154.177 通过 104.167.102.1 dev ens33 128.0.0.0/1 通过 10.172.1.5 dev tun0
答案1
我遇到了类似的问题,并一直在尝试修复此论坛帖子。
这个想法是,目前当您连接到公共 IP 地址时,返回数据包将通过 VPN 路由。您需要强制这些数据包通过您的公共接口路由。
这些路线命令有望解决问题:
ip 规则从 xxxx 表 128 添加
ip route 添加表 128 到 yyyy/y dev ethX
ip 路由添加表 128 默认通过 zzzz
其中 xxxx 是您的公共 IP,yyyy/y 应该是您的公共 IP 地址的子网,ethX 应该是您的公共以太网接口,zzzz 应该是默认网关。
请注意,这对我来说不起作用(使用 Debian 和 PrivateInternetAccess),但可能会对您有所帮助。
答案2
根据@MrK 的回答,我在这里写了一些简单的代码,以便更快地完成工作,这样您就不必检查接口/IP:
ip rule add from $(ip route get 1 | grep -Po '(?<=src )(\S+)') table 128
ip route add table 128 to $(ip route get 1 | grep -Po '(?<=src )(\S+)')/32 dev $(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)')
ip route add table 128 default via $(ip -4 route ls | grep default | grep -Po '(?<=via )(\S+)')
我已经在我的 4 个 VPS 上尝试过这个脚本并且运行良好。
答案3
这可能有点晚了,但是......
问题是默认网关被 OpenVPN 更改,这会中断您当前的 SSH 连接,除非您在启动 OpenVPN 之前设置了适当的路由。
以下内容对我有用。它使用 iptables 和 ip(iproute2)。下面假设 OpenVPN 启动前的默认网关接口是“eth0”。这个想法是为了确保当连接到 eth0 时,即使 eth0 不再是默认网关接口,连接的响应数据包也会再次返回到 eth0。
连接标记、防火墙标记和路由表可以使用相同的数字。我使用不同的数字来使它们之间的区别更加明显。
# set "connection" mark of connection from eth0 when first packet of connection arrives
sudo iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
# set "firewall" mark for response packets in connection with our connection mark
sudo iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 table 3412
# route packets with our firewall mark using our routing table
sudo ip rule add fwmark 4321 table 3412
===
更新:
上面的方法在 Debian Jessie 上对我来说很好用。但在较旧的 Wheezy 系统上,我发现我需要在路由表条目中添加“via”:
# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 via 12.345.67.89 table 3412
这里的“12.345.67.89”肯定是原来的非VPN网关。
答案4
嗯,听起来像是 IP 子网重叠……如果不了解有关您的 IP 方案的更多信息,除了您的 VPN 终端的公共 IP(如 nl.privateinternetaccess.com)之外,无法确定。
因此,例如,如果 nl.privateinternetaccess.com 另一端的远程子网是 10.32.43.0/24,并且您的实例位于子网为 10.32.44.0/24 的 aws vpc 中。但您的源 ssh 客户端位于 10.32.43.0/24(aws vpc 的您所在端),它将不起作用,因为返回 ssh 流量将被错误地通过 vpn 推送到荷兰。
提供完整的 IP/子网信息以获得更多帮助。
...
好的,那么...看起来你的默认路由在隧道中,在你连接到 nl 之后:
0.0.0.0/1 通过 10.172.1.5 dev tun0
因此您可以在连接后进行更改。很多时候 vpn 服务器会为您提供虚假路由。特别是在马虎的公司。在这种情况下,他们会向您推送默认路由,因此来自 vps 盒的所有流量都会流向 nl。将默认路由更改为 104.167.102.x 或您的 vps 提供商的子网网关。