Guide on how to set up split tunneling

Post your questions about SoftEther VPN software here. Please answer questions if you can afford.
Post Reply
chaoscreater
Posts: 12
Joined: Fri Jun 30, 2017 12:32 am

Guide on how to set up split tunneling

Post by chaoscreater » Sun Feb 25, 2018 7:19 am

It took me a while to get this working, so I'm going to share my findings with the community and hope it'll be useful to someone.

There are 2 ways (that I know of) to set this up. Let's start with the SecureNAT method. But before we do anything, we must first make sure that we never set up Local Bridge and SecureNAT at the same time. This will wreck havoc in your network (the one that your Softether VPN server is running from). Let's say that you're running your Softether VPN server on your PC at work and let's say the subnet is 10.10.10.0/24. Let's say your SecureNat is running DHCP for 192.168.30.0/24 and you were to enable Local Bridge in the Softether VPN server settings. This will bridge both networks together, which is obviously bad.

So, on your VPN server running in your remote network (in this case my workplace), go into "Local Bridge Setting" and remove any local bridges that you have configured. Then, go into your VPN hub and go into "Virtual NAT and Virtual DHCP Server (SecureNat)" and edit the configuration. By default, the IP address is set to 192.168.30.1, so just leave that as is. Enable DHCP and just let it use the default settings. Configure the DNS servers to use the same as the DNS servers you're using on your work PC. If your work PC is on the domain, it'll likely use the domain controllers. DO NOT set a default gateway under SecureNAT. Split tunneling will not work properly if you do this.

Next, we need to edit the routing table to push to the client(s) that will be connecting to the VPN server. Let's say your work network is 10.x.x.x/8. You will then push this out:
10.0.0.0/255.0.0.0/192.168.30.1

This is basically saying, for the entire 10.x.x.x/8 range, route traffic through the gateway/interface - 192.168.30.1. Remember, 192.168.30.1 is your Softether VPN server's network interface that we have established previously. If you changed this IP to something else, make sure you update your routing table accordingly.

Once you're done, go to your client machine (in my case my home PC). Install the Softether VPN client if you haven't already. Set up a Softether VPN virtual adapter. Configure the metric of this adapter (either using powershell or go into the IPv4 stack of the adapter) and change the metric to a high value, something like 9000. Just make sure this is higher than the metric value of your primary ethernet / NIC. For example, my primary NIC is set to a metric of 5, my WiFi NIC is set to 40 and my Softether virtual adapter is set to 9000. It doesn't matter what you set yours to, just make sure the Softether one has a higher metric value. To use Powershell to do it, first run Powershell as administrator. Then, run this:

Get-NetIPInterface | sort-object interfacemetric

It should list a bunch of your NICs with the interface metric and ifIndex. The ifIndex is just an index for your NIC. The interface metric however, determines which NIC is used as the primary NIC for routing connections. For example, let's say you have the following:

ifIndex - 14
interfaceAlias - Example1
interfaceMetric - 1

ifIndex - 7
interfaceAlias - Example2
interfaceMetric - 9000

If you ping Google.com, which interface is it going to use? It'll use "Example1", because it has a lower metric of 1 comapred to a metric of 9000.

Anyway, just find your SoftEther VPN adapter and set its metric to 9000, by doing this:

Set-netipinterface -interfaceindex "21"-interfacemetric "9000"

You'll need to change the interfaceIndex to match yours.

Now, from the client machine, connect to your VPN server and try pinging something on your work LAN. It should resolve via the 192.168.30.1 gateway, via your SoftEther VPN adapter. You can check the routing table on your client machine by doing a "route print" in command prompt. Next, go to Google and lookup "what is my IP". If you've done this right, your IP should be reported to be the IP provided by your ISP, not your work's IP. Check multiple "what is my IP" sites to confirm.

Essentially, we are only routing the work network (10.x.x.x/8) through to our VPN adapter on the client side, and anything else will route out using our primary adapter. Because of the routing table, and the fact that the primary NIC has a higher metric value, everything that isn't on the work network range will route using our primary adapter, i.e split tunneling.

The PROBLEM with this setup is that if you were to do a SpeedTest, you won't get the actual speed that you should be getting. So for example, let's say your internet plan is 100 Mbps down and 20 Mbps up. When you are connected to the Softether VPN server, you'll most likely get a slower speed than that, maybe 60 Mbps down and 20 Mbps up. I haven't gotten to the bottom of this yet, but I think that despite it being a split tunnel setup and despite the "What's my IP" showing your home ISP's IP address, somehow traffic is still routed using your SoftEther VPN adapter interface, even though it shouldn't (due to its metric being set to 9000). I think this is an issue related to SecureNAT, perhaps in its implementation.

