如何在pfSense托管的OpenVPN服务器上于客户端连接时执行脚本,实现动态IP路由推送?
我来帮你梳理下两种可行的方案,优先推荐服务器端的实现方式,毕竟不用折腾客户端的脚本维护,更省心:
一、服务器端解析域名并推送路由(推荐)
你之前提到的client-connect其实是服务器端的配置选项,不是客户端的,所以把它写在客户端配置里才会被标记为UNUSED OPTIONS。pfSense的OpenVPN支持在客户端连接时运行服务器端脚本,自动解析动态域名并推送对应路由,步骤如下:
创建服务器端脚本
登录pfSense的SSH终端(或者在Web界面的「Diagnostics > Command Prompt」里执行命令),先创建脚本目录(如果不存在的话):mkdir -p /usr/local/etc/openvpn/scripts然后创建脚本文件
push_dynamic_routes.sh:#!/bin/sh # 这里替换成你需要解析的动态域名,空格分隔多个域名 TARGET_DOMAINS="your-dynamic-domain.com another-domain.net" # 遍历每个域名,解析IP并生成推送路由的命令 for DOMAIN in $TARGET_DOMAINS; do # 用dig解析域名,取第一个IPv4地址 IP=$(dig +short $DOMAIN A | head -n1) if [ -n "$IP" ]; then # 把路由命令写入OpenVPN的临时配置文件($1是脚本接收的参数,对应客户端的临时配置) echo "push \"route $IP 255.255.255.255\"" >> $1 fi done给脚本添加执行权限:
chmod +x /usr/local/etc/openvpn/scripts/push_dynamic_routes.sh配置OpenVPN服务器调用脚本
登录pfSense Web界面,进入「VPN > OpenVPN > Servers」,编辑你的OpenVPN服务器配置:- 找到「Advanced Configuration」部分,在「Custom options」输入框中添加:
client-connect /usr/local/etc/openvpn/scripts/push_dynamic_routes.sh - 保存配置后,重启OpenVPN服务器(可以在「Status > OpenVPN」里点击对应服务器的「Restart」按钮)。
- 找到「Advanced Configuration」部分,在「Custom options」输入框中添加:
这样,每当客户端连接时,服务器会自动解析你指定的动态域名,把实时的IP路由推送给客户端,完全不用客户端做任何额外配置,完美解决动态IP的问题。
二、客户端脚本方案(跨平台处理)
如果因为某些原因无法使用服务器端方案,我们可以针对OpenVPN Connect 3.x调整客户端配置——注意OpenVPN 3.x客户端不支持client-connect选项,这就是你之前配置被标记为UNUSED的原因,我们需要用它支持的up或post-connect脚本。
1. 核心思路
针对不同客户端系统编写脚本,在VPN连接成功后解析动态域名并添加本地路由,配置时在客户端ovpn文件中添加对应脚本调用:
Windows平台(PowerShell脚本示例)
创建update_vpn_routes.ps1脚本:
# 替换成你的动态域名列表 $targetDomains = @("your-dynamic-domain.com", "another-domain.net") foreach ($domain in $targetDomains) { # 解析域名获取IP try { $ip = (Resolve-DnsName -Name $domain -Type A -ErrorAction Stop | Select-Object -First 1).IPAddress if ($ip) { # 添加路由,使用VPN网关作为下一跳(OpenVPN会自动设置环境变量route_vpn_gateway) route add $ip mask 255.255.255.255 $env:route_vpn_gateway } } catch { Write-Host "Failed to resolve $domain : $_" } }
在客户端ovpn配置中添加:
script-security 3 up "powershell.exe -ExecutionPolicy Bypass -File C:\Users\your-user\Documents\update_vpn_routes.ps1"
注意:需要以管理员身份运行OpenVPN Connect,否则无法添加路由。
Mac/Linux平台(Bash脚本示例)
创建update_vpn_routes.sh脚本:
#!/bin/bash TARGET_DOMAINS="your-dynamic-domain.com another-domain.net" for DOMAIN in $TARGET_DOMAINS; do IP=$(dig +short $DOMAIN A | head -n1) if [ -n "$IP" ]; then # 添加路由,指向VPN网关 sudo route add -host $IP $route_vpn_gateway fi done
给脚本加执行权限:chmod +x update_vpn_routes.sh,然后在客户端ovpn配置中添加:
script-security 3 up /home/your-user/scripts/update_vpn_routes.sh
2. 跨平台简化建议
如果需要同时支持多系统,可以考虑用Python编写跨平台脚本,调用系统的DNS解析和路由添加命令,这样只需要维护一份脚本,适配不同系统的逻辑即可。
备注:内容来源于stack exchange,提问作者Eastman




