You are not logged in.
I'm trying to get ssh traffic to be accepted by my computer while connected to a VPN. I was having some issues with iproute2 so I was trying to use
ip route get from 166.175.190.24 iif enp9s0 192.168.1.112
command to emulate the route an ssh packet takes.
When the computer is not connect to the VPN the output is:
local 192.168.1.112 from 166.175.190.24 dev lo
cache <local> iif enp9s0
When the computer is connect I get the follow error:
RTNETLINK answers: Invalid cross-device link
I couldn't really find a good answer on the internet on what causes this erro and I was wondering if I could get some insight as to what causes this error. I assume it is an issue in the main routing table, but I don't see what it is. Here is the output from the main ip routing table:
default via 10.199.1.5 dev tun0 proto static metric 50
default via 192.168.1.254 dev enp9s0 proto static metric 100
10.199.1.1 via 10.199.1.5 dev tun0 proto static metric 50
10.199.1.5 dev tun0 proto kernel scope link src 10.199.1.6
173.199.65.64 via 192.168.1.254 dev enp9s0 proto static metric 100
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.112
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.112 metric 100
I'm not sure if the local table is of any help because it is handle by the kernel but here it just in case it helps:
local 10.170.1.6 dev tun0 proto kernel scope host src 10.170.1.6
broadcast 10.170.1.6 dev tun0 proto kernel scope link src 10.170.1.6
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 192.168.1.0 dev enp9s0 proto kernel scope link src 192.168.1.112
local 192.168.1.112 dev enp9s0 proto kernel scope host src 192.168.1.112
broadcast 192.168.1.255 dev enp9s0 proto kernel scope link src 192.168.1.112
Any help on diagnosing why this error occurs would be appreciated?
Last edited by CyberGhost (2015-07-21 00:36:49)
Offline
I solved my issue. The reason the packets were being dropped was because by default the Linux kernel checks to see the path a hypothetical return packet would take. If the return packet is over another interface it silently dropped. This mechanism is controlled by the rp_filter kernel parameter.
There are two solutions the to the problem.
First (this is the solution I used) is to change the rp_filter parameter to 0:
Run the following command to the list the rp_filter parameters:
sysctl -a| grep rp_filter'
#sample output below
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.arp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.enp9s0.arp_filter = 0
net.ipv4.conf.enp9s0.rp_filter = 0
net.ipv4.conf.lo.arp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.tun0.arp_filter = 0
net.ipv4.conf.tun0.rp_filter = 1
Then change all the relevant entry to 0 using the following sample command
sysctl net.ipv4.conf.all.rp_filter=0
After using this method you will likely have to create a ip route for return traffic to be returned out the correct interface. In my case a create a iptables rule that marked ssh packets over port 22 and then had marked packets routed to a seperate routing table using these commands:
x.x.x.x is your default gateway, y.y.y.y/y is your local subnet, and replace enp9s0 with the non-VPN interface you wish to use.
ip rule add fwmark 1 lookup ssh
ip route add default via x.x.x.x table ssh
ip route add y.y.y.y/y dev enp9s0 table ssh
iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 1
A second possible solution that avoids changing kernel parameters:
This solution came from this forum thread.
This solution involves creating a seperate routing table from the main, that routes all traffic over the regular ethernet interface. Then a rule is created that applies to all traffic from your local ethernet IP address and directs it to the new routing table.. Now when the kernel checks if a hypothetical return packet will be returned over the same interface, it will and the packet won't be dropped. This makes change the kernel parameter unneccassary. The disadvantage with this method is it apply to all types of traffic. I also think this method could cause traffic to be leaked from the VPN unintentionally and could compromise your identity, but I'm not sure.
Anyway the commands for this method is:
x.x.x.x is your default gateway, y.y.y.y/y is your default subnet, and z.z.z.z is your local IP.
ip rule add from z.z.z.z table 128
ip route add table 128 to y.y.y.y/y dev ethX
ip route add table 128 default via x.x.x.x
I hope this helps anyone who comes across an issue like this in the future.
Offline
@CyberGhost Thank you very much. This has been a problem I am looking to answer from so long. I dug into source code and somehow, ended up here. Thanks.
Offline