Proxy and VPN (zev proxy, zev vpn)
When Zaryn or other sites are blocked, use your own VLESS, VMess, Trojan, Shadowsocks, Hysteria2 or WireGuard servers for zev, every app, or the whole computer (a VPN).
Search for a command to run…
When Zaryn or other sites are blocked, use your own VLESS, VMess, Trojan, Shadowsocks, Hysteria2 or WireGuard servers for zev, every app, or the whole computer (a VPN).
Some networks block or slow down the way to Zaryn, GitHub and much else. If you have a proxy server that works on that network (VLESS, VMess, Trojan, Shadowsocks, Hysteria2, WireGuard, SOCKS5 or HTTP), zev uses it at the level you choose:
| What goes through the proxy | How | |
|---|---|---|
| zev only (the default) | zev's own connections: sign-in, clone, push, pull, zev self update, private networks | zev proxy use <name> |
| Every app you point at it | anything that can use a SOCKS5 or HTTP proxy: browsers, git, SSH, pip, npm, cargo, apt… | zev proxy share on (port 10808), then zev proxy system on, zev proxy ssh |
| The whole computer | every program, its DNS and IPv6, without any settings in them | sudo zev vpn on (Linux) |
zev never uses a proxy you didn't choose, and never falls back to going out directly when the proxy fails. With these it replaces apps like v2rayN, NekoRay or Hiddify: moving from v2rayN takes a minute.
zev proxy start # asks for your server's link the first timezev proxy stopzev proxy start does everything: saves the server, installs the engine if needed, opens the shared port 127.0.0.1:10808 for every app, sets your desktop's proxy, and then shows where you appear from. It stays on across restarts. zev proxy stop turns all of it off again.
zev proxy start 'vless://…' # with a new server (keep the quotes)zev proxy start --tun # the whole computer: a VPN (asks for your sudo password)zev proxy start --tun --kill-switch # ... and nothing gets out directly if it stopszev proxy # is it on? through which server?The rest of this page explains each part, for when you want more control.
zev proxy is free on every plan: you bring your own proxy, and Zaryn carries none of its traffic. Private networks are part of Premium, so using them through your proxy is too.
Below: the links zev understands, then how to add yours.
zev understands the share links VPN apps (v2rayN, v2rayNG, Hiddify, Nekoray, Shadowrocket) use, and the subscriptions providers hand out:
| Link | What it is | Needs |
|---|---|---|
vless://… | VLESS: TLS or REALITY, XTLS Vision, VLESS Encryption (such as mlkem768x25519plus), the tcp, ws, grpc, xhttp and httpupgrade transports | the Xray engine |
vmess://… | VMess (the v2rayN format), with the same TLS and transports | the Xray engine |
trojan://… | Trojan, over TLS or REALITY, same transports | the Xray engine |
ss://… | Shadowsocks: the 2022 ciphers (2022-blake3-…) and aes-128-gcm, aes-256-gcm, chacha20-poly1305 | the Xray engine |
hysteria2://… or hy2://… | Hysteria2 over QUIC, with Salamander obfuscation (obfs=salamander) | the Xray engine |
wireguard://… or wg://… | WireGuard, including Cloudflare WARP (reserved=); no root needed | the Xray engine |
socks5://user:pass@host:port | a SOCKS5 proxy | nothing |
http://… or https://… | an HTTP proxy | nothing |
| a subscription URL | a list of any of the above, from your provider: see Subscriptions |
zev refuses what isn't safe or won't work rather than failing later: old Shadowsocks stream ciphers (aes-256-cfb, rc4-md5), Shadowsocks plugins, and the transports Xray dropped (h2, kcp, quic). A link's insecure=1 or allowInsecure never turns certificate checks off; if your server uses its own certificate, pin it with pcs= (or pinSHA256= for Hysteria2), as your provider's app does.
Save it under a name you choose. To keep the link (it holds your credentials) out of your shell history, leave it off and paste it when asked:
zev proxy add work --usePaste the link, then press Enter:vless://…✓ Saved work: vless proxy.example.com:443 tcp+tls xtls-rprx-vision mlkem768x25519plus fp=firefox sni=… pinned--use also makes it the proxy zev uses from now on. Saved links live in ~/.config/zev/proxies, readable by you alone. zev proxy ls lists them without their secrets.
If your provider gives you a subscription URL (one link that lists many servers, updated when they change), add it once:
zev proxy sub add myvpn https://provider.example/sub/abc123✓ myvpn: 24 servers (12 vless, 6 trojan, 4 shadowsocks, 2 hysteria2), named myvpn-1 … myvpn-24 Pick one: zev proxy use myvpn-1 (zev proxy test myvpn-1 tries it first)zev downloads it through the proxy you use now (subscription hosts are often blocked too), or directly if that fails. Servers it can't use are listed with the reason, and the rest are saved.
| Command | What it does |
|---|---|
zev proxy sub update [<name>] | download it again: its servers are replaced by the new list. If the one you use is gone, zev says so and connects directly |
zev proxy sub ls | subscriptions and how many servers each has |
zev proxy sub rm <name> | forget it and its servers |
The usual base64 format and plain lists of links both work. Clash (proxies:) and sing-box (JSON) files aren't share links: ask your provider for the v2ray / share-link format of the same subscription.
Everything except SOCKS5 and HTTP is spoken by Xray-core, which zev runs for you on this computer. Install it once:
zev proxy engine installzev downloads the Xray release it was tested with and checks its SHA-256 before unpacking it. If GitHub is blocked, download the zip for your system another way and run zev proxy engine install --from Xray-linux-64.zip (the same check applies). An Xray you already have also works: zev looks on your PATH, or set ZEV_XRAY=/path/to/xray.
zev proxy testwork: vless proxy.example.com:443 tcp+tls xtls-rprx-vision … engine ✓ Xray on 127.0.0.1:41377 (48 ms) Zaryn ✓ 200 in 310 ms internet ✓ 204 in 290 mszev proxy test <name> tries a saved proxy without switching to it. When a check fails, the last lines of Xray's log are shown below it.
To see exactly what zev makes of a link, zev proxy config <name> prints the Xray config it runs (it contains the proxy's secrets, so don't share it).
zev proxy doctor finds what stands between you and Zaryn, fixes what zev can fix itself, and proves each fix with a real request before keeping it:
zev proxy doctorChecking the way to Zaryn through work: vless proxy.example.com:443 tcp+tls fp=chrome …Network: wlan0 via 192.168.1.1; fixes in force: nonework vless proxy.example.com:443 … ✗ DNS lies: this network answers 10.10.34.36 for proxy.example.com, DNS over HTTPS 203.0.113.9 (only that one accepts connections) fix: look names up with DNS over HTTPS (https://1.1.1.1/dns-query) ✓ TCP: 203.0.113.9:443 connects in 84 ms ✗ SNI filtering: TLS naming proxy.example.com is reset, naming www.example.com goes through · the reset comes from 3 routers away, near you: in your provider's network (the server is 14 away)Finding a way through 8 ways at once · as it is: no way through · firefox fingerprint: no way through · ClientHello in pieces (split: 10-20 byte pieces): 231 ms · ClientHello in pieces (large: 100-200 byte pieces, 10-20 ms apart): 400 ms … ✓ kept: ClientHello in pieces (split: 10-20 byte pieces) (the cheapest that works, and proven again)Clock ✓ within 2 s of api.zaryn.xyz's clockThroughput ✓ a download through the proxy: 2.0 MB in 1.4 s (1.43 MB/s)Result ✓ api.zaryn.xyz answers through the proxy (200 in 310 ms) · fixes for this network: DNS over HTTPS (https://1.1.1.1/dns-query), ClientHello in pieces (split) ✓ saved for wlan0 via 192.168.1.1: every zev command here uses them, and zev picks them up again when you're back on this networkWhat it looks for, and what it does about it:
| Problem | How zev tells | What zev does |
|---|---|---|
| DNS that lies | the network's answer for the proxy's name against DNS over HTTPS (asked straight by IP address); a different answer that accepts no connections, or the filter's own address (10.10.34.x), is a lie | looks names up with DNS over HTTPS from then on, zev and Xray both |
| SNI filtering | TCP connects, but a TLS handshake naming the server is cut while one naming another site goes through | races the ways around it (below) |
| Where the filter is | the handshake is sent again with a TTL of 1, 2, 3 …: it expires that many routers away, so the first distance that gets a reset is where the filter sits | tells you whether it's in your provider's network or nearer the server |
| Broken IPv6 | the name's IPv6 address times out while IPv4 connects (every connection waits for IPv6 first) | IPv4 only |
| A blocked port | the proxy's port doesn't answer while other ports of the same address do | says which ports answer: ask whoever runs the server for a link on one |
| A blocked address | no port of the address answers | says so: another server, or a CDN-fronted link |
| The freeze | small requests work but a download stops after 15-20 KB and never resumes (filters starve connections they can't classify) | says so: a REALITY or XHTTP link, or another server, usually avoids it |
| Throttling | downloads crawl | says so, with the speed |
| The clock | Zaryn's Date header against yours: VMess refuses connections more than 2 minutes off, and certificates look expired when the clock is days off | tells you how to set it (that needs an administrator) |
| TLS interception | Zaryn's certificate isn't trusted on the direct path: something answers in its place (or a Wi-Fi sign-in page) | never turns certificate checks off; a link with a pinned certificate gets around it |
When the way doesn't work, the doctor doesn't make you guess settings. It tries them all at once, in one Xray, each as its own way to the server:
split 10-20 bytes, large 100-200 bytes, tiny 1-5 bytes), so a filter reading the server's name never sees it whole in one packet;Each way's time is measured; the cheapest that works wins (a little extra time counts against the tiny pieces, which slow every connection). The winner must then work again in the engine zev really runs, with a real request; one that only got through once is skipped for the next. Nothing is saved until that passes.
The fixes are saved for the network you're on, which zev tells apart by its router (a hash of the router's address and hardware address; on Linux). Home, the office and a phone's hotspot each keep their own, and zev picks them up again by itself when you come back. Elsewhere, the fixes you set by hand apply.
zev proxy set # this network, its fixes, and the networks zev rememberszev proxy set forget # forget what the doctor found herezev proxy set fragment split # set fixes by hand, for every network (dns <url>, ipv4 on, fp <name> … , or off)zev proxy doctor --no-fix # only look, change nothingzev proxy doctor home # check another saved proxyzev proxy doctor --json prints the whole report as JSON: every finding with its hint, the fixes, whether they were saved, and how far away the filter is. It never contains a link or its secrets, so it's safe to paste into a support request or hand to an assistant.
Once a proxy is chosen there's nothing more to do: every zev command goes through it. The engine starts with the first command that connects and keeps running for the ones after it.
zev proxy status # which proxy, and whether the engine runszev proxy use home # switch to another saved proxyzev proxy off # connect directly againzev proxy stop # everything off (shared port, desktop, VPN)zev proxy rm old # forget a proxyFor a single command, or in scripts and CI, ZEV_PROXY overrides the choice: a saved name, a link, or off.
ZEV_PROXY=off zev pullZEV_PROXY=home zev pushzev proxy share onFrom then on 127.0.0.1:10808 is a proxy port any program can use, SOCKS5 and HTTP on the same port (10808 is the port v2rayN uses, so settings made for it keep working). It runs in the background, starts again when you log in, and:
zev proxy use other switches it, a pool switches to the fastest working server by itself, and the fixes zev proxy doctor found for the network you're on come with you when you move between networks;zev proxy off) the port closes instead of letting traffic go out directly (it fixes itself has more).zev proxy share status # sharing? through which server, since whenzev proxy share on --port 1080zev proxy share offOther devices on your network (a phone, a second laptop): zev proxy share on --lan opens the port to the LAN behind a password, which zev prints. Set the device's proxy to this computer's address, port 10808, user zev and that password. zev proxy share on --local closes it to the LAN again.
Addresses on your own network (LAN, 10.0.0.0/8, 192.168.0.0/16 and the like) are reached directly, not through the proxy.
zev proxy system on # GNOME's or KDE's proxy setting → the shared port; new terminals get http_proxy, all_proxy…zev proxy system offBrowsers and most desktop apps follow the system setting. Terminals opened after a new login pick up http_proxy, https_proxy and all_proxy (from ~/.config/environment.d/90-zev-proxy.conf).
zev proxy ssh # GitHub, GitLab and Codeberg through the proxyzev proxy ssh github.com myserver # or the hosts you namezev proxy ssh offzev puts a marked block at the top of ~/.ssh/config with ProxyCommand zev proxy connect %h %p; git push to GitHub then goes through the proxy, and nothing else in the file changes. zev proxy connect <host> <port> works anywhere a ProxyCommand does, and needs neither nc nor the shared port (it uses zev's own engine when sharing is off).
zev proxy run git pushzev proxy run pip install requestszev proxy run -- curl https://example.comThe command gets http_proxy, https_proxy, all_proxy and a GIT_SSH_COMMAND that goes through the proxy, so HTTP, SOCKS and git over SSH all use it. Its exit code is zev's.
On Linux, zev can carry everything: every program, without any proxy settings in it, plus its DNS lookups and IPv6.
sudo zev vpn onsudo zev vpn on --kill-switchsudo zev vpn on --exclude example.ir,192.0.2.0/24zev vpn statussudo zev vpn offzev proxy use (as yourself: sudo only sets up the network), and follows it when you change it.--exclude sends some sites or addresses directly (names, IP addresses, CIDR ranges). zev proxy route iran sends Iran's sites direct for every mode.--kill-switch: if the VPN stops for any reason, nothing goes out directly; only your LAN keeps working, until the VPN is back or you run sudo zev vpn off.How it works: zev creates a network interface (zev0) that the Xray engine reads, and routes everything into it except what has a more specific route and the engine's own connections (which carry a firewall mark so they don't loop). sudo zev vpn off removes the interface, the routes, the rules and the firewall table; nothing is left behind.
On macOS and Windows, use zev proxy share on with zev proxy system on for now.
The shared port and the VPN check every 30 seconds that traffic really gets through. When it stops for three checks in a row:
zev proxy doctor by itself, at most every 10 minutes. It finds what blocks the way on this network (DNS lies, a blocked port, SNI filtering, a clock that's off) and saves a fix for this network.With a pool, a dead server is simply skipped in the meantime. With the VPN's kill switch on, zev doesn't pause the VPN to run the doctor; it only restarts the engine.
$ zev proxy checkWhere you appear from through zev 203.0.113.9 (DE) without zev 5.160.12.34 (IR)Leaks ✓ every app goes through the VPN (they appear from the proxy's address) ✓ DNS goes through the tunnel ✓ no IPv6 way out (nothing to leak)It shows the address and country websites see through the proxy and without it, and with the VPN on, whether every app, DNS and IPv6 really go through it.
zev proxy topLive traffic of the shared port or the VPN: what each part sent and received in total and right now (zev itself, the shared port, the VPN, each server of a pool, what went direct). --once prints it once.
vless://…) or give you the subscription address.zev proxy engine install # once: the Xray enginezev proxy add home 'vless://…' --use # a server, or:zev proxy sub add work https://… # a subscriptionzev proxy use work # all of its servers as a pool: the fastest, with failoverzev proxy share on # the same port 10808: your SSH config and apps keep workingzev proxy system on # browsers and the desktopsudo zev vpn on.What you get on top: failover between servers ranked by measured speed, self-healing on networks that filter, per-network fixes that follow you, leak checks, and the same settings for zev's own connections.
Servers come and go on filtered networks: one is fast in the morning and blocked by the evening. Give zev several and it uses the best of them, and switches on its own when one stops answering:
zev proxy use myvpn # every server of a subscriptionzev proxy use auto # every proxy you savedzev proxy use work,home,backup # these oneszev times every server at once (a small request through each), keeps the three best running, and Xray sends each connection through the fastest that answers, checking them again every 30 seconds. When the one in use goes down, the next connection takes another; nothing for you to do. Every 30 minutes the next zev command times the whole list again, so a server that got better comes back.
To see the ranking, or rank them now:
zev proxy probeProbing 4 servers at once (https://www.gstatic.com/generate_204)… server now expected answers ● work 92 ms 95+-12 100% vless proxy.example.com:443 … ● home 140 ms 151+-20 100% trojan home.example:443 … ● backup 410 ms 388+-61 83% shadowsocks 203.0.113.9:8388 … old down - 0% vmess old.example:443 …● in use (the best 3 by expected latency and answers; Xray switches between them)zev proxy probe <name>, zev proxy probe auto or zev proxy probe a,b,c rank other servers without switching to them. zev proxy status shows which servers the engine runs now.
A chain reaches its last server through the ones before it. Use one when the server you want to come out of is blocked from your network but reachable from another server:
zev proxy chain out home work # zev → home → work → Zarynzev proxy use outhome sees only that you connect to work; Zaryn sees work's address. Each hop is a saved proxy, any of the kinds above. Hysteria2 and WireGuard run over UDP, so in a chain they can only be the first hop. zev proxy ls lists chains with their hops, and zev proxy rm out forgets one (a proxy that is a hop of a chain can't be removed until the chain is).
Some places are faster without the proxy, or only work without it: a server in your own country, a company mirror, sites that refuse connections from abroad. Routes send those direct and everything else through the proxy (split routing):
zev proxy route iran # Iran's sites and addresses directzev proxy route direct git.company.example 10.20.0.0/16zev proxy route proxy blocked.example.ir # through the proxy, whatever a direct route sayszev proxy route # list themzev proxy route rm git.company.examplezev proxy route clear| A route | Matches |
|---|---|
example.com | that name and every name under it (api.example.com) |
.ir | every name ending in .ir |
full:host.example | that name only |
5.160.0.0/16, 2a01:5ec0::/29, 203.0.113.7 | addresses |
geoip:ir | every address in a country (any two-letter country code) |
geosite:category-ir | a list of a country's or a service's sites, kept by the Xray project |
iran | .ir, geosite:category-ir and geoip:ir together |
Routes apply to every proxy, single servers, pools and chains alike, from the next zev command. geoip: and geosite: use Xray's routing data, which zev proxy engine install puts beside Xray; if you installed the engine before these routes existed, run it once more. With a route on addresses, Xray looks up names on this computer to compare them; names that only resolve through the proxy still go through it.
sudo zev net up takes the proxy you use and saves it with the network, so the network's background service reaches Zaryn and the relay through it as well. The relay's traffic travels inside the proxy too, which is how a device behind a network that blocks everything else still joins its team. zev net status shows through the proxy … when this is the case.
sudo zev net up your-name/office # with the proxy you usesudo zev net up your-name/office --proxy home # with another saved proxy (a pool or a chain works too)sudo zev net up your-name/office --no-proxy # directlyThe service runs its own copy of Xray from /var/lib/zev/net (root only), never one from your home folder. Devices behind a proxy talk to their peers through the relay. Their traffic stays end-to-end encrypted; the proxy and the relay only see WireGuard's encrypted packets.
Addresses on your computer, your local network and private networks: localhost, 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10 (private networks), fc00::/7 and *.zaryn.internal. To change this list, set ZEV_NO_PROXY to your own, in curl's --noproxy form (names, .domains, CIDR ranges).
zev proxy off to connect directly.pcs= / pinSHA256=), and zev passes that on. zev ignores allowInsecure in links: a link someone hands you can't switch certificate checks off.zev proxy share on listens on 127.0.0.1 only; --lan opens it to the network only behind a password.sudo zev vpn on copies Xray into /var/lib/zev/vpn, owned by root, so a root service never runs a file your user account could replace.127.0.0.1 only, behind a random password. curl gets that password from a file only you can read, never from its command line, so other users on the computer can't use your proxy or see it.