I noticed that my Windows SMB performance on my gigabit LAN normally runs at about 950 Mbps for big files. But when OpenVPN is on, it drops. Not immediately, but soon. In like 5 seconds, close to the end of copying a 1 GiB file, it drops to lower than 1 Mbps. When I turn off OpenVPN it immediately jumps back to 950 Mbps. How to fix it?
I'm on Windows 11 and OpenVPN community edition v2.7.0
Some of my routing settings is like this:
Basically it seems splitted in route table:
Get-NetRoute | Sort-Object DestinationPrefix,RouteMetric | Format-Table DestinationPrefix,NextHop,InterfaceAlias,RouteMetric,Publish
DestinationPrefix NextHop InterfaceAlias
0.0.0.0/0 192.168.1.1 Ethernet
192.168.1.0/24 0.0.0.0 Ethernet
10.0.0.0/8 192.168.23.1 OpenVPN Data Channel Offload
192.168.23.0/24 0.0.0.0 OpenVPN Data Channel Offload
192.168.42.0/24 192.168.23.1 OpenVPN Data Channel Offload
...
Then I know I have problems with DNS cos VPN somehow push some high priority windows NRPT policy, which I do not understand, but the dot is making troubles:
Get-DnsClientNrptPolicy
Namespace : .
...
NameServers : 192.168.42.1
After about 3 hours of troubleshooting I finally found the cause.
Problem was that both Windows PCs were connected to the same OpenVPN server. Windows SMB opened multiple SMB channels: one over the local LAN and another over the VPN. In my case, this caused the SMB transfer speed to collapse from about 115 MB/s to 0.6 MB/s, while iperf3 still transferred at about 950 Mbps.
I assume that Windows' implementation of SMB multichannel sucks, otherwise it should just automatically detect that one channel is terribly slow and stop using it... but it is what it is...
To check whether you have the same issue, run:
Get-SmbMultichannelConnection
In my case it returned:
Server Name Selected Client IP Server IP Client Interface Index Server Interface Index Client RSS Capable Client RDMA Capable
----------- -------- --------- --------- ---------------------- ---------------------- ------------------ -------------------
192.168.1.10 True 192.168.23.44 192.168.23.10 4 11 False False
192.168.1.10 True 192.168.1.12 192.168.1.10 5 16 False False
I then checked which interface 192.168.23.44 belonged to:
Get-NetIPAddress -IPAddress 192.168.23.44
It turned out to be:
InterfaceAlias : OpenVPN Data Channel Offload
1. Disable SMB Multichannel
On both machines I disabled SMB Multichannel:
Set-SmbClientConfiguration -EnableMultiChannel $false -Force
Set-SmbServerConfiguration -EnableMultiChannel $false -Force
You can verify the setting with:
Get-SmbClientConfiguration | Select EnableMultiChannel
Get-SmbServerConfiguration | Select EnableMultiChannel
Note: Existing SMB multichannel connections remain active. I had to reboot both machines before the old connections disappeared.
Also to check if interface is offered by SMB you can call:
Get-SmbServerNetworkInterface | Format-List *
And you don't want to see anymore:
...
FriendlyName : OpenVPN Data Channel Offload
...
2. Increase the VPN interface metric
I listed my interface metrics:
Get-NetIPInterface | Sort InterfaceMetric | Select InterfaceAlias,AutomaticMetric,InterfaceMetric
Then I assigned a much higher metric to the VPN interface:
Set-NetIPInterface -InterfaceAlias "OpenVPN Data Channel Offload" -AutomaticMetric Disabled -InterfaceMetric 1000
I'm not sure whether this step was necessary, but I wanted Windows to strongly prefer the physical LAN over the VPN whenever possible.
3. Disable SMB server binding on the VPN adapter
I listed the bindings on the OpenVPN adapter:
Get-NetAdapterBinding -Name "OpenVPN Data Channel Offload"
and found:
Name DisplayName ComponentID Enabled
---- ----------- ----------- -------
OpenVPN Data Channel Offload File and Printer Sharing for Microsoft Networks ms_server True
Since I don't want to share files or printers over the VPN, I disabled that binding:
Disable-NetAdapterBinding -Name "OpenVPN Data Channel Offload" -ComponentID ms_server
After these changes, my SMB transfers stay around 950 Mbps (about 115 MB/s) over the LAN instead of slowing down by a factor of about 1000.
I think that first setting would solved it alone. But I just did all 3 at once... And I would recommend to do all 3 at once...