Linux Lab · · Approx. 18 min read

Install Clash Meta on Fedora: systemd Boot Setup and Mixed Port First Steps (2026)

Fedora ships a polished dnf / rpm culture, firewalld, and a security posture that differs from “drop a .deb on Ubuntu and go.” If you already read an Ubuntu-centric Clash Meta install guide, the mental model still applies—upstream mihomo is the same engine—but the packaging story, paths, and first-time mixed-port tuning deserve a Fedora-shaped checklist. This article walks you from a clean binary placement through a systemd unit for boot auto-start, then locks in a single local listener strategy so your Linux desktop proxy, terminals, and containers can all aim at one well-documented port. Pair it with our Ubuntu Clash Meta + systemd guide when you need the deb-specific commands for comparison.

1. Why Fedora Differs from Ubuntu for mihomo

Most English-language tutorials assume Debian packaging: apt install ./something.deb, predictable paths under /var/lib/dpkg, and AppArmor profiles you may never notice until they bite. On Fedora, you live inside the RPM ecosystem: dnf resolves dependencies from repositories you explicitly trust, rpm -qa inventories what the system believes it owns, and major version upgrades are a first-class expectation rather than an occasional surprise. None of that changes how mihomo parses config.yaml, but it changes how you should narrate your install to future you when you rebuild a laptop or promote a profile from Workstation to Silverblue-style workflows.

Another Fedora-specific angle is the intersection of desktop polish and conservative defaults. You might install the engine from an upstream release archive, a locally built RPM spec, or a third-party repository you audited yourself. The common failure mode is not “I cannot find a deb”—it is “I dropped a binary into ~/bin, it worked until reboot, and now I cannot tell whether systemd or my interactive shell started the second copy that stole mixed-port.” This guide therefore emphasizes a single service definition, one configuration directory, and explicit listener binding so your Linux desktop proxy settings survive updates and sleep cycles.

Finally, remember that “Clash Meta” is conversational branding while the maintained core is commonly shipped as mihomo. Documentation, unit files, and firewall rules should all agree on the binary name you actually invoke in ExecStart. Consistency there prevents subtle divergence between journal entries, process monitors, and your own muscle memory when you SSH in from another machine.

2. Install Paths: Tarball, Local RPM, and dnf Hygiene

Fedora does not magically provide an official “Clash button” in the base OS repositories the way some distributions bundle desktop conveniences. The boring, reproducible pattern is: fetch a release artifact that matches your architecture from the upstream project you trust, verify checksums if your threat model requires it, place the binary under /usr/local/bin/mihomo with executable permissions, and keep the version string in a small operator note. If you prefer RPM semantics, you can wrap the same binary in a local spec file so rpm -q mihomo answers versioning questions during audits; that is more work up front but pays off when you manage dozens of workstations.

Some teams use community COPR repositories for convenience. That can be legitimate, but treat every COPR like untrusted code until you read the spec, inspect the build logs you care about, and understand update cadence. Corporate laptops may forbid third-party repos entirely; in that case the tarball-to-/usr/local/bin path is often the only compliant route. Wherever your binary lands, confirm with command -v mihomo and mihomo -v before you wire systemd, so you are not debugging a unit file that points at a stale path after an upgrade moved files under your feet.

Use dnf for supporting packages you will need on a typical Workstation: certificate bundles are already present, but tooling such as curl for smoke tests, bind-utils for DNS debugging, or iptables-nft documentation packages may save time when you escalate from YAML tweaks to packet-path questions. Keep that package list short; the goal is a maintainable node, not a kitchen-sink developer image.

3. Configuration Layout Under /etc/mihomo

Mirror the Ubuntu mental model: a dedicated directory—commonly /etc/mihomo—owned by root or by a dedicated service account, containing config.yaml plus any downloaded rule providers, GEOIP databases, and cache files the process is allowed to write. On Fedora, pay attention to SELinux contexts if you choose nonstandard paths under /srv or bind-mounted locations; the quick-start layout under /etc usually avoids surprises because administrators already expect configuration there.

Before you enable the daemon, validate YAML in the foreground once: sudo mihomo -d /etc/mihomo, watch for parser errors, confirm outbound policy groups behave as expected, then interrupt. If you are importing a subscription for the first time, follow the dedicated subscription import tutorial so your proxy list and policy anchors are coherent before boot automation enters the picture.

Logging strategy: systemd captures stdout and stderr into the journal when you use a simple Type=simple service, which is often enough. If you also enable verbose file logging under /var/log, rotate consciously so a forgotten debug level does not exhaust disk on a small VM. Operators who live inside journalctl rarely regret centralizing there first.

4. mixed-port First: One Listener for HTTP and SOCKS