One final thing to note with having 2 VPN NICs with different metric values. Even if you push the ip routes to your routing table, sometimes this may not work for specific websites (dunno why). For example, if your work has a ADFS server for authentication, then even though the ADFS server's IP is part of the ip route pushed to your client machine, it will not load correctly via your VPN adapter of metric 9000. You'd have to use the metric value of 2 instead. If you don't know what I mean by this, don't worry. Just create the 2 adapters and when you run into issue, switch between the 2 to test and see if that changes. This of course is assuming that the routes in your routing table is correct.





Next, let's go over the Local Bridge method. I personally prefer this method over 2 reasons. The main reason is that I can get an IP directly from the DHCP server at work, rather than having a NATTed address like with our SecureNAT scenario. The other reason is that this split tunneling method is actually a proper split tunnel in comparison to the SecureNAT method. However, there are some quirks and annoyances.

First of all, on your VPN server, make sure to disable SecureNAT. Then, go into "Local Bridge Settings" and select a LAN adapter as your source for the bridge connection. One caveat here is that you cannot select a virtual NIC (e.g. a Hyper-V NIC) as your LAN adapter. Well, you can, and it will still work, but there is a bug with this (which I'll go over below). Just make sure that the LAN adapter you've selected is not used for a virtual switch or virtual NIC for e.g. Hyper-V or whatever. Then, select your VPN hub and bridge the connection.

On the client machine, we again make sure that the SoftEther VPN adapter's IPv4 metric is set to a high value, e.g. 9000. Next, we need to configure a static route on the client machine. We need this because we don't have an automatic way of pushing / modifying the routable table like what the SecureNat method did. Let's say your work network's range is 10.x.x.x/8 and the default gateway is 10.10.10.254. You'll simply need to do this:

route -p ADD 10.0.0.0 MASK 255.0.0.0 10.10.10.254 metric 1 if 7

What this is saying is, for the 10.x.x.x/8 network, route via the default gateway of 10.10.10.254 and assign this route a metric of 1. Also, route this out the NIC with an ifIndex of 7. To get your ifIndex for your SoftEther VPN adapter, run Get-NetIPInterface | sort-object interfacemetric and just use substitute the value 7 with yours.

Now, make the connection to your VPN server. You'll find that your SoftEther VPN adapter will get an IP directly from your work's DHCP server, as if you're sitting right there in the office. Great. Now, try to ping a work machine, it should resolve OK. If you do an IP lookup, it should return your ISP's IP. If you do a SpeedTest, the result should match what you're actually paying for.

Now, try and access a resource (e.g. a work document) on your work network share via SMB. You will find that you can access it just fine. Now, remember I mentioned earlier that you shouldn't use a virtual NIC (e.g. Hyper-V NIC) as the adapter for the Local Bridge? The reason is that if you did, you will NOT be able to access your network share via SMB. Well, you can, but it will be super slow and opening any resources, such as a document/file from your work network, will be super slow and will not work. This seems to be a bug with SoftEther, as it doesn't seem to support virtual NICs that well.





For those of you using a split DNS at work, you will require one additional configuration. For example, let's say your work machine is on a domain, e.g. contoso.com. It'll probably be using domain controllers or some dedicated DNS server for resolving DNS queries to internal IPs. For example, when you ping contoso.com, it may resolve to 10.10.10.20. But you also have a nameserver that is authoritative for contoso.com. On the nameserver, contoso.com resolves to e.g. 147.44.22.32. Well, when you ping contoso.com on your client machine, it will route through your primary NIC (again, it has a lower metric value comapred to the 9000 metric on your SoftEther VPN NIC), which will then do a DNS query against the public DNS servers, which in turn gets a recursive DNS query from the authoritative nameserver and returns 147.44.22.32 as the result. That might not be what you want, as you might want to have 10.10.10.20 returned instead. For example, when you need to access a work document via SMB - \\contoso.com\data, it wouldn't make sense for DNS to resolve to \\147.44.22.32\data right? So how can you make sure to return the internal IP of whatever resource you're trying to query? The only way I can get around this is to set the DNS for my primary NIC to use my work machine's DNS server. Make sure it doesn't have a secondary DNS server set for your primary NIC. So if my work PC is configured to use e.g. 10.10.20.5, then that's what I'll use for my primary NIC.

Obviously, changing the DNS on your primary connection constantly is a pain. So what you can do is download "RunElevated", create a shortcut of RunElevated edit the shortcut roperties to this:

"C:\Apps\RunElevated\RunElevated.exe" "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy ByPass -File SetDNS.ps1

In the same folder as the shortcut, create a SetDNS.ps1 file and add the following content inside. Here, the interfaceIndex should be your primary NIC, and the DNS IP of 10.10.20.5 should be your work DNS server's IP.


Function Do-DHCP {
Write-Output "Set primary DNS to DHCP"
Set-DNSClientServerAddress –InterfaceIndex 17 -ResetServerAddresses
}

Function Do-WorkDNS {
Write-Output "Set primary DNS to WorkDNS"
Set-DNSClientServerAddress –InterfaceIndex 17 -ServerAddresses 10.10.20.5
}

$choices = @(
'DHCP'
'WorkDNS'
)


Do {
$choice = $choices | Out-GridView -PassThru

If($choice)
{
&"Do-$choice"
}

} Until (-not $choice)

########################


Do
{
Switch (Read-Host -Prompt "Choice")
{
"DHCP" {
Write-Output "DHCP"
}

"WorkDNS"
{
Write-Output "Work DNS"
}

Default
{
Write-Output "Invalid Selection"
$continue = Read-Host -Prompt "Enter to continue, Any character and Enter to exit"
If($continue) { Exit }
}

}
} Until ($False)




Run the RunElevated shortcut (which points to your powershell file) and it should launch your Powershell script just fine. Select WorkDNS and hit enter on your keyboard. It should configure your primary NIC to use your work DNS. Then, do a ipconfig /flushdns and finally ping whatever resource is on your split DNS set up (in our example, contonso.com). It should resolve to the internal IP.

Your primary NIC still has the lower metric, therefore it is used for resolving queries, but because its DNS setting is set to your work's DNS server, it'll do a query using that server. And because the query is sent to 10.10.20.5, it'll use your SoftEther VPN adapter to query. Remember, our routing table is configured to route the 10.0.0.0 network using the Softether VPN interface - (route -p ADD 10.0.0.0 MASK 255.0.0.0 10.10.10.254 metric 1 if 7).

It's a bit confusing to get your head around, but this all works pretty well. Of course, if you don't care about split tunneling, you can use either methods and just set the Softether VPN's metric to a value of 1. Everything will just route out using Softether VPN adapter.




Lastly, there's another quirk you should be aware of. Regardless of which method you use for split tunneling, just make sure that you're not using a network bridge on the machine running Softether VPN server. This will sound confusing, but the network bridge I am referring to here is NOT the same as the "Local Bridge" setting in Softether VPN server's configuration. If you run "ncpa.cpl" to open up "Network Connections", you will see a list of your NICs. You can select 2 or more NICs and bridge the connections together, forming a network bridge. For some reason, Softether doesn't like it when you have a network bridge. From the client machine, if you were to ping the work machine that is hosting the Softether VPN server, ping will not resolve to its IP address. You have to remove the network bridge and then it'll resolve just fine. You can still ping everything else on your work network, just not the PC hosting the VPN server.

To make things even more confusing, the work machine where I am running my VPN server from is not on the domain. Due to this reason, this machine is obviously not registered in DNS on the DNS server. So when you ping something that isn't on the domain, i.e in a Workgroup, it should resolve via NetBIOS. I did try to disable NetBIOS on the NICs that I don't want to provide a response, and only enable NetBIOS on the NIC (or in this case the network bridged connection), but that still didn't allow me to ping and resolve my work machine to its IP. Every other machine in the office can be pinged and resolved just fine, regardless if they are on the domain or not.


Basically, SoftEther VPN server seems to be incomaptible with a network bridge or a virtual NIC (such as a Hyper-V NIC). It seems it only works well with physical adapters. UPDATE -> Looks like this has been resolved in the latest build. I'm using SecureNAT on the VPN server, which is using a Hyper-V virtual NIC for its connection.
Last edited by chaoscreater on Tue Mar 27, 2018 5:54 am, edited 3 times in total.

mantis2k
Posts: 2
Joined: Wed May 29, 2019 11:11 pm

Re: Guide on how to set up split tunneling

Post by mantis2k » Mon Aug 10, 2020 8:00 pm

Chaoscreater,

This is an amazing guide, the best I have found after days and months of searching. A million thanks. We are using the local bridge method for the reasons you mentioned. The big missing piece for us was the static route creation in order for our ADFS environments to work properly.

What would be really nice is if Softether will someday add an option to enable split tunneling, automatically, or at least manually by importing a config file that included the metric and route settings for the client VPN adapter. In the meantime, we'll have to push the script out through our RMM or figure a way to easily email the script to a user.

Thanks again,
Chris Porosky

Post Reply