Friday, April 17, 2009

Per-process routing

Just a quick tip before the big monthly blog post :-)

Today I was asked by a friend if it was possible to assign different network interfaces to different programs for their Internet traffic...

For example, let's say you're a student living on-campus; the university provides you with broadband Internet access via Wi-Fi, which is great, except for the fact that you cannot trust it (yes, even when you're careful to use HTTPS and so on, I'll cover that in subsequent blog posts). A general solution to that problem would be getting your very own private Internet access, but being a student, you would prefer not to waste too much money into it, so you'll most likely take the cheapest subscription. So now you have two routes to the Internet: a fast but insecure one, and another that is private but slow. How to use both on the same computer? As bandwidth-intensive applications are often also the ones that don't really require privacy, one could imagine categorizing programs in a way so as to watch Internet TV over the Wi-Fi network while corresponding over the cable.

Here's how to do it with Linux, assuming that the default route is your private connection and that your Wi-Fi interface is named ath0, has IP address 10.1.2.3 and gateway 10.0.0.1:
  1. Create a "wifi" user

    adduser wifi

  2. Mark packets coming from the wifi user

    iptables -t mangle -A OUTPUT -m owner --uid-owner wifi -j MARK --set-mark 42

  3. Apply the Wi-Fi IP address on them

    iptables -t nat -A POSTROUTING -o ath0 -m mark --mark 42 -j SNAT --to-source 10.1.2.3

  4. Route marked packets via Wi-Fi

    ip rule add fwmark 42 table 42
    ip route add default via 10.0.0.1 dev ath0 table 42

  5. Launch programs as the wifi user

    sudo -u wifi vlc

Step 1 is of course required only once; steps 2, 3 and 4 are better put together in a shell script. Regarding step 5, it is much more practical to edit your KDE menu entries for example and there specify that the program has to be run as the wifi user.

One last remark: know your localhost network architecture, some of the wifi user's traffic might still go via the default route! This will be the case if, for example, you use a local DNS cache such as NSCD or any other kind of local proxying (Privoxy, Tor, etc).