The user intent behind “mixed-port” searches is consolidation: instead of memorizing separate HTTP and SOCKS port numbers, you expose one listener that speaks both families of clients well enough for day-to-day desktop work. In Meta-flavored profiles, that usually means defining mixed-port alongside mode and bind directives that match how paranoid you are about LAN exposure. A conservative laptop profile binds to 127.0.0.1 only; a lab gateway that also serves containers or phones on the same subnet may enable allow-lan and bind more broadly after you understand the firewall story.

Pick a port that does not collide with common developer services. 7890 is culturally popular in Clash examples, but if you run certain Java application servers or legacy stacks, scan with ss -lntp before you commit. Once chosen, document the number in your team wiki and in GNOME/KDE proxy panels so newcomers are not forced to grep your YAML to discover how traffic should leave the browser.

After the daemon runs, verify from the same host with curl -x http://127.0.0.1:<port> https://example.com and, if you rely on SOCKS-aware tools, a second check with your client’s native SOCKS mode pointed at the same port. If HTTP succeeds but SOCKS consumers fail, you are usually looking at a client assumption mismatch rather than a broken tunnel—mixed-port is doing its job when both transports share a coherent outbound policy path.

Example listener skeleton (adapt keys to your template version)

# Excerpt only — merge into your real config.yaml
mixed-port: 7890
allow-lan: false
# Optional: bind-address / interface-name per your build; verify with ss -lntp.

Once mixed-port is stable, environment-variable-based workflows become teachable: export http_proxy and https_proxy to http://127.0.0.1:<port> in shells that should traverse the tunnel, and maintain a thoughtful no_proxy list for intranet hosts. That pattern mirrors what we describe for containers in the Docker through host Clash guide, except here the “remote host” is simply your own loopback interface.

5. systemd Unit: Boot Order, Restart, and Journal Logs

Fedora’s systemd is the right place to express lifecycle policy. Create /etc/systemd/system/mihomo.service with an ExecStart that points at the real binary path and passes -d /etc/mihomo (or your chosen directory). Ordering after network-online.target reduces races on Wi-Fi-centric laptops where DHCP and DNS need a moment to settle before the first outbound subscription fetch.

# /etc/systemd/system/mihomo.service
[Unit]
Description=mihomo (Clash Meta) proxy daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

Reload, start, enable: sudo systemctl daemon-reload, then sudo systemctl start mihomo, inspect systemctl status mihomo --no-pager, and when satisfied run sudo systemctl enable mihomo for boot integration. Logs live in journalctl -u mihomo -e; that command should become your first reflex when a subscription URL rotates or when TLS MITM tooling on a corporate network interferes with remote rule providers.

Restart policy tuning mirrors Ubuntu guidance: Restart=on-failure avoids respawning after a clean operator stop, while Restart=always with rate limits may suit flaky dynamic environments. Whatever you pick, document it next to the unit so a teammate does not “fix” perceived flapping by removing restarts entirely and reintroducing manual babysitting.

6. firewalld, SELinux, and Localhost-Only vs LAN

When mixed-port binds beyond loopback or when allow-lan is true, firewalld becomes part of your security boundary. A typical Workstation profile may still filter incoming connections on Wi-Fi zones; open only the port you intend to share, for the zones you intend to share with, and prefer rich rules tied to source subnets instead of wide global acceptance. Re-test from another device with curl through the proxy only after you confirm the daemon itself listens where you think it does.

SELinux in enforcing mode is good for you, even when it complicates exotic TUN experiments. If you place binaries or configs in unusual paths, you may need restorecon or targeted booleans; consult AVC denials in the journal rather than flipping globally permissive modes during frustration. Most HTTP/SOCKS-only deployments never need deep SELinux surgery when files live under /etc/mihomo and the binary sits in /usr/local/bin.

Treat any external-controller or REST management endpoint as sensitive: bind it to loopback, require secrets, and never expose it on untrusted LANs without tunneling through SSH. The ecosystem has seen too many “temporary” admin sockets left open on coffee-shop networks.

7. GNOME and KDE: Point the Desktop at mixed-port

Fedora Workstation defaults to GNOME; KDE Spin users follow parallel panels. Both environments expose manual HTTP proxy settings that should reference 127.0.0.1 and your chosen mixed-port. SOCKS-aware applications may pick up the same port depending on how they interpret “use system proxy.” Flatpak applications sometimes ignore host-wide GNOME proxy settings unless you configure overrides; when a Flatpak app stubbornly bypasses the tunnel, check its own network permissions before you assume Clash failed.

Terminal workflows inherit environment variables from your shell profile inconsistently: login shells versus non-login shells, tmux panes launched from GUI terminals, and IDE-integrated terminals all diverge. Standardize on a tiny script that exports proxy variables when you want them, rather than permanently forcing global profiles that break local-only tooling.

