How to ensure all traffic from a Windows 8.1 computer enters a PPTP VPN tunnel

This is a follow up article to How to ensure all traffic from a Windows XP computer enters a PPTP VPN tunnel

 
The example network is the same as in the referenced article:
 

  • Fully patched Windows 8.1 machine connected to the router via Ethernet.
  • Sony Playstation 3 connected via WLAN to the router.
  • Router connects to the internet via (A)DSL.
  • LAN is 192.168.1.0/24.
  • Windows 8.1 has the Relakks VPN configured as described on the Relakks Homepage.
  •  
    As long as the VPN tunnel is up everything is fine and all traffic enters/exits via the VPN provider. If the VPN tunnel is unavailable/down/reestablishing, you will be accessing the internet via your internet service provider and not via the VPN provider. This is probably not something you want.

     
    The following steps should enable the Windows 8.1 machine to only have a usable Internet connection when the VPN is up. All other services (for example, the PS3 Media Server for the PS3) should remain unaffected. To avoid providing PS3 Media Server services to the Intenet I configured the PS3 Media Server to bind to the local IP address but this only works if you have static IP addresses in your LAN or have set up DHCP to hand out IP addresses depending on the MAC address of the machine requesting DHCP. The first step is to lock down the machine so only LAN traffic is allowed and Internet is only available when the Relakks VPN is up.

     
    Execute the following as Administrator in the Powershell:

    # clean start
    netsh ipsec static delete all
    
    # create policy
    netsh ipsec static add policy name="Relakks VPN" description="Relakks VPN"
    
    # get the Relakks pptp.relakks.com DNS entries
    $iplist     =  @( [System.Net.Dns]::GetHostAddresses("pptp.relakks.com").IPAddressToString )
     
    # set up filter rules
    netsh ipsec static add filter filterlist="LAN Access"       srcaddr=me dstaddr=192.168.1.0 dstmask=24 mirrored=yes
    netsh ipsec static add filter filterlist="ANY"              srcaddr=me dstaddr=any                      mirrored=yes
    
    # set up individual filter list for each Relakks endpoint
    foreach ($element in $iplist)
    {
      netsh ipsec static add filter filterlist="Relakks Endpoint $element"  srcaddr=me dstaddr=$element mirrored=yes
    }
    
    # set up filter actions
    netsh ipsec static add filteraction name="Allow" action=permit
    netsh ipsec static add filteraction name="Deny"  action=block
     
    # allow Lan2Lan
    netsh ipsec static add rule policy="Relakks VPN" name="Lan2Lan" filterlist="LAN Access" filteraction="Allow" conntype=lan
    
    # allow Lan2Relakks
    foreach ($element in $iplist)
    {
      netsh ipsec static add rule policy="Relakks VPN" name="Lan2Relakks $element" filterlist="Relakks Endpoint $element" filteraction="Allow" conntype=lan
    }
    
    # Enable Lan2Internet via Dialup
    netsh ipsec static add rule policy="Relakks VPN" name="Lan2WorldviaDialup" filterlist="ANY" filteraction="Allow"  conntype=dialup
    
    # Everying else, no go
    netsh ipsec static add rule policy="Relakks VPN" name="DropAll" filterlist="ANY" filteraction="Deny"  conntype=lan
    
    # and activate
    netsh ipsec static set policy name="Relakks VPN" assign=yes
    

     
    Once executed this will limit access to your local area network and the list of pptp.relakks.com IP addresses.

     
    You may get worried that you do not see any of the above changes in the Windows Firewall. This is correct. The changes can be seen (and hence modified) once you have added the IPSec snap-ins in the Microsoft Management Console. Run mmc and then click on IP Security Policies on Local Computer. You should see the Relakks VPN policy. Check if the policy is assigned. If not, it is not active! Although all of the changes performed by the script could have been done in the Microsoft Management Console it is a lot more error prone and requires a lot of clicking around.

     
    Once you have verified the VPN connection works and also that you are unable to access the Internet while the VPN is not running you should run into two problems:

    1. How to start the VPN when the machine starts
    2. How to redial the VPN connection once the Internet connection of the router drops/reconnects

     
    The first problem is easy yet very crude to solve by adding VPNdial.bat to the location provided by WIN+R and running ‘shell:startup’. (Replace the upper case placeholders with the correct information).

     
    Contents of VPNdial.bat:

    @echo off
    rasdial VPNPROFILENAME USERNAME PASSWORD
    

     
    When restarting the machine you should see a Command Windows show up with some information about VPN dialup process. If not and all you see is the file opened in Notepad, the file type is wrong. It should be Windows Batch File.

     
    You might have noticed that when you configured the Relakks VPN, there was no “Redial” option available. Microsoft has removed that option for some odd reason (to be more precise, has chosen to ignore it although the option still exists in ‘C:\Users\THEUSER\AppData\Roaming\Microsoft\Network\Connections\Pbk\rasphone.pbk’:

    RedialAttempts=10
    RedialSeconds=180
    IdleDisconnectSeconds=0
    RedialOnLinkFailure=1
    

     
    Now for the tricky part. How to trigger a redial. Searching the Internet for solutions they usually recommend a third party application and a working Internet connection. The latter will be a problem in our scenario since the whole idea is to have no Internet access when the VPN is down. After even more reading I found a hint in a TechNet forum to set a trigger on an event. Since the dialup events are logged all you need to do is to find the correct event to configure a task which will be triggered. This is actually as simple as it sounds. Start the event log viewer and search for your dialup events. If you have done some extensive testing you should be able to find some events that correspond to a dialup termination event. In my case, the event id was 20226. After identifying the correct event to hook a task to right-Click on the entry and select Attach Task To This Event. This will start the task configuration utility. As we want to start a dialup of the VPN connection and we have already created a Windows batch file to do exactly that upon startup on the machine this can be reused to redial the VPN connection. So when the task configuration utility requests a program to start when the event occurs enter the the full path and name to VPNdial.bat. To test if this works you can manually disconnect the VPN tunnel and a command window should show up redialing the VPN connection.

     
    This approach will work most of the time but what if you are unable to reach pptp.relakks.com (to be more precise, the IP address resolved does not match any in the list you have generated in the Powershell script) or pptp.relakks.com refuses to accept your username and password (Relakks does not like too many dialup attempts within a certain time frame). In both cases the event which would trigger a redial will not fire. In most cases just firing up a redial event when the VPN connection terminates is enough, the other error conditions should not occur but if you want to make it bullet-proof you need to create separate scripts for each possible error event at trigger that. For example, when you get the 691 error it would make sense to trigger a script that will wait 15 minutes and then try the redial. If pptp.relakks.com can not be reached you could add it as a new Relakks endpoint (but I would not recommend to do this automatically, maybe should have a cut&paste output shown in a window when this event occurs. I would recommend watching the event log for a few weeks and see what other termination events occur and if they occur often enough, set a trigger and write a script for it.

     
    Another thing you might not be aware of is that your Windows 8.1 will have a public and valid IPv6 address. I have assumed you are not using IPv6 in your local area network so the IPv6 IP address the Windows 8.1 machine has is from the Teredo IPv6 tunnel. And the tunnel only works/is up when you have Internet connectivity (= if your VPN is up or not). Nevertheless, if you are uncomfortable with the Teredo tunnel, you can turn it off.

     
    Execute the following command as Administrator in the Powershell:

    netsh interface teredo set state disabled
    

     
    Important:
    When the VPN is up your machine is part of the Internet. Directly accessible. Depending on what services you plan to run (PS3 Media Server, Privoxy or the like) try to configure them to bind to the local area network IP address/interface. Sometimes this is not possible and you actually have to create a new inbound rule in the firewall explicitly blocking access to a specific port for the public firewall profile (the VPN dialup connection is considered a public network and hence the public profile firewall rules apply). Always test if the port is really unreachable from the outside by using a host on the Internet and not from within your local area network).

    Advertisements

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s