How to Install Clash on Linux: Desktop Clients vs. a Pure CLI Core

Use Clash on Linux with a desktop client or a Mihomo core managed by systemd. Follow distro-specific installation steps, config paths, autostart setup, and guidance on choosing between them.

Choose Your Path: Desktop Client or the Mihomo CLI Core

There is no single Linux installation method that fits every use case. Users on Ubuntu, Fedora, Linux Mint, or Arch desktops typically want subscription management, policy-group switching, log viewing, and a system-proxy toggle. Servers, soft-router sidecars, and headless hosts prioritize low resource usage, remote maintenance, and startup automation. These needs map to two paths: a desktop client or the pure core.

Comparison Desktop client Mihomo CLI core
Best for Ubuntu, Fedora, Mint, and Arch desktops Servers, development machines, NAS devices, and headless hosts
Subscription import Paste a URL in the GUI and update Prepare or schedule updates for config.yaml
Policy switching Click policy groups and nodes directly Use an external controller API or web panel
Background operation Starts automatically after desktop login Started by systemd during system boot
Typical memory use About 140–320 MB for the UI and core combined About 35–110 MB with a standard ruleset
TUN permissions Usually handled by service mode or an authorization component Requires permissions such as CAP_NET_ADMIN

Check Your CPU Architecture First

Downloading a package for the wrong architecture usually results in “cannot execute binary file” or Exec format error. Run this command in a terminal first:

uname -m
cat /etc/os-release

Your distribution determines the package format: Ubuntu, Debian, and Linux Mint should generally use .deb; Fedora and RHEL-based distributions should use .rpm; other desktop distributions can use AppImage. For server core deployments, use the executable matching your architecture.

Path One: Install a Linux Desktop Client

For the desktop path, choose a maintained client that includes the Mihomo core and provides a Linux build. Package names may include amd64, x86_64, arm64, or aarch64; match them to the earlier uname -m output. Do not copy the macOS ClashX package to Linux—the executable format and system interfaces are incompatible.

Install a DEB on Ubuntu, Debian, or Linux Mint

Assume the package has been downloaded to the “Downloads” directory. Enter that directory, then let APT install the local package. Using APT instead of running only dpkg -i also resolves the package’s declared dependencies.

cd ~/Downloads
sudo apt install ./Clash-Linux-amd64.deb

On systems using English directory names, use cd ~/Downloads. Replace the filename with the exact name downloaded to your machine; type the first few characters and press Tab to autocomplete. After installation, launch the app from the application menu, or run dpkg -l | grep -i clash to confirm that the package is registered.

Install an RPM on Fedora or a RHEL-based Distribution

cd ~/Downloads
sudo dnf install ./Clash-Linux-x86_64.rpm

dnf install reads the RPM dependency metadata. If the system enforces stricter desktop security policies, enabling TUN or service mode for the first time may trigger an administrator authorization prompt. This permission step is needed to create a virtual network interface and modify routes, so do not repeatedly cancel it.

Run and Keep an AppImage

An AppImage does not need to be registered in the distribution’s package database, but the file must be executable. The example below uses a file in the Downloads directory:

cd ~/Downloads
chmod +x Clash-Linux-x86_64.AppImage
./Clash-Linux-x86_64.AppImage

If the system reports a FUSE-related error, install a compatible FUSE runtime component from your distribution’s repositories. You can also try --appimage-extract-and-run to verify that the program starts. For long-term use, move the AppImage to ~/Applications so it is not accidentally deleted when the Downloads directory is cleaned up.

Import a Subscription and Make the First Connection

  1. Open the client’s “Subscription” page and choose “New” or “Import from URL.” In some clients, the path is “Subscription” → “New” → “URL.”
  2. Paste the subscription URL provided by your service provider and run an update once it is confirmed.
  3. Open the “Proxy” or “Policies” page and choose a node in the main policy group. You can also select a URL latency-test group.
  4. Enable “System Proxy,” then visit a test page or use a command to check your exit address.
  5. Configure TUN mode only when you need to capture applications that do not read system-proxy settings. There is no need to change every network setting during the first launch.
curl -I --proxy http://127.0.0.1:7890 https://example.com
curl -I --proxy socks5h://127.0.0.1:7890 https://example.com

The first command tests the HTTP proxy; the second uses SOCKS5 and lets the proxy handle DNS resolution. Use the client’s actual port settings: the common mixed port is 7890, but some configurations separate HTTP and SOCKS onto 7890 and 7891. The settings are usually under “Settings” → “Preferences” → “Port Settings.”

Path Two: Install the Mihomo CLI Core

