Bind IP address to application

Selecting a specific adapter for an application is an application specific setting. You must determine how this is done in your specific application. It cannot be done on the system level.

Windows

You can adjust the priority of adapters on a global system level though. Use the up and down arrows on the Network connections advanced properties page.

http://levynewsnetwork.wordpress.com/2011/12/01/windows-7-default-internet-connection-choice/

Linux

In Linux the process isn't as straight forward. You must tell Linux that one adapter is further away than the other using the metric.

To prioritize adapters in Linux, you'd have to use the route command, to add the route with the desired metric and delete the old entry. For example:

sudo route add -net default gw 10.10.0.1 netmask 0.0.0.0 dev wlan0 metric 1
sudo route del -net default gw 10.10.0.1 netmask 0.0.0.0 dev wlan0 metric 0

For both OSes, the same order will be used for every application when this is done.


There's a simple solution - Daniel Ryde wrote an LD_PRELOAD "shim" library (bind.c) that modifies bind behaviour, for this purpose. Check out this tutorial:

https://www.x4b.net/kb/BindProcessToIPonLinux

Given there is effectively a default bind address for applications (see your routing table), it is in my opinion superbly strange that there usually is no standard way (as in "distribution package code") to override that default interface, yes; on the system level, for a particular set of applications.

Some programs do have command line options to listen to the interface of your choice, which is all fine and well.

My default route goes via a VPN proxy (surely a pretty common scenario). A good default for outgoing connections, this tunnel does not support inbound connections from the internet very well. Therefore I need to force server-oriented programs A, B, and C to bind to some other IP (main ISP provided address). And client-oriented program D, I want to use my public interface for different reasons.

The above library works well, for this purpose!

A solution is:

  1. Create a new user
  2. Header-mangle ALL the packets of that particular user
  3. Run the programs as that user, ONLY to "effectively bind" to the desired interface seems like... an ugly hack, in comparison.

Alternatively:

  1. Create new user SuperFluous
  2. Make SuperFluous use different routing table
  3. Run A, B, C as user SuperFluous; Still not good enough! I want to run "my" servers as "me" (I might not even have privileges to create new users and routing policies).

LISTEN_TO=$THIS_INTERFACE Command; # <- It should be that simple.


While applications can bind to particular IP adresses it's application specific. For your particular example both Chrome and Firefox support HTTP proxies.

You could use Squid with configuration like the following to make them use a specific NIC.

acl browser1 localip 127.0.0.2
acl browser2 localip 127.0.0.3
tcp_outgoing_address 192.168.1.99 browser1
tcp_outgoing_address 197.6.0.1 browser2

Now Firefox would be configured to connect to the proxy at 127.0.0.2 which would use 192.168.1.99 as the NIC for performing outgoing TCP requests.

Chrome would be configured to use 127.0.0.3 as a proxy which would use 197.6.0.1 as the outgoing address.


Actually the subject of the question is a bit inaccurate. Binding an application to an interface applies for an application acting as a server.

In this case the correct term is "Routing the traffic for a specific application in a specific way". In Linux this can be accomplished with Policy routing.

The trick is that one launches the other browser as a different user, and policy routing rules then make all packets from that user use the other default gateway.

http://blog.sebastien.raveau.name/2009/04/per-process-routing.html has a complete description.