MIHOMO CONFIGURATION REFERENCE

Clash Meta Advanced Configuration Guide

From proxy-group selection logic to DNS, TUN, Fake-IP, domain sniffing, and subscription merging, each chapter explains parameters, combinations, and troubleshooting order.

Quick-start guide covers installation, subscription import, and the first connection; this page is for systematic tuning after connectivity is working. If the client is not installed yet, visit the client page to choose your platform. Clash Plus is the preferred option for ordinary desktop and mobile devices; consider running the mihomo core directly for servers and routers.

Reading order

Proxy groups decide “which route to use,” while rule sets decide “which requests enter that group.” DNS and sniffing identify the destination, and TUN takes over the traffic. When something fails, troubleshoot backward through these dependencies; it is usually faster than repeatedly switching nodes.

01

Proxy-group types in practice

Proxy groups form the decision layer of a configuration. Proxy nodes determine “how to establish a connection,” while proxy groups determine “where this class of traffic should go.” Maintainable configurations usually avoid sending rules directly to individual nodes. Instead, create stable groups such as “Daily,” “Auto Test,” “Failover,” and “Downloads,” then reference those names from rules. This keeps the rule layer intact when subscriptions or node names change. Group names may use any language, but they must match exactly across proxy-groups, rules, and other groups’ proxies; spaces, capitalization, and symbols all matter.

select, url-test, fallback, and load-balance

select is a manual selection group for situations where the exit route must be chosen explicitly. It does not assess node quality; it only remembers the current choice. Put automatic groups, failover groups, and a few frequently used nodes inside one select group to balance reliability with manual control. url-test visits a test URL at the configured interval and selects the available node with the lowest measured latency. It suits web browsing and API requests where short-connection responsiveness matters. The result reflects performance between the current device and the test target, not the speed of every website or streaming service.

fallback checks availability in list order, preferring the node near the top and moving to the next only when the current one fails. It suits a fixed primary-and-backup layout, as well as services where login state or exit region should not change frequently. load-balance distributes different connections across multiple nodes, which can help with concurrent downloads or multiple targets. However, connections to one website coming from different exits may trigger login verification. Load balancing should therefore not replace the everyday default group; reference it with dedicated, targeted rules instead.

Type Selection basis Best for Key considerations
select Manual user selection Default exit, fixed region Usually requires manual switching after a node fails
url-test Periodic latency tests Websites, APIs, everyday browsing The test target should be stable and representative of the actual route
fallback List order and availability Primary and backup routes, fixed exit Order directly determines priority
load-balance Connection distribution strategy Concurrent tasks, downloads from multiple targets Not suitable for login sessions that require a consistent exit

A maintainable layered structure

The structure below lets proxy providers supply nodes, uses lower-level groups for automatic selection and failover, and exposes everything to rules through a single “Default Proxy” group. include-all: true adds nodes from available proxy providers to the group. If the client or existing configuration does not use proxy providers, list nodes explicitly under proxies instead. interval is the health-check or latency-test interval in seconds; tolerance defines how much better a new result must be before switching. A suitable tolerance prevents two similarly fast nodes from constantly swapping places.

proxy-groups:
  - name: Default Proxy
    type: select
    proxies:
      - Auto Select
      - Failover
      - DIRECT

  - name: Auto Select
    type: url-test
    include-all: true
    url: https://www.gstatic.com/generate_204
    interval: 600
    tolerance: 80

  - name: Failover
    type: fallback
    include-all: true
    url: https://www.gstatic.com/generate_204
    interval: 300

The test URL should return a small response with a stable status. If it is redirected, cached, or inaccessible on the current network, every node in the group may appear to fail. Check the logs first to determine whether the cause is DNS resolution, a connection timeout, or a TLS error, then consider changing the test URL. Do not shorten the test interval just to obtain a smaller number; frequent tests increase connections and battery use and may repeatedly wake a mobile connection.

Group by purpose, not by node count

Long-term configurations are easier to maintain when groups are named by purpose, such as “Streaming,” “Developer Services,” and “Large Downloads,” rather than exposing dozens of entries for every region and node. A purpose group can reference a region group, which can reference an automatic-test group, creating a clear two- or three-level hierarchy. Excessive nesting makes troubleshooting harder and may create circular references; if group A contains B and B contains A, configuration validation fails. After editing, use the client’s configuration checker or mihomo’s test-start mode to verify syntax, then inspect the logs to see which policy group each rule ultimately matches. For a comparison of the three automatic group types and example combinations, continue with the guide to choosing proxy-group types.

