What this guide covers (and what it assumes)

You already know why you want Clash Meta on Linux: ordered rules, multiple protocols under one Mihomo core, and the option to steer traffic either through a classic mixed port or through a TUN adapter that stubborn applications cannot easily ignore. The missing piece in many forum threads is not another pasted YAML fragment but a coherent operating-system story—where files live, which user owns them, how systemd restarts the daemon, and which capability flags make TUN work without logging in as root.

This article targets recent Ubuntu LTS releases on both desktop and server profiles. It assumes you have a working subscription or profile you are allowed to use, and that you can edit YAML without breaking indentation. It does not try to rank providers or nodes; it focuses on installation mechanics, autostart, and aligning the Linux network stack with what Mihomo expects. If you need a refresher on capture mode concepts before you touch tun: blocks, read the Clash TUN mode guide on this site first—the mental model pays off immediately on Linux where “system proxy” is less universal than on macOS or Windows.

Step 1: Choose a layout for the binary and configuration

Pick one layout and keep it boring. Most administrators use /opt/mihomo or /etc/mihomo for the read-only profile and runtime state separation, while still keeping secrets out of world-readable paths. A common pattern is:

  • /usr/local/bin/mihomo (or clash-meta, depending on the archive you unpack)—the executable.
  • /etc/mihomo/config.yaml—the primary configuration file referenced by your unit.
  • /var/lib/mihomo—writable home for caches, GeoIP databases, and downloaded rule providers.

Create a dedicated Unix user such as mihomo if you want defense in depth: the service account should own the writable tree and should not be a member of sudo-capable groups unless you have a specific reason. For single-user desktops, running as your own UID is acceptable if you accept the trade-off that any app running as you can signal the process.

Grab a maintained build from the official Clash download page for Linux rather than chasing random mirrors. After unpacking, verify the binary runs interactively once before you hide it behind systemd: ./mihomo -d /path/to/work -f /etc/mihomo/config.yaml should print listener lines without immediate fatal errors. If it cannot parse YAML, fix that on the terminal where logs are visible; do not debug syntax through journalctl until the interactive path is clean.

Step 2: Minimal configuration before TUN

Start with a profile that already works in “plain listener” mode. You need a stable mixed port (or explicit HTTP and SOCKS ports) and a sane DNS section that matches how you plan to use fake-ip or redir-host mode. Many Ubuntu failures that look like “TUN broke everything” are actually DNS loops or resolver clashes that only become visible once auto-route turns on.

Confirm these basics in YAML before enabling TUN:

  • mixed-port (or paired HTTP and SOCKS ports) bound to 127.0.0.1 unless you truly intend LAN exposure.
  • An external-controller address you understand, protected from the public interface.
  • DNS inbound that does not fight systemd-resolved on port 53 unless you intend to replace the stub listener—on desktop Ubuntu that conflict is a frequent footgun.

For a structured walkthrough of core upgrades and field renames when you migrate profiles, pair this install with the Clash Meta (Mihomo) upgrade guide so you are not mixing deprecated keys with new TUN defaults.

Step 3: Wire systemd for boot-time autostart

Once interactive startup is reliable, move the same arguments into a unit file such as /etc/systemd/system/mihomo.service. The important ideas are: explicit User= and Group=, a working directory with write permission for caches, Restart=on-failure with a sane burst limit, and LimitNOFILE high enough for busy rule sets.

Example skeleton (adjust paths and user names to match your layout):

[Unit]
Description=Mihomo (Clash Meta) daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/var/lib/mihomo
ExecStart=/usr/local/bin/mihomo -d /var/lib/mihomo -f /etc/mihomo/config.yaml
Restart=on-failure
RestartSec=3
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

Reload units, enable, and start:

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo.service
sudo systemctl status mihomo.service

If the service exits immediately, read journalctl -u mihomo -e. The first pass should reveal YAML errors, missing directories, or permission denials on the state path. Fix those before enabling TUN; otherwise you will blame the kernel for what is actually a filesystem ACL problem.

Step 4: Enable TUN in YAML and understand the stack choice

When listeners alone are insufficient—containers, Go binaries that ignore http_proxy, or games that open raw sockets—TUN mode moves policy to the IP layer. On Ubuntu the Mihomo documentation typically offers multiple stacks; system leverages the kernel path you already trust, while gvisor can help in niche environments at a latency cost. Start with system on bare metal or mainstream VMs unless you have a measured reason to switch.

A representative tun: block might look like this (verify against your exact core version; keys evolve):

tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  strict-route: false

Turn features on one at a time. Enable TUN, restart, confirm a tunnel interface such as tun0 appears in ip link, then add DNS hijack options only after basic forwarding works. If you toggle five keys at once and routing breaks, you will not know which assumption failed.

Capability-wise, CAP_NET_ADMIN is non-negotiable for creating and managing the tunnel; CAP_NET_BIND_SERVICE matters if you bind privileged ports. The sample unit above uses AmbientCapabilities so a non-root user can retain them without a setuid binary. Some administrators prefer setcap on the executable instead; both approaches are common. Avoid running the daemon as root long term unless your threat model explicitly requires it.

