Allow incoming ssh with openvpn client

iptablesnetworkingopenvpnrouterrouting

I have set up an OpenVPN client on my home router. The moment the tunnel goes up, I can no longer ping my router from the internet using its WAN_IP. I would like to allow certain incoming connections (ping, ssh) through the WAN interface while the vpn tunnel is up. I read a little bit about this, and I understand I need source-based routing.

I tried to implement that, but it's not working. Here's what I did:

# 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

My thinking was the following. Please correct me if I misunderstood something:

  • When a packet arrives on vlan2 (the WAN iface), PREROUTING:2 sets a connection mark of 0x1
  • The packet has no packet mark at this point (is this right?)
  • The packet has the router as destination, so it will be received. If this was DNATed, the previous point would be crucial because table 128 is missing LAN stuff.
  • A reply packet is locally generated.
  • OUTPUT:1 will set a packet mark of 0x1 using the connection mark on the reply packet
  • PREROUTING:1 would do the same for DNATed connections on LAN (br0)
  • The reply packet with mark 0x1 will be routed using table 128.

Unfortunately this is not working, and I would like to understand why. From a remote server, if I ping the WAN_IP, I don't see any replies. I also turned on ssh remote access on the router, and I cannot open the port from the remote computer with telnet WAN_IP SSH_PORT, so this is not only an icmp issue. How does one debug these issues?

Update: I checked rp_filter and it was set to 1. I tried setting it to 0, and now everything works as expected (2 didn't work either). Since this is an internet facing router, I'm thinking that no RPF might not be a great idea. From the little I understand, when strict RPF runs on the initial packet, the kernel observes the route back to REMOTE_IP is through TUN_IF, while the packet arrived on WAN_IF, so it is dropped. Is this right? I tried MARK set 0x1 && CONNMARK save as mangle PREROUTING, hoping the kernel would see the mark during RPF, but it doesn't.

Best Answer

I cannot see why you need to use iptables for this. This is a straightforward case of PBR. Set up two routing tables, main setup by OpenVPN and theother which does not involve the VPN, then add the rule

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

and you are done.

Related Question