Platform Setup 12 min read

Install Clash on Linux: Desktop Clients and Command-Line Setup

A complete guide to Linux desktop clients, the mihomo command-line core, service autostart, and configuration directories.

Choose a desktop client or command-line core

Clash deployments on Linux generally follow one of two paths. A desktop client suits workstations running GNOME, KDE Plasma, Xfce, or another graphical environment. It lets you import subscriptions, switch proxy groups, review connection logs, and control the system proxy from the tray menu. The mihomo command-line core is better suited to servers, software routers, development container hosts, and users who want systemd to manage the process centrally.

mihomo is a core compatible with the Clash configuration ecosystem that continues to add capabilities. The core handles common Clash rules, proxy groups, proxy nodes, DNS, and TUN settings, while a desktop client provides configuration management on top of it. They are not two proxy layers that must always run together: most desktop clients already bundle or manage a core. Starting an additional system-wide mihomo process can cause port conflicts, control-port collisions, or repeated changes to the system proxy.

Environment Recommended path Primary management method
Personal Linux desktop Graphical client Import subscriptions, switch nodes, and manage the system proxy from the interface
Headless server mihomo command-line core Configuration files, systemd, and logs
Development workstation Choose one based on your management preference Environment variables, desktop proxy, or TUN
LAN proxy access mihomo service Fixed listen address, firewall, and access controls

Install a Linux desktop client

Confirm the processor architecture before downloading. Run uname -m in a terminal; common results include x86_64, aarch64, and arm64. In package names, amd64 and x64 usually correspond to x86_64, while arm64 refers to 64-bit ARM. With a mismatched architecture, the program will usually report that the binary cannot be executed rather than opening the client interface.

Common desktop distribution formats include AppImage, DEB, and RPM. When choosing a client, first check its maintenance status, supported core types, configuration storage location, and support for Linux system proxy and TUN management. Clients differ in how they handle subscription overrides, core updates, and privilege escalation, so do not assume their interface options are identical when migrating.

Running an AppImage

AppImage does not use a traditional package installation workflow. Download the file matching your architecture, make it executable, and launch it from a terminal. Replace the filename in the commands below with the file you actually downloaded:

mkdir -p "$HOME/Applications"
mv "$HOME/Downloads/client-file.AppImage" "$HOME/Applications/"
chmod +x "$HOME/Applications/client-file.AppImage"
"$HOME/Applications/client-file.AppImage"

If double-clicking does nothing, run it once from a terminal and read the error output. Some distributions require a FUSE compatibility component; newer AppImages may also support their own extraction mode. Do not conclude that installation failed simply because no icon appeared: the window system, tray extensions, and desktop-entry cache can all affect visibility.

Installing DEB and RPM packages

Debian, Ubuntu, and derivatives can use APT to install a local DEB package. APT also resolves the dependencies declared by the package:

cd "$HOME/Downloads"
sudo apt install ./client-file.deb

Systems such as Fedora and Rocky Linux that use RPM packages can install a local file with DNF:

cd "$HOME/Downloads"
sudo dnf install ./client-file.rpm

After installation, launch the client from the application menu. On first run, check the core status before importing a subscription or local YAML configuration. If the client offers a “Set as system proxy” option, it usually changes the proxy settings for the current desktop session; it does not transparently take over every process. Check separately whether terminal programs, containers, and software running as system services read the desktop proxy.

Deploy the mihomo command-line core

A command-line deployment revolves around three things: the executable, the working directory, and the configuration file. We recommend placing the executable at /usr/local/bin/mihomo and system-wide configuration under /etc/mihomo/. This keeps upgrades separate from configuration maintenance and gives systemd a fixed path to launch.

Obtain an architecture-matched archive from a trusted release channel, extract it, and rename the binary to mihomo. Assuming the file has been extracted into the current directory, run:

sudo install -m 0755 mihomo /usr/local/bin/mihomo
/usr/local/bin/mihomo -v
sudo install -d -m 0750 /etc/mihomo

mihomo -v should print the core version and build information. If you see Exec format error, the downloaded architecture is usually wrong. If the system reports that execution is not permitted, check the file mode and whether its filesystem is mounted with the noexec option.

For a first deployment, do not immediately add complex DNS, script, or TUN rules. Start with a basic configuration that parses successfully, confirm that the port and nodes work, and then add advanced settings one at a time. mihomo accepts -d to specify the working directory; its config.yaml file is loaded as the default configuration:

