How to: Proper partial network VPN with "kill switch"

##Goals

  • Configure a private VPN connection from the PFSense gateway to your VPN provider (PIA in my case)
  • Allow hosts to be easily added/removed from the VPN
  • Ensure hosts on the VPN do not leak IP in any way (DNS or otherwise)
  • Ensure hosts on the VPN do not use the naked internet connection if VPN goes down

##Assumptions

  • You are using PFSense 2.3 or newer. This guide probably works with older versions, but I have not tested that.
  • You are more or less capable of setting up the OpenVPN client or have instructions on how to do so.

##Steps

Before we get started please note that many steps in here deal with things other than the VPN itself. If you cut any corners you risk having leaks in your setup. I will do my best at each step to explain what everything does and why it’s set up that way so you can have confidence in your configuration. Also please, I know the temptation to skim this kind of guide can be great, I highly suggest taking the 5 minutes to read everything. I promise to try to be as concise as possible from this point on. Full disclosure: I am not a full time IT engineer, rather I am a software engineer so all advice given here is given by an amateur. If real IT pros show up with suggestions you should be sure to listen.

###1) Set up static IP allocations for every machine you wish to use the VPN.

  • I strongly advise doing this by having the DHCP server assigning static IP’s rather than having the machines self-assign. This limits the chances you accidentally fall off the VPN.
  • Failure to set static IP’s may result in leakage.

###2) Create a Firewall alias group for all clients to go on the VPN.

Be sure to include any IPv6 addresses if you have IPv6 enabled! In my case I have only a single machine using the VPN:

http://i.imgur.com/nYLzzdU.png

Any host you add to this group will be on the VPN. Any host NOT in this group will go out your regular WAN connection. Name this group pia_redirect_group

###3) Setup your VPN

Setup for each VPN is different, however I use PIA myself. You want to use an OpenVPN Client. There are instructions for setting up the PIA VPN here: https://www.privateinternetaccess.com/pages/client-support/pfsense

There are a couple important things to note:

  • Check “Disable IPv6”
  • Check “Don’t pull routes” ← failure to do this will break everything!

Do not set up anything other than the VPN client! This guide will deal with routes/NAT issues later on. So in the PIA guide, stop where it says “Mappings Setup” and again note that they do not have you check “Don’t pull routes” where you will want to.

http://i.imgur.com/yVQJg4Z.png

###4) Setup NAT mappings

Navigated to Firewall → NAT → Outbound

  • If you are on Automatic Outbound change to Hybrid Outbound and save.
  • If you are on Manual Outbound you can still add the mappings the same way.

We are going to add 2 mappings. One for LAN to PIA, and another for Localhost to PIA access. Technically we could add mappings for static port 500 for ISAKMP, but chances are pretty good you don’t need or use this, and if you did you would know.

Save.

http://i.imgur.com/2vi3jTL.png

Please ignore my static_nat_group rule, its used for making xboxes work when needed.

###5) Create an interface for your VPN

Navigate to Interfaces → (assign)

You should see a new interface ready to be added which is your newly created OVPN client. Click the add button. It will automatically name your interface OPT#. Lets change that to PIA_VPN. (Or soemthing that makes sense for you)

http://i.imgur.com/8MqQHpq.png

At this point you should be able to see the interface located on dashboard. It probably wont have an IP address however, so we need to fix that. You may need to do this multiple times throughout the guide if you find the VPN stops responding as you configure it.

Navigate to Status → OpenVPN

Press the “Restart” button on the right next to your VPN client. Your dashboard should now show an IP address for your interface.

###6) Firewall LAN rules and tagging

At this point we have a connection up and running to our VPN, but no traffic is actually going over it. If you go to www.ipchicken.com you should still see your ISP provided IP address. If you are instead seeing the address from your VPN you have missed a step. Most likely you failed to check the “Don’t pull routes” option.

So let’s get some stuff going over the VPN.

Navigate to Firewall → Rules → LAN

We are going to make 3 rules:

  • All three rules apply only to items in the VPN redirect group we made in step 2
  • One rule to block access to the local DNS server as this could leak the IP while using the VPN.
  • One rule to block all ipv6 traffic from the VPN group as the VPN doesn’t support ipv6 and we don’t want to leak via ipv6
  • One rule to shove all traffic down the VPN from hosts in the vpn group, as well as tag that traffic.

http://i.imgur.com/7NhEBvt.png

Rule 1:

- Action: Block
- Interface: LAN
- Address Family: IPv4+IPv6
- Protocol: TCP/UDP
- Source: pia_redirect_group
- Destination: "This firewall (self)"
- Destination Port Range: DNS (53)
- Description: Block PIA group local DNS leak

Save

Rule 2:

- Action: Block
- Interface: LAN
- Address Family: IPv6
- Protocol: Any
- Source: pia_redirect_group
- Destination: any
- Description: Drop PIA group ipv6 traffice
- Advanced Options:
	- Tag: PIA_NO_WAN_EGRESS (technically this will never do anything on this rule, but I have the nafety for safety)

