网络自由行:Windows 10上的VPN连接与路由自动化秘籍

引言

有一台L2TP协议的VPN服务器,这个服务器无法连接外网,只能连接特定的内网服务器,而且网段还与VPN服务器所在的网段不同,因此需要在连接VPN完成之后,自动追加相应的路由条目。这个需求在Linux下,操作起来还不算难,有各种各样的方案。但在Windows10上面,我还真花了一定的时间去研究并最终找到一个比较满意的解决方案,这里记录一下。

原理

Windows自带的VPN客户端,并没有设定连接之后设置路由的地方,远程VPN服务器也没有在完成连接之后推送路由信息,因此,只能在客户端这边编写自动化脚本。

要么,在脚本之中直接调用VPN连接指命,然后检测正常连接之后,再调用路由条目添加指令完成路由添加。

要么,监听Windows网络配置变更事件,事件发生之后,调用特定的Powershell脚本,检测目标VPN是否完成连接,连接完成之后,添加路由条目。

上面两种方案,都需要使用到Powershell编程,方案二,需要还使用计划调度程序。

不过经过一段时间的使用,方案一,门槛相对来说更高一些,需要掌握好几条API的使用,并且脚本也不方便管理。方案二,则近乎完美解决问题。

还有,windows10,其实没有完整的VPN方案,微软把VPN的能力基本都放在Server版本中,在Windows10中那个传入连接(使用RAS服务来实现),只能简单地实现连接进入本地,但无法实现SNAT,导致无法连接到本地网络,这个问题,我折腾了很久,最后没有找到解决方案,放弃了,使用softether vpn来解决。

自动化

第一步:设置正常连接的VPN信息

在设置->网络与Internet->VPN,这个菜单中设置好可以正常连接的VPN信息,如我的。

第二步:编译自动添加路由条目的脚本

C:\Tools\AddRoute.ps1,写入如下的代码,文件可以按每个人的喜欢保存好。

$vpnName = "dellsoft"
$vpnGateway = "192.168.60.1"
$routeDestination = "192.168.20.128"
$routeMask = "255.255.255.192"

# 检查 VPN 是否已连接
$vpnStatus = Get-VpnConnection -Name $vpnName | Select-Object -ExpandProperty ConnectionStatus
if ($vpnStatus -eq "Connected") {
    # 添加路由
    $routeAddCommand = "route add $routeDestination mask $routeMask $vpnGateway"
    Invoke-Expression $routeAddCommand
}


$vpnName = "ten_vpn"
$vpnGateway = "192.168.42.10"

# 定义要添加的路由列表
$routesToAdd = @(
    "route add 192.168.20.128 mask 255.255.255.192 $vpnGateway",
    "route add 10.4.18.0 mask 255.255.255.0 $vpnGateway"
    "route add 192.168.3.46 mask 255.255.255.255 $vpnGateway"
)

# 检查 VPN 是否已连接
$vpnStatus = Get-VpnConnection -Name $vpnName | Select-Object -ExpandProperty ConnectionStatus
if ($vpnStatus -eq "Connected") {
    # 循环遍历路由数组并执行每条命令
    foreach ($route in $routesToAdd) {
        # Write-Host $route
        Invoke-Expression $route
    }
}

代码中,第一段,主要是设置一条路由用的,第二段,主要是设置多条路由用的,而且这个脚本可以集成多个vpn的个性化路由条目。

vpnName这个变量,说明了这两段代码,分别对应两个不同的VPN连接。

第三步:使用任务计划程序创建一个任务,当 VPN 连接成功时运行 PowerShell 脚本。

在计算机管理->系统工具->任务计划程序,创建任务。

  • 在“常规”选项卡中,设置任务的名称,例如 Add Route for dellvpn。 勾选“使用最高权限运行”。 勾选“隐藏”。
  • 在“触发器”选项卡中,点击“新建”,然后设置触发器为“在事件日志中创建事件”,配置如下:
日志:Microsoft-Windows-NetworkProfile/Operational
源:NetworkProfile
事件ID:10000(连接)和10001(断开)
  • 在“操作”选项卡中,点击“新建”,然后配置操作为“启动程序”,并设置如下:
程序/脚本:powershell.exe
添加参数(可选):-NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\Scripts\AddRoute.ps1"

参数说明:

-NoProfile:

这个参数用于启动PowerShell时不加载任何配置文件,包括用户的配置文件和系统配置文件。这样做可以确保脚本在执行时不会受到配置文件中设置的影响,特别是在需要执行特定任务而不想被现有配置干扰时。

-WindowStyle Hidden:

这个参数用于设置PowerShell窗口的样式为隐藏。当脚本不需要交互式输入,或者你不希望用户看到脚本执行时的窗口时,可以使用这个参数。脚本仍然会在后台运行,但不会有任何可见的窗口。

-ExecutionPolicy Bypass:

这个参数用于绕过执行策略。执行策略是PowerShell用来限制脚本执行的一种安全机制。默认情况下,PowerShell可能不允许执行未经签名的脚本。使用-ExecutionPolicy Bypass可以忽略这些限制,允许脚本执行,但这可能会带来安全风险,因为它允许执行任何脚本,无论它们是否被签名。

-NonInteractive

不产生交互界面

第四步:完成计划配置

关掉电源生效,还有其他选项则根据需要勾选,最后点确定。

测试

连接其中一个VPN,并在powershell或者cmd中输入以下命令,查看所设置的路由是否在路由表中。

route print -4

总结

任务计划程序,在windows真的是一个很好的工具。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Scroll to Top