Surge is a powerful network debugging and proxy tool for iOS and macOS, with a plain-text configuration file (`.conf`) at its core. Many people find Surge’s config intimidating, but once you understand its main modules and the order in which they take effect, writing one becomes much clearer. This article starts with the overall structure, explains what each part does and how to write it, and ends with a ready-to-use generic template.
1. The overall structure of the configuration file
A Surge configuration file usually consists of the following [Section] sections, arranged in the order they’re written, though each one has its own rules for when it takes effect (more on this below):
Section
Purpose
`[General]`
Global settings: DNS, logging, listening ports, address ranges to skip proxying, etc.
`[Proxy]`
Defines each proxy node (server information)
`[Proxy Group]`
Combines nodes into “policy groups” that rules can reference
`[Rule]`
Decides which traffic goes to which policy group, or connects directly / is dropped
`[Host]`
Custom domain resolution (like a local hosts file)
`[URL Rewrite]` / `[Header Rewrite]`
Request rewriting (optional)
`[Script]` / `[MITM]`
Scripts and MITM decryption (optional, advanced)
Once you understand this structure, the way to write a config is: first define “what exits you have” (Proxy / Proxy Group), then define “which traffic goes through which exit” (Rule), while General and Host provide the underlying foundation.
2.[General]: Global settings
This section controls how Surge itself behaves. Common and important fields include:
DNS-related:dns-server specifies the DNS server Surge uses;hijack-dns can force-hijack device-hardcoded DNS (e.g., the 8.8.8.8 baked into some apps) into Surge’s DNS stack, so those queries can’t bypass the routing rules.
**Skip proxy skip-proxy**: the LAN ranges (192.168.0.0/16, 10.0.0.0/8, etc.) plus the machine’s own addresses should normally be included, otherwise traffic between LAN devices would get intercepted by the proxy too.
Testing and probing:internet-test-url, proxy-test-url are used for connectivity checks and node speed tests; it’s best to use addresses that are reliably reachable both at home and abroad (e.g., Gstatic, Cloudflare’s 204 probe address).
IPv6: if your network or proxy nodes have incomplete IPv6 support, it’s best to disable ipv6 = false, which cuts down on connection errors.
Port listening:http-listen / socks5-listen handle the local proxy ports on the Mac side; keeping them listening on 127.0.0.1 is usually enough, unless you need to share the proxy with other devices on the LAN.
The guiding principle for this section: first ensure stable connections without sweeping up LAN traffic, then consider other optimizations.
3.[Proxy]: Defining nodes
Each line defines one proxy node. The basic format is:
psk is the pre-shared key, provided by your proxy provider or self-hosted server;
reuse=true enables connection reuse to reduce handshake overhead;
tfo=true enables TCP Fast Open for faster connection setup;
If the server also layers Shadow-TLS on top for traffic obfuscation, add shadow-tls-password, shadow-tls-sni, shadow-tls-version, and similar parameters.
Surge supports Shadowsocks, VMess, Trojan, Snell, HTTP/SOCKS5, and more; check the docs for each protocol to get the exact parameters. This info usually comes from your proxy provider or self-hosted server, so don’t hardcode it into configs you share with others.
4.[Proxy Group]: Organizing policy groups
Managing nodes one by one is unwieldy, so Surge bundles them into “policy groups” that rules can call as a whole. Common group types:
**select**: manual selection — you switch sub-options by hand in the app (each one can be a node or another policy group, enabling “groups within groups”).
**smart / url-test**: automatic speed-based selection — Surge uses url (the probe URL) and interval (the probe interval) to test each node’s latency on a schedule and automatically pick the best one.
**fallback**: primary/backup mode — automatically switches to a standby node when the primary one fails.
**load-balance**: load balancing — spreads traffic across multiple nodes.
Practical tip: create auto speed-test groups by region (US, Japan, Hong Kong…), then build higher-level groups by use case (AI services, streaming, Telegram, etc.) that reference the regional ones — routing becomes more granular and easier to maintain.
5.[Rule]: Routing rules
Rules decide “where this traffic goes,” and Surge matches them top to bottom, applying the first rule that hits, which makes rule ordering critical. Common rule types:
**DOMAIN / DOMAIN-SUFFIX / DOMAIN-KEYWORD**: match by domain, domain suffix, or keyword;
**RULE-SET**: references a rule-set file (local or a remote URL) to import lots of rules at once — the most common approach;
**GEOIP**: matches by the country/region an IP belongs to; GEOIP,CN,DIRECT is the usual catch-all rule for “domestic IPs connect direct”;
**FINAL**: must be the last line — the default policy when no other rule matches.
A recommended general order (top to bottom):
DNS-sensitive traffic or anything that must stay direct (e.g., NTP time sync, LAN, private services)
Ad and malicious-domain blocking rules
Per-app, per-scenario proxy rules (AI, streaming, social apps, etc.)
Catch-all rule for direct-connecting domestic IPs/domains
FINAL fallback policy
The logic behind this order: the more “special” the traffic — the more likely it is to get caught by mistake — the higher its rules should sit; the more “general” a catch-all rule is, the lower it goes.
6.[Host]: Custom domain resolution
Works like the system hosts file: pin a domain to a fixed IP, or force resolution through the system DNS (server:system). Common uses include time sync and internal-service resolution — scenarios that are sensitive to the DNS resolution path.
7. Writing tips and common pitfalls
Write General and Host first to lay the foundation, then Proxy/Proxy Group, and Rule last, validating each step as you go — don’t pile on a mountain of rules and then try to debug everything at once.
Prefer remote RULE-SET over hand-writing long lists of domains; community-maintained rule sets (e.g., the blackmatrix7 and Loyalsoldier repos) are updated frequently and cover a lot of ground.
Keep sensitive information (node addresses, keys, subscription links) out of configs you share with others; use placeholders instead and let them fill in their own.
FINAL rule is a must, and there can be only one; otherwise a rule may fail to match any policy and connections can break.
After reordering rules, retest critical services (messaging and payment apps, for example) to avoid misrouting caused by the new order.
8. A ready-to-use config template
Below is a generic template with all private info — personal nodes, subscription links, and so on — stripped out. It covers every module mentioned in this article and is a solid starting point for your own config. Before using it:
In [Proxy], enter your own node info;
In the 订阅节点 group, replace policy-path with your own subscription link;
In the 自建节点 group, replace DIRECT with the name of a node you’ve added.
A Surge config is essentially a declarative system of “groups + rules.” Once you sort out [Proxy], [Proxy Group], [Rule] — the “node → group → rules call groups” relationship among the three — even a complex config can be understood and debugged piece by piece. Start from a minimal template, get basic direct/proxy routing working, then gradually layer on advanced features like ad blocking and per-app rules.
1. The overall structure of the configuration file
A Surge configuration file usually consists of the following [Section] sections, arranged in the order they’re written, though each one has its own rules for when it takes effect (more on this below):
Section
Purpose
`[General]`
Global settings: DNS, logging, listening ports, address ranges to skip proxying, etc.
`[Proxy]`
Defines each proxy node (server information)
`[Proxy Group]`
Combines nodes into “policy groups” that rules can reference
`[Rule]`
Decides which traffic goes to which policy group, or connects directly / is dropped
`[Host]`
Custom domain resolution (like a local hosts file)
`[URL Rewrite]` / `[Header Rewrite]`
Request rewriting (optional)
`[Script]` / `[MITM]`
Scripts and MITM decryption (optional, advanced)
Once you understand this structure, the way to write a config is: first define “what exits you have” (Proxy / Proxy Group), then define “which traffic goes through which exit” (Rule), while General and Host provide the underlying foundation.
2.[General]: Global settings
This section controls how Surge itself behaves. Common and important fields include:
The guiding principle for this section: first ensure stable connections without sweeping up LAN traffic, then consider other optimizations.
3.[Proxy]: Defining nodes
Each line defines one proxy node. The basic format is:
Take the common Snell protocol as an example:
Surge supports Shadowsocks, VMess, Trojan, Snell, HTTP/SOCKS5, and more; check the docs for each protocol to get the exact parameters. This info usually comes from your proxy provider or self-hosted server, so don’t hardcode it into configs you share with others.
4.[Proxy Group]: Organizing policy groups
Managing nodes one by one is unwieldy, so Surge bundles them into “policy groups” that rules can call as a whole. Common group types:
Example:
Practical tip: create auto speed-test groups by region (US, Japan, Hong Kong…), then build higher-level groups by use case (AI services, streaming, Telegram, etc.) that reference the regional ones — routing becomes more granular and easier to maintain.
5.[Rule]: Routing rules
Rules decide “where this traffic goes,” and Surge matches them top to bottom, applying the first rule that hits, which makes rule ordering critical. Common rule types:
A recommended general order (top to bottom):
The logic behind this order: the more “special” the traffic — the more likely it is to get caught by mistake — the higher its rules should sit; the more “general” a catch-all rule is, the lower it goes.
6.[Host]: Custom domain resolution
Works like the system hosts file: pin a domain to a fixed IP, or force resolution through the system DNS (server:system). Common uses include time sync and internal-service resolution — scenarios that are sensitive to the DNS resolution path.
7. Writing tips and common pitfalls
8. A ready-to-use config template
Below is a generic template with all private info — personal nodes, subscription links, and so on — stripped out. It covers every module mentioned in this article and is a solid starting point for your own config. Before using it:
Closing thoughts
A Surge config is essentially a declarative system of “groups + rules.” Once you sort out [Proxy], [Proxy Group], [Rule] — the “node → group → rules call groups” relationship among the three — even a complex config can be understood and debugged piece by piece. Start from a minimal template, get basic direct/proxy routing working, then gradually layer on advanced features like ad blocking and per-app rules.