Routing and Remote Access - Adding new interfaces

Qlemo"Batchelor", Developer and EE Topic Advisor
CERTIFIED EXPERT
Published:
Updated:
Edited by: Andrew Leniart
Starting with Windows 2012 change for network interfaces (adding, replacing, ...)  requires to uninstall and reinstall RRAS to apply those changes - purging the current RRAS setup.
The following script shows how to add new interfaces without having to  reinstall RRAS.

Background story


We use Windows RRAS for implementing PPTP, L2TP, OpenVPN and some proprietary VPN client connections for centralized remote access to customers we do maintenance for (see my previous article "Using remote client connections (VPN, ISDN, PPTP aso.) for routing in Windows" if interested).


That works well as long as you stay with Windows XP or better Windows 2003 - but since both are the end of life since long, it is not feasible to keep those any longer, and we need to move to a recent Windows Server OS.



So: Back to the future!?

 

"Migrating" to a current Windows Server OS usually is easy for PPTP (yes, it's still used :<) and L2TP/IPsec, where the configuration is even much easier now using PowerShell instead of netsh, though there are occasional incompatibilities.


But if it comes to adding (non-dialout) virtual interfaces, which usually present themselves as an Ethernet interface, the unofficial and secret procedure requires you to export RRAS configuration, uninstall RRAS, then reinstall and reimport your config. You have now lost all certificates for L2TP and all passwords. Very inconvenient if you have around 50 such connections ...

 

Usually, this is a rare case, since you do not just add ethernet interfaces to a router, but aside from the above scenario, you'll hit that wall in a test lab.



PowerShell and some research to the rescue!


The following script allows for adding interfaces at any time. The only restriction is that RRAS needs to be restarted, which of course closes all active connections. But there is no reboot or reinstall!


Before you run the script, add all required interfaces. For OpenVPN, that requires to call the addTap batch several times. The request to allow refreshing the driver can be denied for all but the last round (if you add 5 TAP interfaces, you can skip the refresh for the first 4).


Make sure that all new interfaces are enabled, otherwise, the script will throw errors.


Some VPN clients present an interface only while connected - the old-fashioned Cisco IPsec VPN client is one of those. So you'll have to make sure the VPN connection is active before running the script.


Start the script in an administrative PowerShell console. It will retrieve all not-yet RRAS-aware interfaces, create some registry entries, then restart RRAS and use netsh for adding the interfaces to the (IPv4) routing feature - this can instead be done manually in the RRAS MMC, if you like.


Since it is primarily intended to add "client" type of interfaces, NAT is set up too. Again, this setting can be created and changed in the MMC.


There is a filtering line which I commented out to show how you would apply an interface restriction, here for OpenVPN TAP adapters. As-is, the code just adds all interfaces.


<#
    Adds newly created network interfaces to RRAS
    e.g. OpenVPN TAP Adapters

    Script created by Clemens Hoffmann, 2018 08 22
#>

Set-Location HKLM:\System\CurrentControlSet\Services\RemoteAccess\Interfaces

# get next usuable interface index for RRAS
$IFIdx = ([int[]] (Get-ChildItem .).Name.replace('HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RemoteAccess\Interfaces\','') | Measure-Object -max).Maximum+1

# get all set up RRAS interfaces up to now
$rrasIF = Get-ChildItem . | get-itemproperty | Select-Object -Expand InterfaceName

$ifname = @()
# add those interfaces not yet set up in RRAS:
Get-ChildItem 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}' -exclude properties |
  Get-ItemProperty |
  ? { $_.ComponentID -notlike 'ms_*' -and $_.ComponentID -notlike 'sw\*' -and $_.ComponentID -ne '*isatap' -and $rrasIF -notcontains $_.NetCfgInstanceID } |
# ? { $_.ComponentID -eq 'tap0901' } |
Select-Object -Expand NetCfgInstanceID |
  % {
    # getting the interface display name for activating routing on it after RRAS restart
    $ifname += (Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}\$_\Connection").Name

    Write-Host -f green "adding $($ifname[-1])"

    # create required registry entries
    [void] (New-Item $IFIdx)
    Set-ItemProperty $IFIdx      InterfaceName   $_
    Set-itemProperty $IFIdx      Type            3  -Type DWord
    Set-ItemProperty $IFIdx      Enabled         1  -Type DWord
    Set-ItemProperty $IFIdx      Stamp           0  -Type DWord

    # getting the interface display name for activating routing on it after RRAS restart
    $IFIdx++
  }

if ($ifname) { Restart-Service RemoteAccess }

# Interfaces are now visible inside RRAS
# setting the IPv4 router interface info
foreach ($if in $ifname)
{
  netsh routing ip     add interface "$if" enable
  # following only if using a "public" interface, requiring to apply NAT
  # OpenVPN client (!) and other VPN client interfaces usually need this
  netsh routing ip nat add interface "$if" mode=FULL
}

add-RRASIF.ps1

 

1
3,238 Views
Qlemo"Batchelor", Developer and EE Topic Advisor
CERTIFIED EXPERT

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.