pfSense 上恢复连接后 OpenVPN 切换回主服务器

pfSense 上恢复连接后 OpenVPN 切换回主服务器

我们使用 pfSense 作为 Openvpn 服务器/客户端。我们有大约 20 个站点到站点 pfSense 客户端,它们使用 Openvpn 站点到站点配置连接到主站点。在主 pfSense(vpn 服务器)上,我们确实安装了多个 WAN,并且我们设置了故障转移站点到站点连接,方法是将服务器设置为监听本地主机并将来自多个 WAN 的 vpn 端口转发到 127.0.0.1。在自定义选项中的客户端上,我们添加了:

remote serverAlternatieWanIp VpnPort udp

当主链路中断时,此场景对我们来说可以正常工作,客户端通过备用 WAN 建立了新的连接。

我们不知道的是:
在主 WAN 连接再次启动后,如何推动客户端切换回(重新连接)到主 WAN?(我们的解决方法现在是重新启动 Openvpn 客户端,或者有时重新启动整个 pfSense 以推动 vpn 客户端再次连接到主 WAN,或者“杀死”备用 WAN 以推动 VPN 客户端重新连接到主 WAN。在我看来,所有这些都是糟糕的方法)。

我们还希望看到哪些客户端连接到了备用 WAN。现在的解决方法是在每个 vpn 客户端上使用 pfsense 并读取客户端 vpn 状态上的远程主机地址。我们正在使用 Zabbix 来监控我们的网络基础设施,我们希望尝试以某种 API 方式找出哪个 WAN 用于连接,这样我们至少可以在 Zabbix 上触发错误并告诉管理员将客户端重新连接到主 WAN。

答案1

我有两个想法

1.您可以让 OpenVPN 等到没有活动(如果可能的话,也许在晚上?),然后自动断开连接或重新解析服务器 IP(也许对 DNS 做一些巧妙/有创意的事情)。我没有测试过这些,我只是浏览了一下文档。看起来这对您有用,您只需要试验一下。

除此之外,我认为只要用户能够承受短暂的断线,断开客户端连接以让其通过重启实例或暂时关闭备份链接来重新连接本身并没有什么问题。你担心这个吗?还是只是希望它自动发生?

摘自 OpenVPN 手册页: https://openvpn.net/index.php/open-source/documentation/manuals/65-openvpn-20x-manpage.html

--不活跃 n(实验性)TUN/TAP 设备上 n 秒不活动后,OpenVPN 退出。不活动的时间长度是从最后一个传入隧道数据包开始测量的。

--ping n如果至少 n 秒内没有发送任何数据包,则通过 TCP/UDP 控制通道对远程设备进行 ping 操作(在两个对等点上指定 --ping 可使 ping 数据包在两个方向上发送,因为 OpenVPN ping 数据包不会像 IP ping 数据包那样回显)。在 OpenVPN 的安全模式之一中使用时(指定 --secret、--tls-server 或 --tls-client),ping 数据包将加密安全。此选项有两个预期用途:

(1)与状态防火墙兼容。定期 ping 将确保允许 OpenVPN UDP 数据包通过的状态防火墙规则不会超时。

(2)为远程方使用--ping-exit选项测试其对等方的存在提供基础。

–ping 退出 n导致 OpenVPN 在 n 秒内未收到来自远程的 ping 或其他数据包后退出。此选项可以与 --inactive、--ping 和 --ping-exit 结合使用,以创建两层不活动断开连接。例如,

openvpn [选项...] --inactive 360​​0 --ping 10 --ping-exit 60

当在双方使用时,如果对方断开连接,OpenVPN 将在 60 秒内退出,但如果没有交换实际的隧道数据,则会在一小时后退出。

–ping 重启 n类似于 --ping-exit,但在 n 秒内未收到来自远程的 ping 或其他数据包后触发 SIGUSR1 重启。此选项在远程对等方具有动态 IP 地址并使用低 TTL DNS 名称通过以下服务跟踪 IP 地址的情况下很有用,例如http://dyndns.org/+ 动态 DNS 客户端,例如 ddclient。

如果无法联系到对方,则会触发重新启动,从而导致重新解析与 --remote 一起使用的主机名(如果还指定了 --resolv-retry)。