Step 5: DNS, systemd-resolved, and desktop resolvers

Ubuntu desktops often run systemd-resolved, which listens on 127.0.0.53 and forwards according to NetworkManager. Mihomo may want to become the resolver for captured traffic. The failure mode you are trying to avoid is simple: applications query a stub that bypasses Mihomo, so domains resolve “directly” while packets ride the tunnel, or the opposite—everything resolves through Mihomo but local NXDOMAIN breaks corporate split DNS.

Practical guidance:

  • Decide whether Mihomo or the OS owns upstream DNS for captured clients. Mixing without a diagram leads to loops.
  • If you enable aggressive DNS hijacking in TUN, test both a public hostname and a LAN hostname that must stay on split routing.
  • When in doubt, capture logs with debug DNS logging temporarily, reproduce one failing name, then revert log noise.

For more scenarios—especially fake-ip interplay—reuse the troubleshooting map in the TUN guide; Linux differs from Windows mainly in resolver plumbing, not in the high-level idea that DNS and routing must agree.

Step 6: GNOME proxy versus “TUN only” on the desktop

Even with TUN enabled, some users still toggle GNOME’s manual proxy so Chromium-based apps pick up HTTP settings without relying on capture. That is fine as long as the port numbers match your mixed-port and you understand that double paths can confuse debugging. A cleaner split for many people is: TUN for global capture, mixed port only for diagnostics and for tools that explicitly support SOCKS.

If you prefer not to use TUN on a workstation—perhaps because another VPN already owns the system TUN interface—fall back to manual proxy settings plus shell exports. The ergonomics mirror macOS more than you might expect; the difference is that Ubuntu exposes more moving parts (NetworkManager, resolved, iptables/nftables backends). Pick one primary strategy per profile and document it in your own runbook so future you does not chase two contradictory setups.

Step 7: Align shells, apt, and CI jobs with the mixed port

Servers without a desktop still benefit from Mihomo when outbound policy must respect the same rules as your laptop. Export http_proxy, https_proxy, and uppercase equivalents consistently, and maintain no_proxy for loopback and RFC1918 targets so internal apt mirrors do not traverse a distant node. Tools that ignore environment variables need TUN or explicit tool configuration—there is no third magic option.

For interactive shells, place exports in the file your login and non-login sessions actually source; Ubuntu’s default bash and zsh behaviors differ from minimal cloud images. If you automate with cron or systemd user units, remember those environments often strip variables unless you set them inside the unit. A quick curl -v test from the same context that runs your job prevents silent direct egress.

Step 8: Verification checklist before you touch firewall rules

Work in this order:

  1. systemctl is-active mihomo and a clean status line.
  2. ss -lntp shows listeners on the expected loopback ports.
  3. With TUN on, ip route and interface lists include the Mihomo-managed device without obvious duplicate defaults.
  4. DNS resolution for a canary domain matches the path you expect (direct versus policy).
  5. A controlled download or TLS probe proves egress changes when you switch policy groups.

Only after those pass should you integrate with ufw, nft, or cloud security groups. Otherwise you risk debugging three layers—application YAML, netfilter, and provider routing—simultaneously.

Common Ubuntu pitfalls and how to escape them

  • Service starts then dies: almost always YAML, ownership on /var/lib/mihomo, or a bad -d path. Confirm with logs, not guesses.
  • TUN fails with permission errors: missing CAP_NET_ADMIN, AppArmor profile surprises on custom binaries, or SELinux contexts if you migrated profiles from another distribution.
  • “Connected” but browsers hang: DNS loops or MTU black holes; isolate with dig, ping, and Mihomo logs before rewriting rules.
  • Two VPN clients fighting: only one stack should own default routes; disable the other or split profiles.

Where to go next in the documentation set

Installation is just the shell around policy. After your unit is stable, spend time in the Clash documentation hub for rule ordering, provider refresh intervals, and performance habits that matter more than any single Linux tweak. Keep the daemon updated on a schedule you can explain to future maintainers; the upgrade guide lists the checkpoints that prevent silent behavior changes across versions.

Closing: make Linux behave like one coherent client

Ubuntu rewards boring engineering: explicit paths, a systemd unit you can inspect, capabilities instead of root, and DNS decisions you can draw on a whiteboard. Clash Meta on Linux is not harder than on other platforms—it simply exposes more knobs because the OS expects you to understand them. Lay down listeners first, prove YAML health, add TUN when capture buys you more than configuration debt, then align desktops or shells with the same mixed port story.

Compared with stitching together unrelated proxy snippets per application, a maintained Mihomo core with transparent upgrade paths and clear documentation usually wins on stability. If you want curated installers and room to grow into advanced routing without hunting nightly artifacts, pick a profile you trust, walk the checklist above, and validate with two tests: one host that must stay direct and one that must show policy egress. When both behave, you can leave the terminal and let systemd handle the rest.

Download Clash for free and experience the difference

Download Clash from this site