02

Managing rules with subscriptions

Rules send requests to DIRECT, a proxy, REJECT, or a purpose-specific proxy group. Writing thousands of domains and IPs directly into the main configuration may work, but updating, reviewing, and troubleshooting it becomes difficult. rule-providers moves rule content into separate files while the main configuration declares the source, behavior type, cache path, and refresh interval. The actual rules then reference it with RULE-SET. Media, intranet, and developer-service rules can be updated independently, while the local cache remains usable when a source is temporarily unavailable.

behavior and format must match the content

behavior describes the structure of the rule-set content. domain is for domain entries, including full domains, suffixes, and keyword collections; ipcidr is for IPv4 and IPv6 networks; classical stores complete rules with type prefixes, such as DOMAIN-SUFFIX,example.org or IP-CIDR,192.0.2.0/24. These types cannot be converted simply by renaming a field; the remote file’s actual structure must match the declaration. Common format values are yaml, text, and mrs. The correct format depends on the file supplied by the rule source, so an ordinary text link must not be declared as a binary rule format.

rule-providers:
  private-domains:
    type: http
    behavior: domain
    format: yaml
    url: https://rules.example.com/private-domains.yaml
    path: ./ruleset/private-domains.yaml
    interval: 86400

  private-networks:
    type: http
    behavior: ipcidr
    format: yaml
    url: https://rules.example.com/private-networks.yaml
    path: ./ruleset/private-networks.yaml
    interval: 86400

rules:
  - RULE-SET,private-domains,DIRECT
  - RULE-SET,private-networks,DIRECT,no-resolve
  - GEOIP,LAN,DIRECT,no-resolve
  - MATCH,Default Proxy

The example domain illustrates the structure; in practice, replace it with the complete URL of a trusted rule source. path is the cache location under the core’s working directory, which varies by client. When running mihomo manually, ensure the process can write to that directory. If the first download fails and no local cache exists, the provider cannot participate in matching. After a successful download, the core can usually continue reading the cache, but it will not include new content from the remote source.

Rules match from top to bottom

The order of rules is decisive: once a request matches the first applicable rule, matching stops. Put narrow, clearly intended rules first and broad rules later; MATCH belongs only at the end as a final fallback. For example, direct connections for internal company domains should come before a general proxy-domain set, and LAN ranges should be handled before broad IP rules. If a wide proxy set comes first, later direct exceptions will never trigger even when their syntax is correct.

no-resolve is used with IP-based rules to prevent an extra DNS lookup during matching. It reduces unnecessary queries and avoids changing the matching path before a domain has been resolved. It should not be added mechanically to every rule: domain rules inherently require a domain, while a process that supplies only an IP and has no sniffing result still needs later IP rules. When analyzing a rule problem, check the destination host, rule type, and final policy in the logs rather than looking only at the proxy-group name.

Handling update failures and rollback

Rule-set updates usually fail for one of four reasons: the remote URL is invalid, DNS cannot resolve it, the download requires a proxy that is not ready, or the cache directory is not writable. Check the HTTP status or network error in the logs, then access the rule URL from the same device with a browser or command line. If only the core cannot reach it, verify whether the rule provider must download through a proxy and whether startup DNS can resolve the source domain. Permission problems typically appear as failures to create files, rename temporary files, or write data.

Remote rules do not mean every startup must fetch them online. For production, keep the last known-good cache, validate the file format before updating, and limit the scope of changes. Replacing every rule source, DNS setting, and proxy group at once makes the cause difficult to identify. A safer sequence is to add the provider without referencing it, confirm the download succeeds, add one RULE-SET and observe matches, then remove the old rule. To roll back, restore the reference in the main configuration; the cache can remain for comparison.

Rule count is not configuration quality

More rules do not automatically produce more accurate routing. Duplicate collections increase load time and may give conflicting results for the same domain. Define a small number of purpose groups first, then choose rule sets that cover those purposes. When a website uses the wrong group, find the first rule it actually matched in the logs, then adjust the order or add a precise exception; replacing the entire rule set often introduces new unknown behavior. For further checks on GeoIP or rule-provider update failures, see the relevant branch in FAQ.

