Open markfoodyburton opened 8 years ago
That's because mlvpn uses UDP:
socket(7):
SO_BINDTODEVICE
Bind this socket to a particular device like “eth0”, as specified in the passed
interface name. If the name is an empty string or the option length is zero, the
socket device binding is removed. The passed option is a variable-length null-ter‐
minated interface name string with the maximum size of IFNAMSIZ. If a socket is
bound to an interface, only packets received from that particular interface are
processed by the socket. Note that this works only for some socket types, particu‐
larly AF_INET sockets. It is not supported for packet sockets (use normal bind(2)
there).
I figured a ticket would help track this, I tried the bindztodev branch, and as you predicted, it doesn't work, for a number of reasons I haven't got to the bottom of it, but for a start, you need to run as root it seems which isn't ideal. Apart from that the branch works (but you need the same branch on both ends due to crypto).
Is there some more context? Where’s the prediction? What exactly doesn’t work?
I’ve also tried using SO_BINDTODEVICE
and for me, it works once I also enable source-based routing:
ip rule add from 172.20.10.2 table 1
ip rule add from 10.0.0.218 table 2
ip route add 172.20.10.0/28 dev wlp4s0 scope link table 1
ip route add default via 172.20.10.1 dev wlp4s0 table 1
ip route add 10.0.0.0/24 dev enp0s25 scope link table 2
ip route add default via 10.0.0.1 dev enp0s25 table 2
ip route add default scope global nexthop via 10.0.0.1 dev enp0s25
(Where 172.20.10.2/28
is connected via WiFi to my iPhone, and 10.0.0.218/24
is connected via Ethernet.)
I haven’t understood yet why source-based routing is required. The symptom I’m seeing without source-based routing is that the mlvpn link never authenticates. While the response packets appear in tcpdump, the Linux kernel seems to not deliver the packet to mlvpn.
Reverse-path filtering is off for all interfaces:
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.enp0s25.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.wlp4s0.rp_filter = 0
Any input appreciated.
I've lost the context a little, and in the end, I think it was my own stupidity. I was in the (random, and seemingly fortunate) position that Orange allocated my two ADSL lines different concentrators, I thought it was a good idea to have my firewall set up the two ppp interfaces using the concentrator to differentiate. And therefore, having mlvpn bind to those interfaces was ideal. It did work (for a while).... Then one day, Orange being Orange...... - I would advise anybody following not to do that. Hence the approach I'm taking now is to use the modem to make the connection (as per normal), I have each modem on a different sub-net, and MLVPN binds to each of the different IP addresses as per normal.
Hence, for me, I can no longer even test binding to devices - but from what I can remember, it worked ok.
(From my point of view, you can close this ticket).
Cheers
Mark
The problem with UDP is that it's not a connected protocol.
When mlvpn will try to send a packet outside, it will only tell the kernel the destination address, destination port and, enventually the bind address.
bind address is used because the kernel needs to know how to send the packet. What source IP address should it use?
By default, the kernel will lookup the destination address in the routing table, then if a source address is specified in the routing table, will choose this address (if bind address is not set) and send the packet.
Said otherwise, if you have the following:
CLIENT
NET1 -----\
------------------ SERVER IP
NET2 -----/
In that case, source routing is required because it's the only way to tell the kernel how to send a packet to the same destination two different ways. (By using the source routing system).
If you have two ip addresses on the same server on the other side, everything is much simplified. All you have to do is set two entries in the routing table with "src" set to the correct addresses.
Hope it clarifies a bit.
Managed to solve the issue I had in https://github.com/zehome/MLVPN/issues/70#issuecomment-235400270:
Turns out that NixOS installs a rpfilter
iptables rule (!) by default:
$ sudo iptables -nvL -t raw
Chain PREROUTING (policy ACCEPT 38644 packets, 67M bytes)
pkts bytes target prot opt in out source destination
1762 274K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 rpfilter invert
I wasn’t even aware there is a raw
netfilter table or an rpfilter
target, but once I removed that using sudo iptables -t raw -F
, using SO_BINDTODEVICE
works just fine, no source routing required.
So, with the issue I’ve had being resolved, I’d be very interested to see the SO_BINDTODEVICE
code merged — in the setup I’m doing, the IP addresses will be assigned via DHCP, so I’d like to configure ethernet devices in the MLVPN config instead of IP addresses.
@zehome What needs to happen before the branch can get merged?
I figured a ticket would help track this, I tried the bindztodev branch, and as you predicted, it doesn't work, for a number of reasons I haven't got to the bottom of it, but for a start, you need to run as root it seems which isn't ideal. Apart from that the branch works (but you need the same branch on both ends due to crypto).
Cheers
Mark.