在服务器模式下,--ping-restart、--inactive 或任何其他类型的内部生成信号将始终应用于单个客户端实例对象,而不会应用于整个服务器本身。还请注意,在服务器模式下,任何通常会导致重启的内部生成信号都会导致删除客户端实例对象。

在客户端模式下,--ping-restart 参数默认设置为 120 秒。此默认值将一直保持,直到客户端根据服务器配置中的 --keepalive 设置从服务器提取替换值。要禁用 120 秒默认值,请在客户端上设置 --ping-restart 0。

有关 SIGUSR1 的更多信息,请参阅下面的信号部分。

请注意,可以通过 --persist-tun、--persist-key、--persist-local-ip 和 --persist-remote-ip 选项修改 SIGUSR1 的行为。

还要注意,--ping-exit 和 --ping-restart 是互斥的,不能一起使用。

我建议你读一下手册。那里有更多内容。

另请参阅此内容 - PfSense 关于此事的具体讨论:https://forum.pfsense.org/index.php?topic=42935.0

2. 另一个想法是在接口状态改变时运行脚本(重新启动 OpenVPN?)。这个也是,我不会去测试或做任何事情,但我确实发现了一些关于它的讨论。

https://forum.pfsense.org/index.php?topic=65846.0

显然你可以将命令存储在/etc/devd.conf

我的包含:

# $Id$
# $FreeBSD: src/etc/devd.conf,v 1.26.2.1 2005/09/03 22:49:22 sam Exp $

options {
        directory "/etc/devd";
        directory "/usr/local/etc/devd";
        pid-file "/var/run/devd.pid";
        set scsi-controller-regex
                "(aac|adv|adw|aha|ahb|ahc|ahd|aic|amd|amr|asr|bt|ciss|ct|dpt|\
                esp|ida|iir|ips|isp|mlx|mly|mpt|ncr|ncv|nsp|stg|sym|trm|wds)\
                [0-9]+";
};

# CARP notify hooks. This will call carpup/carpdown with the
# interface (carp0, carp1) as the first parameter.
notify 100 {
    match "system"          "CARP";
    match "type"            "MASTER";
    action "/usr/local/sbin/pfSctl -c 'interface carpmaster $subsystem'";
};

notify 100 {
    match "system"          "CARP";
    match "type"            "BACKUP";
    action "/usr/local/sbin/pfSctl -c 'interface carpbackup $subsystem'";
};

notify 100 {
    match "system"          "CARP";
    match "type"            "INIT";
    action "/usr/local/sbin/pfSctl -c 'interface carpbackup $subsystem'";
};

# When a USB keyboard arrives, attach it as the console keyboard.
attach 100 {
        device-name "ukbd0";
        action "kbdcontrol -k /dev/ukbd0 < /dev/console 2>/dev/null";
};

detach 100 {
        device-name "ukbd0";
        action "kbdcontrol -k /dev/kbd0 < /dev/console 2>/dev/null";
};

#
# Signal upper levels that an event happened on ethernet class interface
#
notify 0 {
        match "system"          "IFNET";
        match "type"            "LINK_UP";
        media-type              "ethernet";
        action "/usr/local/sbin/pfSctl -c 'interface linkup start $subsystem'";
};

notify 0 {
        match "system"          "IFNET";
        match "type"            "LINK_DOWN";
        media-type              "ethernet";
        action "/usr/local/sbin/pfSctl -c 'interface linkup stop $subsystem'";
};

#
# Signal upper levels that an event happened on 802.11 class interface
#
notify 0 {
        match "system"          "IFNET";
        match "type"            "LINK_UP";
        match "subsystem"       "[a-z]+[0-9]+_wlan[0-9]+";
        action "/usr/local/sbin/pfSctl -c 'interface linkup start $subsystem'";
};

# Notify all users before beginning emergency shutdown when we get
# a _CRT or _HOT thermal event and we're going to power down the system
# very soon.
notify 10 {
        match "system"          "ACPI";
        match "subsystem"       "Thermal";
        match "notify"          "0xcc";
        action "logger -p kern.emerg 'WARNING: system temperature too high, shutting down soon!'";
};

也许这对你有用

相关内容