1. Configuration Structure and Processing Order

config.yaml defines connection entry points, DNS resolution, available outbound connections, and routing rules. A useful way to follow the flow is: app traffic → local port or TUN → rule matching → proxy group → node or direct connection. DNS supports hostname resolution along the way, but not every connection follows the same DNS path.

This guide follows the order commonly used in configuration files. YAML top-level fields can usually be rearranged; placing dns before rules does not give it higher priority. Order matters within the rules list itself. Protocol support and some fields depend on the core, and the capabilities of legacy Clash and Clash Meta (now mihomo) are not identical.

  • Top-level mappings: Fields such as dns: and proxies: start at the beginning of a line.
  • Nested indentation: Use two spaces per level and avoid tabs. Keep - before list items.
  • Name references: Proxy group and node names must match exactly, including capitalization and spaces.
  • Client-generated configuration: Subscriptions, overrides, merge scripts, and UI settings can all contribute to the runtime configuration. Editing a YAML file on disk may not immediately change how the core behaves.

2. Ports, Runtime Mode, and the Control Interface

Port fields specify where the client accepts connections on your local machine, not the server port on a remote node. The example below uses 7890 as a mixed proxy port. These numbers are examples; use the values in your active configuration and check for port conflicts.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
FieldPurposeNotes
portHTTP proxy portSupports HTTP proxy requests and CONNECT tunnels; it is not a web server port.
socks-portSOCKS proxy portThe app must be explicitly configured to use the SOCKS proxy protocol.
mixed-portShared HTTP and SOCKS portOne listening port accepts both proxy protocols. Make sure the app is still set to use the correct protocol.
allow-lanAllow LAN connectionsLAN access also depends on the listening address, system firewall, and access controls.
modeOperating moderule routes traffic according to rules, global uses the global policy, and direct connects directly.
external-controllerController listen addressUsed to check status and switch policies, not as a proxy endpoint for apps.

Why You Shouldn't Confuse Ports 7890 and 9090

If the active configuration sets mixed-port to 7890, enter host 127.0.0.1 and port 7890 in your browser's manual proxy settings. If the configuration also has external-controller: 127.0.0.1:9090, 9090 is the control API port. Using it as the browser proxy port will cause the connection to fail.

Bind the control interface to a loopback address whenever possible, and set a separate secret. Enabling LAN proxy access is no reason to expose the control interface on every network adapter. The client usually manages the system proxy toggle; changing mixed-port alone does not ensure that every app will switch to the new port.

3. DNS: Resolvers, Listen Address, and Fake-IP

The dns section configures the core's DNS features. enable turns DNS on or off, listen sets the DNS listen address, and nameserver specifies upstream resolvers. The DNS listen port is a separate service from the HTTP and SOCKS proxy ports—don't use a proxy port as a DNS server port.

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 1.1.1.1

This example serves DNS on port 1053 at a loopback address. The listed IP addresses use plain DNS; they do not provide encrypted DNS. Starting this listener does not automatically change your operating system's DNS settings. Apps, the system resolver, or TUN-based DNS interception need to be configured separately to use it.

Fake-IP Addresses Aren't Real Server Addresses

In fake-ip mode, the core assigns synthetic addresses from a configured range and keeps track of which domain each address represents, so it can route subsequent connections by hostname. If a lookup returns an address beginning with 198.18., first check whether the core is still handling the connection. Don't assume the address is the website's real IP.

  • App compatibility: Some device discovery, gaming, and other apps that rely on real DNS answers may need a targeted fake-ip-filter entry. Avoid adding broad wildcards as a first step.
  • Upstream reachability: First make sure your current network can reach the selected DNS server. When adding encrypted DNS, also consider how the resolver's hostname will be resolved initially.
  • Advanced fields: mihomo fields such as respect-rules and proxy-server-nameserver handle specific routing and resolution scenarios. Configure them according to the documentation for your core, and don't conflate DNS request routing with ordinary traffic rules.

To troubleshoot, run dig @127.0.0.1 -p 1053 example.com in an environment that supports specifying a port, then check for a response. This only tests whether the specified DNS listener responds; it does not prove that system traffic is being intercepted or that a proxy node can connect.

4. proxies: Node Definitions and Protocol Parameters

proxies is a list of node objects. Each object typically includes name, type, server, and port; other fields depend on the protocol. For example, Shadowsocks uses cipher and password, while other protocols may require a UUID, TLS, or transport settings. Changing type alone does not convert a node to another protocol.

proxies:
  - name: "Local Test Node"
    type: ss
    server: 127.0.0.1
    port: 8388
    cipher: aes-128-gcm
    password: "local-demo-only"

Node Names and Server Addresses Are Different Things

name is the label shown in the UI and referenced by proxy groups; server is the connection destination. If you rename “Local Test Node,” update any proxy groups that reference it. The node's port: 8388 points to the server and has no numerical relationship to the local mixed-port: 7890.

Quote strings that contain colons or hash marks, or that could be interpreted as Boolean values. Treat credential fields as strings, too. When sharing configuration files or logs, redact passwords, tokens, and full subscription URLs. Renaming a node in the UI does not remove this sensitive information.

5. proxy-groups: The Policy Layer Between Rules and Nodes

proxy-groups organizes nodes or other groups into selectable outbound policies. Rules typically target a stable group name, while subscription updates replace the nodes within that group. This lets you manage which traffic uses a route separately from which node is currently selected for it.

