WSL2 & Linux · systemd · Xray TUN

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.

wsl2 — bash
$ 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
Why tunx

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.

Deployment Modes

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.

Default Mode

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
--gateway

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
Architecture

Three kernel policy rules, one firewall boundary

No autoSystemRoutingTable magic, no fragile IP exemptions for changing DDNS upstreams.

Rule 8991 · uidrange tunx

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.

Rule 8995 · fwmark inbound

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.

Rule 9100 · table 100

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.

CLI Reference

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.