Linux is where many power users actually live: remote shells on cloud instances, long-running desktops on Ubuntu or Debian, CI runners, and homelab servers that never touch a GUI. Those environments reward the same qualities people like about Clash—predictable rule-based routing, modern protocols, and a single configuration surface you can version-control. What Linux historically lacked was a single, copy-paste-friendly story that connects three pieces end to end: command-line installation of a maintained Clash Meta (Mihomo) binary, TUN transparent proxy so traffic does not depend on broken HTTP_PROXY conventions, and a systemd unit that brings the stack up on boot without manual intervention. This guide closes that gap for 2026, with Ubuntu and Debian as the reference distros and security-conscious defaults you can tighten further.
1. What You Are Building (and What TUN Changes)
Most introductory tutorials stop at “set environment variables and run curl.” That works until you hit binaries that ignore proxies, containers with their own network namespaces, or long-lived daemons that resolve DNS outside your rules. TUN mode creates a virtual network interface and lets the Clash core participate in the host routing table so eligible packets are steered through your policy engine before they leave the machine. On Linux this is closer to how commercial VPN clients behave than to a browser-only HTTP proxy.
The trade-off is responsibility: you are manipulating interfaces and DNS behavior on a general-purpose OS, so you should treat this like any other network-facing service—explicit paths, readable logs, and a service manager that restarts sanely. That is why we pair TUN with systemd: it gives you journalctl visibility, dependency ordering, and a clear autostart contract after reboots.
mihomo or clash-meta depending on the release channel; functionally they refer to the same family of features (TUN, RULE-SET, modern outbounds).
2. Prerequisites on Ubuntu and Debian
These steps assume a 64-bit x86_64 or arm64 machine running a recent Ubuntu LTS (22.04/24.04) or Debian 12 “Bookworm,” with sudo available. You need kernel support for TUN (/dev/net/tun present—true on stock kernels) and permission to install packages. If you are on a headless server, perform the download on a trusted workstation and verify checksums before copying the binary across; if you fetch directly on the host, prefer HTTPS endpoints and pin versions.
Install baseline tooling once:
sudo apt update
sudo apt install -y curl ca-certificates iptables iproute2 dnsutils
iptables (or nftables, depending on your stack) matters because some TUN implementations expect policy routing hooks to coexist with your firewall; having the userspace tools installed avoids opaque failures when you later tune forwarding. If you use only nft, keep your rule sync discipline—the point is not to fight Clash’s routing layer with a forgotten FORWARD DROP.
3. CLI Install: Place the Binary and a Working Directory
GUI installers do not exist in this workflow by design. Create a dedicated directory for configuration and runtime state—this keeps upgrades simple and makes SELinux/AppArmor policies easier if you add them later:
sudo mkdir -p /etc/clash
sudo install -o root -g root -m 0755 /path/to/mihomo /usr/local/bin/mihomo
Replace /path/to/mihomo with the unpacked binary you obtained from a trusted release channel. On Ubuntu/Debian, verifying with sha256sum against published checksums is non-negotiable when you automate downloads. If your organization mirrors artifacts internally, keep the same directory layout so your unit files remain portable across machines.
Seed a minimal configuration at /etc/clash/config.yaml. At minimum you need a listening mixed port for local apps, a sane logging level, DNS settings that cooperate with TUN, and at least one outbound plus a rule that references it. Most users import a remote profile via proxy-providers; conceptually you are telling the core to refresh subscription material on an interval and merge it into the active policy graph. For a deeper tour of RULE-SET design and DNS modes, see our Ultimate Clash Meta 2026 guide—the ideas map directly to Linux, even though the examples there are not distro-specific.
4. Enable TUN: Transparent Proxy Without Guessing Ports
In the configuration, locate the tun section (exact keys vary slightly by core version; always diff against the upstream sample for your release). A typical intent looks like this:
tun:
enable: true
stack: system
auto-route: true
auto-detect-interface: true
strict-route: true
stack: system uses the operating system’s native TUN implementation; gvisor is available on some builds when you need userspace TCP semantics, at the cost of complexity. auto-route asks the core to manage routing entries so user traffic can follow your rule outcomes without hand-maintaining tables for every subnet. strict-route reduces accidental leaks in split-tunnel setups, but you should still validate DNS separately—routing without DNS alignment produces the classic “page half loads” failure mode.
Pair TUN with a deliberate DNS block. On Linux desktops and servers alike, we recommend starting from fake-ip mode for browsing-shaped workloads when your rules and providers support it, combined with explicit nameserver lists and fallback behavior that does not silently bypass the core. If you run systemd-resolved, pay attention to stub listeners on 127.0.0.53; either integrate cleanly or stop fighting split DNS you did not intend. The goal is one coherent resolution path for traffic Clash handles.
5. systemd: Unit File, Autostart, and Logs
Create /etc/systemd/system/clash.service:
[Unit]
Description=Clash Meta (Mihomo) Daemon
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/clash
Restart=on-failure
RestartSec=3
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
Reload units, enable autostart, and start now:
sudo systemctl daemon-reload
sudo systemctl enable --now clash.service
sudo systemctl status clash.service --no-pager
Your operational interface becomes journalctl:
journalctl -u clash.service -f
When something breaks after a reboot, check three places before editing YAML at random: the unit’s exit code, whether /etc/clash permissions still allow reading providers, and whether an automatic update changed schema expectations. A service that restarts in a tight loop is almost always a config parse error or a missing file path—both show up early in logs if you look.
6. Verification: From Interface Up to End-to-End Policy
First confirm the daemon stays up and the tun interface appears (name varies):
ip link show
ss -lntp | head
Then validate DNS and routing decisions with tools that respect the stack you actually configured—dig against the listener you intend, and curl tests against endpoints whose geography or CDN behavior you already understand. If you maintain a private RFC1918 mesh, add explicit rules that pin those prefixes to DIRECT so Clash never surprises your internal APIs.
For comparison with desktop ecosystems, our macOS setup guide walks through analogous TUN enablement and DNS caveats on Apple systems—the mental model transfers even when the implementation details differ.
7. Hardening and Day-Two Operations
Once autostart works, tighten the deployment: restrict file permissions on /etc/clash, rotate subscription URLs if leaked, and keep the core updated when security advisories land. If multiple operators share a host, prefer configuration management (Ansible, Nix, or plain Git) over ad hoc edits. For CI runners, consider a dedicated network namespace or container with an explicit entrypoint that mirrors production routing—avoid “works on my laptop” proxies that hide missing egress rules until deploy time.
When you outgrow a single host, revisit outbound selection and observability: health checks, policy tracing, and metrics endpoints are where Clash Meta shines. The Clash blog index collects focused articles on load balancing and rule syntax that pair well with a stable Linux baseline.
8. Troubleshooting Shortlist
Service fails immediately: run the binary interactively with the same -d directory to surface YAML errors. No tun interface: confirm kernel modules and that nothing else exclusively owns routing policy. DNS oddities: align systemd-resolved, NetworkManager, or static resolv.conf behavior with the DNS stanza in your config—mixed setups cause fake-ip mismatches. Unexpected LAN breakage: verify DIRECT rules for private ranges and that strict routing did not overfit a transient interface name.
9. Closing Thoughts
Linux users do not need another fragmentary gist—they need a coherent pipeline from binary to policy to persistence. Installing Clash Meta from the CLI, turning on TUN for genuine transparent proxy semantics, and wrapping the daemon in systemd gives you that pipeline without sacrificing observability. The result is closer to infrastructure than to a one-off hack: repeatable, auditable, and ready for the same discipline you already apply to the rest of your stack.
Compared with juggling ad hoc environment variables and per-tool proxy flags, a routed TUN setup with sane DNS feels almost unfairly stable—especially when your workload mixes browsers, language package managers, and background services that were never proxy-aware to begin with. If you would rather start from a curated client experience and still benefit from Meta-class cores on desktop platforms, grab our maintained build from the download hub and map what you learn here onto GUI workflows later.