sudo /usr/local/bin/mihomo -d /etc/mihomo

Foreground mode is best for the initial check. The terminal will continuously show configuration parsing, listening ports, proxy connections, and rule matches. Once the configuration starts successfully, create the systemd service described below. This avoids repeated service restarts masking the first error.

Configuration directories, subscription files, and basic ports

The simplest layout contains only /etc/mihomo/config.yaml. After enabling GeoIP, rule sets, or other external resources, the working directory may also contain databases, caches, and downloaded files. The service user must be able to read the configuration and write to any cache locations that need updating. If the configuration contains subscription credentials or a control-interface key, restrict directory and file permissions.

sudo install -m 0640 config.yaml /etc/mihomo/config.yaml
sudo chmod 0750 /etc/mihomo
sudo ls -la /etc/mihomo

A basic configuration for local testing can include a mixed proxy port, a LAN access switch, the operating mode, and a control interface. The example below shows structure only; proxy nodes and rules should come from a working Clash or Mihomo configuration:

mixed-port: 7890
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
ipv6: true

external-controller: 127.0.0.1:9090
secret: "Set a random, sufficiently long control key"

proxies: []
proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - DIRECT

rules:
  - MATCH,PROXY

mixed-port accepts both HTTP and SOCKS5 connections, making it convenient for browsers, terminal tools, and development software to share one port. allow-lan: false initially restricts access to the local machine. Even if bind-address uses a wildcard address, do not treat the setup as shared access until LAN access is explicitly enabled.

external-controller is a control interface, not a regular proxy port. For local-only management, bind it to 127.0.0.1 and set a control key. If remote management is genuinely required, also plan firewall rules, a trusted network scope, and access authentication. Never expose the control port directly to an untrusted network.

Keep a fallback file when importing subscriptions

Graphical clients usually manage subscription URLs, update intervals, and local configuration copies themselves. With a command-line deployment, you must decide who handles updates. A controlled script can fetch the configuration into a temporary file, ask the core to validate it, and then replace the active file. Never overwrite the existing config.yaml directly when a download fails; an empty response or expired authentication could otherwise make the service fail on its next restart.

Subscription URLs commonly contain access credentials, so they should not be written directly to shell histories, service logs readable by other users, or public scripts. A safer approach is to store credentials in a permission-restricted environment file, have the update task read only that file, and restrict access to the update output. If the provider returns a generic node list rather than Clash YAML, convert it for compatibility first; arbitrary text cannot be started as a mihomo configuration.

Configure systemd and startup at boot

After the basic configuration passes validation, create /etc/systemd/system/mihomo.service. The service unit below runs as a system-level process and retains the network-management capabilities that TUN may require. If you use only HTTP or SOCKS ports, narrow the capability set after confirming your configuration needs.

[Unit]
Description=Mihomo proxy service
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
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

After saving the file, reload the systemd configuration, start the service, and enable it at boot:

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo
sudo systemctl status mihomo --no-pager

To view logs from this startup, run:

sudo journalctl -u mihomo -b --no-pager
sudo journalctl -u mihomo -f

Restart=on-failure restarts the service only after an abnormal exit, which is useful for exposing configuration and runtime errors. If the service keeps restarting, first run systemctl stop mihomo, then launch it in the foreground with the same configuration directory to find the first error. Common causes include incorrect YAML indentation, an occupied listen port, a rule referencing a nonexistent proxy group, insufficient configuration-directory permissions, or unavailable TUN or network capabilities.

Connect the desktop system proxy, terminal tools, and TUN mode

Running the core does not mean all traffic is automatically proxied. With only mixed-port: 7890 configured, applications must connect to that port explicitly. In a desktop environment, point the HTTP, HTTPS, and SOCKS proxies to 127.0.0.1:7890. Terminal programs can set environment variables as needed:

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"

socks5h delegates DNS resolution to the SOCKS proxy as well, although support depends on the application. Environment variables affect only the current shell and its child processes. When using sudo, systemd services, containers, or graphical launchers, variables may not be inherited, so configure them separately in the relevant runtime environment.

What TUN mode does and what it requires

