You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fedora下FortiClient VPN自动重连及Expect脚本故障排查

修复FortiClient VPN自动重连的Expect脚本及Python替代方案

修复Expect脚本

你的脚本存在几个关键问题,直接导致无法正确响应输入提示:

  • spawn命令语法错误:不能将整个命令用引号包裹,Expect会把它当作单个可执行文件路径,需分开传递命令与参数
  • 错误使用echo:Expect中向终端输出信息需用send_user,而非shell的echo命令
  • 多余的sleep:expect会自动等待目标输出,强制sleep可能错过输入提示时机
  • 确认提示匹配逻辑:重复的提示可通过正则表达式匹配,且发送确认指令后需添加回车\r
  • 断开命令执行方式:直接写forticlient vpn disconnect在Expect中无法正确执行,需用exec调用外部命令

修复后的完整脚本:

#!/usr/bin/expect -d
set timeout -1

# 断开现有VPN连接
exec forticlient vpn disconnect

# 配置变量
set username "{{USER-NAME}}"
set password "{{USER-PASSWORD}}"
set vpn_name "{{VPN-NAME}}"

# 启动VPN连接命令
spawn forticlient vpn connect $vpn_name -u $username
send_user "命令已执行\n"

# 匹配密码提示并发送密码
expect "password:"
send "$password\r"

# 匹配确认提示(兼容重复输出的情况)
expect -re "Confirm \\(y/n\\) \\[default=n\\]:"
send "y\r"

# 等待连接流程结束(可选,根据实际输出调整)
expect eof

使用说明:替换{{USER-NAME}}、{{USER-PASSWORD}}、{{VPN-NAME}}为实际值,添加执行权限后直接运行。

Python实现方案(基于pexpect)

如果更熟悉Python生态,可以用pexpect库实现交互式连接,还能轻松加入状态监控与自动重连逻辑:

  1. 安装依赖:
sudo dnf install python3-pexpect
  1. 编写自动重连脚本(vpn_auto_reconnect.py):
import pexpect
import time
import subprocess

# 配置参数
VPN_NAME = "{{VPN-NAME}}"
USERNAME = "{{USER-NAME}}"
PASSWORD = "{{USER-PASSWORD}}"
CHECK_INTERVAL = 60  # 每60秒检查一次VPN状态

def check_vpn_status():
    """检查VPN是否处于连接状态"""
    try:
        result = subprocess.run(
            ["forticlient", "vpn", "status"],
            capture_output=True,
            text=True,
            check=True
        )
        return "Connected" in result.stdout
    except subprocess.CalledProcessError:
        return False

def connect_vpn():
    """执行VPN完整连接流程"""
    # 先断开现有连接
    subprocess.run(["forticlient", "vpn", "disconnect"], capture_output=True)
    time.sleep(2)
    
    try:
        child = pexpect.spawn(f"forticlient vpn connect {VPN_NAME} -u {USERNAME}")
        # 匹配密码提示并发送
        child.expect("password:")
        child.sendline(PASSWORD)
        # 匹配确认提示并发送
        child.expect(r"Confirm \(y/n\) \[default=n\]:")
        child.sendline("y")
        # 等待连接完成
        child.expect(pexpect.EOF, timeout=30)
        print("VPN连接成功")
    except pexpect.TIMEOUT:
        print("VPN连接超时")
    except pexpect.EOF:
        print("VPN连接进程意外退出")

def main():
    while True:
        if not check_vpn_status():
            print("VPN已断开,尝试重新连接...")
            connect_vpn()
        time.sleep(CHECK_INTERVAL)

if __name__ == "__main__":
    main()
  1. 后台运行方案:
    可以用nohup让脚本后台运行:
nohup python3 vpn_auto_reconnect.py &

或者配置systemd服务实现开机自启与自动重启:
创建服务文件/etc/systemd/system/vpn-auto-reconnect.service:

[Unit]
Description=FortiClient VPN Auto Reconnect Service
After=network.target

[Service]
User=你的用户名
ExecStart=/usr/bin/python3 /脚本绝对路径/vpn_auto_reconnect.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

启用并启动服务:

sudo systemctl daemon-reload
sudo systemctl enable --now vpn-auto-reconnect.service

内容的提问来源于stack exchange,提问作者David Fager

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:02:46