9

I have multiple network interfaces on a single machine. I am wondering how I can bind a network interface to an application.

Example: Network Interfaces: eth0, eth1

Application A use dummy0 Application B use dummy1

Is it possible to bind an application to an interface like this?

Use Case: 1 machine with 2 internet connections; eth0 -> internet connection 0 eth1 -> internet connection 1

Application use a predefined interface Firefox -> eth0 -> internet connection 0 Chrome -> eth1 -> internet connection 1

OS: CentOS 5.9 32bit

dooffas
  • 395
  • 2
  • 6
  • 13

6 Answers6

4

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.

krowe
  • 5,493
  • 1
  • 24
  • 31
  • Good answer, but the OP mentions `eth0` and `eth1` so I suspect he's not using Windows. – Flup Apr 09 '14 at 12:33
  • Apologies, I did not specify the OS. I will make an edit. – dooffas Apr 09 '14 at 12:40
  • @dooffas I've updated with information on how this is done in Linux. It still isn't exactly what you originally asked for though. – krowe Apr 09 '14 at 12:44
2

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.

Jet
  • 2,506
  • 25
  • 35
1

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.

Anders J
  • 146
  • 7
1

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.

Tero Kilkanen
  • 1,640
  • 11
  • 11
0

Solution

Under Linux there are several solutions to bind an application to a specific interface each one have its pro and con this unix stackexchange answer explain with details most of the available possibilities

intika
  • 1,303
  • 1
  • 10
  • 28
0

As krowe already said it's application specific. If you application doesn't support the binding to a given interface/IP you can use iptables (Linux) or ipfilter (*BSD).

The Ubuntu-Wiki has some rather nice introduction to iptables: https://help.ubuntu.com/community/IptablesHowTo

gpkvt
  • 31
  • 3
  • Unless I am misunderstanding, isn't iptables for routing traffic by port? For instance all traffic on port 80 -> eth0 – dooffas Apr 09 '14 at 12:41
  • @dooffas iptables does many things, it is a firewall, or mainly a firewall, i've used it for that.. it has setting for NAPT too for example.. Perhaps It may be able to re-route traffic as well but if one can say it has a primary function, I don't think that re-routing traffic would be its primary function. – barlop Aug 23 '15 at 10:59
  • @DenisWitt You mention ipf with BSD. BSD also has ipfw, and now with BSD people often use the rather powerful pf (it may be 3rd party). – barlop Aug 23 '15 at 11:03