Harry-kp/vortix
GitHub: Harry-kp/vortix
Vortix 是一款轻量级终端 UI 工具,用于集中管理 WireGuard 和 OpenVPN 连接,提供实时遥测监控和流量泄漏防护。
Stars: 503 | Forks: 21
# Vortix
[](https://github.com/Harry-kp/vortix/actions/workflows/ci.yml)
[](https://github.com/Harry-kp/vortix/blob/main/LICENSE)
[](https://github.com/Harry-kp/vortix/blob/main/CONTRIBUTING.md)
[](https://crates.io/crates/vortix)
[](https://crates.io/crates/vortix)
[](https://www.npmjs.com/package/@harry-kp/vortix)
[](https://www.npmjs.com/package/@harry-kp/vortix)
[](https://github.com/Harry-kp/homebrew-tap)
[](https://github.com/Harry-kp/vortix#installation)
[](https://github.com/Harry-kp/vortix)
[](https://github.com/Harry-kp/vortix)
[](https://www.rust-lang.org/)
[](https://github.com/Harry-kp/vortix)
[](https://github.com/sponsors/Harry-kp)
用于 WireGuard 和 OpenVPN 的终端 UI,提供实时遥测和泄漏防护。

## 为什么选择 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 历史
[](https://star-history.com/#Harry-kp/vortix&Date)
标签:Docker 部署, OpenVPN, Rust, VPN, WireGuard, 可视化界面, 暗色界面, 终端UI, 网络流量审计, 网络运维, 通知系统