Monday, July 13, 2015

Notes on various ways of configuring a VPN using policy-based / selective routing

I expect a lot of people want to do what I want to do:  set up a VPN on my router.  This allows everything I do online to run through a VPN service first, and setting this up on a router automatically ensures that everything on my network (wired or wireless) is protected.

Kewl though this is, there are lots of potential problems and pitfalls with setting up a VPN.  For example:

-  Skype or VoIP devices not working properly
-  Game consoles or online games not working properly
-  Inability to remotely access web (http) and/or FTP servers within the protected network
-  Inability to access remote web portals / management interfaces within the protected network

These come down to two issues:

-  Increased latency, which causes gaming, VoIP, Skype, streaming services etc. to fail
-  Inability to "see" servers and remote interfaces living within the VPN from the outside world

Finding answers to these issues is not easy.  Investigation of these topics is grossly complicated by the fact that there are two kinds of VPN you can set up:

-  The kind where you are outside your network, and VPN "in" to the network so the networks acts like you are there (i.e. working as if you were at home/work/office, but you're actually somewhere else); and

-  The kind where you are inside your network, and use a VPN to access the outside world.

along with two kinds of VPN services:

-  A "client" where you are connecting to a VPN service, and
-  A "server" where you are creating a VPN service to be connected to.

Fortunately, VPN issues appear to be few, but the above situations certainly affect a bunch 'o people.


The solution to most of these problems appear to be policy-based routing.  This is a way to configure your VPN setup (in this case, OpenVPN) to include or exclude certain things from using the VPN connection.

Notes:

-  This guide applies to DD-WRT.  In DD-WRT-land, it's called "policy-based routing".

-  pfsense people should search for "selective routing".  "Policy-based routing" is a different thing in pfsense.  To set up selective routing, try starting with this NordVPN guide.



I'm going to try to compile a few how-tos using the policy-based iptable configurations


Notes:

-  This only applies if you are planning to set up a VPN client on your router to connect to a third-party VPN service to protect activity from inside your network from being seen by others.  (In my case, configuring a Netgear R7000 router running DD-WRT to use Private Internet Access using the OpenVPN protocols.)  If you're not doing this, go ahead and stop reading now.

-  This assumes your VPN basically works; i.e. you can connect to it and everything.  It's just that certain specific things don't work when you're connected through the VPN.

-  This deals with situations where you have only one router.  Multi-router setups can get around these limitations by creating both VPN and non-VPN sections of your network, but can be impractical.  (Plus, shouldn't you be able to solve the issues with the damn router you bought?)

-  Once making changes, you really need to go to the Admin section of DD-WRT and hit "Reboot Router".  Turning the router off and on again may not do it!  A forced reboot will force a reload of the VPN settings.

-  There appear to be situations regarding specific builds of OpenVPN, DD-WRT or whatever that can prevent these from working.  If they don't work, I can't help - I don't know anything more than I've written here.

-  Be aware these are just notes to myself on what/how to do for various simple situations.  I have not actually tried most of these!



Also note you need to know a few things:

-  The "name" of your VPN connection, as used by the router.  DD-WRT is based on linux, so the name is probably "tun0" or "tun1".  These stand for "tunnel0" or "tunnel1", are are virtual names given to the VPN connection by linux to identify them.

-  The "name" of your non-VPN connection.  This is usually "def1" or something similar.  This is the virtual name of your "regular" internet connection - the one that is not going to the VPN provider.



What you want:  Have only one machine use the VPN; everything else does not use the VPN connection.

Why:  This is useful when you want to keep one machine protected - such as a work machine or your primary PC - without affecting anything else on your network.

How:  Enter the IP address of the machine to protect into the policy-based routing field of DD-WRT, plus the suffix "/32".  For example:

192.168.1.110/32

Note that the /32 is typically used, but some people claim it is not needed.  YMMV.

What this means:  It means "let 192.168.1.110 use the VPN, all others excluded." 

The "/32" is a masking field:  /32 means "no masking", meaning that the exact addresses 192.168.1.110 is used.

Important note:  As soon as you do this, ONLY the listed IP address uses the VPN.  All others are automatically excluded by default!

Or, to put it another way, you have changed from an "everything on" VPN to an "everything off" VPN.  Only the specific IP address(es) listed in the policy-based routing field will use the VPN from now on.


What you want:   Have all machines except one use the VPN; everything else does use the VPN.

Why:  You have a single device that doesn't work through the VPN, such as a game console (latency), VoIP device (latency), web server (no access / dynamic DNS issues), FTP server (no access / dynamic DNS issues), Plex server (no remote access), webcam (no remote admin access), or whatever.

How:  This is the reverse of the situation above, but it is a lot harder.

The reason is that OpenVPN doesn't support a single exclude.  It supports a single include, but not an exclude.  So it is really easy to make only one device use the VPN, it is harder to make only one device not use the VPN.

Note that this appears to be true regardless of the existence of the command "redirect-gateway def1" (or similar) that may exist in the OpenVPN configuration.  Logically, this command is supposed to make the default connection your non-VPN connection, but DD-WRT overwrites this "under the covers" when policy-based routing is in effect.  See "Short story" in this thread for details.

Method 1:  List everything on the network that should use the VPN, and just leave out the device(s) that should not.  In other words, make a manual list.

Let's assume we have 2 devices:  192.168.1.103 and 192.168.1.104.  These are the machines we want to use the VPN; all others will not.  In the policy-based routing field of DD-WRT, enter:

192.168.1.103/32
192.168.1.104/32

What this means:  It means "let 192.168.1.103 and 192.168.1.104 use the VPN, all others excluded."

The "/32" is a masking field:  /32 means "no masking", meaning that the exact addresses 103 and 104 are used.
A bigger list might resemble the following:


192.168.1.1/32
192.168.1.2/32
192.168.1.110/32
192.168.1.111/32
192.168.1.112/32

et cetera, et cetera.  Note that these are all just single, individual IP addresses.

Pros:  Easy and quick.


Cons:  This doesn't work well for situations where devices get added to the network.  They will not be included in the manually-generated list, and won't use the VPN by default.  Buy a new tablet/phone/PC/Boxee/Roku/whatever, you have to edit your policy-based routing field again. 


Method 2:  You can create a block of addresses that use the VPN.  Everything in the block goes through the VPN; everything not in the block does not.  You then have to set the problematic machine (or machines) to use IP addresses outside the permitted block, meaning they will not use the VPN.


Here are several examples of how to set up blocks of addresses that will use the VPN.  For more information, research "ip subnet masking" to figure out how to set up an address-mask pair that includes the block you want.  You can also use the IPv4 Subnet Mask Calculator or the Subnet Calculator to work it out.

Note that when setting up the block, you must not allow the IP address of your router to be included.  Most routers will live at 192.168.1.1, so you have to ensure that this IP address is not included in the block.  If it is, the VPN will probably fail to work.


192.168.1.15/29 = all addresses between 192.168.1.8 and 192.168.1.15 use the VPN
192.168.1.16/28 = all addresses between 192.168.1.16 and 192.168.1.31 use the VPN
192.168.1.32/28 = all addresses between 192.168.1.32 and 192.168.1.47 use the VPN
192.168.1.32/27 = all addresses between 192.168.1.32 and 192.168.1.63 use the VPN
192.168.1.64/26 = all addresses between 192.168.1.64 and 192.168.1.127 use the VPN

Again, anything not in the block does not use the VPN connection; it connects "in the clear".  This behavior cannot be changed on DD-WRT OpenVPN owing to how OpenVPN is implemented; see "Short story" in this post for details.

Pros:  Allows easy device adding.

Cons:  Obviously this only works if you can set the devices/machines in question to use a static IP address, or ensure dynamic addresses fall inside/outside the VPN block as desired.  This is usually possible, but there may be exceptions, and it might take some router tweaking.


This is additionally (slightly) inconvenienced by the fact that only the upper IP addresses can be conveniently blocked out.  Most people start building their networks from the lower IP addresses on up, not the other way around, so most existing machines / devices will probably be living in the lower address space - close to the router IP address that we cannot use.

As a guide, you may want to set all devices not using the VPN to static IP addresses below the permitted block (i.e. 192.168.1.2 to 192.168.1.63), and tell your router to assign DHCP addresses starting with 192.168.1.64.  This will ensure all DHCP clients use the VPN, while you can set static IPs either below this range to bypass the VPN, or within this range to use the VPN, as you see fit.  This might feel weird but should work OK.

Method 3:  List both specific IP addresses plus a block, all of which use the VPN.  Good for situations where you have a bunch of machines you don't want to renumber.

192.168.1.8/32
192.168.1.10/32
192.168.1.110/32
192.168.1.64/26

The last line above includes everything from 192.168.1.64 to .127.

This works well if you want to use DHCP for most machines (as per above) but have a few machines already on static IPs that also should use the VPN.


Method 4:  Set up a second router that doesn't have a VPN enabled.  The correct order is:

ISP <->  Non-VPN router (192.168.1.1) <->  VPN router (192.168.1.2) <-> rest of network

The following might also work, I'm not sure:

ISP <-> Non-VPN router (192.168.1.2) <-> VPN router (192.168.1.1) <-> rest of network

(This would keep you from having to re-set a bunch of machines to use 192.168.1.2 instead of 192.168.1.1 as their router/gateway.  If it works.)

The VPN-router has to have its gateway set to the non-VPN router and (probably) needs to have DHCP disabled.  You will also need to make sure dynamic DNS is set in the internet-facing non-VPN router and disabled in the VPN router.

Pros:  Once set up, it's easy - anything that connects to the non-VPN router is not VPN'd, everything else is.  You even have encrypted and unencrypted Wi-Fi networks available!

Cons:  Obviously you need two routers, and this takes a bit of setup.

Actually, a lot of setup in most cases.  Typically, any machine connected to the non-VPN router will not be able to "see" machines connected to the VPN router, and/or vice versa, since you have actually created two distinct and separate networks!  This can play hell with your file- and print-sharing setups.  Solving this requires network skills you typically need to go to school to learn.

Also obviously, you need to be able to force different devices to connect to the different routers as appropriate.  Wi-Fi devices can be set to connect to the appropriate Wi-Fi network (non-VPN or VPN) while wired devices will need to have static IPs set and be directed to connect to the appropriate router.


What you want:  Have machines use the VPN or not according to their internal network IP address.  (That is, according to the machine's identification to the internal network.)

Why:  Well, maybe you have several webcams that you want to remotely access and configure, but cannot.  Or a few game consoles.  Or whatever.  The point is, you have more than one device you need/want to exclude from using the VPN.

How:  This is the same process as for excluding a single machine, which is given above.  You need to explicitly include all machines that use the VPN; everything else gets excluded.  So you will need to write in the IP addresses / blocks for all machines that should use the VPN.




What you want:  Have machines use the VPN or not according to the port number of specific software.

Why:  Useful where you have one machine where everything works but one (or a few) specific services, such as Skype.  Allowing only Skype to bypass the VPN keeps everything else (like web browsing, streaming, chat, etc) private while allowing Skype to bypass nasty VPN latency and work like it should.

How:  I don't know how to do this yet, sorry.  Try using the connection by destination IP method, listed below.






What you want:  Have all connections to a particular external IP address use the VPN, and all others not.  Alternatively, have all connections to a particular kind of external IP address (i.e. USA based addresses) use the VPN, and all others not.

Why: Useful for keeping most connections "in the clear", while telling certain sites or services that you are located elsewhere.

For example, you might want to tell Amazon you're in the USA, to connect to Amazon.com, and to get the shipping info you want.  Or Netflix, or Pandora, etc.  For example, putting Netflix in the VPN could let you access USA-only Netflix from any device on your network.

How:  You have to tell OpenVPN to route everything through the non-VPN connection, and then explicitly list all of the IP addresses you want to go through the VPN.  It's all put into the "Additional Config" section of the OpenVPN client in DD-WRT.

For example:

###
### OpenVPN common configuration
###
route-nopull
route XXX.XXX.XXX.XXX 255.255.255.255 net_gateway

###
### OpenVPN routes
###

# whatismyip.org
route 98.207.0.0 255.255.0.0 vpn_gateway

# pandora.com
route 208.85.40.0 255.255.248.0 vpn_gateway

# amazon ec2 (us)
# https://forums.aws.amazon.com/ann.jspa?annID=1528 & extended via whois
route 23.20.0.0 255.252.0.0 vpn_gateway
route 50.16.0.0 255.252.0.0 vpn_gateway
route 50.112.0.0 255.255.0.0 vpn_gateway
route 54.224.0.0 255.240.0.0 vpn_gateway
route 54.240.0.0 255.240.0.0 vpn_gateway
route 67.202.0.0 255.255.192.0 vpn_gateway
route 72.44.32.0 255.255.224.0 vpn_gateway
route 75.101.128.0 255.255.128.0 vpn_gateway
route 107.20.0.0 255.252.0.0 vpn_gateway
route 174.129.0.0 255.255.0.0 vpn_gateway
route 184.72.0.0 255.254.0.0 vpn_gateway
route 184.169.128.0 255.255.128.0 vpn_gateway
route 204.236.128.0 255.255.128.0 vpn_gateway

What this means:  First thing to know is that XXX.XXX.XXX.XXX must be replaced with the IP address of your VPN provider.  This is the same number as entered in the "Server IP" field.

Second thing to know is, at one point, this functionality was broken in DD-WRT.  Specifically, any build above 18777.  I don't know when or if it was fixed.

For the actual script:  First, you tell the router that everything goes through non-VPN connection "net_gateway".  Then, after, you tell it that specific IP addresses go through the VPN connection "vpn_gateway".  Since it's a script, later commands overwrite the former commands, so this works.

For a more complete example, see this post in the DD-WRT forum, which lists some of the more common USA-based services that you may wish to create rules for.

Pros:  This targets specific services, while leaving everything else "in the clear".

Cons:  The IP addresses of the services can change anytime.  Some change frequently, making this a moving target.  Entering all of the ranges can be labor-intensive.




What you want:  You want to use a VPN with torrent software (such as uTorrent).

Why:  Duh.


Method 1:  Using torrent software inside the VPN

This method may require port forwarding to be set up.  This is probably not required for downloading, but it may be required for uploading (seeding).  Obviously lack of download is an issue; tou get to decide if lack of upload is really a problem or not.

However, some people report that uTorrent works "just fine" through the VPN, no special setup required.  So you may as well just try it first before deciding there is an issue.

If port forwarding is required, it is not port forwarding on the local router.  It is port forwarding at the PIA servers. 

The reason for this is that the PIA firewall configuration will block torrent software ports.  The PIA servers need to 'know' that we want to use that port.

This is typically done via the client software installed on a PC that does VPN support.  When we are using a DD-WRT router for VPN, the option for finding out our forwarded port via the client software is obviously unavailable.  I currently do not know how to overcome this.


Note that some users have reported that the list of PIA servers that support port forwarding is not accurate.  Specifically, the North York Canada node is listed as supporting port forwarding, but it doesn't work.  So if you're having problems, try a different one (the Netherlands is supposed to work).

Also note that port forwarding is not supported on any United States-based server.  As an example, if you want USA Netflix, you want to use a USA-based server to get a USA-based IP address.  However, you cannot use port forwarding at the same time, because none of the USA-based servers will do it.  There is currently no workaround for this.

Between the two problems of not being able to discover the forwarded port provided by PIA and the inability use a USA VPN server,  I didn't look into this any further.


Method 2:  Using torrent software outside the VPN

To do this, we will exclude the torrenting machine from using the VPN, and just use a proxy instead.  As proxy servers don't force all traffic through the VPN "tunnel" connection - they just try and hide your IP address - they don't mess with your torrent connections.

This works because PIA and other VPN providers provide a free proxy service along with their VPN service.  If you have VPN, you also have proxy automatically.

In fact, you may already be using a proxy server for torrenting.  In which case, by not moving the uTorrent machine to the VPN, you're keeping it's configuration pretty much unchanged. If you're not already using proxy, the setup is fairly simple and unlikely to cause issues.

Obviously this only works if you have a torrenting device (or devices) you're willing use off the VPN.  If you only have one computer, and it has to be on the VPN for other reasons, this method will not work.  Or, if you have several devices for torrenting, this might not be a convenient method.



Pros:  Easier to set up.  If you already have proxy, you can keep the existing settings (unless your username/password change when you sign up for VPN).  Doesn't mess with popular torrent software.

Cons:  Though your IP address is hidden, torrent downloads are not encrypted, and are not as secure as when using the VPN.  You need to have a machine for torrenting that you are willing to move off the VPN, and you need to be able to set it up to do so (per the instructions above in this post).






1 comment:

  1. Excellent Post, different methods, options. one & quick place to learn about DIY VPN + PBS..

    ReplyDelete