我想在我的云虚拟机(EC2实例)上以客户端模式运行OpenVPN,以便通常从虚拟机退出的stream量通过VPN。 但我仍然希望现有的IP地址可用于SSH连接(所以它不会中断我当前连接到计算机的SSH连接)。
这里是我正在使用的当前.ovpn设置文件:
client dev tun proto udp remote xxx.yyy.com 1198 resolv-retry infinite nobind persist-key persist-tun cipher aes-128-cbc auth sha1 tls-client remote-cert-tls server auth-user-pass comp-lzo verb 1 reneg-sec 0 crl-verify crl.rsa.2048.pem ca ca.rsa.2048.crt disable-occ
编辑:这个问题可能是防止login到服务器上的VPN的SSH连接丢失的重复…但没有在那里接受的答案。
我build议使用“–up”和“–down”选项来运行shell脚本,这些脚本可以根据需要在虚拟机上操作防火墙和路由表。 这将允许你隧道通过你的VPNstream量(如果openvpn没有这样做),并为sshstream量例外。 请记住,iptables规则是以自顶向下的方式应用的,因此请确保您的例外规则在隧道规则之前应用。 还有其他一些问题可以用作关于如何pipe理路由表和防火墙规则的示例。
iptables – 目标将数据包路由到特定的接口?
我认为你面临的问题是,默认路由是在VPN上,并且有一些路由过滤掉了从没有路由到接口的接口来的数据包。 这就是所谓的RPfilter 。
你有2个解决scheme,比其他进程有不同的默认路由sshd。 您可以使用networking名称空间,也可以使用cgroups。 我对这些知之甚less,但你可以在下面的答案中阅读:
https://superuser.com/questions/271915/route-the-traffic-over-specific-interface-for-a-process-in-linux
您可以使用高级路由通过相同的接口在主接口上路由传入的包。 这样,来自服务器的任何stream量都将通过VPN路由,但服务器的主要接口将保持可用于连接。 这里的想法是,如果一个数据包通过主接口,它会使用一个名为“vpn”的不同路由表,所以它不会受到VPN客户端路由设置的影响。
为了实现这一点,请执行以下操作:
编辑/etc/iproute2/rt_tables文件。 它应该包含这样的东西:
# # reserved values # 255 local 254 main 253 default 0 unspec # # local #
将此行添加到文件的末尾:
1 vpn
在/etc/network/interfaces文件中,在主界面的设置下(或/etc/network/interfaces.d/的相应文件),添加以下行:
up ip route add 0.0.0.0/0 via def.ault.gw table vpn up ip rule add from the.primary.ip.addr table vpn down ip route del 0.0.0.0/0 table vpn down ip rule del from the.primary.ip.addr
将the.primary.ip.addrreplace为主接口的IP地址(即希望服务器可用的IP)和def.ault.gw ,并使用默认网关地址。
您可以按照build议通过高级路由来完成,但并不那么简单。
实现目标的最简单的解决scheme是以不同方式发送处理(家庭)IP地址的包。 限制ssh访问几个安全的IP地址总是个好主意。 例如,你可以做:
ip route add 1.1.1.1 via 9.9.9.9
这里1.1.1.1是你的家庭IP地址,9.9.9.9是在路由表中已经可以访问的一些默认网关。 现在,从机器到外部IP的所有软件包将以相同的方式返回。 正常情况下,您可以通过VPN路由一切。 您甚至可以在openvpnconfiguration文件中添加此路由。 一切都超级。
但是,如果您的家庭IP变化(又名dynamic地址),或者您必须从随机地址(多个用户,旅行)到达您的机器,那么它并不是那么好。 这种情况下,你必须坚持下去。
请注意,如果你什么都不做,ssh软件包将会到达你的外部接口(和ip),但是如果你通过VPN路由它们,它们是不会找回来的(实际上它们可以取决于你的VPN设置,但是源IP将会不同,包将被丢弃)。 你的目标是将一些传出的包redirect到外部接口,一些到VPN。 这就是问题。
创build一个替代路由表:
echo "100 secure" >> /etc/iproute2/rt_tables
填充和控制路由:
# route ssh over external iface eth0 to router 9.9.9.9 ip route add default via 9.9.9.9 dev eth0 table secure # send all packages with fwmark 1 to the secondary routing table ip rule add fwmark 0x1 table secure # Mark outgoing ssh packages with the mark 1 iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 1
在这里,我们将标记所有传出的ssh包,然后通过备选路由redirect所有标记的包。 当然,现在你将不能 SSH上你的VPN,因为所有的答案将被redirect到另一个接口。 关键是,你可以创build任意复杂的iptables规则,并使用set-mark来区分它们。
幸运的是,我们有一个叫做CONNMARK的东西(利用内核的连接跟踪function)可以来回标记整个连接(你将需要xt_connmark模块)。
# mark incoming ssh *connection* with 1. Here eth0 is your external interface iptables -A INPUT -m state --state NEW -i eth0 -p tcp --dport 22 -t mangle -j CONNMARK --set-mark 1 # restore connection mark (eg mark the packages) iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark # send all packages with fwmark 1 to the secondary routing table as before.. ip rule add fwmark 0x1 table secure
在理解了概念之后,请根据您当前的设置使用上面的内容,而不是复制粘贴。
如果你从你的ssh连接所在的同一台机器上使用你的VPN,会出现一个额外的问题。
默认情况下,VPN对等端是默认网关。 由于您的ssh软件包将通过VPN通道进行路由(服务器将从tun或tap界面而不是从物理eth界面获取),因此它可以轻松地破坏现有连接。 简单的解决scheme不包括客户端configuration中的默认网关选项(或不推送)。 只推送首选子网的路由。 警告:如果您使VPN隐藏您的(家庭)公共地址,这可能不是你想要的!