TUN mode uses a virtual network interface to capture more traffic that cannot be configured with a manual proxy. It is useful when desktop applications, command-line tools, and some game connections need unified handling. It depends on Linux's /dev/net/tun device, routing rules, and the required network-management capabilities. Containers, minimal kernels, or restricted virtual machines may not expose the TUN device; the interface cannot be created even when the configuration syntax is valid.

A typical configuration enables these settings only after the existing DNS setup has been confirmed to work:

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-redirect: true
  auto-detect-interface: true

auto-route configures routes automatically, while auto-detect-interface identifies the default egress interface. The behavior of auto-redirect depends on the Linux network environment, kernel capabilities, and mihomo version. When Docker, Podman, a VPN, custom NetworkManager routes, or multiple network interfaces are present, check route priorities and firewall rules. Otherwise, container networks, private addresses, or the proxy server's own connections may be sent back through TUN incorrectly.

If domain resolution fails after enabling TUN, do not simply keep switching nodes. Check the DNS listener, upstream DNS reachability, DNS policies in the rules, virtual-interface routes, and whether the system is still sending requests to another local resolver. Changing DNS and TUN extensively at the same time makes troubleshooting harder. Validate port-based proxying first, then enable DNS, and add TUN last.

Startup checks and common troubleshooting

After deployment, work outward from the process rather than judging success by whether a webpage opens. First confirm that the service is running. Next confirm that the port is listening. Then send a request through an explicit proxy, inspect rule matches and node-connection logs, and only afterward enable the system proxy or TUN.

systemctl is-active mihomo
ss -lntup | grep -E '7890|9090'
curl --proxy http://127.0.0.1:7890 https://example.com/
journalctl -u mihomo -n 100 --no-pager

If port 7890 is not listening, check configuration parsing and port conflicts first. Use ss -lntup to find the process holding a port. If the port exists but requests fail, determine from the logs whether the cause is DNS failure, a connection timeout, an authentication error, or no available proxy. A node appearing in a proxy group does not guarantee that it is reachable; rely on connection logs and real requests.

The desktop client starts but cannot proxy traffic

  • Check that the client's core is running, not merely that its window is open.
  • Confirm that the active configuration is loaded and that proxy groups are not pointing to failed or unavailable nodes.
  • Check that the desktop system proxy was written successfully and that the target application follows system proxy settings.
  • If using TUN, confirm that privilege escalation completed, the virtual interface exists, and no other VPN has overridden the routes.
  • Quit other proxy clients to prevent multiple programs from changing proxy and routing settings at the same time.

The service exits immediately after startup

Use journalctl -u mihomo -b to read logs from the current boot and focus on the earliest error. YAML uses spaces for indentation; tab characters, incorrect nesting, or unquoted special characters can all cause parsing failures. The core may also reject the configuration when a rule points to a nonexistent proxy group. After editing, run the configuration in the foreground first, confirm that it is error-free, and then restart the systemd service.

LAN devices cannot connect

Sharing a proxy requires four conditions at once: the configuration must allow LAN access, the service must listen on an address reachable from the LAN, the host firewall must allow the relevant TCP or UDP port, and clients must use the Linux host's LAN address rather than 127.0.0.1. Also check that wireless client isolation is disabled. Before opening a port, restrict it to a trusted subnet and avoid exposing the proxy port on a public interface.

Linux deployment maintenance checklist

  1. Record the current core source, version, architecture, and executable path.
  2. Restrict configuration-directory permissions and protect subscription credentials and control-interface keys.
  3. Confirm that only one instance occupies each planned proxy, DNS, and control port.
  4. Keep temporary files and fallback copies for configuration updates; replace the active file only after validation succeeds.
  5. Check configuration compatibility changes before upgrading, then review startup logs and rule matches afterward.
  6. When using TUN, record additional routes, firewall rules, and interactions with VPN and container networking.
  7. When you stop using a desktop client, restore the system proxy settings as well so an inactive port is not left behind.

For a desktop client, focus on choosing an actively maintained interface that supports your current distribution, and understand the difference between the system proxy and TUN. For a command-line deployment, focus on fixed directories, validating the configuration first, and then handing process management to systemd. Checking in the order “binary — configuration parsing — port listening — explicit proxy — system integration” narrows most Linux installation issues to a specific stage.

Next route

Choose a Linux client and continue configuration

Choose a client based on your desktop environment, processor architecture, and maintenance status. Then follow its documentation to import a subscription, check proxy groups, and configure the system proxy.