Changelog
All notable changes to this project are documented in this file.
[2.0] - 2026-08-30
Added
- Liveness testing pipeline (
liveness/package) — every run now tests configs in two stages before publishing anything:- TCP check (
liveness/tcp_check.py) — 3 rounds of TCP handshake, run directly from the GitHub Actions runner. Cheap, fast, and drops configs whose port isn't even open. - Real proxy test (
liveness/wireguard.py,liveness/xray_knife_test.py) — configs that survive stage 1 are tested with xray-knife from behind a WireGuard tunnel, so target servers see a VPN exit IP instead of GitHub's IP range (avoids flagging/blocking servers that are sensitive to datacenter/CI IPs).
- TCP check (
- Multi-WireGuard failover — the
WG_CONFIGSsecret can hold several WireGuard configs (e.g. multiple ProtonVPN servers); if one tunnel fails to come up or drops mid-run, the pipeline automatically tries the next one. sub/top100.txt— the fastest configs that passed both stages, ranked by latency.sub/clash.yaml— a ready-to-import Clash/Mihomo config built from the same top set (supports vmess, vless including Reality, trojan, and shadowsocks).docs/WIREGUARD_SETUP.md— step-by-step guide for exporting a WireGuard config (e.g. from ProtonVPN) and adding it as theWG_CONFIGSrepo secret.- New "Live Configs" section in
README.mdshowing a stage-by-stage funnel: how many configs were fetched, how many passed TCP, and how many passed the real WireGuard test — so it's clear at a glance which stage is actually working on a given run. requirements.txt(addedpyyaml, needed forclash.yamlgeneration).
Changed
- Dead configs are no longer published. Previously, every fetched config was written to
sub/anddetailed/regardless of whether it worked; now the TCP check (stage 1) runs before any output files are written, and only configs that pass it are categorized and committed to the repo. .github/workflows/main.ymlnow installswireguard-toolsand downloads/verifies a pinnedxray-kniferelease (SHA-256 checked) before running the script.- The README summary table now includes a "Published (passed TCP check)" row alongside the existing fetched/unique/duplicate counts.
- If the
WG_CONFIGSsecret is missing or every WireGuard tunnel fails to come up, the pipeline no longer fails the workflow — it falls back to TCP-only ranking fortop100.txt/clash.yamland states that explicitly in the README instead.
Fixed
- WireGuard configs with dual-stack
Address/DNSfields (comma-separated IPv4 + IPv6, as exported by ProtonVPN) were mishandled —ip address addonly accepts one address at a time, so the tunnel failed to come up. Each value is now applied individually. - The network namespace used for the WireGuard tunnel had no DNS resolver, so every health-check (and later, hostname-based config tests) silently failed.
/etc/netns/<namespace>/resolv.confis now generated from the tunnel's own DNS entry (with a public fallback). - A single malformed config (a remark/name containing a NUL byte) would corrupt xray-knife's CSV output enough that Python's CSV parser rejected the entire file — discarding thousands of otherwise-valid real-test results and silently falling back to TCP-only ranking. NUL bytes are now stripped before parsing, so one bad config no longer takes the whole batch down with it.