03

Optimizing DNS configuration

DNS converts domain names into addresses and directly affects whether rules can see the correct destination. Problems such as “the node works but webpages do not,” “the same domain sometimes uses DIRECT and sometimes a proxy,” or “logs show only an IP, making the domain impossible to identify” are often caused not by node speed but by misaligned DNS routing, cached results, and traffic interception. Before configuring DNS, answer three questions: who handles queries, which resolvers receive them, and how the resolvers’ own hostnames are resolved. Once these relationships are clear, decide whether to enable Fake-IP.

nameserver, default-nameserver, and proxy-specific DNS

nameserver is the primary resolver for ordinary domain queries. It can use traditional UDP/TCP DNS or encrypted forms such as DoH. default-nameserver is mainly used for startup dependencies such as resolving DoH server and proxy-server hostnames. IP-based resolvers that are directly reachable help avoid the loop of “resolving the DNS service hostname before that DNS service can be used.” proxy-server-nameserver can resolve proxy node server hostnames separately from ordinary business domains, reducing the chance that business rules affect proxy connectivity.

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  respect-rules: true

  default-nameserver:
    - 223.5.5.5
    - 1.1.1.1

  nameserver:
    - https://dns.alidns.com/dns-query
    - https://1.1.1.1/dns-query

  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query

  nameserver-policy:
    "geosite:cn":
      - https://dns.alidns.com/dns-query
    "geosite:geolocation-!cn":
      - https://1.1.1.1/dns-query

The example illustrates field relationships and does not mean every network should use the same resolvers. Consider reachability, returned results, and privacy requirements when choosing a DNS service. If a DoH service requires a proxy but is the only DNS entry during startup, it can create a dependency loop: the proxy is not ready while DNS is waiting for the proxy. Keeping a directly reachable fallback path and resolving proxy-server hostnames separately is usually more reliable.

How nameserver-policy is matched

nameserver-policy assigns resolvers by domain, rule set, or geosite category. Local domains can go to a nearby resolver while other domains use another group. It answers “which resolver receives the query,” not “which proxy group carries the final traffic”; that remains the job of rules. DNS policies and routing rules may use similar categories, but they do not need to be identical. If many overlapping domain collections are assigned at once, it becomes difficult to tell which resolver was selected, so keep entries ordered from specific to broad.

respect-rules: true means DNS connections themselves follow routing rules. After enabling it, make sure DNS server hostnames and addresses have a path that works during startup; otherwise resolver requests may be sent to a group that is not ready. If all domains fail after changing this option, temporarily use a directly reachable resolver to validate the path, then check which rule matches the DNS service hostname.

IPv6, caching, and differing results

ipv6: false generally means the DNS module does not return AAAA records, which suits devices or exits without stable IPv6 connectivity. If both the local network and proxy nodes support usable IPv6, enable it only after checking TUN, system routes, and IPv6 rule handling. Enabling IPv6 in DNS while TUN or the exit lacks support can make applications try IPv6 first, wait for a long time, and only then fall back to IPv4.

After changing DNS, old results may remain in the operating system, browser, client, and core caches. Restart the relevant client or clear the system DNS cache before repeating the same-domain test. Browsers may also use their own secure DNS, bypassing the system resolver. If system tools work but the browser does not, check the browser settings; if the browser works but the terminal does not, investigate system DNS, environment variables, or whether the terminal program uses the expected traffic path.

Symptom Check first How to determine the cause
All domains fail Listening port, upstream reachability, startup dependencies Look for timeout, connection refused, or request loops
Only node hostnames fail proxy-server-nameserver Verify that node server hostnames resolve before the proxy is established
Browser and terminal results differ Browser secure DNS and system proxy scope Compare system query tools with the browser’s developer tools
IPv6 takes a long time to connect initially AAAA responses and exit IPv6 capability Test IPv4 and IPv6 separately and check fallback timing
04

TUN and Fake-IP

System proxying depends on applications actively reading proxy settings. Browsers generally support it well, but some terminal programs, games, system services, and apps with custom network stacks may ignore it completely. TUN mode uses a virtual network interface and system routes to intercept a broader range of TCP and UDP traffic before passing it to mihomo. Fake-IP assigns reserved addresses to domains during DNS resolution; when an application connects to one, the core restores the original domain from its mapping so domain rules can work in more situations. They are often used together but have different roles: TUN handles interception, while Fake-IP handles domain mapping.

