在具有活动OpenVPN客户端的服务器上允许SSH


15

我有一个运行CentOS 7的VPS,并通过SSH连接到该VPS。我想在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
解析无限
Nobind
持久键
坚持不懈
ca cart
客户端
远程证书服务器
验证用户密码
康宝
动词1
reneg-sec 0
crl-verify 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
       永远有效_lft永远首选_lft
    inet6 :: 1/128作用域主机
       永远有效_lft永远首选_lft
2:ens33:mtu 1500 qdisc pfifo_fast状态UP qlen 1000
    链接/以太00:50:56:be:16:f7 brd ff:ff:ff:ff:ff:ff:ff
    inet 104.167.102.77/24 brd 104.167.102.255作用域全局ens33
       永远有效_lft永远首选_lft
    inet6 fe80 :: 250:56ff:febe:16f7 / 64作用域链接
       永远有效_lft永远首选_lft
4:tun0:mtu 1500 qdisc pfifo_fast状态未知qlen 100
    链接/无
    inet 10.172.1.6对等体10.172.1.5/32作用域全局tun0
       永远有效_lft永远首选_lft

VPS的IP路由:

通过10.172.1.5 dev tun0 0.0.0.0/1
默认通过104.167.102.1 dev ens33 proto static metric 1024
通过10.172.1.5 dev tun0通过10.172.1.1
10.172.1.5 dev tun0原型内核作用域链接src 10.172.1.6
104.167.102.0/24 dev ens33原始内核作用域链接src 104.167.102.77
109.201.154.177通过104.167.102.1 dev ens33
通过10.172.1.5 dev tun0通过128.0.0.0/1

Answers:


15

我有与此类似的问题,并且一直在尝试解决此论坛帖子中描述的问题

这个想法是,当前当您连接到公用IP地址时,返回数据包将通过VPN路由。您需要强制通过公共接口路由这些数据包。

这些路由命令有望达到目的:

从xxxx表128添加IP规则

ip route将表128添加到yyyy / y dev ethX

IP路由添加表128默认通过zzzz

其中xxxx是您的公共IP,yyyy / y应该是您的公共IP地址的子网,ethX应该是您的公共以太网接口,zzzz应该是默认网关。

请注意,这不适用于我(使用Debian和PrivateInternetAccess),但可能会对您有所帮助。


1
不仅要链接到解决方案,还请在此处声明或至少总结一下解决方案。这样,如果您链​​接到的帖子消失了,那么将来您的帖子仍然有用。
Andrew Schulman 2015年

我已经运行了这些命令,但无济于事...我该如何列出该表(我看不到用route或添加的新规则ip route show)并将其删除?
侯赛因·哈利勒

当我在家庭服务器上站起openvpn时,我在公共IP上丢失了ssh。运行上面列出的第一个命令可以使我不在本地LAN上时就可以通过ssh访问服务器。使用PIA + OpenVPN + ubuntu 16.04。
无聊的

它真的只将SSH端口路由到我的公共IP吗?您能否进一步说明这到底是什么?我看不到您设置特定端口或协议的任何地方
Freedo

它根本不基于端口进行路由(表号为128,而不是端口)。基本上是说,如果数据包是通过您的公共IP地址到达的,则响应应该在同一接口上发送(不使用VPN)。
MrK

17

这可能有点晚了,但是...

问题在于,OpenVPN会更改默认网关,并且除非您在启动OpenVPN之前设置了适当的路由,否则这会中断当前的SSH连接。

以下内容对我有用。它使用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

原始的非VPN网关必须为“ 12.345.67.89”。


1
谢谢!几天来我一直在寻找解决方案,您的回答为我解决了。这应该是公认的答案。
Mike Turley

此解决方案也对我有用。非常感谢您的分享。
alecov

路由表中是否可以有两条目的地相同的路由(ip route add default)?我收到“ RTNETLINK答案:文件存在”。我正在运行Ubuntu Xenial。“通过”无济于事。我只是在Arch Linux上尝试过,第一次ip route add default似乎成功了,但是ip route输出没有改变。任何后续运行都会导致“文件存在”消息。
x-yuri

我看到,该路由已添加到3412路由表中。要实现这一目标,您必须:ip route show table all | grep 3412。如果没有“通过”未建立(如果我没记错的话)的连接就会停止工作(Ubuntu Xenial)。至少我能够更正路由表。但是,尽管如此,运行后我仍无法访问服务器openvpn
x-yuri

出于某种原因而不是针对我工作,与thisthisthis相对。基本上是相同的。
x-yuri

14

基于@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上尝试过此脚本,并且运行良好。


非常感谢!
Jordi Goyanes

0

hmm听起来像是ip子网重叠。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

因此,例如,如果nl.privateinternetaccess.com另一端的远程子网为10.32.43.0/24,并且您的实例位于aws vpc中,其子网为10.32.44.0/24。但是您的源ssh客户端位于10.32.43.0/24(aws vpc的一侧)上,它将无法正常工作,因为返回的ssh流量会错误地通过vpn推送到荷兰。

提供完整的IP /子网信息,以获取更多帮助。

...

好的,所以...连接到nl后,您的默认路由似乎在隧道中:

通过10.172.1.5 dev tun0 0.0.0.0/1

因此您可以在连接后进行更改。很多时候,VPN服务器为您提供虚假路由。特别是在草率的军团 在这种情况下,他们将默认路由推送给您,因此来自vps框的所有流量都将流向nl。将默认路由更改为104.167.102.x或ur vps提供商处的任何子网网关。


什么命令的输出就足够了?
odie5533

1
在ssh客户端,ssh服务器/ vpn客户端和nl vpn服务器上输出“ ip addr”和“ ip route”。确保在输出时vpn已启动。
nandoP 2015年

我确实希望流量默认通过VPN。但是,我希望允许104.167.102.77:22上的传入流量,以便可以SSH到VPS。
odie5533

您使用tcpdump进行了验证,但是听起来像是在连接后,默认路由成为了隧道,允许从Internet上其他位置入站的新ssh通信进入,但它没有返回,因为默认路由通过隧道发送ssh响应,而不是回到你身边。您可以通过“通过[您的vps网关]通过IP路由添加[your-ip-addr] / 32”来解决此问题。查找您的vps网关,只需断开与隧道的连接,然后查看默认路由
nandoP 2015年

0

启动VPN时,将替换默认网关。这意味着从您的设备生成或通过您的设备路由的任何流量都将转发到VPN网关。

一个简单的解决方案是过滤所有您不想通过VPN路由的流量,并对其进行其他处理。一种可能是使用您的本地源地址来接收从框产生的流量,并将其路由到本地网关。这样可以使SSH等服务正常工作。

我们将在这里进行。首先,创建一个新的路由表并添加一个默认路由,该路由通过您的本地网关路由所有内容:

# <table> is any number between 2 and 252.
# Check /etc/iproute2/rt_tables for more info.
ip route add default via <gateway> table <table>
ip route add <lan-addr> dev <device> table <table>

接下来,创建一个新的数据包筛选器规则,该规则将使用给定的标识符标记从给定源地址离开您的邮箱的所有流量。

# <mark> is any number.
iptables -tmangle -AOUTPUT -s<local-addr> -jMARK --set-mark <mark>

最后,创建一个路由策略,以选择所有上述标记的流量,并使用上面生成的表对其进行路由。

ip rule add fwmark <mark> table <table>

再一次,值<mark><table>是你自己选择的任意标识符。


0

对于我自己在pfSense中运行OpenVPN服务器来说,要取消选中“强制所有客户端生成的IPv4通信通过隧道”设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.