关于 PassTunnel
PassTunnel 是面向 OpenVPN 和 FortiGate SSL VPN 配置的开源 macOS 应用,将 TOTP 密钥存于 Keychain,并在连接时处理验证码。其 MCP 服务让 AI 客户端查看 VPN 状态和日志、排查问题,同时不泄露密码或验证码。
主要功能
- 01OpenVPN 和 FortiGate SSL VPN 配置
- 02TOTP 存储与验证码生成
- 03查看 VPN 状态和日志
- 04用于连接与验证码任务的 CLI
- 05可选的只读 MCP 访问
适用场景
- 01检查活动 VPN 配置的状态
- 02查看 VPN 日志以排查连接问题
- 03让 AI 客户端检查 VPN 而不暴露机密
MCP 相关
`passtunnel mcp` 可运行 MCP 服务,让兼容客户端检查 VPN 状态、读取日志并诊断问题。除非允许连接操作,否则访问为只读;密码、密钥和验证码不会提供给客户端。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
PassTunnel
连接 VPN,从此无需再输入一次性验证码。
PassTunnel 是一款适用于 OpenVPN 和 FortiGate SSL VPN 的开源 macOS 应用。它会将你的 TOTP 密钥保存在 Keychain 中,并在每次连接时填入当前验证码(以及你的密码)。
网站 · 功能 · 安装 · 快速入门 · 验证码格式 · 命令行 · 与 AI 助手配合使用 · 常见问题 · 安全 · 项目 · Türkçe
功能
一次性验证码,轻松搞定
- 不再手动输入验证码。 TOTP 密钥保存在 macOS 钥匙串中;点击“连接”时,PassTunnel 会生成验证码并与密码一同发送。如果当前验证码窗口剩余时间不超过 5 秒,它会等待新验证码,而不是争分夺秒(此设置默认开启)。已发送的验证码绝不会再次发送。
- 支持服务器要求的任意格式。 可将验证码追加或前置,也可使用
password:code、password,code,或包含任意字面文本的自定义模板;还可以单独发送验证码(OpenVPN 静态质询、FortiGate OTP 字段)。请参阅配置验证码格式。 - 验证器风格的主窗口。 侧边栏列出每个配置及其状态和实时验证码;选中的配置会以大号数字显示验证码、倒计时环以及服务器实际收到的内容。点击验证码即可复制;1 分钟后剪贴板会自动清空(也可在“设置”中设为 30 秒或 2 分钟),除非你在此期间复制了其他内容。验证码可以设为隐藏,点击后才显示。
- 扫描二维码导入。 拖入服务提供商二维码的屏幕截图、选择图片或从剪贴板粘贴;也可以(macOS 14 及更高版本)直接扫描屏幕上的二维码,例如浏览器中的二维码,无需保存截图。数字位数、周期和算法(SHA-1/256/512)均从
otpauth://链接中读取。也支持粘贴 Base32 密钥或otpauth://链接。 - 自动输入(可选,默认关闭)。 开启全局快捷键后,按 ⌃⌥C 即可在当前聚焦的字段中输入验证码(菜单栏面板中也可使用),适用于仍要求输入验证码的网站门户和其他场景。需要辅助功能权限,但只有开启此功能时才会请求该权限。
- 使用 Touch ID 确认(可选,按配置单独设置)。 连接前和显示验证码前,需通过 Touch ID 或 Mac 密码确认(命令行也可设置为仅在连接前询问);此时保存的密钥会使用 Mac 安全隔区中的密钥进行加密,因此一键连接需要你本人确认,而不仅仅是解锁 Mac。
VPN 客户端
- 支持 OpenVPN 和 FortiGate SSL VPN,内置签名版
openvpn和openfortivpn。无需安装其他软件。 - 菜单栏面板。 显示所有已固定或正在使用的配置及其状态和实时验证码,并提供连接或断开开关,以及复制和输入当前验证码的功能。彩色徽章(五种配色)会标记需要注意的配置;连接意外中断时还会显示红点。
- 保持连接。 可选的退避式自动重连、VPN 内部的健康检查主机、唤醒后重连、登录时连接指定配置,以及服务器端会话时限即将到期前的提醒。
- 可同时连接多个 VPN,每个 VPN 都有独立的状态、日志和设置。
- 可分享的配置。 可为团队导出
.passtunnel文件,其中绝不包含密码、TOTP 密钥或用户名。 - 命令行工具。 支持
passtunnel connect、passtunnel code -c、--json输出、稳定的退出代码和 Shell 补全;功能与应用相同。 - 兼容 AI 助手。
passtunnel mcp是 MCP 服务,因此 Claude Code、Claude Desktop 和其他 MCP 客户端可以检查你的 VPN、读取日志并诊断问题。除非你允许连接,否则仅提供只读访问;绝不会提供密码、密钥或验证码。 - 无需 sudoers 规则,也无需每次连接时输入管理员密码。 一个小型特权辅助程序通过 macOS 自带的
SMAppService注册并经一次批准后运行;它只会运行应用内附带且经过签名的 VPN 工具,并使用经过清理的配置。请参阅 SECURITY.md。 - 用户界面支持英语和土耳其语(遵循 macOS 语言设置)。
工作原理
PassTunnel.app ──XPC──▶ PassTunnelHelper (root) ──▶ bundled openvpn / openfortivpn
│ (code-signature checked) │
├─ Keychain: password + TOTP secret └─ management socket (OpenVPN),
└─ ~/Library/Application Support/PassTunnel log file, status ──▶ back to the app
- 点击 Connect。应用会从 Keychain 读取密码和 TOTP 密钥,计算当前验证码,并构造服务端所需的内容(例如
secret123456)。 - 应用通过 XPC 将请求交给特权辅助程序。辅助程序只接受经过签名的 PassTunnel 应用,检查配置文件夹是否归你所有,清理 OpenVPN 配置(或根据输入的字段自行写入 openfortivpn 配置),然后启动捆绑的工具;只有在检查实际加载的代码的签名后,才会允许该工具运行。
- 应用跟踪连接状态(通过只有你的用户才能打开的管理套接字监测 OpenVPN,通过日志监测 FortiGate),并在窗口和菜单栏中显示状态。
完整的安全模型(包括不受保护的内容)请参阅 SECURITY.md。代码布局见 docs/ARCHITECTURE.md。
安装
需要在配备 Apple silicon 的 Mac 上运行 macOS 13 Ventura 或更高版本。
下载
下载磁盘映像,打开后将 PassTunnel 拖到 Applications。从该文件夹启动应用:辅助程序只能从 Applications 文件夹安装。应用由 Developer ID 签名,并经 Apple 公证。变更内容请见 发行说明。
PassTunnel 会自动更新(设置 → 更新);更新经过签名和检查后才会安装。更新后,只要没有活动的 VPN 连接,辅助程序就会自动更新(仅当 PassTunnel 从 Applications 文件夹运行时)。
Homebrew
brew trust passtunnel/tap
brew install --cask passtunnel/tap/passtunnel
从 Homebrew 6 起,只有在信任第三方 tap 后才会加载其中的 cask,因此需要先运行第一行命令。该 cask 也会链接 passtunnel 命令。更新通过应用本身进行,因此 brew upgrade 不会更新它,除非你运行 brew upgrade --greedy。
从源代码构建
需要 Xcode 15.3 或更高版本(Swift 5.10,以及用于土耳其语字符串的 xcstringstool)和 Homebrew,它会提供捆绑到应用中的 VPN 工具:
brew install openvpn openfortivpn openconnect
git clone https://github.com/passtunnel/passtunnel.git
cd passtunnel
scripts/build-app.sh # → build/PassTunnel.app (ad-hoc signed)
build-app.sh 会构建发布版二进制文件、组装应用包、将 openvpn、openfortivpn、openconnect(用于即将推出的 Cisco AnyConnect 支持)及其库复制到应用中(通过 scripts/bundle-tools.sh,并附带相应的许可证文件),使用这些指定工具和库的代码签名哈希编译辅助程序,然后从内到外使用强化运行时为所有内容签名。临时签名构建会在不启用库验证的情况下为应用签名:临时签名没有 Team ID,否则 macOS 会拒绝将 Sparkle.framework 加载到应用中。
重要
辅助程序只与使用项目 Developer ID Team ID 签名的应用通信,也只运行使用该 ID 签名的工具。 临时签名构建可用于窗口、验证码、二维码导入、配置文件和 CLI,但无法连接。要使用自己的构建进行连接,请在
Sources/PassTunnelShared/Identifiers.swift中设置teamID,并使用你的证书签名:scripts/build-app.sh --sign "Developer ID Application: Your Name (TEAMID)"然后将
build/PassTunnel.app移至/Applications,再安装辅助程序。
快速开始
如果没有任何配置文件,窗口会打开并显示 添加首个 VPN:
- 安装辅助工具。 底部的卡片会说明它的用途。点击 安装辅助工具, 然后在 系统设置 → 通用 → 登录项 中启用 PassTunnel(macOS 会询问一次)。 你也可以稍后在 设置 → 辅助工具 中进行此操作。
- 添加 VPN。 将文件拖到虚线区域,或选择其他添加方式之一。
添加配置文件
点击边栏底部的 +(同一视图,标题为 添加 VPN),或将文件拖到窗口上。文件菜单中也有相同的选项:
| 你有…… | 操作 |
|---|---|
OpenVPN 文件(.ovpn / .conf) | 将文件拖到虚线区域,或点击 选择文件…(文件 → 导入 .ovpn…)。保存任何内容之前,你可以先查看文件内容;文件引用的文件(ca ca.crt、tls-auth ta.key 1,……)会自动嵌入。 |
| FortiGate 网关 | 手动输入详细信息,选择 FortiGate(文件 → 新建 FortiGate 配置文件…),然后输入主机和端口,并点击 获取指纹以固定网关证书(SHA-256)。 |
同事发来的 .passtunnel 文件 | 双击它(或从 AirDrop 打开),或将它拖到窗口上。然后添加你自己的用户名、密码和 TOTP 密钥。 |
| 身份验证器的二维码 | 扫描屏幕上的二维码(macOS 14 及更高版本)或 使用二维码图像,也可以将屏幕截图拖到窗口或编辑器中。 |
然后打开配置文件编辑器(点击工具栏中的 编辑):
- **登录信息:**用户名(留空则每次都会询问)和密码,保存在 Keychain 中。 在 高级 中,也可以改为每次询问密码,或不使用密码(仅使用证书的 OpenVPN)。
- **一次性验证码:**扫描屏幕上的二维码(macOS 14 及更高版本)、选择二维码图像或粘贴密钥(也可以将屏幕截图拖到卡片上), 然后在保存前将实时验证码与手机上的验证码进行比对。验证码格式用于设置验证码的发送方式; 服务器接收内容会显示发送结果,并隐藏密码。在 高级 中,也可以改为每次询问验证码或不使用验证码。
只有点击 保存后,密钥才会写入 Keychain。
连接
点击 连接。如果配置文件需要尚未保存的信息(例如,密码设为每次询问),系统会弹出一个小窗口,只询问所需信息,并预先填入验证码。
在边栏中选择配置文件,然后点击 连接;如果连接失败,系统会说明原因并提供 重试选项。无论身处何处,都可以使用菜单栏面板执行相同操作:每个已固定或正在使用的配置文件都有一个开关和实时验证码,并提供用于复制当前验证码的选项(自动输入开启时,还可以输入验证码):
可选的全局快捷键(设置 → 快捷键,默认关闭):⌃⌥V 连接或断开默认配置文件,⌃⌥C 复制当前验证码,或在自动输入开启时输入验证码。
不同服务器对一次性代码的接收方式各不相同。请在编辑器的 代码格式 弹出菜单中为每个配置文件选择格式。
与密码一起发送(Append、Prepend、password:code、password,code、Custom template):使用模板将代码和密码合并为一个密码。{password} 和 {otp} 会被替换;其他文本将按原样发送。模板必须包含 {otp};{password} 可选。
密码为 secret,代码为 123456 时:
| 格式 | 模板 | 作为密码发送 |
|---|---|---|
| Append(默认) | {password}{otp} | secret123456 |
| Prepend | {otp}{password} | 123456secret |
| Password:code | {password}:{otp} | secret:123456 |
| Password,code | {password},{otp} | secret,123456 |
| Custom | {password}#{otp} | secret#123456 |
| Custom(仅代码) | {otp} | 123456 |
分别发送:密码和代码各自单独发送:
- **OpenVPN:**作为静态质询响应(
SCRV1:…)。导入的.ovpn包含static-challenge时,PassTunnel 会自动选择此方式。 - **FortiGate:**通过 openfortivpn 的单独 OTP 字段发送。新建 FortiGate 配置文件时,默认使用此方式。
更改格式时,编辑器的 服务器接收内容 会显示使用配置文件中的用户名和实时验证码生成的结果;密码始终会被遮蔽。
命令行
在 设置 → 通用 → 命令行工具 中安装 passtunnel 命令。该命令是指向 /usr/local/bin 中应用程序二进制文件的符号链接;如果该文件夹不可写,则会链接到 ~/.local/bin。配置文件 ID 根据配置文件名称生成(Work → work)。
passtunnel # status of all profiles
passtunnel connect # connect the default profile
passtunnel connect work # connect a specific profile
passtunnel code work -c # print the live code and seconds left, copy it (for 1 min by default)
passtunnel status work --json # exit code 3 when not connected
passtunnel disconnect --all
passtunnel import ~/Downloads/work.ovpn --name Work
passtunnel secret work password # prompts without echo
pbpaste | passtunnel secret work totp # Base32 secret or otpauth:// link from stdin
passtunnel set work otp_mode=totp otp_template=prepend
passtunnel set work otp_template='{password}:{otp}'
passtunnel set work auto_reconnect=true health_host=10.0.0.1
passtunnel add Lab --type forti
passtunnel set lab host=203.0.113.10 port=443 username=sam
passtunnel log work -f
passtunnel log work --activity # what PassTunnel did: connecting, codes, sign-in, drops
passtunnel helper status
passtunnel diagnose --check-clock # what would stop a connect; is the clock off?
passtunnel completion zsh > ~/.zfunc/_passtunnel
passtunnel set ID key=value… 接受与编辑器相同的设置;passtunnel help set 会列出可用键,passtunnel help 会列出所有命令。
**用于脚本:**每个命令都支持 --json(结果输出到 stdout,错误格式为
{"error":{"code":…,"message":…}})、--no-input(绝不在终端上询问;也可设置
PASSTUNNEL_NO_INPUT=1)和 --no-auth-prompt(不显示 Touch ID,而是直接失败);
connect --wait --timeout 90 可限制等待时间。退出码:0 表示成功,1 表示错误,2 表示用法错误,3 表示未找到或未连接,4 表示确认已取消或无法确认,5 表示辅助程序缺失或已过时,6 表示连接失败,7 表示超时。对象和代码的说明见
docs/CLI-JSON.md。
passtunnel connect work --timeout 90 --no-input --json
passtunnel status --json | jq '.[] | select(.state == "connected") | .id'
与 AI 助手配合使用(MCP)
passtunnel mcp 会在标准输入和输出上运行 Model Context Protocol 服务,使 AI 助手能够回答“我的 VPN 是否已连接?”,读取连接失败日志并告诉你问题所在。
| 工具 | 功能 |
|---|---|
list_profiles | 列出配置文件及其类型、状态、连接时是否需要 Touch ID、是否自动重新连接、是否在登录时连接 |
get_status | 显示状态、隧道 IP、开始时间、上次错误及原因(登录被拒、服务器无法访问或未找到等;以及是否已发送登录信息);是否已安装辅助程序且为最新版本 |
get_logs | 显示配置文件 VPN 日志的最后几行(最多 500 行),并对看起来像凭据的内容进行隐藏;使用 source: "activity" 时,显示 PassTunnel 实际执行的操作(连接、等待验证码、登录被接受或拒绝、连接中断),不含密码或验证码数字 |
diagnose | 显示应用版本和位置、辅助程序状态、各个随附 VPN 工具能否在此 macOS 版本上启动(使用 --version 运行)、Mac 是否联网以及所用网络(仅系统自身的判断,不会联系任何对象),以及每个配置文件的配置、服务器和已保存凭据是否就绪、上次时钟测量结果;使用 check_clock 时,还会询问 Apple 的时间服务器,检查时钟偏差 |
connect、disconnect | 仅在使用 --allow-connect 时可用 |
默认只读。 不使用 --allow-connect 时,助手只能查看,不能操作。使用该参数后,助手可以连接和断开配置文件;启用了 Confirm with Touch ID 的配置文件仍会在 Mac 上显示 Touch ID 提示,只有确认后才会执行操作。没有用于验证码、密码或机密信息的工具,也没有用于创建、修改或删除配置文件的工具。该服务器拥有与 passtunnel 命令相同的访问权限;其含义(包括提示词注入)请参阅 SECURITY.md。
Claude Code(使用 shell 的 PATH;passtunnel 命令随 Homebrew cask 提供,也可通过“设置” →“通用” →“命令行工具”获取):
claude mcp add passtunnel -- passtunnel mcp # read-only
claude mcp add passtunnel -- passtunnel mcp --allow-connect # may also connect and disconnect
如果没有 passtunnel 命令,可直接使用应用二进制文件:
claude mcp add passtunnel -- /Applications/PassTunnel.app/Contents/MacOS/PassTunnel mcp
Claude Desktop: 从最新版本下载 PassTunnel-mcp-<version>.mcpb 并双击;Claude Desktop 会打开 MCP bundle 并安装。其设置 Allow connect and disconnect(默认关闭)会添加 --allow-connect。该 bundle 仅包含一个用于启动应用内置服务器的启动器,因此必须将 PassTunnel 安装在 /Applications 中;否则服务器会停止运行并提示安装。此 bundle 也是 PassTunnel 在 MCP Registry 中条目 io.github.PassTunnel/passtunnel 的软件包。
也可以手动配置。Claude Desktop 启动服务器时不会使用 shell 的 PATH,因此请填写完整路径。在 ~/Library/Application Support/Claude/claude_desktop_config.json 中:
{
"mcpServers": {
"passtunnel": {
"command": "/Applications/PassTunnel.app/Contents/MacOS/PassTunnel",
"args": ["mcp"]
}
}
}
上方的 Cursor 和 VS Code 按钮会添加相同的只读条目。在 args 中添加 "--allow-connect" 即可允许连接。其他 MCP 客户端的配置方式相同:命令为应用二进制文件(或 passtunnel),参数为 mcp。诊断信息会输出到 stderr。服务器使用 MCP 2026-07-28 协议;对于通过 initialize 握手启动的客户端,还支持 2025-11-25 至 2024-11-05 版本。
共享配置文件
⋯ → 分享…(或 passtunnel export work -o work.passtunnel)会创建一个 .passtunnel 文件,其中包含连接设置、外观、验证码格式,以及 OpenVPN 配置文件(如有)。
文件中绝不会包含密码、TOTP 密钥或用户名;嵌入在 OpenVPN 配置中的用户名和密码或代理凭据也会被移除。接收者双击该文件(或从 AirDrop 打开)即可添加自己的配置。嵌入的 OpenVPN 配置可能包含证书和密钥,因此文件会以 0600 权限写入;请像分享 .ovpn 文件一样谨慎分享。
常见问题
为什么 PassTunnel 需要特权辅助程序?
创建隧道接口以及更改路由和 DNS 需要 root 权限。PassTunnel 不会在每次连接时都要求你输入管理员密码,也不会添加 sudoers 规则,而是通过 `SMAppService` 注册一个小型 launchd 守护进程,你只需在“系统设置” → “通用” → “登录项”中批准一次。此辅助程序只接受来自已签名 PassTunnel 应用的请求,只运行随应用提供的 `openvpn` 和 `openfortivpn`(它们及其库都来自 root 所有的副本),且仅在检查签名后才运行这些程序,并拒绝危险的 OpenVPN 指令。详见 [SECURITY.md](SECURITY.md)。我的密码和 TOTP 密钥存储在哪里?
它们存储在你的登录钥匙串中,作为通用密码,服务名称为 PassTunnel(账户为
<profile-id>/password 和 <profile-id>/totp)。它们不会同步到 iCloud 钥匙串;迁移助理和备份会像迁移其他登录钥匙串内容一样,将它们带到新 Mac 上。导入的 .ovpn 中嵌入的用户名和密码也会移入钥匙串。配置文件设置和 OpenVPN
配置存放在
~/Library/Application Support/PassTunnel/ 中,只有你的用户可以读取。除发送到你的 VPN 服务外,不会将任何内容发送到其他地方。
支持哪些 VPN 类型?
OpenVPN(OpenVPN 2.x 客户端配置:用户名/密码、仅证书和静态质询设置)以及 FortiGate SSL VPN(通过 openfortivpn)。其他类型可以作为新后端添加;请参阅参与贡献。
我的 .ovpn 文件被拒绝了。为什么?
辅助程序以 root 身份运行 OpenVPN,因此会拒绝运行脚本、加载插件或读写任意文件的指令。导入文件时,PassTunnel 会自行处理的指令(例如,带有 script-security 2 的 up 和 down 等脚本、log、management、daemon……)会被跳过:添加配置文件前,你会看到这些指令;它们会以注释形式保留在已保存的配置中。涉及安全性的指令(tls-verify、plugin、config、不在 .ovpn 同一目录下的 ca 文件……)仍会导致文件被拒绝,错误信息会列出所有此类指令。导入时引用的文件会自动嵌入。完整列表见
SECURITY.md。
我的 .p12 证书无法加载(“unsupported”、“RC2-40-CBC”)。为什么?
较旧的 PKCS#12 文件使用 RC2 加密,OpenSSL 3 和 4 只能通过 legacy provider 读取。PassTunnel 的 OpenVPN 不会加载任何 OpenSSL provider 或模块(它们会来自应用之外的路径),因此此类文件无法直接使用。请使用 OpenSSL 3(例如 Homebrew 的版本,brew install openssl@3;macOS 自带的 /usr/bin/openssl 是 LibreSSL,没有 -legacy 选项)重新导出一次,并使用现代加密方式:
OPENSSL="$(brew --prefix openssl@3)/bin/openssl"
"$OPENSSL" pkcs12 -legacy -in old.p12 -nodes -out temp.pem # asks for the old password
"$OPENSSL" pkcs12 -export -in temp.pem -out new.p12 # asks for a new password
rm temp.pem # holds the unencrypted key
然后在配置中使用 new.p12(或者重新导入 .ovpn,以便将其嵌入)。
没有 TOTP 代码也能使用吗?
可以。对于普通的用户名/密码或仅证书 VPN,请将一次性代码设为 None;如果你使用硬件令牌或短信验证码,请设为 Ask each time。
如何彻底卸载 PassTunnel?
-
断开所有配置文件的连接。
-
移除辅助程序:“设置” → “辅助程序” → 移除辅助程序…,或运行
passtunnel helper uninstall。 请在删除应用之前先完成此操作。 -
关闭登录时启动:“设置” → “通用” → 登录时打开,显示在菜单栏中。检查“系统设置” → “通用” → “登录项”下是否已无相关项目。
-
退出 PassTunnel,并将
PassTunnel.app移到废纸篓。 -
删除你的数据:
rm -rf ~/Library/Application\ Support/PassTunnel # profiles, configs, logs, preferences defaults delete com.furkanprlk.passtunnel 2>/dev/null # open-at-login question rm -f /usr/local/bin/passtunnel ~/.local/bin/passtunnel # CLI symlink, if installed -
**删除钥匙串项目:**打开“钥匙串访问”并搜索
PassTunnel,或运行while security delete-generic-password -s PassTunnel >/dev/null 2>&1; do :; done(在应用中删除配置文件也会移除其钥匙串项目。)
辅助程序的运行时文件夹 /var/run/passtunnel 归 root 所有,并会在重启时清空。
构建与测试
swift build # debug build of the app, CLI and helper
swift test # unit tests
scripts/build-app.sh # full app bundle in build/PassTunnel.app
# The portable library (PassTunnelKit) for iOS
xcodebuild -scheme PassTunnelKit -destination 'generic/platform=iOS Simulator' build
发布流程(签名、公证、Sparkle 源和 Homebrew cask)见 docs/RELEASING.md。
测试绝不会触碰你的真实数据:它会将 PASSTUNNEL_HOME 指向临时文件夹,并通过
PASSTUNNEL_KEYCHAIN_SERVICE 使用一次性 Keychain 服务。
**屏幕截图。**应用可以在屏幕外将主界面渲染为 PNG 文件,并使用示例配置文件、 临时支持文件夹和临时 Keychain 服务。屏幕上不会显示任何内容,也不会触碰 VPN、 辅助程序或系统设置:
swift build
PASSTUNNEL_RENDER=/tmp/passtunnel-shots "$(swift build --show-bin-path)/PassTunnel"
这会生成主窗口(浅色/深色、首次运行、每种配置文件状态、隐藏和锁定的代码、导入审核、错误状态)、凭据表单、菜单栏面板、状态项在每种配色方案下的徽章、所有设置选项卡、配置文件编辑器状态,以及设计系统的令牌和组件。
docs/images 中的图片由此生成。
参与贡献
欢迎提交问题和拉取请求。较大的改动请先提交问题。
开发在 dev 分支上进行:每个问题对应一个分支,向 dev 提交拉取请求,标题使用
Conventional Commits 格式(feat: …、fix: …),并采用压缩合并。
将 dev 合并到 main 即会发布。工作流、标题规则和检查见
CONTRIBUTING.md。
- 阅读 docs/ARCHITECTURE.md(目标平台、存储、辅助程序协议、安全 规则)以及 docs/APP.md(应用和 CLI 行为)。
- **新增 VPN 类型意味着新增后端:**添加一个新的
VPNType分支、所需的配置文件字段、 一个配置由类型化字段生成或经过严格验证的辅助程序请求、一个像openvpn/openfortivpn一样 随应用捆绑并经过签名检查的工具,以及在ConnectionManager中进行状态跟踪。绝不要让辅助程序运行 客户端提供的路径或原始配置。 - 面向用户的字符串须通过
String(localized:)处理,并在Sources/PassTunnel/Resources/Localizable.xcstrings中提供土耳其语翻译。 - 如果改动涉及手机应用共用的行为(代码、otpauth 链接、OpenVPN 配置、共享文件、
slug、配置文件合并),也要更新
fixtures/中的黄金测试用例。 - 除用于更新的 Sparkle 和用于在 Linux 上提供 CryptoKit API 的 swift-crypto 外,不使用第三方 Swift 依赖项。提交 PR 前请运行
swift test。
项目
PassTunnel 由一人以开源方式维护。
- GOVERNANCE.md:如何做出决策、各自负责什么、谁持有哪些访问权限,以及当前的单点风险。
- ROADMAP.md:未来一年的计划,以及不在计划中的事项。
- CODE_OF_CONDUCT.md:贡献者公约,以及如何举报行为问题。
- SECURITY.md:保护范围与非保护范围、受支持的版本、漏洞报告方式和处理流程,以及所用的密码学技术。
- docs/ASSURANCE.md:保障论证(威胁模型、信任边界、设计原则、应对的弱点)。
- CONTRIBUTING.md:工作流、编码规范、测试政策和问题报告方式。
许可证
PassTunnel 采用 MIT 许可证 发布。版权所有 © 2026 Furkanprlk。
该应用捆绑了 openvpn(GPL-2.0)、openfortivpn(GPL-3.0)及其库(OpenSSL、LZO、
LZ4、pkcs11-helper),以及 openconnect(LGPL-2.1,目前尚未使用)及其库(GnuTLS、nettle、
GMP 等,大多采用 LGPL)。这些是与 PassTunnel 一同分发的独立程序,各自遵循其许可证。请参阅 THIRD_PARTY_NOTICES.md。完整许可证文本位于应用内的 Contents/Resources/licenses,也可通过 设置 → Helper → 显示许可证… 查看。
PassTunnel 与 OpenVPN Inc. 或 Fortinet 均无关联。OpenVPN 和 FortiGate 是其各自所有者的商标。
土耳其语
PassTunnel 是一款面向 Apple silicon Mac、适用于 macOS 13 及更高版本的开源 VPN 应用。它只需单击一下,即可连接 OpenVPN 和 FortiGate SSL VPN。您的 TOTP 密钥保存在钥匙串(Keychain)中;PassTunnel 会在连接时替您发送当前的一次性验证码和密码。您无需查看手机上的验证码再手动输入。
您可以为每个配置文件选择验证码的发送方式:附加到密码末尾或开头、使用类似 密码:验证码 的分隔格式、使用自定义模板,或作为单独字段发送。主窗口会像身份验证器应用一样显示实时验证码。菜单栏面板会显示每个配置文件的状态和验证码;连接中断时,会显示彩色徽章提醒。二维码可从屏幕截图中读取。您可以通过不含凭据的 .passtunnel
文件与团队共享配置文件,也可以使用 passtunnel 命令行工具执行相同操作。使用 passtunnel mcp,Claude 等 AI 助手可以读取 VPN 状态并诊断问题(默认仅允许读取,不会提供密码、密钥或验证码)。
您也可以为每个配置文件启用“连接前要求 Touch ID”选项:PassTunnel 会在连接和显示验证码前,要求您使用 Touch ID 或 Mac 密码进行确认,并使用 Mac 的 Secure Enclave 中的密钥加密已保存的密码和 TOTP 密钥。界面支持土耳其语和英语,并会遵循 macOS 的语言设置。
安装: 下载已签名并经过公证的
磁盘映像,
打开后将 PassTunnel 拖入应用程序文件夹
(发行说明),或使用 Homebrew 安装:
brew trust passtunnel/tap,然后运行 brew install --cask passtunnel/tap/passtunnel(Homebrew 6
及更高版本仅在您信任第三方 tap 时才会安装其中的 cask)。应用会自动保持更新(设置 → 更新)。要从源代码构建,请参阅上文的
从源代码构建部分。
首次打开时,系统会提示您安装以管理员权限运行 VPN 工具的小型辅助程序(helper)。
您只需在系统设置 → 通用 → 登录项中确认一次。辅助程序只会运行应用内已签名的 openvpn 和 openfortivpn 副本;无需 sudoers 规则。有关安全模型,请参阅 SECURITY.md;其他内容请参阅本文档的英文部分。
项目: 有关治理模型,请参阅 GOVERNANCE.md;有关路线图,请参阅 ROADMAP.md; 有关行为准则,请参阅 CODE_OF_CONDUCT.md;有关保证分析,请参阅 docs/ASSURANCE.md;有关贡献指南,请参阅 CONTRIBUTING.md (文档为英文)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。