Save

Rule 3:

- Action: Pass
- Interface: LAN
- Address Family: IPv4
- Protocol: Any
- Source: pia_redirect_group
- Destination: any
- Description: Send PIA group over VPN
- Advanced Options:
	- Tag: PIA_NO_WAN_EGRESS
	- Gateway: Select your VPN gateway interface (PIA_VPN_VPNV4 or some shit like that)

Save

At this point you may be thinking “great I’m done, it works”. Yes it works, if you connect the VPN now you will see that any machine in pia_redirect_group ends up on the VPN if you go to IPChicken.com. You will have 2 problems however:

  • If you disable the VPN in Status → OpenVPN, you will find your machine falls back into the WAN group… Oops, that’s not good!
  • You probably don’t have working DNS right now because well… we just blocked it.

###7) Fix DNS

Navigate to Services → DHCP Server

Remember those static mapping you made earlier for your machines on your pia_redirect_group? Open them up and add DNS servers to them.

http://i.imgur.com/ahDzIv4.png

The reason we want to use external servers and not the DNS Resolver is this will make any machine in the pia_redirect_group send its DNS queries down the VPN. If queries were sent to your default resolver, they would go out your WAN gateway and not your VPN. This would be a leak. Machines on your VPN should now be able to visit websites correctly (you may need to renew their DHCP leases)

###8) Add the “kill-switch”

Now this isn’t so much a “kill-switch” as it is just a firewall rule that prevents any pia_redirect_group machine from talking out the WAN interface.

Navigate to Firewall → Rules → Floating

http://i.imgur.com/wdXL1UD.png

Add rule:

- Action: Block
- Interface: WAN
- Direction: any (!important, do not make this out or in, must be any)
- Address Family: IPv4+IPv6
- Protocol: Any
- Source: Any
- Destination: Any
- Description: Disable PIA WAN Egress
- Advanced Options:
	- Tagged: PIA_NO_WAN_EGRESS

Save
###9) DONE!

Testing process:

  • Enable VPN
    • On VPN grouped machine navigate to ipleak.com
      • Ensure no IP’s shown match your actual ISP provided IP
    • On non VPN grouped machine navigate to ipleak.com
      • Ensure IP’s shown match your actual ISP provided IP (DNS may or may not match)
  • Disable VPN (Status → OpenVPN)
    • On VPN grouped machine ensure you have zero internet access. No pings, no ability to do DNS queries, nothing.
    • On non VPN grouped machine everything is normal
  • Re-enable VPN
    • Everything works again as it did before you disabled the VPN. May take a minute for the states to resolve correct and internet access to fully return.

Some final thoughts:

  • Do not under any circumstances enable UPnP or NAT-PMP for machines in the pia_redirect_group. UPnP can also leak your IP address through a variety of methods, and I have not checked that this setup 100% ensure UPNP traffic goes out the correct gateway. I explicitly ban mine from using UPnP with the following rule:

deny 88-65535 192.168.1.224/32 88-65535

  • Consider configuring your DNS Resolver to be able to resolve clients in the pia_redirect_group and then use the DNS names in the alias stage. This makes it easier to change their IP addresses in the future.
  • I am still trying to figure out if it might be possible instead to force the DNS Resolver to use the PIA VPN instead. This would allow all member of the network to use the DNS Resolver and simplify some things considerably. Setting the outbound interface works, but makes DNS stop responding when your VPN goes down, which is bad.

Thanks for taking the time to write a detailed guide, this should help many. I took somewhat different approach but the results are the same. Originally dhcp handled all vpn clients while static mappings were reserved for wan connections. I also used the no wan egress (tagging) to prevent leaks. I believe you can continue to use the resolver for the vpn by disabling forwarding mode in general settings and adding only the vpn under dns resolver->outgoing interfaces. As for my static mapping devices I entered the preferred dns servers (non vpn dns servers). The lan firewall rules consisted of all devices defined by static mappings first (under advanced I chose wan as the gateway) then my default rule (edited for the no wan egress) set as gateway vpn, last. Upnp was default deny with acl entries for only the devices I wanted. With this setup everything worked accordingly except trouble with open nat on xboxes was sporadic (this was fixed by setting up a vlan for all non vpn clients). Unfortunately at the time I was unable to find a guide like yours so all my efforts were trial and error (at the time I was a pfsense newbie - still am to a point but learning fast). Thanks again for taking the time to write such a detailed guide, this will benefit many. Edit: from what I understand, if you leave the disable dns fowarder unchecked, the clients will use the root dns servers (dnsleak will show your vpn gateway ip through initial test and will reveal only your wan ip after running the extended test). I may be wrong but believe this would also protect from isp snooping. This was my original rules prior to adding the vlan http://imgur.com/rvTRUeN. The following images show dns general setting with vpn set as outgoing interface, current lan rules, floating rules, and lastly general setup with local host removed http://imgur.com/a/OOnvZ.