TUN basics and platform permissions

tun:
  enable: true
  stack: mixed
  dns-hijack:
    - any:53
    - tcp://any:53
  auto-route: true
  auto-detect-interface: true
  strict-route: true

stack determines which network stack processes TUN packets; mixed is a common compatibility choice, but available values and behavior depend on the core and platform implementation. auto-route adds the required routes automatically, while auto-detect-interface identifies the physical interface used by the default exit and is especially useful when switching between Ethernet, Wi-Fi, hotspots, and VPNs. dns-hijack sends matching DNS requests to the core’s DNS module instead of the system resolver. strict-route more tightly restricts bypass paths, reducing leaks and routing deviations but making conflicts with virtual machines, LAN sharing, or other VPN routes more likely.

Creating a virtual network interface and changing routes usually requires administrator privileges. Windows clients may perform this through service mode; macOS may request network-extension or system permissions; Linux requires the appropriate network capabilities when running the core directly, along with suitable systemd service permissions. If the entire device loses connectivity after enabling TUN, do not switch nodes first. Disable TUN to confirm that basic system networking recovers, then check whether the virtual interface was created and whether the default route was overwritten incorrectly.

How Fake-IP works

With enhanced-mode: fake-ip, the DNS module returns an address from fake-ip-range for each domain. The application then connects to that address, and the core retrieves the original domain from its mapping table before applying domain rules and resolving the real destination. 198.18.0.0/15 is a reserved range for benchmarking and is commonly used for this mapping; do not mistake a Fake-IP address for the actual remote server. Seeing this range in packet captures or logs does not mean DNS was redirected to an unfamiliar host—it indicates that the mapping path is working.

Fake-IP preserves domain information more completely, makes rule decisions more direct, and reduces cases where an application obtains the real IP early and bypasses domain rules. The trade-off is that some applications validate DNS responses, depend on LAN discovery, use special UDP protocols, or pass resolution results to a process outside the same core; these cases may not work well with mapping. Use fake-ip-filter to return real addresses for specific domains instead of disabling Fake-IP entirely.

dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter-mode: blacklist
  fake-ip-filter:
    - "*.lan"
    - "*.local"
    - "time.*.com"
    - "ntp.*.com"
    - geosite:private

blacklist mode excludes listed domains from Fake-IP while mapping all others. Keep the filter as precise as possible. A broad wildcard sends many requests back to real-IP mode and weakens domain-based rules. If LAN device discovery fails, first add exceptions for the device’s .local names, private domains, or vendor services, then observe the logs; do not exclude an entire common top-level domain at once.

Conflicts with other VPNs, virtual machines, and LANs

When TUN runs alongside an enterprise VPN, game accelerator, virtual-machine interface, or container network, conflicts usually involve route priority, DNS interception, or an overlapping reserved range. Record the default route and DNS behavior with TUN disabled, then enable network components one at a time to identify which change affects the exit. If a company VPN permits only specific ranges, preserve the correct routes for those ranges and send internal domains to the enterprise DNS; otherwise internal services may remain unreachable because DNS and routing are split.

When LAN access fails, check whether private ranges are assigned DIRECT, whether TUN preserves LAN routes, and whether the system firewall permits virtual-interface access. Router or side-gateway deployments must also avoid sending client traffic back to themselves and creating a loop. On Linux, use ip route and ip rule to inspect routes and policy rules; on Windows, use route print; on macOS, use netstat -rn. These commands only inspect the system and do not modify its configuration.

# Linux: inspect routes and policy rules
ip route
ip rule

# Windows: inspect IPv4 and IPv6 routes
route print

# macOS: inspect the current routing table
netstat -rn

If only the browser and common desktop applications need proxying, system proxy mode is simpler and easier to troubleshoot. Enable TUN only when an application truly ignores the system proxy. For differences in scope, permissions, and performance, see TUN mode vs. system proxy.

05

Domain sniffing

Not every connection carries a domain name when it reaches the core. An application may resolve DNS itself and connect directly to an IP, while transparent-proxy or gateway deployments may see only an address. Domain sniffing reads early protocol signals and extracts names from HTTP Host, TLS SNI, or a QUIC handshake for rule matching. It does not decrypt application data and does not work with every protocol; it uses only destination identifiers visible during the handshake to supply information needed for routing decisions.