Browser extensions that manage proxy switching can still coexist with a system-wide default; just avoid having two different extensions fighting over PAC files while mihomo also rewrites DNS in ways those extensions do not understand. Pick one steering layer per browsing profile.

8. Rules, DNS, and dnf Through the Proxy

Package managers are HTTPS clients like anything else. If you force all traffic through a policy group that blocks Fedora mirror domains by mistake, dnf will fail in cryptic ways. Keep domestic mirror and CDN domains on sane paths—often DIRECT when that matches your policy—or dedicate a “system update” policy group with a stable exit. The routing and rules reference on this site explains how rule order interacts with GEOIP and fallback groups; read it once, then encode explicit domain rows for the mirrors you actually hit rather than hoping broad GEOIP guesses match Fedora’s CDN reality.

DNS deserves equal paranoia. fake-ip modes interact with systemd-resolved, browser DNS-over-HTTPS, and corporate split-horizon DNS in ways that look like “Clash broke dnf” when the real issue is name resolution returning addresses your rules never classify the way you expect. When debugging, compare dig results with and without the tunnel, and read mihomo logs for which DNS outbound handled each query.

Corporate environments sometimes require an explicit proxy for all egress including updates; in that case export proxy variables for the root session running dnf, or configure dnf’s proxy keys in /etc/dnf/dnf.conf with the same host and port you validated for interactive shells. Document the split between “user session uses mixed-port” and “root dnf uses the same mixed-port” so future migrations do not drop updates silently behind a policy change.

9. Optional TUN and Capabilities on Fedora

Application-level proxies cover many developer workflows; TUN mode exists for users who want broader capture without per-app configuration. On Linux that path frequently implies elevated capabilities such as CAP_NET_ADMIN. systemd can grant capability bounding sets through unit directives, but each widening is a conscious security trade-off you should review with the same rigor as opening a firewall port.

Read the upstream documentation for the exact keys your profile revision expects, validate with short foreground runs, and keep a rollback YAML without TUN stanzas before you touch default routes on a remote-only server. For conceptual background, see the TUN mode overview on this site; it remains client-agnostic enough to apply to Fedora hosts even when your daily driver elsewhere is Windows or macOS.

IPv4/IPv6 dual-stack homes add another layer: if you enable TUN but leaks persist, you may need explicit IPv6 policy alignment. That is a different deep dive than this first-boot article, yet it is worth naming so you do not assume TUN alone magically harmonizes both address families without YAML and OS-level cooperation.

10. Troubleshooting Checklist

Active unit but curl fails. First confirm the listener with ss -lntp, then re-read mixed-port bind settings. Second, inspect rules for accidental REJECT on the domains you test. Third, remember DNS: fake-ip can make failures look like TCP timeouts when the name never resolved the way you thought.

Works until reboot. You forgot systemctl enable, or a conflicting user-session autostart launches a second binary. Use systemctl is-enabled mihomo and search your desktop autostart directories for duplicate launchers.

dnf is slow or fails only when Clash is on. You probably need explicit mirror domain rules or a dedicated update policy group, not another restart of the daemon.

LAN clients cannot reach mixed-port. Revisit firewalld zones, confirm allow-lan intent matches your bind addresses, and avoid Wi-Fi client isolation on guest networks that will never allow lateral proxy access regardless of YAML perfection.

11. Closing Thoughts

Installing Clash Meta on Fedora is less about memorizing a single magical rpm name and more about adopting habits that survive audits: one trusted binary location, one configuration directory, one systemd story for boot and crash recovery, and one clearly documented mixed-port that your desktop, terminals, and adjacent guides can all reference. Compared with ad hoc terminal sessions, that structure keeps your Linux desktop proxy boring—and boring is what you want when you are halfway through a remote presentation and the network path changes under you.

When you maintain multiple machines across Ubuntu and Fedora, the YAML may stay similar while the packaging diverges; keep a short internal runbook per distribution so you do not accidentally apply apt muscle memory to dnf hosts. The operational payoff is fewer “it worked on the other laptop” mysteries when teammates borrow hardware during travel.

Upstream source code and release artifacts for the mihomo core are maintained in the MetaCubeX/mihomo repository on GitHub. That link is for transparency, changelogs, and issue tracking; for curated client bundles across platforms, prefer this site’s download flow rather than treating GitHub as the primary installer channel.

If you want a single place to compare ecosystem clients after your Fedora service is stable, browse the official download hub for maintained builds and cross-platform options. Compared with juggling stray archives, that approach keeps versions legible across the fleet of machines you actually carry. → Download Clash for free and experience the difference

Hand-picked deep-dives on the same topic — practical Clash routing guides in the same category.