Limited routing with IPredator / PPtP in NetworkManager

Abstract

NetworkManager. The future of the Network Managing. It provides competitive interface for networking in Linux. For long gone are the days when one would need to hand edit - and know how - million different networking configuration files on million different Linux distributions.

It’s not as great as some other modern dbus -gadgets, like systemd, but for most parts it works well enough. But for hard core geeks, it can feel a bit restrictive. And in this post, I’m going to summarize how one limitation can be circumvented, namely not routing everything through VPN tunnel.

Preamble

For most parts, this post will presume that one is using IPredator service, but for most parts, there shouldn’t be any reason why not every other PPtP/VPN service wouldn’t work too.

VPN Setup

For most parts, IPredator manual for Ubuntu should be followed, as it provides somewhat up-to-date manual how to configure NetworkManager for VPN. Depending upon on your VPN provider, some configuration steps might vary.

Exception is that one should not enable default routing tables from VPN provider, as they are usually defining default routes for everything - which is exactly what this post is not about. Rather, from “PPTP” Settings, one should select tab “IPv4 Address”, from pull-down menu select “Routes” and make sure both “Ignore automatically obtained routes” and “Use only for resources on this connection” are selected.

Route Tables

To know what to route, new routing table is needed. This can be easily configured on using file /etc/iproute2/rt_tables, or by using numeric value in following script. Even though using rt_tables file is more work, in this case we are going to as it’s more understandable to debug later on.

As the most simplest, one should just add some numeric value with name-identifier for VPN route. In this case, I’ve used value 100 and connection name for name:

# echo "100 IPredator" >> /etc/iproute2/rt_tables

NetworkManager Dispatcher

Upon establishing - or losing - network connections, NetworkManager calls scripts located in /etc/NetworkManager/dispatcher.d/. And this is where one should save his/her script.

Download script from pastebin, and save it in /etc/NetworkManager/dispatcher.d/ -folder, in name of your selection and make it executable. In this case, I’ve named it as “90-ipredator”:

# wget http://pastebin.com/download.php?i=b4gXg3FR -o /etc/NetworkManager/dispatcher.d/90-ipredator
# chmod a+x /etc/NetworkManager/dispatcher.d/90-ipredator

You might want to edit it, specially if you’re customer of Elisa in Finland, as it contains lines which make’s one to violate court mandated agreement rules with Elisa.

Editing Script

After comments, first thing in script is variables:

  • RT_TABLE=$CONNECTION_ID
    Edit this, if you like to use different name for your routing table, than your connection name. Value should match one defined previously in rt_tables -file, or it can be numeral - between 1 to 252 - for which case rt_tables modification is not necessary.
  • FWMARK="0x50"
    This value defines firewall mark value. Every connection marked with this value should route through VPN connection:
    iptables -t mangle -AOUTPUT -m owner --uid-owner "i-like-porn" -j MARK --set-mark 0x50
    If this doesn’t say anything to you, leave at is, or remove it.
  • VPN_ROUTED_ADDRESSES="static.thepiratebay.se thepiratebay.se"
    List of addresses, which always should be routed through VPN connection. It only works if you defined/left value in $FWMARK. And if you are Elisa customer in Finland, you should remove default values as it would cause you to be in contract violation with Elisa - and possibly with other ISP too, in future.
  • VPN_CHAIN_POSTROUTING="VPN-${VPN_IP_IFACE}-POSTROUTING"
    VPN_CHAIN_OUTPUT="VPN-${VPN_IP_IFACE}-OUTPUT"
    Name of iptable chains, which to use generating nat/mangle rules. Safe bet is one can ignore these. Please note, that do notdefine “POSTROUTING” and “OUTPUT” into them, as they are destroyed when VPN connection closes. Thease values can be viewed when VPN is up by looking for VPN-pppN-POSTROUTING and VPN-pppN-OUTPUT chains in iptables mangle and nat tables:
    # iptables -tnat -L
    [...]
    Chain VPN-ppp0-POSTROUTING (1 references)
    target     prot opt source               destination         
    SNAT       all  --  anywhere             anywhere             to:<your.vpn.ip.address>
    
    # iptables -tmangle -L
    [...]
    Chain VPN-ppp0-OUTPUT (1 references)
    target     prot opt source               destination         
    MARK       all  --  anywhere             static.thepiratebay.org  MARK set 0x50
    MARK       all  --  anywhere             thepiratebay.org     MARK set 0x50
    MARK       all  --  anywhere             anywhere             owner UID match polipo MARK set 0x50
    

Advanced

By default, script checks if one has polipo is installed as system wide, and if so, creates firewall rule to route all traffic through VPN service (depends on $FWMARK -variable):

( /usr/bin/id "polipo" > /dev/null 2>&1 && checkproc /usr/bin/polipo ) &&
	iptables -t mangle -A $VPN_CHAIN_OUTPUT -m owner --uid-owner "polipo" -j MARK --set-mark $FWMARK

With using FoxyProxy, it becomes possible to use VPN service per-website basis, and it’s better suited when there is a lot of sites than using $VPN_ROUTED_ADDRESSES variable from script.

KTorrent Network SettingsIn most torrent programs, it’s possible to select default interface to use. In KTorrent, this can be found in “Settings” -> “Configure KTorrent” -> “Network” -> “Network Interface:”, and by selecting “ppp0”, it will cause KTorrent to use VPN connection - presuming you’re not using dial-up modem anymore.

11 months ago Via pastebin.com