Limit the scope by protocol and port

sniffer:
  enable: true
  parse-pure-ip: true
  force-dns-mapping: true

  sniff:
    HTTP:
      ports:
        - 80
        - 8080-8880
      override-destination: true
    TLS:
      ports:
        - 443
        - 8443
    QUIC:
      ports:
        - 443
        - 8443

  force-domain:
    - "+.example.org"

  skip-domain:
    - "Mijia Cloud"
    - "+.push.apple.com"

parse-pure-ip allows sniffing attempts on connections whose original destination is an IP, which is useful for transparent interception. force-dns-mapping uses DNS mappings to look up domain information and is often paired with Fake-IP. Limit ports separately by protocol to avoid unnecessary inspection on connections that are clearly not HTTP, TLS, or QUIC. Adjust port ranges to the applications in use; sending every port to every sniffer does not improve accuracy and can increase false positives and troubleshooting cost.

override-destination replaces the original destination information with the result obtained by sniffing. This makes domain rules easier to match, but an incorrect result directly affects where the connection goes, so enable it only for clearly identified protocols. force-domain can require selected domains to use sniffed results, while skip-domain excludes known-incompatible services. Domain patterns must follow the wildcard syntax supported by the core; after editing, verify in the logs that the extracted domain matches the actual request.

How sniffing, DNS, and rules interact

A connection may contain three kinds of destination information: the domain supplied by the application, the domain preserved in a DNS mapping, and the domain discovered by sniffing. Applications that submit a domain through a standard proxy protocol usually do not need additional sniffing; when an application connects only to an IP, the core must recover the domain from a mapping or handshake. The information ultimately used by the rule engine depends on the interception method and configuration. During troubleshooting, check whether the logged destination changes from an IP to a domain, which rule matches, and the actual address used for the final connection.

Sniffing cannot replace DNS. It occurs after a connection has started, while proxy-server hostnames, rule-provider URLs, and protocols without an identifiable handshake still require normal resolution. It also cannot replace rule design: after extracting a domain, a matching DOMAIN, DOMAIN-SUFFIX, or rule set is still needed to send the connection to the right policy group. If the logs already show the correct domain but the wrong group is selected, return to rule ordering instead of expanding the sniffing port range.

Common false positives and exceptions

Some applications use custom protocols on non-standard ports whose opening bytes happen to resemble HTTP or TLS. Other services use shared addresses and fronting domains, so the handshake name may not match the business domain shown to the user. If enabling sniffing breaks a connection that works when it is disabled, record the destination IP, port, sniffed domain, and matched rule. Once the issue is confirmed to affect one service, add it to the skip list rather than disabling sniffing globally.

QUIC runs over UDP and is highly affected by the network, firewall, and the proxy node’s UDP support. A browser may switch between QUIC and TCP/TLS when accessing the same website, making the problem intermittent. Compare the destinations and policies of both connections in the logs. If a node does not support UDP, adjust the policy or let the application fall back instead of blaming every UDP issue on DNS. After a mobile device resumes from sleep or switches from Wi-Fi to cellular data, an old connection may remain; reconnect before evaluating the new configuration.

Build reproducible samples from logs

When adjusting sniffing, change one field at a time and test the same application, domain, and network. Record the destination representation, matched rule, and error type with sniffing off and on. If the error is timeout, distinguish between an unreachable destination, an unreachable policy node, and unavailable UDP. If the error is a certificate-name mismatch, focus on whether the overridden destination is correct. For reading log fields and common connection errors, see the guide to diagnosing Clash runtime logs.

06

Local overrides and subscription merging

Subscriptions usually provide nodes, base proxy groups, and some rules, but personal LAN exceptions, DNS preferences, and TUN settings should not be written back to a remote subscription. When a subscription updates, the client regenerates the configuration, so edits to the generated file may be overwritten. A safer structure treats remote content as input and keeps durable local settings in overrides, merge scripts, or a separate main configuration. Clients use different names and syntax for “overrides,” “extensions,” and “merges”; confirm whether the client performs replacement, shallow merging, or deep merging before relying on it.

Distinguish replacement, append, and deep merge