Mihomo is an open-source core that continues the Clash configuration model, with support for rule-based routing, policy groups, rule providers, DNS, and TUN. A CLI deployment does not include subscription lists or a tray menu. Its core tasks are installing the executable, placing config.yaml, and handing process management to systemd.

Install the Binary and Create a Dedicated Account

The commands below use the already downloaded and extracted mihomo-linux-amd64-v1.19.12 as an example. The version number only illustrates the filename format; for an actual deployment, choose the current version and correct architecture from the download page.

sudo install -Dm755 mihomo-linux-amd64-v1.19.12 /usr/local/bin/mihomo
sudo useradd --system --home-dir /var/lib/mihomo --create-home --shell /usr/sbin/nologin mihomo
sudo install -d -o mihomo -g mihomo -m 750 /var/lib/mihomo
/usr/local/bin/mihomo -v

If the distribution does not provide /usr/sbin/nologin, run command -v nologin to find the actual path. A dedicated system account separates the runtime directory from regular user home directories and makes it easier for systemd to grant network capabilities precisely.

Prepare a Minimal Working Configuration

Save the complete converted or exported Clash/Mihomo configuration as /var/lib/mihomo/config.yaml. The snippet below shows the basic structure for ports, the controller, DNS, and rules, but contains no proxy nodes; it can only verify that the core starts and that direct connections work.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: true

external-controller: 127.0.0.1:9090
secret: "change-this-controller-secret"

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: true
  enhanced-mode: fake-ip
  nameserver:
    - 1.1.1.1
    - 8.8.8.8

proxies: []

rules:
  - MATCH,DIRECT

mixed-port: 7890 accepts both HTTP and SOCKS connections; external-controller is the control interface, not a proxy port. Binding the control interface to 127.0.0.1 prevents direct exposure to the local network. In a real configuration, set a separate strong secret; for remote administration, prefer SSH port forwarding.

After copying the configuration, fix its ownership and run a syntax test. YAML is indentation-sensitive: list items are typically two spaces deeper than their parent, and Tab characters should not be used for indentation.

sudo chown mihomo:mihomo /var/lib/mihomo/config.yaml
sudo chmod 640 /var/lib/mihomo/config.yaml
sudo -u mihomo /usr/local/bin/mihomo -t -d /var/lib/mihomo

A successful test means the configuration was parsed. For yaml, mapping, or unmarshal errors, inspect indentation, colons, and field types near the reported line. A subscription response that is a web page, login prompt, or Base64 node list cannot be used directly as a complete config.yaml.

Run in the Background and Start at Boot with systemd

If Mihomo runs directly in an SSH session, the process may exit when the terminal closes. systemd provides consistent startup ordering, automatic restarts, log access, and boot-time startup. Create /etc/systemd/system/mihomo.service with the following contents:

[Unit]
Description=Mihomo Proxy Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/var/lib/mihomo
ExecStartPre=/usr/local/bin/mihomo -t -d /var/lib/mihomo
ExecStart=/usr/local/bin/mihomo -d /var/lib/mihomo
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/mihomo

[Install]
WantedBy=multi-user.target

ExecStartPre tests the configuration before every start, so an invalid configuration will not replace the currently working process. Restart=on-failure restarts only after an abnormal exit, with a five-second delay. CAP_NET_ADMIN and CAP_NET_RAW support TUN and related network operations. If you only expose local HTTP/SOCKS ports and do not use TUN, remove both capability lines to reduce the permission scope.

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo
systemctl status mihomo --no-pager
journalctl -u mihomo -n 80 --no-pager

active (running) means the service is running. After editing the YAML, run the test command first, then sudo systemctl restart mihomo. Follow the logs with journalctl -u mihomo -f; pressing Ctrl+C exits the log view without stopping the service.

Verify That the Port Is Actually Listening

ss -lntp | grep -E '7890|9090'
curl -I --proxy http://127.0.0.1:7890 https://example.com

If systemd reports that the service is running but 7890 is not listening, check whether the configuration uses another port and whether the process exited after failing to load a ruleset. If the port exists but requests time out, inspect policy-group selection, node connectivity, DNS logs, and the server firewall instead of reinstalling the binary.

Choosing Between TUN, System Proxy, and Terminal Environment Variables

For Everyday Desktop Use, Start with System Proxy

System proxy changes are limited and work well for browsers, desktop chat apps, and applications that follow GNOME or KDE proxy settings. A common client path is “Settings” → “System Proxy” → “Enable.” If you only need everyday web access and developer documentation, start with system proxy to make troubleshooting easier.

For Terminal Tools, Set Proxy Variables Per Process

