Linux desktop client for V2Ray-style links, built with Python 3.11+ and PyQt6, powered by Xray-core.
Current release target: v0.2.0
Project status: beta (stable for daily use, focused feature scope).
- Validate and run
vless://links through Xray-core - Save/manage multiple profiles (favorite/default/duplicate/edit/delete)
- Validation persistence for saved profiles (no unnecessary revalidation)
- Local SOCKS5 + HTTP proxy endpoints (auto-select free ports when needed)
- Optional desktop system-proxy apply/restore while running
- Health indicator + ping + speed test + traffic/uptime metrics
- Traffic Monitor dashboard with Overview, Applications, Proxy Profiles, History, Settings, and Diagnostics tabs
- Local SQLite proxy/profile traffic history with daily totals, profile totals, session history, charts, and CSV export
- Optional per-application tracking preparation through the advanced
v2link-netmonhelper path - Diagnostics panel with runtime proxy state and log access
- Built-in update check against GitHub Releases
- Light/Dark theme
- Linux desktop environment (GNOME/KDE/etc.)
Official AppImage, .deb, and APT releases include bundled Xray-core for normal operation. Source builds may use bundled vendor files from ./scripts/fetch_xray_core.sh or a system xray from PATH as a fallback.
Primary supported release artifacts:
- AppImage
- Debian package (
.deb)
Also available for Debian/Ubuntu users:
- APT repository (published from release workflow)
- Download the latest AppImage from GitHub Releases.
Expected artifact name pattern:
v2link-client-<version>-linux-<arch>.AppImage<arch>isx86_64oraarch64
- Make executable and run:
chmod +x v2link-client-*.AppImage
./v2link-client-*.AppImage- Optional launcher setup:
mkdir -p ~/.local/bin
cp v2link-client-*.AppImage ~/.local/bin/v2link-client.AppImage
chmod +x ~/.local/bin/v2link-client.AppImageCreate ~/.local/share/applications/v2link-client.desktop:
[Desktop Entry]
Name=v2link-client
Exec=/home/YOUR_USER/.local/bin/v2link-client.AppImage
Icon=v2link-client
Type=Application
Categories=Network;
Terminal=false- Download the latest
.debfrom GitHub Releases.
Expected artifact name pattern:
v2link-client_<version>_<arch>.deb<arch>isamd64orarm64
- Install:
sudo dpkg -i v2link-client_<version>_amd64.deb
sudo apt -f install- Launch:
v2link-clientImport the repository key:
curl -fsSL https://udayasri0.github.io/v2link-client/apt/public.key \
| gpg --dearmor \
| sudo tee /usr/share/keyrings/v2link-client-archive-keyring.gpg >/dev/nullAdd the source list:
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/v2link-client-archive-keyring.gpg] https://udayasri0.github.io/v2link-client/apt stable main" \
| sudo tee /etc/apt/sources.list.d/v2link-client.list >/dev/nullInstall:
sudo apt update
sudo apt install v2link-clientpython3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
./scripts/dev_run.shBuild AppImage only:
./scripts/build_appimage.shBuild .deb only:
./scripts/build_deb.shBuild full release set (PyInstaller + AppImage + .deb + checksums):
./scripts/build_release.shThe release build fetches a pinned official Xray-core release into vendor/xray/<arch>/ and bundles it into the AppImage and .deb. Maintainers can refresh the vendor copy directly:
./scripts/fetch_xray_core.shArtifacts are written to dist/:
v2link-client-<version>-linux-<arch>.AppImagev2link-client_<version>_<arch>.debSHA256SUMS
Canonical version source: pyproject.toml ([project].version).
- Update
pyproject.tomlversion. - Update
CHANGELOG.md. - Commit changes.
- Create and push matching tag:
git tag v<version>
git push origin v<version>- GitHub Actions workflow
.github/workflows/release.ymlwill:
- verify
tag version == pyproject version - build AppImage +
.deb+SHA256SUMS - upload artifacts to GitHub Release
- publish/update signed APT repo to
gh-pages
Public key file is committed at apt/public.key.
Export matching private key:
gpg --armor --export-secret-keys "v2link-client APT Repository <apt@v2link-client.local>"GitHub secrets:
APT_GPG_PRIVATE_KEY: ASCII-armored private keyAPT_GPG_PASSPHRASE: key passphrase (if protected)
- Paste
vless://link. - Click Validate & Save.
- Click Start.
- Enable System Proxy for desktop-wide proxying, or use Copy manual proxy settings.
The app resolves Xray-core in this order: custom path from Xray Settings, bundled Xray, then system xray from PATH. Diagnostics and About show the active Xray source, path, and version.
The Traffic Monitor records local traffic history and shows:
- Dashboard tabs for Overview, Applications, Proxy Profiles, History, Settings, and Diagnostics
- Today upload/download totals
- Current session upload/download and live speed
- This month upload/download totals
- Per saved-profile upload/download totals
- Daily usage aggregation and a lightweight in-app daily usage chart
- Daily history with Today, Last 7 days, Last 30 days, This month, and custom date ranges
- Session history for each selected date, including start/end time, duration, profile, download, upload, total, average speed, and status
- Session drill-down charts for speed or cumulative usage over time
- Advanced Applications tab for future per-application tracking
- Settings for detailed sample retention, CSV export, and clearing local traffic history
- Diagnostics for the stats API, helper readiness, and local traffic database
Proxy/profile tracking records traffic from Xray's Stats API while the core is running. It works in the normal GUI with no root permission because Xray provides proxy counters through its local API. The app does not use xray api -reset, so live labels and history do not fight over counters.
Bundled Xray-core is enough for proxy/profile tracking in official AppImage, .deb, and APT installs. Per-application tracking is separate and still needs the optional helper service described below.
Daily totals are aggregated by sample date and are useful for range summaries. Session totals are grouped by each Start/Stop run, so a connection from 20:00 to 20:30 appears as one session under that date. CSV export supports daily summaries, session summaries, and selected-session samples.
Traffic history is stored locally only in SQLite:
$XDG_DATA_HOME/v2link-client/traffic.sqlite3
If XDG_DATA_HOME is not set, the app uses the platform default data directory through platformdirs, usually ~/.local/share/v2link-client/traffic.sqlite3 on Linux.
Settings are stored at:
$XDG_CONFIG_HOME/v2link-client/traffic_settings.json
Per-application tracking is advanced and optional. It is separate from normal proxy/profile traffic tracking, which works through Xray's Stats API without root permission. True Linux app attribution needs the optional privileged helper service v2link-netmon, because process/executable attribution must happen outside the unprivileged GUI. The GUI never runs as root.
Debian packages install the optional helper and systemd service, but do not enable it automatically:
sudo systemctl enable --now v2link-netmon
sudo systemctl disable --now v2link-netmonThe helper exposes read-only JSON stats over /run/v2link-client/netmon.sock. In v0.2.0 this path is prepared/scaffolded and remains optional; if the helper, permissions, or eBPF backend are unavailable, the GUI stays unprivileged and shows a clear unavailable/diagnostic state.
Traffic history never leaves your machine. Proxy/profile stats come from Xray counters. Application traffic tracking records local process names, executable paths, UIDs, and byte counters only. It does not decrypt traffic, inspect packet payloads, read messages, collect tokens/cookies, or upload telemetry anywhere.
Per-application attribution is not perfect when a local proxy is involved. When system proxy is enabled, apps may connect to 127.0.0.1 while Xray performs the encrypted remote connection, so some traffic can appear under Xray Core / Proxy Tunnel. Xray is shown separately and is not hidden.
- If proxy/profile totals stay at zero, confirm Xray is running and the diagnostics tab shows a configured stats API server.
- If the Applications tab says the helper is unavailable, enable the optional service with
sudo systemctl enable --now v2link-netmon. - If the helper is running but eBPF is unavailable, check Traffic Monitor diagnostics for kernel/capability details.
- AppImage builds work without the helper and will show the helper-unavailable state.
Currently implemented:
vless://security=tlsandsecurity=none- transport:
tcp,ws,grpc - optional:
sni,fp,alpn,allowInsecure,flow - limited
headerType=httphandling for TCP
Not yet implemented:
vmess://,trojan://,ss://- REALITY and advanced routing profiles
- Saved profiles:
$XDG_CONFIG_HOME/v2link-client/profiles.json(fallback~/.config/v2link-client/profiles.json) - Preferences/legacy compatibility:
~/.config/v2link-client/profile.json - Optional custom Xray path:
$XDG_CONFIG_HOME/v2link-client/xray_settings.json - Runtime state and generated config:
~/.local/state/v2link-client/ - Logs:
~/.local/state/v2link-client/logs/
Common causes:
- Invalid endpoint or blocked server
- Mismatched
sniand certificate with strict TLS verification (allowInsecure=0)
Actions:
- verify link/server settings
- try
snialigned with target host - inspect logs via Open logs folder
Install missing runtime library:
sudo apt update
sudo apt install -y libxcb-cursor0