YAML mappings and lists merge differently. A mapping key such as dns.enable can be overridden by key, but rules, proxies, and proxy-groups are lists. Many tools replace a list wholesale rather than appending automatically; writing one local rule may therefore remove every rule from the subscription. Some clients provide explicit prepend and append operations. Before using them, export the final configuration with one easily recognizable test rule and confirm its position and whether the original content remains.

Local overrides are suitable for ports, log levels, DNS, TUN, sniffing, and a small number of rule exceptions. Nodes and frequently changing remote rules are better managed by the subscription or provider. Do not modify the same field at multiple layers—for example, setting mixed-port in a subscription-conversion template, client override, and startup argument—because the final value depends on application order and becomes difficult to trace.

# Local main configuration example: nodes are updated by the provider,
# rule and policy names remain stable.
proxy-providers:
  work-subscription:
    type: http
    url: https://subscription.example.com/work.yaml
    path: ./providers/work.yaml
    interval: 21600
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 600

proxy-groups:
  - name: Default Proxy
    type: select
    use:
      - work-subscription
    proxies:
      - DIRECT

rules:
  - DOMAIN-SUFFIX,internal.example,DIRECT
  - GEOIP,LAN,DIRECT,no-resolve
  - MATCH,Default Proxy

The example URL only demonstrates provider structure. Real subscription URLs often contain access credentials and should not be copied into public logs, screenshots, or shared configurations. use references the name of a proxy-providers entry, not a node name. After the provider updates, groups that reference it receive the new nodes while rules continue pointing to the stable “Default Proxy” group, so adding or removing nodes on the subscription side does not break the routing layer.

Naming and deduplication for multiple subscriptions

When work, personal, or different-source subscriptions are used together, duplicate node names are the most common problem. If two providers both contain “Hong Kong 01,” flattening them into one list makes their origins unclear. Keep each provider separate and distinguish them with filter, exclude-filter, or a client-supported name prefix. Start with simple keyword filters, confirm that the group contains a reasonable number of nodes, and only then add conditions. An overly complex regular expression can filter out every node.

Multiple subscriptions do not mean every node belongs in one automatic-test group. Create separate lower-level groups such as “Work Routes” and “Daily Routes,” then let a top-level manual group choose between them. Work-service rules should point to the work group, while everyday traffic uses the default group, preventing automatic tests from switching a business exit to an unsuitable source. If subscriptions contain policy groups with the same names, rename them consistently in the local main configuration rather than depending on remote names to remain unchanged.

Content Recommended source Why
Nodes and proxy providers Subscription or provider Changes frequently; suitable for automatic updates
Purpose-specific proxy groups Local main configuration Names must remain stable for rule references
LAN and internal-domain rules Local override, applied first Clearly scoped and should not be affected by remote rule changes
Large public rule sets rule-provider Easy to refresh and cache independently
DNS, TUN, and sniffing Local device configuration Directly tied to the current system and network environment

Pre-update checks and failure rollback

Before updating a subscription, keep the last working final configuration rather than only the raw subscription. After the update, check four things: the configuration parses successfully, key policy groups still exist, groups contain nodes, and the final fallback rule remains. Then test connectivity. If the client will not start, restore the previous final configuration and compare nodes, group names, and list indentation instead of repeatedly editing the broken version.

YAML is indentation-sensitive, and list items must be at the correct level. Tabs, full-width punctuation, and seemingly identical special spaces can all cause parse failures. Configurations generated by subscription-conversion tools should still be validated like ordinary configurations; automatic generation is not a reason to skip checks. For provider paths, confirm that the directory exists and is writable. When several files are involved, check relative paths again after moving the main configuration.

Migrating configurations between clients

Clash Plus, Clash Verge Rev, FlClash, and Clash Nyanpasu can all work with mihomo configurations, but their override methods, configuration directories, and service modes differ. During migration, first import a core YAML without device-specific paths, then configure system proxying, TUN permissions, and startup behavior in the new client. Do not copy the entire old client data directory, which may carry caches, lock files, and platform-specific paths into the new environment. Compare client and platform differences in the cross-platform review.

07

External control panels

mihomo provides an external control API for viewing connections, switching policies, updating providers, and reading logs. Desktop clients usually connect to this API through their built-in interface; server, router, and command-line deployments can use a separate Web control panel. Because the API can change runtime state, treat it as an administrative entry point rather than an ordinary web service. Secure deployment centers on limiting the listening scope, setting access credentials, and using a trusted network or reverse proxy for remote access.