Many command-line programs read HTTP_PROXY, HTTPS_PROXY, and ALL_PROXY. A temporary setting affects only the current terminal session and expires when the terminal closes:

export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5h://127.0.0.1:7890

curl -I https://example.com

To restore direct connections, run:

unset HTTP_PROXY HTTPS_PROXY ALL_PROXY
unset http_proxy https_proxy all_proxy

Git can also be configured independently, without permanently affecting every terminal program:

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

git config --global --unset http.proxy
git config --global --unset https.proxy

For Containers, Games, and Apps That Ignore Proxy Settings, Consider TUN

TUN mode creates a virtual network interface and uses routes to send more traffic through Mihomo. It covers programs that do not support HTTP/SOCKS proxies, but adds DNS, route-priority, LAN-access, and permission concerns. Before deploying it remotely on a server, keep a second SSH session open so an incorrect route does not cut off the active management connection.

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-redirect: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

auto-detect-interface identifies the default egress interface; auto-route adds routes for intercepted traffic; dns-hijack sends specified DNS traffic to the core. Supported options vary by core version and operating-system network stack, so run mihomo -t before enabling them. Docker, Podman, virtual-machine bridges, and policy-routing setups also require checking reserved subnets to prevent container traffic from being routed through the proxy accidentally.

Configuration Files, Subscription Updates, and Log Maintenance

Where Desktop Clients Store Configuration

Desktop clients usually store configuration in the user data directory rather than /etc. Common Linux locations include ~/.config/app-directory and ~/.local/share/app-directory; Flatpak apps are often under ~/.var/app/app-id. Do not overwrite an entire directory in bulk while the client is running. Prefer its built-in import, update, and backup functions.

Find recently modified YAML files with:

find ~/.config ~/.local/share -type f \
  \( -name '*.yaml' -o -name '*.yml' \) \
  -mtime -7 2>/dev/null

Updating Subscriptions in a CLI Deployment

A CLI core does not validate subscription formats for you. The safe workflow is to download the new configuration to a temporary file, run a syntax test, then replace the live configuration and restart the service. Never overwrite the file in use directly; an incomplete download could prevent the service from starting again.

  1. Save the new content as a temporary YAML file.
  2. Verify that the response is actually a Clash/Mihomo configuration, not an HTML error page.
  3. Run mihomo -t from a separate temporary directory.
  4. After the test succeeds, move it to /var/lib/mihomo/config.yaml.
  5. Fix the file ownership and restart the systemd service.

If the configuration uses proxy-providers, Mihomo can refresh the provider at the interval specified in the configuration. A typical interval: 86400 means an update every 86,400 seconds, or 24 hours. A health-check interval: 300 means checking every five minutes; the two serve different purposes, so do not set both to very small values just to update faster.

Log Levels and Disk Usage

For normal operation, use log-level: info. Temporarily switch to debug when investigating DNS, rule matching, or connection failures, then switch back after the issue is confirmed. systemd logs are managed by journald; use the following command to check service usage:

journalctl --disk-usage
journalctl -u mihomo --since "30 minutes ago"
journalctl -u mihomo -p warning --since today

In logs, connection refused usually means the destination is reachable but no service is listening on the port; i/o timeout more often indicates a network-path or node-response timeout; no such host and DNS resolve failed call for checks of upstream DNS, hijacking settings, and IPv6 availability. First identify whether the error occurs at local listening, DNS resolution, node connectivity, or the destination site; this is more effective than repeatedly switching nodes.

Common Installation Problems and What to Check

Exec format error at startup

This is almost always an architecture mismatch. Run uname -m again, then use file /usr/local/bin/mihomo to inspect the binary’s target architecture. An x86_64 host needs an amd64 build; an aarch64 host needs an arm64 build.

The Desktop Client Opens, but System Proxy Has No Effect

systemd Keeps Restarting

systemctl status mihomo --no-pager
journalctl -u mihomo -b -n 120 --no-pager
sudo -u mihomo /usr/local/bin/mihomo -t -d /var/lib/mihomo

Common causes include YAML indentation errors, a port already occupied by another process, insufficient permission for the runtime account to read the configuration, failed Geo data downloads, or missing TUN permissions. Find port conflicts with sudo ss -lntp; for permission issues, inspect the permissions of every directory level in the output of namei -l /var/lib/mihomo/config.yaml.

LAN Devices Cannot Connect to the Linux Host’s Proxy

The default allow-lan: false permits local access only. If trusted LAN devices genuinely need to use the proxy, change it to allow-lan: true, set an explicit bind-address, and configure the host firewall to allow the proxy ports only from the LAN subnet. Do not expose the external controller at 9090 simply because proxy ports are open.

Download Clash