1. Why Debian 12 Deserves Its Own mihomo Runbook
Debian’s social contract and stable release cadence attract operators who value reproducibility over bleeding-edge churn. That mindset collides awkwardly with copy-paste tutorials written for Ubuntu LTS, where “add this PPA” or “just grab the deb from a random launchpad build” is treated as normal. On Debian 12, you are more likely to start from a minimal netinst, harden sshd, and only then think about userland proxies—so your Clash Meta deployment should look like any other piece of infrastructure: explicit file paths, a single systemd unit, and logs you can grep in journalctl without hunting orphaned terminal tabs.
Another Debian-specific reality is package provenance. The project does not ship mihomo in the main archive as a blessed “apt install clash-meta” story the way some rolling distributions wrap community packages. That is not a judgment on the software; it is a reminder that the boring, supportable pattern is usually “vendor the upstream release you audited, pin its checksum, install under /usr/local/bin, and document the version string.” When you later migrate the same YAML to a fleet of Bookworm servers, that narrative survives security reviews far better than “I followed a blog that hot-linked a rehosted binary.”
Finally, Debian’s default networking stack and firewall posture differ from Fedora’s firewalld world. Bookworm commonly exposes nftables through the iptables-nft compatibility layer, and many admins layer ufw on top for ergonomics. None of that changes how mihomo parses rules, but it changes the checklist you run through when you toggle allow-lan or bind mixed-port beyond loopback on a Linux server proxy that also faces the public internet through another interface.
2. Prerequisites, Architectures, and Naming (Clash Meta vs mihomo)
This walkthrough assumes Debian 12 (Bookworm) on a supported CPU architecture—typically amd64, but arm64 laptops and Raspberry Pi-class boards matter too. Match the upstream release asset to your uname -m output before you copy binaries. You need sudo or root for system-wide paths, working HTTPS to reach subscription endpoints, and the usual ca-certificates bundle Debian installs by default so TLS validation behaves predictably.
Install a small toolkit if your image is extremely minimal: sudo apt update followed by sudo apt install -y curl ca-certificates covers most smoke tests. Add vim or nano according to taste, plus dnsutils when you know you will debug split-horizon DNS alongside Clash Meta DNS modes.
Terminology: people say “Clash Meta” in forums, but the maintained core is commonly distributed and executed as mihomo. Your systemd unit, audit logs, and operator runbooks should all agree on the binary name in ExecStart. If you symlink clash-meta to mihomo for muscle memory, document it—future you should not wonder which path a security scanner flagged.
3. Install the Upstream Binary on Bookworm
The reproducible path on Bookworm is to download a release archive for your architecture from the upstream project you trust, verify the checksum if your policy requires it, extract the binary, and install it to /usr/local/bin/mihomo with mode 0755. That location is on root’s PATH for administrative shells, plays nicely with immutable infrastructure patterns, and avoids fighting dpkg ownership unless you deliberately package the software.
A typical operator sequence looks like: create a staging directory under /tmp, fetch the tarball or gzip bundle with curl -fLO, compare sha256sum output against the published digest, extract, then sudo install -m 0755 mihomo /usr/local/bin/mihomo. Adjust filenames to whatever the release ships; the invariant is “one canonical binary path referenced by systemd.” After installation, run /usr/local/bin/mihomo -v to print the build string you will record in change-management notes.
Corporate environments sometimes require air-gapped transfers. In that workflow, copy the same verified artifact through your file gateway, keep the hash in the ticket, and install identically—Bookworm does not care whether the bits arrived by browser or by USB, only whether the binary matches what security approved.
When you standardize clients across platforms, prefer a transparent download surface for GUI bundles while treating the server core as infrastructure you version explicitly. The download hub on this site helps compare ecosystem options for desktops and phones; on Debian servers you may still run bare mihomo without a GUI, but the habit of curated channels carries over.
4. Optional: Local .deb With apt (When You Have One)
Sometimes your organization builds an internal .deb that wraps the same upstream binary with policy-compliant metadata. Debian’s APT happily installs a local package when you pass a path: sudo apt install ./mihomo_*.deb from the directory that contains the file. The leading ./ matters; without it, APT assumes a repository package name instead of a filesystem path.
After installation, confirm where dpkg -L placed the binary—often /usr/bin/mihomo—and point your systemd unit’s ExecStart at that exact location. The remainder of this guide assumes /usr/local/bin/mihomo for clarity; swap the path if your package layout differs.
Do not confuse “someone hosted a deb on the internet” with “Debian stable officially ships this package.” Treat third-party debs like any other unsigned artifact until your process says otherwise.
5. /etc/mihomo Layout, Permissions, and Foreground Validation
Create a dedicated configuration directory, commonly /etc/mihomo, owned by root:root (or by a dedicated service user if you prefer privilege separation). Place config.yaml there alongside any rule-provider caches or GEOIP databases the process should read. File mode 0640 on YAML is reasonable when only administrators may edit outbound policy; tighten further if your threat model demands.
Before you enable systemd, validate the profile interactively: sudo /usr/local/bin/mihomo -d /etc/mihomo, watch for parser errors, confirm subscription downloads succeed, then interrupt with Ctrl+C once satisfied. Automation amplifies mistakes—if YAML is invalid, you want to see it in the foreground first.
If you are importing a subscription URL for the first time, walk through the subscription import tutorial so proxy groups, anchors, and naming stay coherent before boot integration. Returning readers can skim that page for URL schema reminders while keeping this article focused on Debian service wiring.
Logging: a Type=simple systemd service already captures stdout and stderr into the journal. Add separate file logs only if you have a rotation plan; duplicate logging is how small VMs run out of disk during a forgotten debug weekend.
6. mixed-port First: Subscriptions, Listeners, and Loopback-First Safety
Search intent around mixed-port is consolidation: one listener that serves both HTTP proxy clients and SOCKS-aware stacks well enough for daily work, so you are not juggling parallel port numbers in every environment variable table. On a fresh Bookworm laptop, bind to 127.0.0.1 semantics via conservative defaults—keep allow-lan false until you explicitly design a LAN or container bridge scenario.
Choose a port that does not collide with local services. 7890 is culturally common in Clash examples, but always confirm with ss -lntp on your machine. Document the final number next to your Linux desktop proxy settings in GNOME, KDE, or your shell profile so teammates are not forced to read YAML for basic connectivity.
After the daemon runs, verify HTTP with curl -x http://127.0.0.1:<port> https://example.com and exercise SOCKS consumers with the same port if your client supports mixed listeners. If HTTP works but a SOCKS-only tool fails, suspect client assumptions before you rip apart systemd.
Example listener skeleton (merge into your real config.yaml)
# Excerpt — adapt keys to your mihomo template version mixed-port: 7890 allow-lan: false # Add mode, log-level, dns:, proxies/proxy-groups, rules:, and proxy-providers as needed.
Subscription blocks belong in the same profile before you declare yourself “done.” Whether you inline proxies: or use proxy-providers: with url: keys, ensure the first fetch succeeds while you still have a foreground terminal—TLS errors, captive portals, and clock skew show up here, not during a silent reboot at 3 a.m.
7. systemd Unit: network-online Ordering and Journal Logs
Debian’s systemd is the right abstraction for boot autostart. Place a unit at /etc/systemd/system/mihomo.service, order after network-online.target, and reference the real binary path you validated earlier.
# /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, sudo systemctl start mihomo, then sudo systemctl status mihomo --no-pager. When the state reads active (running), enable boot integration with sudo systemctl enable mihomo. Reboot once and confirm systemctl is-active mihomo prints active.
Logs: journalctl -u mihomo -e for a live tail, or journalctl -u mihomo --since "30 min ago" when correlating with apt failures. That journal discipline matters on headless Debian servers where nobody is watching colored terminal output.
Hardening directives such as ProtectSystem or capability bounding sets are available, but they interact with cache directories and optional TUN experiments. Start minimal, prove stability, then tighten with testing—Bookworm rewards patience over theatrical security theater that breaks legitimate writes.
8. apt, deb.debian.org, and Rule Order That Will Not Break Updates
apt is just another HTTPS client. If your mihomo rules send deb.debian.org, security.debian.org, and CDN mirror hostnames down a flaky exit—or block them outright—updates fail in ways that resemble “Debian networking is broken.” The fix is rarely reinstalling the OS; it is reordering YAML so domestic mirrors and security endpoints hit a sane policy group, often DIRECT when that matches your compliance story.
Export http_proxy and https_proxy to http://127.0.0.1:<mixed-port> in the root shell when you intentionally want apt to traverse the tunnel, and maintain no_proxy for intranet repositories. Some teams instead configure Acquire::http::Proxy in /etc/apt/apt.conf.d/; pick one documented approach per machine class.
DNS interactions deserve the same rigor as on Fedora or Ubuntu. fake-ip modes, local systemd-resolved stubs, and split-horizon corporate DNS can make apt update fail with errors that look like TLS problems. When in doubt, compare dig deb.debian.org with and without the tunnel and read mihomo logs for which resolver path answered.
For deeper rule-order theory—GEOIP catch-alls, fallback groups, and explicit domain rows—keep the routing and rules reference open while you edit YAML. The goal is explicit rows for the Debian mirror hostnames you actually hit, not blind hope that a broad GEOIP rule matches Fastly’s edge layout this week.
9. nftables, UFW, and Desktop Proxy Integration
Bookworm typically manages firewall rules through nftables; many tutorials still speak in iptables vocabulary because of the compatibility shim. If you enable allow-lan and bind mixed-port beyond loopback, you must open the port only on interfaces and zones you trust. ufw allow can help if you standardized on UFW, but understand that you are still programming the same underlying nftables policy—test from a second machine with curl only after ss -lntp confirms the listener.
On Debian desktops running GNOME or KDE, set manual HTTP proxy values to 127.0.0.1 and your chosen port. Flatpak applications may ignore global desktop proxy settings until you add overrides; diagnose that before blaming Clash Meta.
SSH bastion workflows deserve caution: if you push aggressive TUN or routing experiments on a remote Bookworm server without an out-of-band console, you can lock yourself out. Keep a known-good YAML and a disabled override directory before you change default routes.
When containers on the same host must share the tunnel, the loopback-only pattern often forces you toward host-gateway or HTTP proxy environment variables; compare with the Docker through host Clash guide for bridge-IP details that complement this Debian base install.
10. Optional TUN Mode and Capabilities
Application proxies cover most developer flows; TUN mode targets users who want broader capture without per-app configuration. On Linux that often implies capabilities such as CAP_NET_ADMIN, which systemd can express through unit directives after you accept the security trade-off.
Read upstream documentation for the exact keys your mihomo revision expects, validate with short foreground runs, and keep a rollback profile without TUN stanzas. Conceptual background lives in the TUN mode overview on this site—it is client-agnostic enough to apply to Debian hosts even when your daily driver is Windows or macOS.
IPv6-heavy networks add another layer: if dual-stack leaks appear, you may need explicit IPv6 policy work beyond this first-setup article. Name the possibility now so you do not assume TUN alone fixes every address family interaction.
11. Troubleshooting Checklist for Debian Hosts
systemctl reports active but curl fails. Check ss -lntp for the expected listener, re-read mixed-port bind semantics, and verify YAML rules are not sending your test domain to a dead policy group. DNS fake-ip setups can masquerade as “proxy down” when resolution is the real culprit.
Service exits immediately. Run journalctl -u mihomo -b, then foreground mihomo -d /etc/mihomo to reproduce parser errors. Permission issues on /etc/mihomo show up here as clearly as malformed indentation.
Works until reboot. Confirm systemctl is-enabled mihomo and ensure no second autostart copies the binary. Desktop session autostart files love to resurrect duplicates that fight over the same port.
apt fails only when Clash is enabled. You almost certainly need explicit Debian mirror domain rules or a dedicated update policy group—not another binary reinstall.
Security hygiene. Bind management APIs such as external-controller to loopback, require secrets, and never expose them on untrusted LANs without SSH tunneling. Treat Linux server proxy deployments with the same suspicion you apply to any network-facing daemon.
12. Closing Thoughts
Debian 12 rewards operators who spell things out: an audited mihomo binary under /usr/local/bin, a tidy /etc/mihomo tree, a mixed-port profile that matches how your desktop and shells actually behave, and a systemd unit that brings the stack back after reboots without terminal babysitting. Compared with cargo-culting Ubuntu-only instructions, that structure stays legible when you promote the same pattern from a laptop to a rack-mounted Bookworm host—and when security asks which artifact hash you deployed last quarter.
Clash’s ecosystem spans glossy GUI clients and bare daemons; what they share is the discipline of transparent updates and readable configuration. When you consolidate installers and compare cross-platform options before you commit YAML to production disks, you avoid the drift that turns a “quick proxy” into an undocumented single point of failure.
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 checksum verification—not as the primary end-user installer channel; keep client downloads aligned with your organization’s approved flow.
If you want curated builds and a single place to evaluate ecosystem choices after your Bookworm service is stable, browse the official download hub alongside this server-focused setup. Compared with juggling stray archives, that approach keeps versions legible across the machines you actually maintain—and makes the next migration less of a treasure hunt. → Download Clash for free and experience the difference
Related Reading · topic cluster
Hand-picked deep-dives on the same topic — practical Clash routing guides in the same category.
Install Clash Meta on Arch Linux: systemd Auto-Start and First Setup (2026)
Arch or Manjaro: install mihomo with yay/paru (AUR) or a manual binary, use systemd (system or user) for boot, set mixed-port, import subscriptions, and keep pa…
Read moreInstall Clash Meta on Fedora: systemd Boot Setup and Mixed Port First Steps (2026)
Fedora Workstation or RHEL-like desktop: install mihomo without Ubuntu deb habits, place config under /etc/mihomo, wire systemd for boot and crash recovery, set…
Read moreDocker Through Host Clash: HTTP Proxy Env vs Gateway Setup (2026)
Point containers at host Clash mixed-port with HTTP_PROXY and NO_PROXY, or use Linux gateway-style egress. Covers Docker bridge IPs, Compose, BuildKit, npm/pip/…
Read more