proxy-groups:
  - name: "Manual Outbound"
    type: select
    proxies:
      - "Local Test Node"
      - DIRECT
  • select: Choose a member manually or through the control API. Useful when you want to specify an outbound route.
  • url-test: Automatically selects a member based on probe results. The test URL, interval, and tolerance affect the choice; results don't necessarily reflect actual download speeds.
  • fallback: Tries members in list order and uses an available one. Suitable for primary/backup switching, not for sorting by lowest latency.
  • load-balance: Selects a member for each connection according to a supported distribution strategy. It does not automatically combine multiple nodes' bandwidth for a single ordinary connection.

The list above references the “Local Test Node” defined in the previous section, as well as the built-in DIRECT outbound. Removing the node while keeping the reference causes a configuration error. Groups can reference other groups, but avoid circular dependencies—for example, A referencing B while B references A.

Subscription Nodes May Not Appear Directly Under proxies

A configuration using proxy-providers can load nodes from providers, and proxy groups can reference provider names with use. So an empty top-level proxies: [] does not necessarily mean there are no nodes. Check that providers loaded successfully, that groups include use, and that the UI hasn't applied filters.

6. rules: Match from Top to Bottom, Then Select an Outbound

In mode: rule, the core checks rules in list order and uses the policy specified by the first matching rule. A typical rule contains a type, a match value, and a target outbound. MATCH needs no match value and is usually placed last to handle connections that didn't match earlier rules.

rules:
  - DOMAIN,example.com,Manual Outbound
  - DOMAIN-SUFFIX,example.org,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,Manual Outbound
RuleWhat It MatchesWhat to Check
DOMAINExact domainexample.com does not automatically include its subdomains.
DOMAIN-SUFFIXDomain and its subdomainsexample.org can match www.example.org.
IP-CIDRDestination IPv4 rangeno-resolve prevents the rule from triggering a DNS lookup just for matching; it does not disable all DNS.
RULE-SETReference a rule providerA matching rule-providers definition and available rule data must exist.
MATCHRemaining connectionsPutting it earlier prevents later rules from being checked.

A “direct LAN” rule that covers only the example range 192.168.0.0/16 may not work for every network. Your network could also use 10.0.0.0/8, 172.16.0.0/12, or IPv6 addresses. Add rules based on your local subnets and service discovery needs; don't treat the example as a complete ruleset.

If you move MATCH,Manual Outbound to the first line, the domain rules below it will never run. If a rule appears to have no effect, first confirm that rule mode is active. Then check for earlier rules and client-added overrides, and finally inspect the connection log for the matched rule and actual outbound.

7. Minimal Complete Example and the Limits of TUN

Here's a minimal configuration for checking the structure: it enables a mixed port, core DNS, and rule mode, and includes a proxy group with only a direct connection. It does not provide remote proxy access. Use it to check whether the YAML loads, the port is listening, and group references are consistent.

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

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5

proxies: []

proxy-groups:
  - name: "Manual Outbound"
    type: select
    proxies:
      - DIRECT

rules:
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,Manual Outbound

TUN Captures Traffic; It Doesn't Replace Routing Rules

TUN captures traffic through a virtual network interface, commonly for apps that don't follow the system proxy settings. It is not part of proxies and won't fix invalid node credentials. For example, on mihomo builds that support these fields, add the following snippet to your existing configuration. It is not a universal configuration for every legacy Clash core.

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

To enable TUN, you'll still need operating system permissions, a supported virtual network adapter, and correct routing. dns-hijack handles relevant DNS traffic that enters this capture path; it does not mean that every app's built-in encrypted DNS over HTTPS will be intercepted. If the client already manages TUN through its UI, check the generated configuration first to avoid maintaining conflicting settings in multiple places.

8. How to Edit, Validate, and Roll Back

  1. Keep a backup: Export the current profile and note the selected proxy group member. Back up subscription files and local overrides separately.
  2. Change one thing at a time: Update the port and verify it first, then adjust DNS, and finally change nodes, groups, and rules. Don't switch cores, enable TUN, and replace the entire DNS setup all at once.
  3. Validate the configuration: If you're using the mihomo command line and the config is in the current directory, run mihomo -t -f ./config.yaml. For other cores, check the available options with -h first. Passing a command-line check does not guarantee network connectivity.
  4. Check the active configuration: After reloading, review the logs for YAML parsing errors, missing node references, port conflicts, and other issues.
  5. Test each layer: Check the local proxy endpoint, DNS responses, node connectivity, and rule matching in that order. When reviewing connection logs, note the destination hostname, matched rule, proxy group, and final member.
  6. Roll back if something breaks: Switch back to the last working profile, restore the previous system proxy or TUN setting, and then isolate the change that caused the issue. Don't keep importing unknown configs; that can hide the original problem.

Find the Relevant Field Based on the Error

  • A line number appears on load: Check indentation, quotes, colons, and list formatting first. Then check whether the preceding line is missing part of the structure.
  • Proxy or policy not found: Check name references across rules, proxy-groups, and proxies.
  • Address already in use: Check whether ports such as 7890 and 1053 in the active configuration are occupied by another process or another running core.
  • DNS resolves, but connections fail: Check the node server, protocol parameters, selected member, and outbound network. Don't keep changing DNS without checking these first.
  • Manual changes disappear after an update: Check whether you edited a subscription cache file. Move settings you want to keep into an override or merge mechanism supported by the client.

When reading a configuration, start with the local proxy ports, then follow the groups referenced by rules and the members within those groups. Check DNS and TUN requirements separately. Understanding how these layers fit together helps distinguish three different outcomes: the file loads, a rule matches, and a connection works. For more setup steps, see Advanced; for field definitions, see the glossary.