Listening address and access scope

external-controller: 127.0.0.1:9090
secret: "your-control-secret"
external-ui: ./ui
external-ui-name: dashboard

127.0.0.1:9090 accepts connections only from the local machine, making it suitable when the desktop client or control panel runs alongside the core. With 0.0.0.0:9090, other LAN devices may also connect, so configure the firewall and strong credentials at the same time. Credentials in examples are instructional only; use a separate, unpredictable value in production and never reuse a subscription URL or another account password.

external-ui points to the directory containing the static control-panel files, including its entry file. external-ui-name distinguishes or selects the interface directory; download and update procedures depend on the chosen panel and core configuration. If the API connects but the page is blank, check the static-file path and process working directory. If the page opens but cannot connect to the core, check the API address, protocol, browser same-origin restrictions, and credentials.

LAN and remote-access boundaries

For LAN administration, bind the control API to a private network address and allow access only from the management subnet. Do not expose the control port directly to the public internet. For remote administration, enter a trusted VPN first, or use a reverse proxy with authentication and TLS. The reverse proxy should also restrict allowed methods, request-body size, and origins so that anyone who can load the page cannot operate the core.

Switching policies in the control panel changes the current runtime state but may not write back to the original configuration. Whether the choice survives a restart depends on settings such as profile.store-selected and the client implementation. Enable the relevant persistence option if the selection should return after restart. If a server must always start with a fixed exit, disable saving and define the default order explicitly in the configuration.

profile:
  store-selected: true
  store-fake-ip: true

log-level: info
unified-delay: true
tcp-concurrent: true

store-selected saves the current selection of each policy group, while store-fake-ip saves Fake-IP mappings and can help preserve some connection behavior after a restart. The save file still requires write access to the working directory. log-level: info suits routine monitoring; temporarily increase verbosity for troubleshooting, but avoid keeping extensive logs indefinitely because they increase disk writes and information exposure. unified-delay makes latency tests use a more consistent calculation method, while tcp-concurrent tries destination addresses concurrently to improve some dual-stack connection setups. Test both according to device resources and network behavior.

How to troubleshoot through the control panel

The connection list answers three questions: which destination the application reached, which rule matched, and which policy was ultimately used. When a website fails, filter connections by domain and confirm that the request appears. If there is no record, traffic may not have entered the core; check system proxying or TUN. If a record appears with only an IP, investigate DNS and sniffing. If the rule and policy are correct but the connection times out, check node and destination reachability.

Latency tests on the policy-group page are health checks, not route ratings. A node may respond quickly to the test URL yet remain unusable for a specific service. Use actual connection logs for judgment. When a provider update fails, determine whether it is a proxy provider or rule provider, then check the relevant subscription URL, rule URL, DNS, and write permissions. Repeated clicks can trigger overlapping updates; waiting for the current task to finish before retrying usually produces clearer logs.

Panel symptom Relevant layer Next check
No destination connections at all Traffic interception System proxy, TUN, and the application’s own proxy settings
Connections show only IPs and rules match incorrectly Destination identification DNS mapping, Fake-IP, and domain sniffing
The wrong policy group is selected Rule layer Rule order, rule-set content, and group names
Rules match correctly but the connection times out Exit and destination Node health, UDP support, and destination reachability
Policy selection resets after restart State persistence store-selected and working-directory permissions

A safe process for configuration changes

Before reloading a configuration through the control API, validate its syntax in a separate location. When changing the listening address, TUN, or default route on a remote server, keep the current management session open and prepare a command that can restore the old configuration. With a systemd deployment, check service logs before performing a controlled restart; do not delete the old file until the new configuration has been confirmed readable. If the service repeatedly fails to start, stop automatic restarts and inspect the first failure line directly; later errors are often only cascading results.

# View service status and recent logs
systemctl status mihomo
journalctl -u mihomo -n 100 --no-pager

# Restart only after validating the configuration
sudo systemctl restart mihomo

The service name depends on how it was installed, so verify the local unit name before running commands. A pure command-line deployment requires more system-administration knowledge; desktop users who want to manage subscriptions, policies, and system proxying directly should start with the Linux client or another GUI client for their platform. For Linux desktop and systemd deployment paths, continue with the Clash Linux installation guide.

Download Clash