I found it better to just disable LAN * to WAN, and instead make a Whitelist of IPs that don’t use the VPN

Thank you for writing the guide, it’s really helped! Kill switch seems to work, however it’s now not allowing connections to start up again, instead i’m having to restart the device for the connection to become live. Any ideas for this?

Thanks,

Saved! cant wait to try this. Was just getting ready to set up pfsense in the next few days

Great HOWTO,

Is this also applicable when the VPN is not on the router itself?

Say I have a host on my network that handles VPN host to host. Is pfSense able to handle this in a way like “if source-host is trying to talk to anything but the vpn address then block communication” ?

Nice summary. Small suggestion: you may want to add some context for why to block UPnP or NAT-PMP

I’m a bot, bleep, bloop. Someone has linked to this thread from another place on reddit:

^(If you follow any of the above links, please respect the rules of reddit and don’t vote in the other threads.) ^(Info ^/ [1](/message/compose?to=/r/TotesMessenger))


  1. Contact ↩︎

Deebeeoh, stumbled across this thread while simply browsing the pfsense forums https://forum.pfsense.org/index.php?topic=88664.0. I’ve changed my setup accordingly and only briefly tested a few things. Utilizing unbound for both my vpn (lan devices) and vlan, only my wan ip is exposed via dnsleaktest.com after running the extended test. It’s my understanding that only the root dns servers are seeing my queries and not my isp. I’ll post a few screenshots later detailing my configuration. I’m also able to utilize dnsbl for both the lan and vlan with this particular setup.

Forgive me if I’m wrong, but did you base your guide off the one I wrote recently? I noticed you even included the over-precautious block LAN DNS step :slight_smile:

https://www.reddit.com/r/PFSENSE/comments/6ectba/packet_capture_vpn_traffic_question/?st=J3GPHCMP&sh=48c254e7

It didn’t work for me. :confused: I even reverted back to factory settings, which I thought I was making progress. However, on step 6 (before adding the rules), that’s when it all goes to hell. I retraced my steps to see if I did something wrong, but I copied everything correctly. My guess is that this won’t work for me because I have a quad NIC and I have the 1 client I want VPN’d on OPT1. I did set up OPT1 to look like your LAN but maybe there’s something else I have to do. I am completely new to pfSense. Also, on step 8, that step completely kills off my entire VPN and internet (no matter what client on any interface).

Second whole day wasted with no results, sigh…I’m starting to regret building this rig.

Well, I managed to make it “work”. However, it leaks badly. dnsleaktest.com shows my fake IP but hitting Standard- or Extended test shows up my real IP right away. ipleak.net shows both my fake and real IPs.

On “Some final thoughts” you have some extra steps but I have no idea how those settings work. I am at a loss and thinking I should just give upon pfSense. Something so simple shouldn’t be so complex. It won’t even let me use VPN FROM inside client itself for some reason.

This needs to be put on the side bar. Fuckin awesome guide. I tried to set up a second network (my main is 192.168.20.0/24 so I wanted to make 192.168.21.0/24 my VPN network) but I couldn’t get it to work. However setting up certain hosts via firewall alias works perfectly. I have two NICs in my main PC so I set up the second NIC as a VPNed client and then assigned all my P2P software to use that NIC and bind to that IP. I lowered the net priority of the second NIC so even though it also has a default gateway set, it has a higher metric and is never used. If I disable the primary NIC, it shows all my traffic going through the VPN.

I would recommend not using ipchicken.com. For some reason, even though I had gotten everything working like it should, ipchicken still showed my IP as the old IP. I went to other sites and it showed the VPN IP.

Really good guide, thanks. My setup is a little bit different, but still your guide was a huge help for getting things right.

I am trying to set this up but I would like to just have an entire VLAN that uses PIA VPN and my standard LAN would go out my ISP.

Could you possible to a quick write up on what that would entail?

I’ve followed your awesome guide but I’ve got the host receiving the IP address for my VPN services DNS server, and it’s also not resolving anything. So, it’s not getting the DNS set in pfsense general settings, or the specific ones set in the DHCP static. Is there anywhere else that might be breaking DNS for just this host?

Too bad that OP has deleted their account at this point.

Not a single one of the guides I found before this mentioned enabling “Don’t pull routes” in the VPN client… I think what that setting does is prevent OpenVPN from modifying the routing table in Pfsense / OpnSense. What the client will do by default is add itself as the default gateway.

The problem with setting the outgoing interface for the forwarder is that my testing showed that when the VPN goes down DNS stops working. This is sub-optimal as we know that when the VPN goes down our VPN hosts cant communicate out the WAN interface anyway, but we shouldn’t knock out DNS for the entire network.

Really what we want is a preferred interface for the DNS Resolver.

This is certainly a viable approach. I dislike it personally simply because I prefer to have the exceptional scenario (VPN use) be the exceptional configuration. However some pretty simple swapping around of some of these rules and mechanisms will achieve the desired result.

Did anyone having the same issue ? Did anyone managed to solve this issue ?