允许使用 openvpn 客户端传入 ssh

允许使用 openvpn 客户端传入 ssh

我已经在家用路由器上设置了 OpenVPN 客户端。隧道启动后,我无法再使用路由器的 WAN_IP 从互联网 ping 路由器。我想在 vpn 隧道启动时允许某些传入连接(ping、ssh)通过 WAN 接口。我读了一些相关内容,我知道我需要基于源的路由。

我尝试过实现这个,但是没有成功。下面是我所做的:

# ip rule list
0:      from all lookup local 
32765:  from all fwmark 0x1 lookup 128 
32766:  from all lookup main 
32767:  from all lookup default
# ip route list table 128
default via WAN_IP dev vlan2
# iptables -t mangle -nvL PREROUTING
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 CONNMARK   all  --  br0    *       0.0.0.0/0            0.0.0.0/0           CONNMARK restore 
    0     0 CONNMARK   all  --  vlan2  *       0.0.0.0/0            0.0.0.0/0           CONNMARK set 0x1
# iptables -t mangle -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0           CONNMARK restore

我的想法如下。如果我误解了什么,请纠正我:

  • 当数据包到达 vlan2(WAN iface)时,PREROUTING:2 设置连接标记 0x1
  • 此时数据包没有数据包标记(对吗?)
  • 数据包的目的地是路由器,因此会被接收。如果这是 DNAT 的,那么前一点就至关重要,因为表 128 缺少 LAN 内容。
  • 本地生成应答数据包。
  • OUTPUT:1 将使用回复数据包上的连接标记设置数据包标记 0x1
  • PREROUTING:1 将对 LAN (br0) 上的 DNATed 连接执行相同操作
  • 标记为 0x1 的回复数据包将使用表 128 进行路由。

不幸的是,这不起作用,我想了解原因。从远程服务器,如果我 ping WAN_IP,则看不到任何回复。我还在路由器上打开了 ssh 远程访问,但我无法使用 从远程计算机打开端口telnet WAN_IP SSH_PORT,因此这不仅是 icmp 问题。如何调试这些问题?

更新:我检查了一下rp_filter,发现它被设置为 1。我尝试将其设置为 0,现在一切都按预期工作(2 也不起作用)。由于这是一台面向互联网的路由器,我认为没有 RPF 可能不是一个好主意。据我所知,当对初始数据包运行严格的 RPF 时,内核会观察到返回 REMOTE_IP 的路由是通过 TUN_IF 的,而数据包到达 WAN_IF,因此被丢弃。这是对的吗?我尝试MARK set 0x1 && CONNMARK save使用 mangle PREROUTING,希望内核在 RPF 期间能看到标记,但没有。

答案1

我不明白为什么你需要使用 iptables。这是一个 PBR 的简单案例。设置两个路由表,主要的由 OpenVPN 设置另一个不涉及VPN,然后添加规则

  ip rule from IP.Of.Your.Router table theother

您已经完成。

答案2

问题是默认网关被 OpenVPN 更改,这会中断任何来自非 VPN 接口的连接。Linux 会将对来自真实接口的数据包的响应发送到 VPN 接口之外!您需要在启动 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网关。

相关内容