Harry-kp/vortix

GitHub: Harry-kp/vortix

Vortix 是一款轻量级终端 UI 工具,用于集中管理 WireGuard 和 OpenVPN 连接,提供实时遥测监控和流量泄漏防护。

Stars: 503 | Forks: 21

# Vortix [![CI](https://github.com/Harry-kp/vortix/actions/workflows/ci.yml/badge.svg)](https://github.com/Harry-kp/vortix/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/Harry-kp/vortix/blob/main/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Harry-kp/vortix/blob/main/CONTRIBUTING.md) [![Crates.io](https://img.shields.io/crates/v/vortix.svg)](https://crates.io/crates/vortix) [![Crates.io Downloads](https://img.shields.io/crates/d/vortix.svg)](https://crates.io/crates/vortix) [![npm](https://img.shields.io/npm/v/@harry-kp/vortix?logo=npm)](https://www.npmjs.com/package/@harry-kp/vortix) [![npm Downloads](https://img.shields.io/npm/dm/@harry-kp/vortix?label=npm%20downloads)](https://www.npmjs.com/package/@harry-kp/vortix) [![Homebrew](https://img.shields.io/badge/Homebrew-tap-orange?logo=homebrew)](https://github.com/Harry-kp/homebrew-tap) [![Nix Flake](https://img.shields.io/badge/Nix-flake-blue?logo=nixos)](https://github.com/Harry-kp/vortix#installation) [![macOS](https://img.shields.io/badge/macOS-000000?logo=apple&logoColor=white)](https://github.com/Harry-kp/vortix) [![Linux](https://img.shields.io/badge/Linux-FCC624?logo=linux&logoColor=black)](https://github.com/Harry-kp/vortix) [![Rust](https://img.shields.io/badge/Rust-1.85+-orange?logo=rust)](https://www.rust-lang.org/) [![GitHub Stars](https://img.shields.io/github/stars/Harry-kp/vortix?style=social)](https://github.com/Harry-kp/vortix) [![GitHub Sponsors](https://img.shields.io/github/sponsors/Harry-kp?logo=github)](https://github.com/sponsors/Harry-kp) 用于 WireGuard 和 OpenVPN 的终端 UI,提供实时遥测和泄漏防护。 ![Vortix Demo](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/f389439217045810.gif) ## 为什么选择 Vortix? 我想要一个单一的界面来: - 一目了然地查看连接状态、吞吐量和延迟 - 无需运行单独的工具即可检测 IPv6/DNS 泄漏 - 无需记住 CLI 参数即可在 VPN 配置文件之间切换 现有的选项(`wg show`、NetworkManager、Tunnelblick)要么缺乏实时遥测,要么需要 GUI。 | 功能 | Vortix | GUI 客户端 | 纯 CLI | |---------|:------:|:-----------:|:--------:| | 内存使用 | ~15MB | 200-500MB | ~5MB | | 启动时间 | <100ms | 2-5s | 即时 | | 实时遥测 | ✅ | ✅ | ❌ | | 泄漏检测 | ✅ | 部分 | ❌ | | 终止开关 | ✅ | ✅ | 手动 | | 键盘驱动 | ✅ | ❌ | ✅ | | 支持 SSH 连接 | ✅ | ❌ | ✅ | ## 功能 - **WireGuard 和 OpenVPN** — 自动检测 `.conf` 和 `.ovpn` 文件 - **多隧道** *(v0.4.0 新增)* — 同时连接多个 VPN 配置文件;注册表跟踪主要隧道和可寻址的次要隧道;支持每个配置文件的重试/自动重连;自动接管外部启动的隧道(在另一个终端运行 `wg-quick up X` 会在约 1 秒内显示在 TUI 中) - **高级遥测** — 实时吞吐量、延迟、**抖动** 和 **丢包率** - **地理位置** — 即时检测您出口 IP 的城市和国家 - **泄漏检测** — 实时监控 IPv6 泄漏和 DNS 泄漏 - **终止开关** — 平台原生防火墙(macOS 上是 PF;Linux 上是 `iptables` 或 `nftables`)。三种模式 — **关闭**(无防火墙)、**断开时阻止**(仅在 VPN 意外断开时启用)、**仅限 VPN**(无论 VPN 是启动还是关闭,防火墙始终保持启用 — 消除断开到重连之间的泄漏窗口)。支持多隧道:每个活动隧道的接口都会被列入白名单 - **会话事件日志** *(v0.3.0)* — 每个会话的 JSONL 事件日志存储在 `${XDG_DATA_HOME}/vortix/sessions/` 下,保留 30 天;对诊断和编写脚本很有用 - **按进程的 socket 审计** *(v0.3.0)* — `vortix audit` 通过按 PID 的 socket 清单来回答“此流量是否确实通过隧道路由?”;支持 Linux 和 macOS - **带版本的结构化输出** *(v0.3.0)* — 每个 `--json` 封包都带有 `schema_version` 字段(目前为 `2`),以便使用者可以检测到破坏性变更,而不是在运行时才发现它们 - **交互式导入** — 直接在 TUI 中轻松添加新配置文件 - **配置查看器** — 直接在 TUI 中检查配置文件配置 - **键盘驱动** — 无需鼠标 ## 平台支持 Vortix 目前主要在 macOS 上积极开发和使用。 Linux 支持是当前的重点,并且正在快速改进,CI 覆盖了 Ubuntu 和 Fedora。然而,Linux 环境在不同的发行版、防火墙后端、DNS 工具和权限模型之间仍然存在很大差异,因此可能仍然存在特定于发行版的问题。 如果您在 Linux 上使用 Vortix 并遇到问题,请提交一个 issue,并尽可能附上 `vortix report` 的输出。Ubuntu、Fedora 和 Arch 用户在测试候选发布版本和在正式发布前验证修复方面尤其有帮助。如果您想帮助测试 Linux 支持,请加入 [Linux 测试人员讨论](https://github.com/Harry-kp/vortix/discussions/184)。 ## 要求 ### 运行时依赖 | 依赖 | macOS | Linux | 用途 | |------------|-------|-------|---------| | `openvpn` | `brew install openvpn` | `apt install openvpn` | OpenVPN 会话 | | `wireguard-tools` | `brew install wireguard-tools` | `apt install wireguard-tools` | WireGuard 会话 | | `resolvconf` / `systemd-resolved` | 不适用(使用原生 DNS) | 自动检测;参见下方的 DNS 说明 | WireGuard DNS 管理(仅在非 resolved 的主机上) | | `iptables` 或 `nftables` | 不适用(使用 `pfctl`) | 预装 | 终止开关 | **DNS 工具说明:** 如果您的 WireGuard 配置文件包含 `DNS =` 指令,Vortix 会自行管理每个链接的 DNS: - **systemd-resolved 主机(默认开启 `services.resolved.enable = true` 的 Arch / Omarchy、NixOS、以及默认的 Fedora Workstation):** 不需要额外的包。Vortix 调用 `resolvectl`(随 systemd 一起提供)在内核接口上注册隧道的 DNS 服务器。不再需要这些发行版上的旧版 `systemd-resolvconf` / `openresolv` 垫片。 - **非 resolved 的 Linux(没有 resolved 的 Debian/Ubuntu 等):** Vortix 会回退到 `wg-quick` 内置的 `resolvconf` 路径 — 如果您的发行版没有提供此工具,请安装 `openresolv`(`sudo apt install openresolv`)。 - **Alpine/Void (OpenRC):** 作为通用回退方案,编辑 `/etc/resolv.conf`。 ### 构建依赖(仅源码安装) - Rust 1.85+(用于 `edition2024` 传递依赖;提供旧版 Rust 的发行版 — 例如 Ubuntu 24.04 的 apt — 对于源码构建需要使用 `rustup`) - macOS 12+ 或 Linux 内核 3.10+(对于原生 WireGuard 推荐使用 5.6+) ### 快速安装命令 **Ubuntu/Debian:** ``` sudo apt install wireguard-tools openvpn iptables systemd-resolved ``` **Fedora/RHEL:** ``` sudo dnf install wireguard-tools openvpn iptables systemd-resolved ``` **Arch Linux**(仅源码构建需要 — `pacman -S vortix` 会自动处理依赖): ``` sudo pacman -S wireguard-tools openvpn iptables ``` ## 安装 **Homebrew (macOS/Linux):** ``` brew install Harry-kp/tap/vortix ``` **npm/npx:** ``` npm install -g @harry-kp/vortix # 或无需安装直接运行: npx @harry-kp/vortix ``` **从 crates.io:** ``` cargo install vortix ``` **Arch Linux ([extra 仓库](https://archlinux.org/packages/extra/x86_64/vortix/)):** ``` pacman -S vortix ``` **快速安装 (二进制):** ``` curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Harry-kp/vortix/releases/latest/download/vortix-installer.sh | sh ``` **静态二进制文件 (Linux):** 从 [releases 页面](https://github.com/Harry-kp/vortix/releases) 下载 `x86_64-unknown-linux-musl` 版本。这是一个静态链接的二进制文件(不需要 glibc),但您仍然需要上述的运行时依赖(openvpn/wireguard-tools 和终止开关工具)。 **Nix (flakes):** ``` nix run github:Harry-kp/vortix # Run without installing nix profile install github:Harry-kp/vortix # Install to profile ``` **从源码:** ``` git clone https://github.com/Harry-kp/vortix.git cd vortix cargo install --path . ``` ### Linux:设置 sudo 访问权限 Vortix 需要 root 权限来管理 VPN 连接和防火墙规则。在 Linux 上,`sudo` 使用受限的 PATH(`/etc/sudoers` 中的 `secure_path`),其中**不包含** `~/.cargo/bin/` — 因此 `sudo vortix` 会失败并提示 `command not found`。 **修复(一次性):** ``` sudo ln -s ~/.cargo/bin/vortix /usr/local/bin/vortix ``` 完成此操作后,`sudo vortix` 将按预期工作。 **受影响的用户:** - `cargo install vortix` — 是 - Shell 安装程序 (`curl | sh`) — 是 - 从源码 (`cargo install --path .`) — 是 - `pacman -S vortix` (Arch) — **否**,安装到 `/usr/bin/` - `brew install` (Homebrew) — **否**,安装到 Homebrew 前缀 - `npm install -g` (npm) — **否**,安装到 npm 全局 bin - Nix (`nix profile install`) — **否**,安装到 Nix profile bin - macOS — **否**,sudo 保留用户 PATH ### Linux 支持说明 大部分日常开发都在 macOS 上进行。Linux 支持在 CI 中进行了持续测试,但真实世界的发行版覆盖范围仍在扩大。如果在您的 Linux 设置中某些行为有所不同,请将其视为有用的信号并报告,而不是认为这是预期行为。 ## 用法 Vortix 有两种模式:交互式 TUI 仪表板(默认)和无头 CLI(用于脚本、自动化和 AI 代理)。 ``` sudo vortix # Launch TUI dashboard (default) ``` ### CLI 命令 每个子命令都支持 `--json`(用于机器可读的输出)和 `--quiet`(用于静默操作,仅返回退出码)。 **连接(感知多隧道):** ``` sudo vortix up work-vpn # Connect to a profile sudo vortix up vpn-b --yes # Bypass the conflict gate (default-route # takeover / route overlap with another # active tunnel; non-interactive) sudo vortix down # Disconnect every active tunnel sudo vortix down work-vpn # Disconnect only the named profile sudo vortix down --force # Force-disconnect (SIGKILL) sudo vortix reconnect # Cycle every currently-Connected tunnel vortix status # Show connection state + telemetry vortix status --json # v2 envelope: data.connections[] + # data.primary (back-compat data.connection # populated when exactly one tunnel is up) vortix status --brief # One-line: "● Connected to work-vpn" vortix status --watch # Live updates every 2s vortix status --watch --json # NDJSON stream for monitoring ``` 多个隧道可以同时处于活动状态。拥有内核默认路由的隧道是*主要*隧道;次要隧道是*可寻址的*(仅在其声明的 `AllowedIPs` 上可达)。当 A 已经启动时运行 `vortix up B`,如果两者都声明拥有默认路由或者它们的 `AllowedIPs` 发生重叠,将会触发冲突门控 — 为脚本传递 `--yes` 可绕过此限制。 **配置文件管理:** ``` vortix list # List all imported profiles vortix list --names-only # Profile names for scripting vortix list --sort last-used # Most recently used first vortix import ./work.conf # Import a WireGuard profile vortix import ./configs/ # Bulk import from directory vortix show work-vpn # Display profile configuration vortix show work-vpn --raw # Raw config file contents vortix delete old-vpn --yes # Delete without confirmation vortix rename old-vpn new-vpn # Rename a profile ``` **安全:** ``` # Kill switch — 每种模式一个 label,用于 TUI、JSON envelope、 # CLI 输入和 CLI 输出。 # off 所有流量通过。如果 VPN 断开,将暴露真实 IP。 # block-on-drop 仅在 VPN 意外断开时阻止流量。 # vpn-only 仅允许 VPN 流量。没有 VPN 则无法联网。 sudo vortix killswitch off sudo vortix killswitch block-on-drop sudo vortix killswitch vpn-only vortix killswitch # Show current mode + behaviour sudo vortix release-killswitch # Emergency firewall release ``` **系统:** ``` vortix info # Config paths, versions, profile count vortix update # Self-update from crates.io vortix report # Generate bug report vortix completions bash >> ~/.bashrc # Shell completions vortix completions zsh > ~/.zfunc/_vortix ``` **高级子命令(socket 审计、daemon):** ``` # Per-process socket 审计 — “此流量是否确实通过 # 隧道进行路由?” 基于拉取的快照;支持 Linux + macOS。 vortix audit # tabular vortix audit --json # structured envelope vortix audit --pid 12345 # filter to one process vortix audit --vpn-only # only sockets on the tunnel # Daemon IPC — 将 engine 托管为长期运行的进程。Wire # contract + socket 绑定 + UID-gated accept 循环已就绪 # (目前一次仅支持单个 client;通过 daemon 路由 engine 是 # 后续工作)。 vortix daemon # default socket path vortix daemon --socket /tmp/vortix.sock # custom path ``` 引擎 FSM、JSONL 会话日志、分层设置和 sidecar 迁移都隐藏在现有的命令之后 — 日志路径会显示在 `vortix info` 输出中,迁移在启动时运行,并且 `settings.toml` 无论您是否创建都能正常工作。 有关升级指南以及 secret store、日志和 daemon 的选择性开启详情,请参阅 [`docs/MIGRATION.md`](https://github.com/Harry-kp/vortix/blob/main/docs/MIGRATION.md)。 **用于 AI 代理/脚本的 JSON 输出:** ``` # 每个命令上的结构化 JSON envelope vortix status --json # {"ok":true,"command":"status","data":{...},"next_actions":[...]} vortix list --json | jq '.data[].name' # Extract profile names # 用于监控的 NDJSON 流 vortix status --watch --json ``` **退出码** 是语义化且可编写脚本的: | 代码 | 含义 | |------|---------| | 0 | 成功 | | 1 | 常规错误 | | 2 | 权限被拒绝(需要 sudo) | | 3 | 未找到(配置文件不存在) | | 4 | 状态冲突(已连接、接管默认路由、路由重叠) | | 5 | 缺少依赖 | | 6 | 超时 | ### 快捷键 | 按键 | 动作 | |-----|--------| | `Tab` | 循环切换焦点(面板)。连接详情镜像侧边栏的选择 — 通过导航配置文件列表来切换隧道。 | | `1-9` | 连接到快捷槽位 1-9 | | `Enter` | 连接 / 切换配置文件 | | `d` | 断开焦点隧道(侧边栏行,或没有侧边栏焦点时的主要隧道) | | `D` | 断开所有活动的隧道(当 N > 1 时需要确认) | | `c` | 从连接详情中取消正在进行的 `Connecting` 配置文件 | | `r` | 重连 —循环每个已连接的隧道 | | `B` | "两者" — 从接管覆盖层连接两个隧道(多隧道) | | `i` | 导入配置文件(直接) | | `v` | 查看配置文件配置 | | `y` | 将公共 IP 复制到剪贴板 | | `K` | 切换终止开关 (Shift+K) | | `z` | 切换缩放视图(面板) | | `x` | 打开操作菜单(上下文) | | `b` | 打开批量菜单 | | `Del` | 删除配置文件(侧边栏) | | `q` | 退出应用程序 | ## 配置 ### 配置目录 默认情况下,vortix 将配置文件、身份验证凭证和日志存储在 `~/.config/vortix/` 中。 通过 CLI 参数或环境变量进行覆盖: ``` sudo vortix --config-dir /path/to/custom/dir # 或 export VORTIX_CONFIG_DIR=/path/to/custom/dir sudo vortix ``` 优先级:`--config-dir` 参数 > `VORTIX_CONFIG_DIR` 环境变量 > 默认路径。 当使用 `sudo` 运行时,vortix 会自动解析调用者的主目录(通过 `SUDO_USER`),因此配置文件位于*您*的主目录中,而不是 `/root/`。 ### 目录结构 ``` ~/.config/vortix/ ├── profiles/ VPN configuration files │ ├── work.conf WireGuard profile │ ├── work.meta.toml Sidecar metadata (new in v0.3.0; auto-generated) │ ├── office.ovpn OpenVPN profile │ └── office.meta.toml Sidecar metadata (new in v0.3.0; auto-generated) ├── auth/ Saved OpenVPN credentials │ └── office Username + password for "office" profile ├── run/ OpenVPN runtime files (temporary) │ ├── office.pid Daemon PID (source of truth for disconnect) │ └── office.log Raw daemon output (monitors connect/failure) ├── logs/ Application logs (daily rotation) │ └── 2026-02-09.log Same content as the TUI Logs panel ├── config.toml User settings (optional, see below) ├── settings.toml Figment-layered settings (optional, new in v0.3.0) ├── metadata.json Profile metadata (last used, sort order) ├── killswitch.state Kill switch state for crash recovery └── real-ip.cache Cached pre-VPN public IP (Security Guard's Real IP row) ``` 会话事件日志位于单独的 XDG 目录中,因为它们是可观测性数据,而不是用户配置: ``` ${XDG_DATA_HOME}/vortix/sessions/ (new in v0.3.0) ├── 2026-...-pid.jsonl JSONL event log per session └── ... 30-day / 30-file retention ``` 各平台解析后的路径: - **Linux:** `~/.local/share/vortix/sessions/` - **macOS:** `~/Library/Application Support/vortix/sessions/` 使用 `vortix info` 查找当前会话的路径。 即使 vortix 在 `sudo` 下运行,配置目录下的所有文件和目录都归您的用户帐户所有。您无需提升权限即可读取、修改或删除此处的任何内容。 | 路径 | 模式 | 描述 | |------|:----:|-------------| | `profiles/` | `600` | 您的 `.conf` 和 `.ovpn` 文件以及自动生成的 `.meta.toml` sidecar(v0.3.0 新增)。Sidecar 是幂等的 — 删除后会自动重新生成。 | | `auth/` | `600` | 保存的 OpenVPN 用户名/密码对。每个配置文件一个,从 TUI 的身份验证提示或通过手动 `printf 'user\npass\n' > auth/.auth` 写入。 | | `run/` | `644` | **仅限 OpenVPN。** VPN 会话期间创建的 PID 和日志文件。`.pid` 文件标识要终止的 daemon;`.log` 被轮询以获取成功/失败信息。断开连接时自动清理。WireGuard 不使用此项。 | | `logs/` | `644` | 应用程序会话日志(每日轮换,可配置大小/保留期)。不是 `run/` 中的原始 OpenVPN 输出。 | | `config.toml` | `644` | 可选的用户设置(旧版)。只有在您手动创建时才存在(见下文)。 | | `settings.toml` | `644` | 可选的 figment 分层设置(v0.3.0 新增):默认值 → 系统文件 → 此用户文件 → `VORTIX_*` 环境变量。不会自动创建。 | | `metadata.json` | `644` | 内部记录(上次使用、排序顺序)。自动管理。 | | `killswitch.state` | `644` | 在崩溃后保持终止开关模式。自动管理。 | | `real-ip.cache` | `600` | 最后已知的 VPN 前公共 IP,每当 vortix 观察到您处于未隧道化状态时写入。在启动时加载,以便安全卫士的 `Real IP` 行立即填充 — 包括在 VPN 已经启动时打开 vortix 的情况。两行纯文本(`\n\n`)。在任何未来的断开连接样本上刷新;过期的条目(vortix 关闭时的网络移动)会在您下次断开连接时自动纠正。 | ### 配置文件 创建 `~/.config/vortix/config.toml` 以自定义设置。所有字段均为可选 — 缺少的字段使用默认值: ``` # --- Timing --- # UI 刷新率,以毫秒为单位(默认:1000) tick_rate = 1000 # 遥测轮询间隔,以秒为单位(默认:30) telemetry_poll_rate = 30 # HTTP API 超时时间,以秒为单位(默认:5) api_timeout = 5 # Ping 超时时间,以秒为单位(默认:2) ping_timeout = 2 # OpenVPN 连接超时时间,以秒为单位(默认:20) connect_timeout = 20 # 在强制终止前等待 VPN 断开连接的最大秒数(默认:30) disconnect_timeout = 30 # --- Logging --- # TUI 事件日志中显示的最低日志级别:"debug"、"info"、"warning"、"error"(默认:"info") log_level = "info" # TUI 事件日志中保留的最大日志条目数(默认:1000) max_log_entries = 1000 # 日志文件轮转大小,以字节为单位(默认:5242880 = 5 MB) log_rotation_size = 5242880 # 保留旧日志文件的天数(默认:7) log_retention_days = 7 # --- OpenVPN --- # OpenVPN daemon 详细级别,--verb 标志,范围 0-11(默认:"3") openvpn_verbosity = "3" # --- 遥测端点 --- # 用于延迟测量的 Ping 目标(按顺序尝试) ping_targets = ["1.1.1.1", "8.8.8.8", "9.9.9.9", "208.67.222.222"] # IPv6 泄漏检测端点 ipv6_check_apis = ["https://ipv6.icanhazip.com", "https://v6.ident.me", "https://api6.ipify.org"] # 主要 IP/ISP API ip_api_primary = "https://ipinfo.io/json" # 备用 IP API ip_api_fallbacks = ["https://api.ipify.org", "https://icanhazip.com", "https://ifconfig.me/ip"] ``` ## 工作原理 **遥测:** 后台线程每秒轮询一次系统网络统计信息以获取吞吐量(macOS:通过 `libc::getifaddrs` 读取 BSD `if_data`;Linux:`/proc/net/dev`)。网络质量(延迟、抖动、丢包)通过基于无特权 `SOCK_DGRAM` socket 的手动 ICMP 回显探测进行测量(当 ICMP 受限时回退到 TCP-连接-到-443)。公共 IP、ISP 和地理位置数据通过 rustls-TLS 上的 `ureq` 获取 — 无需 `curl` shell-out,在基于 std::thread 的遥测 worker 中没有 tokio 运行时的开销。 **安全(终止开关和泄漏检测):** - **终止开关:** 平台原生防火墙集成。macOS 通过 `pfctl` 使用 PF(Packet Filter)。Linux 支持 `iptables`(默认 DROP OUTPUT 策略 + 用于回环 / RFC1918 / DHCP / 每个活动隧道接口 + 服务器 IP 的显式 ACCEPT 规则,通过 `iptables-restore` 应用以实现原子切换)和 `nftables`(原子 `vortix_killswitch` 表)。三种模式 — 每种模式对应一个标签,在 TUI、`vortix status` / `vortix killswitch` 的人类可读输出和 JSON 封包中完全相同: | 标签 / CLI 动词 | 行为 | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`off`** | 所有流量流动;如果 VPN 断开,将暴露真实 IP。 | | **`block-on-drop`** | *仅*在活动的 VPN 意外断开时启用默认 DROP 出口流量。 | | **`vpn-only`** | 无论 VPN 是启动还是断开,默认 DROP 出口流量始终保持启用,因此断开和重连之间的间隙永远不会泄漏。标准的 Linux 终止开关形态。 | 这三个标签名也是您输入的命令(`vortix killswitch <标签名>`)和您读取到的内容(TUI、`vortix status`、JSON 封包)。感知多隧道:每个已连接的隧道都会贡献 ACCEPT 规则;持久化的状态在 `vortix` 重启后依然保留。 - **IPv6 泄漏:** 通过 `api6.ipify.org` 进行主动监控。VPN 处于活动状态时检测到的任何 IPv6 流量都会触发泄漏警告。 - **DNS 泄漏:** 监控 DNS 配置以确保域名服务器与安全隧道对齐(macOS:通过 `system-configuration` crate 使用 `SCDynamicStore`;Linux:`resolvectl` / `nmcli` / `/etc/resolv.conf`)。 **WireGuard 集成:** macOS 通过 `/var/run/wireguard/*.name` 解析接口名称。Linux 直接使用内核 WireGuard 接口(`wg0`、`wg1` 等)。这两个平台都解析 `wg show` 以获取握手时间、传输统计信息和 endpoint 元数据。 **OpenVPN 集成:** 通过 macOS/Linux 的进程列表 API(macOS 上为 `libc::proc_listpids`,Linux 上为 `/proc//cmdline`)跟踪会话正常运行时间和连接状态。接口检测在两者上都使用 `libc::getifaddrs`。 ### 平台说明 | 功能 | macOS | Linux | |---------|-------|-------| | 终止开关 | `pfctl` (PF) | `iptables` 或 `nftables` | | 网络统计 | `libc::getifaddrs` + `if_data` | `/proc/net/dev` | | 接口检测 | `libc::getifaddrs` + `/var/run/wireguard/` | `libc::getifaddrs` + `/sys/class/net/` + `wg show` | | DNS 检测 | `SCDynamicStore` (SystemConfiguration 框架) | `resolvectl`, `nmcli`, `/etc/resolv.conf` | | 默认 VPN 接口 | `utun0` | `wg0` | | 已测试发行版 | macOS 12+ | Ubuntu, Fedora, Arch | ## 故障排除 ### 快速参考:常见错误 | 错误信息 | 原因 | 解决方案 | |---------------|-------|----------| | `Missing dependencies: resolvconf (systemd)` | WireGuard 配置文件具有 DNS 设置,systemd-resolved *不是*解析器,且未安装 `resolvconf` 垫片。如果您在使用 resolved 的主机上,将不再触发此错误 — vortix 会直接通过 `resolvectl` 路由 DNS。 | **仅在非 resolved 的 Linux 上**运行 `sudo apt install openresolv`(或您的发行版的等效命令)。使用 resolved 的主机不需要额外的包。 | | `iptables-restore: unable to initialize table` | 云内核不支持 iptables;配置文件使用了 `AllowedIPs = 0.0.0.0/0` | 将 `AllowedIPs` 更改为 `10.0.0.0/8` 或禁用终止开关 | | `wg-quick: The config file must be a valid interface name` | 配置文件名称 > 15 个字符 | 重命名:`vortix rename long-name short-name` | | `Connection succeeded but no internet` | `AllowedIPs` 不包含您的目标 | 在配置中将目标 IP 添加到 `AllowedIPs` | | `connection timed out` 或 `Connection refused` | 无法连接到 VPN endpoint | 检查防火墙/云服务提供商的端口限制 | ### 常规问题 **升级后配置文件丢失 (Linux)** 如果您之前使用 `sudo` 运行了 vortix,并且配置文件存储在 `/root/.config/vortix/` 中,应用程序将提供一次性的迁移提示。接受提示以将您的数据移动到您真实用户帐户下的 `~/.config/vortix/`。 如果您拒绝了迁移并希望继续使用旧路径: ``` sudo vortix --config-dir /root/.config/vortix ``` **权限被拒绝错误** 如果配置文件属于 root,请修复所有权: ``` sudo chown -R $(whoami) ~/.config/vortix/ ``` ### Arch Linux 和特定发行版常见问题解答 #### 问:连接失败,提示 "Missing dependencies: resolvconf (systemd)" **答:** 从 v0.4 版本开始,vortix 在 systemd-resolved 主机上直接通过 `resolvectl` 管理每个链接的 DNS — Arch、Omarchy、启用了 `services.resolved.enable = true` 的 NixOS 以及默认的 Fedora Workstation 不再需要 `systemd-resolvconf` / `openresolv` 垫片包。 此错误现在仅在以下情况触发: - 您的 `.conf` 文件包含 `DNS = …`,并且 - systemd-resolved 不是主机的解析器(或者安装了 resolved 但 `resolvectl` 本身损坏),并且 - PATH 中没有可用的 `resolvconf` 垫片 在仍然适用此问题的地方(非 resolved 的 Linux)进行修复: ``` sudo apt install openresolv # Debian/Ubuntu without resolved sudo zypper install openresolv # openSUSE ``` 如果您在使用 resolved 的主机上仍然看到此错误,说明您的 `resolvectl` 探测失败 — 运行 `resolvectl --version` 进行调试,然后携带输出提交一个 issue。 #### 问:连接失败,提示 "iptables-restore: unable to initialize table" **答:** 您的系统没有 `ip_tables` 内核模块。这通常发生在: - **云服务提供商**(DigitalOcean、AWS Lambda、Google Cloud Run 等)有意禁用了 netfilter - 具有最小内核功能的**容器** - 编译时没有 netfilter 支持的**自定义内核** 这**不是 Vortix 的问题** — 这是一个影响所有 Linux VPN 工具的系统限制,具体包括: - **Vortix 的终止开关**(需要 iptables/nftables 来配置防火墙规则) - **wg-quick 的自动路由**(当 WireGuard 配置中设置 `AllowedIPs = 0.0.0.0/0` 时) **解决方法 1:禁用终止开关(在云服务提供商上无效):** ``` sudo vortix killswitch off sudo vortix up your-profile ``` 只有在您的 WireGuard 配置文件不使用 `AllowedIPs = 0.0.0.0/0` 时,此方法才有效。如果使用了,wg-quick 仍会尝试配置 iptables。 **解决方法 2:修改云服务提供商的 WireGuard 配置文件:** 如果您的配置文件具有 `AllowedIPs = 0.0.0.0/0`(将所有流量通过 VPN 路由),wg-quick 会自动配置防火墙规则。在云服务提供商上,将其更改为更严格的设置: ``` # ❌ 这需要 iptables(在云提供商上会失败) AllowedIPs = 0.0.0.0/0 # ✅ 这仅路由 VPN 子网(无需 iptables) AllowedIPs = 10.0.0.0/8 ``` 使用 `vortix show --raw` 编辑您的配置文件,查看当前的 `AllowedIPs` 设置。 **验证您的系统是否支持 iptables:** ``` modprobe ip_tables && echo "✓ Supported" || echo "✗ Not available on this kernel" ``` **云服务提供商的最佳:** 如果您需要在云服务提供商上通过 VPN 路由所有流量,您需要一个具有标准内核(而不是受限的云内核)的实例。或者,使用具有完整内核支持的家庭服务器、专用主机或裸金属服务器。 #### 问:我如何知道我的系统使用什么 DNS 解析器? **答:** 运行此命令以检查 Vortix 将使用哪种方法: ``` # Systemd(大多数现代 Linux 发行版) resolvectl status 2>/dev/null && echo "✓ Using systemd-resolved" # NetworkManager nmcli dev show 2>/dev/null | grep DNS && echo "✓ Using NetworkManager" # 备用检查 cat /etc/resolv.conf | head -3 ``` Vortix 会自动检测并尊重您系统的 DNS 设置。 #### 问:我可以在非 systemd 的发行版上使用 Vortix 吗? **答:** 可以,但在 DNS 管理方面有一些限制: - **Arch、Fedora、Ubuntu、Debian** → 完全支持(支持 systemd 或替代方案) - **Alpine、Void、Gentoo (OpenRC)** → Vortix 回退到直接编辑 `/etc/resolv.conf` - **NixOS** → 可以工作,但 DNS 可能需要自定义配置 如果您使用非 systemd 的发行版并遇到问题,请带上 `vortix report` 的输出[提交一个 issue](https://github.com/Harry-kp/vortix/issues)。 #### 问:为什么连接成功但 DNS 无法正常工作? **答:** 如果 `vortix up` 成功但您无法解析域名,这意味着: 1. **VPN 隧道处于活动状态**(IP 变更工作正常) 2. **DNS 配置失败**(resolvconf 未正常工作) **调试步骤:** ``` # 检查 resolvconf 是否正常工作 resolvconf --version # 检查活动的 DNS 服务器 resolvectl status | grep -A5 "DNS Servers" # 通过 VPN 手动测试 DNS dig @8.8.8.8 google.com # 检查系统的 resolv.conf 符号链接 ls -la /etc/resolv.conf ``` 如果 `/etc/resolv.conf` 不是由 systemd 管理的(不是指向 `/run/systemd/` 的符号链接),您可能需要安装 `systemd-resolvconf` 或 `openresolv`。 #### 问:WireGuard 接口名称太长 **答:** Linux WireGuard 接口有 15 个字符的名称限制。如果您的配置文件名称更长,wg-quick 将失败并提示 "invalid interface name"。 **修复:** 将您的配置文件重命名为更短的名称: ``` vortix rename my-very-long-profile-name work-vpn ``` WireGuard 接口名称只能包含字母数字字符、连字符和下划线。 #### 问:如何报告特定于发行版的问题? **答:** 在提交 issue 时包含以下信息: ``` vortix report # Generates a complete report uname -a # Kernel version cat /etc/os-release # Distro info systemctl --version # Init system ``` CI 中测试和支持的 Linux 发行版有:**Ubuntu 20.04/22.04**、**Fedora 40+**、**Arch Linux**。如果您使用的是其他发行版并遇到了问题,那对该项目来说是很有价值的信号。 ### WireGuard 配置指南 #### 了解 AllowedIPs 您 WireGuard 配置中的 `AllowedIPs` 设置决定了哪些流量通过 VPN: ``` # 通过 VPN 路由所有流量(firewall 规则需要 iptables/nftables) AllowedIPs = 0.0.0.0/0 # ⚠️ May fail on cloud providers, containers # 仅路由 VPN 子网流量(无需特殊的 firewall 规则) AllowedIPs = 10.0.0.0/8 # ✅ Works everywhere, even cloud providers # 仅路由特定流量 AllowedIPs = 192.168.1.0/24 # ✅ Route only corporate network ``` **为什么这很重要:** - 当 `AllowedIPs = 0.0.0.0/0` 时,wg-quick 会自动通过 iptables/nftables 配置防火墙规则 - 云服务提供商(DigitalOcean、AWS Lambda、Google Cloud Run)会禁用 iptables 内核模块 - 严格的 `AllowedIPs` 可以完全避免防火墙配置 **针对云服务器的建议:** 如果您在云服务提供商上运行 Vortix 并且需要通过 VPN 路由流量,请使用 `AllowedIPs = 10.0.0.0/8` 或其他私有子网,而不是 `0.0.0.0/0`。 #### 常见的 WireGuard 配置问题 **问题:连接成功但无法访问互联网** 检查您的 `AllowedIPs` 设置: ``` vortix show your-profile --raw | grep AllowedIPs ``` - 如果是 `10.0.0.0/8` 或类似设置,则只有前往该子网的流量通过 VPN - 将您的目标 IP/子网添加到 `AllowedIPs` 以将其通过隧道路由 - 示例:`AllowedIPs = 10.0.0.0/8, 192.168.0.0/16` **问题:无法从云服务提供商连接到 VPN 服务器** 一些云服务提供商阻止了出站 UDP 51820 或其他端口。尝试: ``` # 检查您是否可以到达端点 ping -c 1 138.197.3.155 # 测试特定端口(替换为您的端点) nc -zu 138.197.3.155 51820 && echo "✓ Port open" || echo "✗ Port blocked" ``` 如果被阻止,请联系您的云服务提供商以允许 WireGuard 端口。 **问题:DNS 有效,但仅限于部分域名** 这通常意味着: 1. 配置了 VPN DNS 服务器,但并非所有流量都通过 VPN 路由 2. 您系统的 DNS 回退正在本地解析一些查询 检查配置中是否包含 `DNS =` 并与您的 VPN 提供商的 DNS 服务器相匹配。 #### 测试您的 WireGuard 配置文件 在创建/导入配置文件后,测试配置: ``` # 查看 profile vortix show my-profile --raw # 检查必填字段 vortix show my-profile --raw | grep -E "^(PrivateKey|PublicKey|AllowedIPs|Endpoint|Address|DNS)" # 预期输出: # PrivateKey = (base64) # Address = 10.0.0.2/24 # Endpoint = 1.2.3.4:51820 # AllowedIPs = 10.0.0.0/8 (or 0.0.0.0/0) # PublicKey = (base64) # DNS = 8.8.8.8, 8.8.4.4 (optional) ``` 除 `DNS`(可选)外,上述所有字段都是必填的。 ## 路线图 请查看[项目看板](https://github.com/users/Harry-kp/projects/6) 了解我们正在探索的内容。有想法?[加入讨论](https://github.com/Harry-kp/vortix/discussions/34)。 ## 开发 ``` cargo build # Build binary cargo test # Run unit/integration tests cargo clippy # Enforce code quality (Fail-fast via pre-commit) ``` **Nix 用户** 可以进入预配置好所有 Rust 工具的开发 shell: ``` nix develop ``` ## 收录于 - [awesome-rust](https://github.com/rust-unofficial/awesome-rust) — Rust 代码和资源的精选列表 - [awesome-ratatui](https://github.com/ratatui/awesome-ratatui) — Ratatui 应用程序和工具的精选列表 - [awesome-tuis](https://github.com/rothgar/awesome-tuis) — 最佳 TUI 程序列表 - [Arch Linux [extra]](https://archlinux.org/packages/extra/x86_64/vortix/) — 官方 Arch Linux 软件包仓库 - [Terminal Trove](https://terminaltrove.com/vortix/) — 终端中一切事物的 $HOME ## Star 历史 [![Star History Chart](https://api.star-history.com/svg?repos=Harry-kp/vortix&type=Date)](https://star-history.com/#Harry-kp/vortix&Date)
标签:Docker 部署, OpenVPN, Rust, VPN, WireGuard, 可视化界面, 暗色界面, 终端UI, 网络流量审计, 网络运维, 通知系统