Every packet through your Xray config. Fail-closed by design.
Send all TCP, UDP, and DNS traffic on WSL2 or Linux into an Xray TUN interface.
tunx handles only the kernel routing, nftables physical-interface lock, DNS, and self-healing services — your own Xray config decides every outbound and split rule.
$ git clone https://github.com/tunx-org/tunx.git && cd tunx $ cp examples/vless-reality.jsonc my.jsonc # fill upstream $ sudo ./install.sh install --config my.jsonc
TCP egress : 203.0.113.7 DNS egress : 203.0.113.7 DNS repeat : 0 ms UDP (STUN) : 203.0.113.7 IPv6 : none Bind eth0 : blocked
Infrastructure only. Zero silent leaks.
Programs that ignore HTTP_PROXY, raw UDP sockets, and stray local resolvers are all captured at the kernel boundary.
Your Xray Config, Untouched
Outbounds, domain split rules, and LAN direct live in /etc/tunx/config.json. Existing configs are validated before reload and never overwritten.
Fail-Closed Policy Routing
Routing rules load before network-pre.target with an unreachable fallback in table 100. If Xray crashes or stops, packets cut off rather than leaking direct.
Physical Interface Lock
An inet tunx nftables ruleset blocks applications from binding sockets directly to eth0 to bypass the TUN, verified automatically on every test run.
Self-Healing Guard
tunx-guard.service subscribes to ip monitor and nft monitor plus 10-second ruleset verification, restoring flushed tables or altered rules within ~0.5 s.
Zero-Leak Cached DNS
Intercepts port 53 traffic (including private DHCP resolvers), blocks WSL's 10.255.255.254 stub, and caches DoH answers inside Xray for 0 ms repeat lookups.
IPv6 & Exit Time Zone
Persistently disable TUN IPv6 with --disable-ipv6, or align Linux /etc/localtime (and WSL useWindowsTimezone=false) to your egress IP via tz with clean restore on uninstall.
Host TUN or transparent LAN gateway
Run inside WSL2 / desktop Linux for local workloads, or deploy on a minimal Debian VM to serve devices across your LAN.
WSL2 & Linux Workstation
Captures all traffic of the Linux host or WSL2 distribution while keeping Windows host processes untouched. Optional flags lock off IPv6 and sync Linux time zone to the exit.
git clone https://github.com/tunx-org/tunx.git cd tunx cp examples/vless-reality.jsonc my.jsonc sudo ./install.sh install --config my.jsonc --disable-ipv6 sudo ./install.sh tz
Transparent LAN Side-Router
Point any LAN device's default gateway and DNS at this host. Forwarded TCP/UDP enters tunx0, port 53 returns IPv4-only answers, and clients cut off cleanly if Xray is down while host SSH stays reachable.
git clone https://github.com/tunx-org/tunx.git cd tunx cp examples/gateway.jsonc gateway.jsonc sudo ./install.sh install --gateway --config gateway.jsonc ./install.sh test
Three kernel policy rules, one firewall boundary
No autoSystemRoutingTable magic, no fragile IP exemptions for changing DDNS upstreams.
Xray Egress Bypass
Xray runs as the dedicated tunx system user. Its own outbound sockets use the main routing table and conntrack marks, following DDNS upstreams and interface changes naturally.
Inbound Reply Symmetry
Connections initiated from outside (such as Windows accessing a service in WSL2 or SSH into a gateway VM) are marked in conntrack so replies leave via the original interface.
TUN Capture & Unreachable
All remaining traffic looks up table 100: default route into tunx0, backed by an unreachable route and nftables inet tunx physical-interface drop rules.
Lifecycle commands
Every configuration change is checked with Xray and structural DNS/TUN assertions before touching running services.
| Command | Purpose |
|---|---|
| sudo ./install.sh install [--config FILE] | Install or update Xray (SHA-256 verified), policy routing, nftables ruleset, DNS, and systemd units, then verify egress. |
| sudo ./install.sh reload | Validate /etc/tunx/config.json and restart Xray; leaves the running service untouched if validation fails. |
| sudo ./install.sh check | Validate TUN name, upstream DNS bootstrap rules, and Xray config syntax without restarting anything. |
| ./install.sh status | Show systemd unit states, active kernel routing rules, DNS configuration, Linux time zone, and WSL time sync setting. |
| ./install.sh test | Verify TCP, DNS, DNS cache latency, UDP (STUN), IPv6 mode, and physical-interface bind blocking (Bind eth0 : blocked). |
| sudo ./install.sh tz | Set Linux time zone to match the egress IP looked up through the TUN and persist useWindowsTimezone=false on WSL. |
| sudo ./install.sh uninstall | Remove services and rules, back up config.json, and restore original resolv.conf, wsl.conf, and time zone state. |