I have a machine with two network interfaces and two different internet connections. I know there are multiple routing tables and stuff like that. However I have a very easy scenario. Outgoing ssh application should always go via wlan0. So why doing so complicated stuff?
First testing with curl which does its job perfect:
curl --interface wlan0 ifconfig.me
185.107.XX.XX
curl --interface eth0 ifconfig.me
62.226.XX.XX
So without setting up any special routing rules for two interfaces, it works exactly as I want. eth0 is the default route
ip route
default via 192.168.178.1 dev eth0 proto dhcp src 192.168.178.21 metric 202
default via 172.16.1.1 dev wlan0 proto dhcp src 172.16.1.88 metric 303
172.16.1.0/24 dev wlan0 proto dhcp scope link src 172.16.1.88 metric 303
192.168.178.0/24 dev eth0 proto dhcp scope link src 192.168.178.21 metric 202
Now try to do the same with wget. Wget is ideal for debugging as it has with --bind-address
the same option as ssh with -b
.
wget -O- --bind-address=192.168.178.21 ifconfig.me 2> /dev/null
62.226.XX.XX
You get the same output when omitting --bind-address
wget -O- --bind-address=172.16.1.88 ifconfig.me 2> /dev/null
This command just hangs for about 9 (!) minutes and outputs nothing at the end, like ssh will do.
I know this Bind unix program to specific network interface thread. However even if the title is “Bind unix program to specific network interface” all solutions working with LD_PRELOAD bind to an IP adress. This feature is already supported by ssh, but does not help here.
Firejail could solve this, but as explained in other topic has still the bug not working that way via Wifi.
So how can one really force an appliation to use a specific interface without all that complicated routing, netns or iptables rules? LD_PRELOAD looks very promising, however so far this code only focuses on changing bind IP not bindinterface.