# Surge Manual - Complete Documentation > Surge is a web development and proxy utility for network debugging, HTTPS inspection, and traffic forwarding with flexible rule-based routing. --- # Surge Overview Surge is a web development and proxy utility designed for developers requiring professional knowledge to operate effectively. ## Core Workflow The software provides four fundamental capabilities: **Takeover:** Surge captures network connections via proxy service or virtual NIC takeover. **Processing:** Users can modify intercepted network requests and responses through URL redirection, local file mapping, JavaScript customization, and other methods. **Forwarding:** Taken-over requests route to other proxy servers either globally or via flexible rule-based policies. **Intercept:** Specific request/response data can be captured and saved, including HTTPS traffic decryption via man-in-the-middle techniques. ## Key Features - High performance with industrial-grade stability and minimal resource consumption - Flexible rule system supporting domain names, IP CIDR, and GeoIP-based forwarding - HTTPS decryption with CA certificate generation - Customizable local DNS mapping with wildcard and alias support - Policy groups enabling auto speed testing, SSID-based selection, and manual proxy switching - HTTP request rewriting and blocking capabilities - Remote dashboard connectivity to iOS or Mac instances - Complete IPv6 compatibility ## Platform-Specific Features **Mac:** Enhanced mode (virtual network interface), metered network controls, and gateway mode functionality **iOS:** Cellular network support, comprehensive traffic capture from all apps, system DNS override, and network analysis via dashboard ## Documentation Structure - [Overview](overview/) - Components and configuration basics - [Rules](rule/) - Domain-based, IP-based, HTTP, process, and logical rules - [Policies](policy/) - Built-in policies, proxy configuration, WireGuard, SSH - [Policy Groups](policy-group/) - Selection, URL test, fallback, load balance groups - [DNS](dns/) - DNS override, local mapping, encrypted DNS - [HTTP Processing](http-processing/) - MITM, URL/header/body rewrite, mocking - [Scripting](scripting/) - HTTP request/response, rule, event, DNS, cron scripts - [Others](others/) - Misc options, modules, HTTP API, panels, CLI --- ## Overview ### Components # Components Surge includes several components. ## Surge Proxy Server The core component of Surge is a full-function HTTP/SOCKS5 proxy server. Built using Objective-C and optimized for macOS and iOS, it delivers high performance and stability. ## Surge Virtual Network Interface (Surge VIF) Certain applications bypass system proxy settings because they require raw TCP socket access (Mail.app serves as an example). The Surge VIF handles this type of traffic. For Surge iOS, this component is enabled by default. On Surge Mac, you can activate it by enabling Enhanced Mode. ## Surge Dashboard (Mac Version Only) Available exclusively on Mac, Surge Dashboard provides a graphical interface for monitoring and inspecting requests and reviewing DNS cache information. It can connect to either a local Surge instance or a remote instance when external-controller-access is configured. ### Configuration # Profile The core functionality of Surge is controlled by the profile. While most settings can be adjusted through the user interface, certain experimental features may require manual editing to access. ## Profile Content Profiles follow INI file format with `[Section]` segments organizing different settings. Most sections use `key = value` syntax: ``` [General] key = value ``` In sections like `[General]` and `[MITM]`, configuration line order doesn't matter. However, in sections such as `[Rule]`, order is critically important. ## Profile Classifications Profiles fall into three categories: 1. **Normal profile** — manually created or default 2. **Managed profile** — typically supplied by administrators; cannot be locally modified but can be updated remotely. Create a copy to make changes. 3. **Enterprise profile** — enterprise version only; cannot be modified, viewed, or copied ## Detached Profile Sections Surge supports separating profile sections into separate files for managing complex configurations. **Main.conf example:** ``` [Proxy] #!include Proxy.dconf ``` **Proxy.dconf must contain:** ``` [Proxy] ProxyA = http, 1.2.3.4, 80 ``` This enables: - Referencing managed configuration sections while customizing others locally - Sharing sections across multiple profiles - Maintaining consistency between iOS and macOS configurations **Multiple includes (Surge iOS 4.12.0+, Mac 4.5.0+):** ``` [Proxy] #!include A.dconf, B.dconf ``` When multiple files are included, the section becomes read-only via UI. ### Linked Profiles (Mac 6.0.0+) Include remote managed profiles directly: ``` [Rule] #!include https://example.com/managed.conf ``` This creates a local "overlay" receiving automatic upstream updates. ## Modules Modules are patches applied to profiles for specific tasks. They differ from detached sections by offering: - **Flexible toggling** on and off - **Multi-section tuning** within one file - **URL-based installation and updates** **Limitations:** - Cannot adjust `[Proxy]`, `[Proxy Group]`, or `[Rule]` sections - Cannot modify MITM CA certificates - Settings override main profile configuration (not adjustable via UI) ## Comments Three comment formats are supported: ``` # Comment ; Comment // Comment ``` Inline comments require at least one space before the delimiter: ``` dns-server = 8.8.8.8 // inline comment ``` ## Line Requirements (iOS 5.11.0+, Mac 5.7.0+) Conditionally activate configuration lines using `#!REQUIREMENT`: ``` Group = url, policyA, policyB #!REQUIREMENT CORE_VERSION<22 ``` **Available variables:** `CORE_VERSION`, `SYSTEM`, `SYSTEM_VERSION`, `DEVICE_MODEL`, `LANGUAGE` **Supported operators:** `=, ==, >=, <=, >, <, !=, AND, OR, NOT, BEGINSWITH, CONTAINS, ENDSWITH, LIKE, MATCHES` **Simplified notation (iOS 5.14.3+, Mac 5.10.0+):** ``` DOMAIN,reject.com,REJECT #!MACOS-ONLY ``` --- ## Rule # Proxy Rule ## Rule Surge forwards requests to proxy servers or direct connections based on customized rules. ### Priority "Rules are matched from the first one to the last one, in the order they appear in the config file." Rules positioned earlier in the configuration have precedence over subsequent ones. ### Composition Each rule contains three components: the rule type, a matcher (except for FINAL rules), and a proxy policy: ``` TYPE, VALUE, POLICY DOMAIN-SUFFIX,apple.com, DIRECT IP-CIDR, 192.168.0.0/16,ProxyA ``` Surge supports multiple rule types (detailed in subcategories). Policies can be built-in options, proxy policies, or policy groups. All rule sets must conclude with a FINAL rule to establish default behavior. ### Example Configuration ``` [Rule] DOMAIN-SUFFIX,company.com,ProxyA DOMAIN-KEYWORD,google,DIRECT GEOIP,US,DIRECT IP-CIDR,192.168.0.0/16,DIRECT FINAL,ProxyB ``` Domain-based rules include DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD. IP-based rules encompass IP-CIDR and GEOIP. ### Domain based # Domain-based Rule Domain-based rules determine proxy routing by matching request domains. There are three main types available. ## Rule Types **DOMAIN** ``` DOMAIN,www.apple.com,Proxy ``` Matches when the domain exactly equals the specified value. **DOMAIN-SUFFIX** ``` DOMAIN-SUFFIX,apple.com,Proxy ``` Matches domains that end with the specified suffix. For instance, `google.com` will match `www.google.com`, `mail.google.com`, and `google.com` itself, but it will not match `content-google.com`. **DOMAIN-KEYWORD** ``` DOMAIN-KEYWORD,google,Proxy ``` Matches when the domain contains the specified keyword anywhere within it. **DOMAIN-SET** Optimized for matching large numbers of domains with efficient searching capabilities. Lines beginning with a period (`.`) match the specified domain and all its subdomains, making this useful for ad-blocking scenarios. ## Extended Matching Parameter The `extended-matching` parameter (iOS 5.8.0+, Mac 5.4.0+) enables matching against both SNI and HTTP Host Header (or `:authority`). This parameter applies to `DOMAIN`, `DOMAIN-SUFFIX`, and `DOMAIN-KEYWORD` rules, and can be propagated to `DOMAIN-SET` entries by appending it to the corresponding ruleset line. ### Final # Final Rule The FINAL rule serves as a catch-all mechanism that must appear after all other rules in a configuration. It establishes the default policy for any requests that don't match preceding rule conditions. ## Example Configuration ``` [Rule] DOMAIN-SUFFIX,company.com,ProxyA DOMAIN-KEYWORD,google,DIRECT GEOIP,US,DIRECT IP-CIDR,192.168.0.0/16,DIRECT FINAL,ProxyB ``` ## Options ### dns-failed "Use the FINAL rule if the DNS lookup fails during rule evaluation." This option applies only when paired with a non-DIRECT policy, allowing fallback behavior when domain resolution encounters errors. ### Http # HTTP Rule HTTP rules apply to HTTP and HTTPS requests but do not affect TCP connections. ## USER-AGENT ``` USER-AGENT,Instagram*,DIRECT ``` This rule type matches requests based on the user agent string. The pattern supports wildcard characters `*` and `?`. ## URL-REGEX ``` URL-REGEX,^http://google\.com,DIRECT ``` This rule matches requests where the URL conforms to the specified regular expression pattern. ### Extended Matching Option You can add the `extended-matching` parameter to also evaluate the HTTP Host header (or `:authority`) and SNI values, which is useful when TLS handshake details are required: ``` URL-REGEX,^https://example\.com,Proxy,extended-matching ``` ### Ip based # IP-based Rule IP-based rules match requests based on their IP addresses. There are three main types available in Surge. ## Rule Types **IP-CIDR** Matches when the request's IP address falls within a specified CIDR range: ``` IP-CIDR,192.168.0.0/16,DIRECT IP-CIDR,10.0.0.0/8,DIRECT IP-CIDR,172.16.0.0/12,DIRECT IP-CIDR,127.0.0.1/8,DIRECT ``` Starting with Surge Mac 6.0.0, single IPv4 addresses can be written without a mask (treated as `/32`). **IP-CIDR6** Matches when the request's IPv6 address falls within a specified range: ``` IP-CIDR6,2001:db8:abcd:8000::/50,DIRECT ``` Single IPv6 addresses are supported similarly to IPv4. **GEOIP** ``` GEOIP,US,DIRECT ``` Matches based on the country code derived from GeoIP lookups. **IP-ASN** ``` IP-ASN,1234,DIRECT ``` Matches when the autonomous system number of the remote IP address corresponds to the specified value. ## Important Behavior "An IP-based rule will trigger a DNS lookup if the hostname of the request is a domain. If the DNS lookup fails, Surge will abort the rule testing and report an error." ## Parameters **no-resolve** ``` GEOIP,US,DIRECT,no-resolve IP-CIDR,172.16.0.0/12,DIRECT,no-resolve ``` This parameter skips DNS queries for domain-based requests, preventing rule testing failures when domains cannot be resolved locally. ### Logical rule # Logical Rule Logical Rule allows you to "combine multiple rules for complex scenarios" and enables nesting of logical rules within one another. ## AND Rule This rule type matches when all sub-rules evaluate as true. **Syntax:** `AND,((#Rule1), (#Rule2), (#Rule3)...),Policy` **Example:** ``` AND,((SRC-IP,192.168.1.110), (DOMAIN, example.com)),DIRECT ``` ## OR Rule This rule type matches when at least one sub-rule evaluates as true. **Syntax:** `OR,((#Rule1), (#Rule2), (#Rule3)...),Policy` **Example:** ``` OR,((SRC-IP,192.168.1.110), (SRC-IP,192.168.1.111)),DIRECT ``` ## NOT Rule This rule type inverts the evaluation result of the wrapped rule. **Syntax:** `NOT,((#Rule1)),Policy` **Example:** ``` AND,((NOT,((SRC-IP,192.168.1.110))),(DOMAIN, example.com)),DIRECT ``` ### Misc rule # Misc Rule ## Miscellaneous Rule ### Port Number Rules Port number rules support three expression types: - Direct port numbers: `IN-PORT,6153` - Closed intervals: `DEST-PORT,10000-20000` - Operators (>, <, <=, >=): `SRC-PORT,>=50000` (iOS 5.8.4+, Mac 5.4.4+) #### DEST-PORT Matches if the target port of the request corresponds to the specified value. ``` DEST-PORT,80-81,DIRECT ``` #### IN-PORT Matches if the incoming port where Surge is listening matches. Useful when Surge listens on multiple ports. ``` IN-PORT,6152,DIRECT ``` #### SRC-PORT Matches if the client port number matches the specified value. ``` SRC-PORT,>=50000,DIRECT ``` ### Other Rule Types #### SRC-IP Matches if the client IP address matches. Only applies to remote machines. Supports CIDR notation. ``` SRC-IP,192.168.20.100,DIRECT SRC-IP,192.168.20.0/24,DIRECT ``` #### PROTOCOL Matches if the request protocol corresponds to specified values: HTTP, HTTPS, TCP, UDP, DOH, DOH3, DOQ, QUIC, STUN. ``` PROTOCOL,HTTP,DIRECT ``` Notes: TCP covers HTTP/HTTPS; DOH/DOH3/DOQ match encrypted DNS from Surge; UDP can match QUIC traffic; STUN filters P2P traffic. #### SCRIPT Executes JavaScript to determine if a match occurs. ``` SCRIPT,ScriptName,DIRECT ``` #### CELLULAR-RADIO iOS only. Matches cellular radio technology: GPRS, Edge, WCDMA, HSDPA, HSUPA, CDMA1x, CDMAEVDORev0, CDMAEVDORevA, CDMAEVDORevB, eHRPD, HRPD, LTE, NRNSA, NR. ``` CELLULAR-RADIO,LTE,DIRECT ``` #### DEVICE-NAME Matches the client device name from system settings or custom names in the device view. #### MAC-ADDRESS Matches the MAC address of accessing devices on the same local area network (Mac 6.1.0+). #### HOSTNAME-TYPE Matches hostname forms. Supported keywords: `IPv4`, `IPv6`, `DOMAIN`, `SIMPLE` (Mac 5.7.3+). ``` HOSTNAME-TYPE,IPv6,REJECT HOSTNAME-TYPE,SIMPLE,DIRECT ``` ### Process # Process Rule Process Rule enables you to assign a proxy policy to requests from a specified process. This feature is available exclusively for Surge Mac; Surge iOS does not support process rules. ## PROCESS-NAME (Mac Only) **Syntax:** ``` PROCESS-NAME,Telegram,Proxy ``` **Functionality:** The rule matches when the process name associated with the request corresponds to the specified value. The rule supports wildcard characters `*` and `?` for pattern matching. **Note on Specification:** You can designate either the filename or the complete path of the executable file. For macOS application packages, the executable is typically located within the `.app/Contents/MacOS` directory structure. ### Ruleset # Ruleset Rulesets allow bundling multiple rules from files or URLs. Surge provides two internal rulesets and supports external sources. ## Internal Rulesets ### SYSTEM `RULE-SET,SYSTEM,DIRECT` "Includes rules for most requests sent by macOS and iOS itself." This covers system services like Maps, Find My, and Weather Foundation, though App Store and iTunes content services are excluded. Sample rules include USER-AGENT matching for Apple services, domains like `api.smoot.apple.com` and `captive.apple.com`, and process-based filtering. > "These rules may be updated with Surge updates." ### LAN `RULE-SET,LAN,DIRECT` "Includes rules for LAN IP addresses and .local suffix." This ruleset triggers DNS lookups and covers: - Local domain suffix - Private IP ranges (192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 127.0.0.0/8, 100.64.0.0/10) - IPv6 link-local addresses (fe80::/10) ## External Rulesets External rulesets reference text files from URLs or local storage. Each line contains a rule without a policy assignment: ``` DOMAIN,exampleA.com DOMAIN,exampleB.com ``` Optional parameters for `RULE-SET` include: - `no-resolve`: Skip DNS resolution during matching - `extended-matching`: Match domain rules against both SNI and HTTP Host headers ## Inline Rulesets (Mac 5.3.1+) Rules can be embedded directly in profiles using `[Ruleset Streaming]` sections: ``` [Ruleset Streaming] DOMAIN-SUFFIX,netflix.com DOMAIN-SUFFIX,netflix.net [Rule] RULE-SET,Streaming,StreamingProxy ``` Inline rulesets use identical syntax to external files with the same optimization benefits. ### Subnet # Subnet Expression & Rule ## Subnet Rule ### Subnet Expression A subnet expression can match networks using one of these formats: - **SSID matching**: `SSID:value` matches Wi-Fi network names (wildcards supported) - **BSSID matching**: `BSSID:value` matches Wi-Fi hardware addresses (wildcards supported) - **Router IP**: `ROUTER:value` matches the router's IP address - **Network type**: `TYPE:WIFI`, `TYPE:WIRED`, or `TYPE:CELLULAR` for broad categorization - **Legacy format**: Omitting a prefix attempts to match SSID/BSSID/Router for backward compatibility ### SUBNET Rule The SUBNET rule applies a policy when the subnet expression matches the current network environment. **Examples:** ``` SUBNET,TYPE:WIRED,DIRECT SUBNET,SSID:MyHome,Proxy ``` These examples demonstrate routing traffic directly for wired connections and through a proxy when connected to the "MyHome" Wi-Fi network. --- ## Policy # Proxy Policy ## Overview Surge can forward requests to another proxy server or connect to the host directly, depending on customized rules. A policy indicates how Surge will deal with the requests. ## Policy Types The system supports three distinct categories of policies: 1. **Proxy policies** - Direct proxy forwarding configurations 2. **Policy groups** - Grouped policy management 3. **Built-in policies** - Pre-configured default policies ### Built in # Built-in Policy ## Overview Surge provides several built-in policies for routing requests. The two most fundamental are: - **DIRECT**: Routes requests directly to the destination host - **REJECT**: Blocks incoming requests ## Available Built-in Policies ### DIRECT Sends the request directly to the target host without proxy routing. ### CELLULAR (iOS Only) Prioritizes cellular network connectivity over Wi-Fi connections. ### CELLULAR-ONLY (iOS Only) Routes exclusively through cellular networks. The connection fails if cellular is unavailable. ### HYBRID (iOS Only) Establishes simultaneous connections across both Wi-Fi and cellular networks. This option is only relevant when the "All Hybrid" setting is disabled. ### NO-HYBRID (iOS Only) Prevents cellular network usage when Wi-Fi is available. This applies only when either "All Hybrid" or "Wi-Fi Assist" is enabled. ## Creating Policy Aliases Built-in policies can be referenced directly in rules and policy groups, or you can create custom aliases for convenience: ``` [Proxy] On = direct Off = reject ``` This allows using "On" and "Off" as policy names throughout your configuration. **Note**: For information on REJECT variations (REJECT-DROP, REJECT-NO-DROP), see the dedicated REJECT Policy documentation. ### External proxy # External Proxy Program ## Overview Surge Mac supports the External Proxy Program policy, enabling integration with other proxy software. This feature is Mac-only and allows Surge to manage external proxy processes. ## Configuration The policy type keyword is `external`. Here's an SSH example: ``` [Proxy] external = external, exec = "/usr/bin/ssh", args = "11.22.33.44", args = "-D", args = "127.0.0.1:1080", local-port = 1080, addresses = 11.22.33.44 ``` ### Required Parameters - `exec`: Path to the external executable - `local-port`: Local port for SOCKS5 forwarding ### Optional Parameters - `args`: Command arguments (can be repeated) - `addresses`: Proxy server IPs to exclude from VIF routes ## How It Works 1. Surge launches the external process using the specified `exec` and `args` parameters, then forwards requests to SOCKS5 at `127.0.0.1:[local-port]` 2. If the process terminates, Surge automatically restarts it when needed 3. In Enhanced Mode, Surge excludes specified addresses from VIF routing (only IP addresses supported) 4. External process requests always route through DIRECT policy 5. All external processes terminate when Surge exits ## Important Notes - Logs from external processes appear in `/tmp/Surge-External-xxxxxx.log` - Surge retries failed connections up to 6 times with 500ms intervals if the process needs startup time - Surge iOS treats external policies as REJECT (unsupported) - Address exclusions reduce processing overhead compared to relying solely on DIRECT policy defaults ### Parameters # Common Policy Parameters ## Egress Parameters Available for both built-in and proxy policies. ### `interface` (Default: automatically) Specifies a particular outgoing network interface for connections. ``` ProxyHTTP = http, 1.2.3.4, 443, username, password, interface = en2 ``` The Direct policy also supports this parameter: ``` [Proxy] Corp-VPN = direct, interface = utun0 WiFi = direct, interface = en2, allow-other-interface=true ``` Ensure the interface has valid routing to the destination. ### `allow-other-interface` (Boolean, Default: false) When enabled, the system may fall back to the default interface if the specified one becomes unavailable. When disabled, connection attempts fail instead. ### `dns-follow-interface` (Boolean, Default: false) *iOS 5.15.2+, Mac 5.2.0+* Applies the interface parameter to DNS queries as well. ### `no-error-alert` (Boolean, Default: false) Suppresses error notifications for this policy. ### `ip-version` Controls IPv4/IPv6 behavior. Only affects connections to the proxy server itself: - dual (Default) - v4-only - v6-only - prefer-v4 - prefer-v6 ### `hybrid` (Boolean, iOS Only, Default: false) Establishes simultaneous connections via both cellular and Wi-Fi, selecting the faster path. ### `tfo` (Boolean, Default: false) Enables TCP Fast Open functionality. ### `tos` (Decimal or Hexadecimal, Default: 0) Customizes the IP TOS field value. ### `ecn` (Boolean, Default: false) *iOS 5.8.0+, Mac 5.4.0+* Enables ECN support for improved performance in high-loss scenarios, though may cause issues in unsupported networks. ### `block-quic` *iOS 5.8.0+, Mac 5.4.0+* Controls QUIC blocking since proxying QUIC may degrade performance: - auto - on - off ## Testing Parameters ### `test-url` Overrides the global testing URL for availability and latency checks. ### `test-timeout` (In seconds) Overrides the global timeout for testing operations. ### `test-udp` Example: `test-udp=google.com@1.1.1.1` Overrides global UDP testing settings using DNS lookups. ### Proxy # Proxy Policy A proxy policy directs requests to another proxy server. Surge supports HTTP/HTTPS/SOCKS5/SOCKS5-TLS and additional proxy protocols. ## Configuration Proxy policies are declared in the `[Proxy]` section: ``` [Proxy] ProxyHTTP = http, 1.2.3.4, 443, username, password ProxyHTTPS = https, 1.2.3.4, 443, username, password ProxySOCKS5 = socks5, 1.2.3.4, 443, username, password ProxySOCKS5TLS = socks5-tls, 1.2.3.4, 443, username, password, skip-common-name-verify=true ``` ## Supported Proxy Types **Standard Protocols:** - HTTP Proxy - HTTPS Proxy (HTTP via TLS) - SOCKS5 - SOCKS5 via TLS - SSH - WireGuard (L3 VPN) **Community Protocols:** - Snell - Shadowsocks - VMess - Trojan - TUIC - Hysteria 2 - AnyTLS ### UDP Relay Surge supports UDP relay of SOCKS5, Snell v4/v5, Shadowsocks, Trojan, WireGuard, Hysteria 2, and TUIC protocols. Manual enablement requires the `udp-relay=true` parameter for certain protocols. ## Common Parameters **Proxy Chain:** - `underlying-proxy`: Connect through another proxy or policy group **TLS-Based Proxies:** - `skip-cert-verify`: Disable certificate verification - `sni`: Customize Server Name Indication - `server-cert-fingerprint-sha256`: Pin server certificate **Protocol-Specific Parameters:** HTTP/HTTPS: `always-use-connect` for CONNECT method usage Shadowsocks: `obfs`, `obfs-host`, `obfs-uri`, `udp-port` VMess: `ws`, `ws-path`, `ws-headers`, `encrypt-method`, `vmess-aead` Trojan: `ws`, `ws-path`, `ws-headers` TUIC: `token` (required), `alpn`, `port-hopping`, `port-hopping-interval` ## Client Certificates TLS proxies support client certificate verification via the `[Keystore]` section. ## Shadow TLS Support Shadow TLS v2 and v3 obfuscation can wrap TCP-based proxies using `shadow-tls-password`, `shadow-tls-sni`, and `shadow-tls-version` parameters. ### Reject # REJECT Policy Surge offers multiple built-in REJECT policies to handle different rejection scenarios. In most cases, using REJECT directly is sufficient. ## Policy Types **REJECT** Returns an error page for HTTP requests. This behavior is controlled by the `show-error-page-for-reject` parameter. **REJECT-DROP** Silently discards connections without responding. Useful for applications with aggressive retry logic that could cause request storms. **REJECT-NO-DROP** Prevents automatic escalation to REJECT-DROP. When 50+ requests to a hostname trigger rejection within 30 seconds, Surge normally upgrades to REJECT-DROP to save resources. This policy bypasses that behavior. **REJECT-TINYGIF** Returns a 1-pixel transparent GIF for HTTP requests. Designed for ad-blocking purposes. ## Pre-matching Feature (iOS 5.14.0+, Mac 5.9.0+) Rules marked with `pre-matching` take effect before normal rule matching, executing during DNS resolution and TCP SYN phases with highest priority. This minimizes overhead for storm requests and ad-blocking. **Syntax:** ``` [Rule] DOMAIN,ad.com,REJECT,pre-matching ``` **Supported rule types:** DOMAIN variants, IP-CIDR variants, GEOIP, IP-ASN, logical rules (AND/OR/NOT), SUBNET, DEST-PORT, SRC-PORT, SRC-IP, and RULE-SET. Each rule appears once per 5 minutes in request logs to prevent flooding. ## Technical Implementation Details **DNS responses:** - REJECT: Returns No Record (or discards if frequency limit triggered) - REJECT-DROP: Discards without response - REJECT-NO-DROP: Returns special IP 198.18.0.244 **TCP responses:** - REJECT: Generates TCP RST (or drops packets if frequency limit triggered) - REJECT-DROP: Discards SYN packets - REJECT-NO-DROP: Generates TCP RST (with protection mechanism at 100+ packets/3 seconds) **UDP packets:** - REJECT: Sends ICMP Administratively Prohibited (or drops if frequency limit triggered) - REJECT-DROP: Discards packets - REJECT-NO-DROP: Sends ICMP Administratively Prohibited ### Ssh # SSH Proxy Policy You can configure SSH protocol as a proxy policy, functioning similarly to `ssh -D`. ## Configuration Syntax **Password Authentication:** ``` [Proxy] proxy = ssh, 1.2.3.4, 22, username=root, password=pw ``` **Public Key Authentication:** ``` [Proxy] proxy = ssh, 1.2.3.4, 22, username=root, private-key=key1 [Keystore] key1 = type=openssh-private-key, base64=[The base64 encoded content of the private key file] ``` ## Key Requirements - The private key file must be base64-encoded twice—once for the key format itself and again for the configuration - Supported key types: RSA, ECDSA, ED25519, and DSA - OpenSSH v7.3+ is required (released August 2016) - Surge supports `curve25519-sha256` for key exchange and `aes128-gcm` for encryption ## Optional Parameters **Idle Timeout:** ``` proxy = ssh, 1.2.3.4, 22, username=root, password=pw, idle-timeout=180 ``` Default value is 180 seconds. ## Server Fingerprint Verification Protect against MITM attacks by specifying the server's public key fingerprint: ``` server-fingerprint = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBk2No6KBq2m9VTCcHXXJBX4/A3RNr+L+yDBl5+TF9qz" ``` Multiple fingerprints can be specified (comma-separated) for servers with multiple keys. Obtain fingerprints from `~/.ssh/known_hosts` or using `ssh-keyscan` in a trusted network. ### Wireguard # WireGuard Surge functions as a WireGuard client, enabling L3 VPN capabilities to be utilized as an outbound proxy policy. ## Configuration Example ``` [Proxy] wireguard-home = wireguard, section-name = HomeServer [WireGuard HomeServer] private-key = sDEZLACT3zgNCS0CyClgcBC2eYROqYrwLT4wdtAJj3s= self-ip = 10.0.2.2 self-ip-v6 = fd00:1111::11 dns-server = 8.8.8.8, 2606:4700:4700::1001 prefer-ipv6 = false mtu = 1280 peer = (public-key = fWO8XS9/nwUQcqnkfBpKeqIqbzclQ6EKP20Pgvzwclg=, allowed-ips = 0.0.0.0/0, endpoint = 192.168.20.6:51820) ``` ## Configuration Notes - Keys accept base64 or hexadecimal encoding - Configure both `self-ip` and `self-ip-v6` for dual-stack or just one for single-stack - Each device requires different IP addresses to prevent conflicts - When `prefer-ipv6` is enabled, IPv6 takes precedence for domains with both A and AAAA records - Multiple peers can be configured (comma-separated with parentheses notation) - Optional peer parameters include `preshared-key` and `keepalive` - Peer endpoints support domain names, resolved via DNS settings in the General section - "0.0.0.0/0 means the policy can be used to access any address" or specific networks - Domain-based access requires DNS server configuration - Configuration sections can be split into detached profile files - Multiple instances may operate simultaneously ## Usage Considerations WireGuard's L3 VPN design creates significantly higher overhead than other general proxy protocols, making it suitable for low-bandwidth scenarios. The tunnel supports TCP and UDP, with basic ICMP/ICMPv6 responses available post-handshake. Protocol limitations mean most errors manifest as timeouts rather than explicit messages, requiring packet analysis for troubleshooting. ## Advanced Features **Reserved Bits Customization** (iOS 5.3.1+, Mac 4.10.3+): Customize WireGuard reserved bits for implementations like Cloudflare WARP. **ECN Support** (iOS 5.8.0+, Mac 5.4.0+): Preserves TOS/DSCP/ECN tags during UDP forwarding through the tunnel when `ecn=true` is configured. --- ## Policy group ### Common parameters # Common Policy Group Parameters ## `no-alert` This parameter prevents notification displays when the policy group changes. ## `hidden` This parameter conceals the group from the menu interface on Surge Mac and removes it from the policy selection interface on Surge iOS. ### Fallback # Fallback Group ## Overview A Fallback Group selects an available policy based on priority and availability. It tests availability by accessing a URL, similar to an automatic testing group, but focuses solely on availability rather than latency measurements. Policies listed first have higher priority. **Example syntax:** ``` FallbackGroup = fallback, ProxySOCKS5, ProxySOCKS5TLS ``` ## Temporary Override Users can manually override automatic testing results: - **Surge Mac:** Access the override option through the main menu within the corresponding group - **Surge iOS:** Long-press the policy menu in the policy group view to find override options ## Configuration Parameters **`interval`** (optional, default: 600 seconds) Controls how long cached benchmark results remain valid before being discarded. **`timeout`** (optional, default: 5 seconds) Sets the maximum duration to wait for a policy response; policies exceeding this threshold are abandoned. ### Group # Policy Group A policy group may contain multiple policies. It can be a proxy policy, another policy group, or a built-in policy. ## Purpose The existence of policy groups is to allow for flexible adjustment of the specific policies being used when proxy rules are applied, without the need to modify the rules themselves. ## Group Types There are several group types available: - `select` - Manual Selection Group - `url-test` - Automatic Testing Group - `fallback` - Fallback Group - `load-balance` - Load Balance Group - `subnet` - Subnet Group Policy groups should be declared in section `[Proxy Group]`. ### Load balance # Load Balance Group A load-balancing group randomly selects a policy from the available sub-policies to use. ## Parameters ### `persistent`: Optional When `persistent=true`, the same policy will be used for the same target hostname. This approach helps prevent triggering risk controls on the target site due to different egress IPs. However, a policy change may occur when availability changes. ### Policy including # Policy Including ## Include External Policies Policy groups can import policies from external files or URLs: ``` egroup = select, policy-path=proxies.txt ``` External files contain policy definitions matching the main profile format: ``` Proxy-A = https, example1.com, 443 Proxy-B = https, example2.com, 443 ``` ### Optional Parameters **`update-interval`** — Specifies refresh timing in seconds, applicable only for URL-based sources. **`policy-regex-filter`** — Filters policies by matching regex patterns against policy names. **`external-policy-modifier`** — Adjusts parameters of imported policies. For example: `"test-url=http://apple.com/,tfo=true"` **`external-policy-name-prefix`** — Prepends a prefix to imported policy names for easier identification when using multiple external groups. ## Include Existing Policies (iOS 4.12.0+, Mac 4.5.0+) Reuse policies from the main configuration or other groups: **`include-all-proxies`** — Set to `true` to include all proxy policies from the [Proxy] section, compatible with `policy-regex-filter`. **`include-other-group`** — References policies from other groups using comma-separated names: `"group1,group2"`. Supports `policy-regex-filter` for selective inclusion. ### Usage Notes - All three parameters (`include-all-proxies`, `include-other-group`, `policy-path`) can coexist in a single group - `policy-regex-filter` applies universally across all three - For order-dependent scenarios (like fallback groups), nest policy groups using `include-other-group` ### Select # Manual Selection Group ## Overview A Manual Selection Group allows users to actively choose which policy will be applied through the application interface. ## Syntax ``` SelectGroup = select, ProxyHTTP, ProxyHTTPS, DIRECT, REJECT ``` ## Usage by Platform **Surge iOS**: Use the Widget feature to quickly switch policies for manual selection groups. **Surge Mac**: Access policy switching through the menubar menu. ## Key Feature This group type enables dynamic, user-controlled policy selection rather than automatic routing decisions. Users can change the active policy at any time based on their immediate needs. ### Subnet # Subnet Group ## Overview A Subnet policy group enables automatic policy selection based on the current network environment using subnet expressions as conditions. ## Basic Syntax ``` Subnet Group = subnet, default = ProxyHTTP, TYPE:WIFI = ProxyHTTP, SSID:MyHome = ProxySOCKS5 ``` ## Key Information **Naming Convention:** Starting with Surge iOS 4.12.0 and Surge Mac 4.5.0, the SSID group was renamed to Subnet Group. Legacy SSID Group syntax remains supported for backwards compatibility. Both `subnet` and `ssid` keywords work. ## Parameters ### `default` (Required) Specifies the policy applied when no subnet expression matches the current network. ### `cellular` (Optional, Deprecated) Previously used to designate policy for cellular networks. Use `TYPE:CELLULAR` instead for current implementations. If omitted, the default policy applies. ## Related Concepts This feature integrates with subnet expressions to create conditional routing rules based on network characteristics like connection type and SSID names. ### Url test # Automatic Testing Group ## Overview The Automatic Testing Group dynamically selects a proxy policy based on latency benchmarking to a specified testing URL. This selection can be overridden temporarily or adjusted through general settings. **Basic Syntax:** ``` AutoTestGroup = url-test, ProxySOCKS5, ProxySOCKS5TLS ``` ## Temporary Override Manual policy selection can temporarily override automatic testing results: - **Surge Mac:** Access the override option via the main menu within the corresponding group - **Surge iOS:** Long-press on the policy's menu in the policy group view ## Configuration Parameters **interval** (Optional, seconds | Default: 600) Benchmark results expire after this duration. Retesting occurs if the policy group is subsequently accessed. **tolerance** (Optional, milliseconds | Default: 100) The policy will be changed only when the new winner has a higher score than the old winner's score plus the tolerance. This prevents frequent switching between similarly-performing policies. **timeout** (Optional, seconds | Default: 5) Policies that fail to complete within this timeframe are abandoned. **evaluate-before-use** (Optional, Boolean | Default: false) By default, the first policy is used initially while testing runs in the background. When enabled, testing completes before the first request is made. --- ## Dns ### Dns override # DNS Server Surge implements a specialized DNS client with advanced capabilities that may differ from standard operating system DNS clients. ## Upstream DNS Server By default, Surge retrieves DNS servers from your system settings. You can customize this with the `dns-server` parameter: ``` [General] dns-server = 8.8.8.8, 8.8.4.4 ``` To supplement system settings with additional servers, use the `system` keyword: ``` [General] dns-server = system, 8.8.8.8, 8.8.4.4 ``` (Duplicate entries are automatically filtered out) ## Technical Details Surge queries all configured DNS servers simultaneously to optimize performance. It uses the first answer from servers rather than sequential querying. If no response arrives within 2 seconds, Surge retries all servers. After four retry attempts, the client reports a DNS error. When domains have underperforming authoritative servers, upstream DNS providers may timeout or fail to respond. Surge reports an empty result only if all servers explicitly return empty answers, or if some return empty while others timeout beyond the 2-second window. IPv6-enabled systems receive both A and AAAA record queries. The first A or AAAA answer returned will be used. ### Doh # Encrypted DNS If encrypted DNS is configured, traditional DNS is only used to test connectivity and resolve the domain in the encrypted DNS URL. ## Supported Protocols - DNS over HTTPS: `https://example.com` - DNS over HTTP/3: `h3://example.com` - DNS over QUIC: `quic://example.com` ## Use Encrypted DNS for All Domains ``` [General] encrypted-dns-server = https://8.8.8.8/dns-query ``` Multiple encrypted servers can be specified and separated by commas. ## Use Encrypted DNS for Specified Domains ``` [Host] example.com = server:https://cloudflare-dns.com/dns-query ``` ## Use Encrypted DNS with Proxy To route DoH queries through a proxy, set `encrypted-dns-follow-outbound-mode` to true: ``` [General] encrypted-dns-follow-outbound-mode=true ``` All encrypted DNS connections will follow the outbound mode settings. Configure a rule for the DoH hostname to use a proxy. Alternatively, use `PROTOCOL,DOH`, `PROTOCOL,DOH3` or `PROTOCOL,DOQ` rules to match all encrypted DNS connections. ### Local dns mapping # Local DNS Mapping Surge supports customized DNS mapping functionality. It functions similarly to `/etc/hosts` but with enhanced capabilities like wildcards, domain aliases, and custom DNS server assignments. ## Basic Syntax The configuration uses a `[Host]` section with simple key-value pairs: ``` [Host] abc.com = 1.2.3.4 *.dev = 6.7.8.9 foo.com = bar.com bar.com = server:8.8.8.8 ``` ## Wildcard Support The system supports asterisk prefixes to match subdomains. However, matching uses basic string comparison, so `*google.com` matches `google.com`, `foo.google.com`, and `bargoogle.com`, while `*.google.com` does not match the root domain. ## Domain Aliases You can create alias mappings similar to CNAME records by pointing one domain to another. ## Custom DNS Server Assignment Domains can be configured to resolve through specific DNS servers using the `server:` syntax. Special options include: - `server:system` — delegates to the operating system's resolver - `server:syslib` — routes queries through macOS DNS servers while staying within Surge - By default, domains ending in `.local` resolve via the system ## Remote Rule Set Integration Entire `DOMAIN-SET` or `RULE-SET` files can be bound to DNS mappings, allowing shared upstream or IP assignments without manual duplication. ## Proxy-Specific DNS Handling Enabling `use-local-host-item-for-proxy=true` in the `[General]` section allows Surge to use locally-mapped IP addresses for proxy requests instead of forwarding domain names to remote servers. --- ## Http processing # HTTP Processing Surge provides multiple capabilities for modifying HTTP requests and responses. These modifications follow a specific processing sequence: 1. URL Rewrite 2. Header Rewrite 3. Body Rewrite 4. Script Processing ## Processing Rules An important distinction exists in how these modifications interact: script processing can only be modified by one script, while if there are multiple hits for other rewrite rules, they will take effect in sequence. This means that when multiple URL rewrite, header rewrite, or body rewrite rules match a request, all applicable rules execute in order. However, only a single script can process any given request at the script processing stage. ### Body rewrite # Body Rewrite **Availability:** iOS 5.10.0+ | Mac 5.6.0+ ## Overview Surge enables rewriting HTTP request and response bodies using regular expressions to replace original content. ### Basic Syntax Rules follow this format: ``` http-request ^http(s)?://example\.com regex replacement http-response ^http(s)?://example\.com regex replacement ``` The structure consists of: 1. Direction (`http-request` or `http-response`) 2. URL pattern (regular expression) 3. Search pattern (regex to match) 4. Replacement text ### Multiple Replacements You can chain multiple regex-replacement pairs on a single line: ``` http-response ^https?://example\.com/ regex1 replacement1 regex2 replacement2 ``` ### Key Behaviors - If a request hits multiple body rewrite rules, they will be executed in sequence - Rules can generate new content even when the original request lacks a body (using patterns like `^$`) ## JQ Body Rewrite **Availability:** iOS 5.14.0+ | Mac 5.9.0+ Manipulate JSON bodies using JQ expressions: ``` http-request-jq url-pattern jq-expression http-response-jq url-pattern jq-expression ``` **Example:** ``` http-response-jq ^http://httpbingo.org/anything '.headers |= with_entries(select(.key | test("^X-") | not))' ``` ### Header rewrite # Header Rewrite Surge enables modification of request or response headers before forwarding them to servers. ## Syntax Structure A rewrite rule contains: 1. HTTP direction (`http-request` or `http-response`) 2. URL regular expression 3. Action type 4. Header field name 5. Value (omitted for header-del) 6. Replace template (only for header-replace-regex) Legacy syntax omits the HTTP direction. ## Operations ### header-add Appends a new header line, even if the field already exists. ``` http-request ^http://example.com header-add DNT 1 ``` ### header-del Removes a header line from the request/response. ``` http-request ^http://example.com header-del DNT ``` ### header-replace Replaces an existing header value. Takes no action if the field doesn't exist. ``` http-request ^http://example.com header-replace DNT 1 ``` To add-or-replace (ensuring a value exists), combine deletion and addition operations. ### header-replace-regex Replaces header values using regular expression matching and template substitution. Has no effect if the header field is absent. ``` http-request ^http://example.com header-replace-regex User-Agent Safari Chrome ``` This approach enables pattern-based transformations of header content. ### Mitm # HTTPS Decryption ## Overview Surge can decrypt HTTPS traffic through Man-in-the-Middle (MitM) interception. ## Certificate Management The certificate generator creates a new CA certificate for debugging purposes, available in Surge Dashboard (Mac) and Surge iOS Config Editor. Certificates are generated locally, stored in your profile file and system Keychain, with keys created randomly via OpenSSL. You may also use an existing CA certificate by exporting it to PKCS#12 format (.p12) with a passphrase (required—cannot be empty). Encode the certificate in base64 and add these settings to your config: ``` [MITM] ca-p12 = MIIJtQ......... ca-passphrase = password hostname = *google.com h2 = true ``` ## Hostname Configuration Surge only decrypts traffic to hosts listed in the hostname parameter. A typical configuration might look like: ``` hostname = -*.apple.com, -*.icloud.com, * ``` Some applications have a strict security policy to use pinned certificates or CA. Enabling decryption to these hosts may cause problems. This parameter uses the Host List type—see documentation for detailed rules. ## Configuration Options **skip-server-cert-verify** (Boolean, default: false) Skip verification of the remote host's certificate during MitM. **h2** (Boolean, default: false) Enable MitM over HTTP/2 protocol for improved concurrent request performance. **client-source-address** Restrict MitM to specific devices by IP address or CIDR block (IPv4/IPv6 supported). Use `-` prefix to exclude clients. Includes `127.0.0.1` if enabling for the current device. Supports MAC addresses on Mac version 6.1.0+. **auto-quic-block** (Boolean, default: true) Automatically blocks QUIC connections matching the MitM hostname list, forcing fallback to HTTP/2 or HTTP/1.1 for interception. ### Mock # Mock (Map Local) ## Overview The Mock feature enables you to simulate HTTP server responses by returning static content. This capability is also referred to as Map Local or API Mocking. For dynamic responses, consider using scripting instead. ## Example Configuration ``` [Map Local] ^http://surgetest\.com/json data-type=text data="{}" status-code=500 ^http://surgetest\.com/gif data-type=tiny-gif status-code=200 ^http://surgetest\.com/file data-type=file data="data/map-local.json" header="a:b|foo:bar" ^http://surgetest\.com/base64 data="dGVzdA==" data-type=base64 ``` ## Parameters ### URL Pattern Each configuration line contains parameters separated by spaces. The first parameter is a regular expression matching the target URL. When an HTTP (or decrypted HTTPS) request matches this pattern, the rule applies. ### `data-type` Four data types are supported: - **`file`**: Returns content from a specified file or URL - **`text`**: Returns UTF-8 encoded text (iOS 5.9.1+, Mac 5.5.1+) - **`tiny-gif`**: Returns a 1-pixel GIF (iOS 5.9.1+, Mac 5.5.1+) - **`base64`**: Returns binary data in base64 encoding (iOS 5.9.1+, Mac 5.5.1+) ### `data` - For `file`: Path to the data file, relative to the configuration directory (absolute paths supported on macOS) - For `text`: The actual content to return - For `tiny-gif`: This field is ignored - For `base64`: Valid base64-encoded data Use `data-type=text data=""` to return an empty response. ### `header` Customize HTTP headers in the returned response. Separate multiple key-value pairs with `|`. ## Content-Type Handling Surge automatically determines Content-Type when not explicitly provided via the `header` parameter: - **`file`**: Converts file extension to MIME type; defaults to `application/octet-stream` - **`text`**: Defaults to `text/plain` - **`tiny-gif`**: Defaults to `image/gif` - **`base64`**: Defaults to `application/octet-stream` ### Url rewrite # URL Rewrite Surge enables rewriting of request URLs using two different methods or rejecting specific requests based on URL patterns. ## Structure Rewrite rules consist of three components: a regular expression pattern, a replacement value, and a mode type. ## Header Mode In this mode, Surge will modify the request header and redirect the request to another host if necessary. The client will not notice this rewrite action. The Host field in the request header is automatically updated to match the new URL. Example: ``` ^http://www\.google\.cn http://www.google.com header ``` ## 302 Redirect Mode This method returns a 302 HTTP redirect response to the client. HTTPS requests can be redirected if the hostname has MitM enabled. Example: ``` ^http://yachen\.com https://yach.me 302 ``` ## Reject Mode Matching requests are blocked entirely. The replacement parameter is ignored in this mode. HTTPS requests are rejected when the hostname has MitM enabled. Example: ``` ^http://ad\.com/ad\.png _ reject ``` --- ## Scripting ### Common # Scripting: Basic *Requires Surge iOS 4 or Surge Mac 3.3.0+* ## Overview JavaScript extends Surge's capabilities. Scripts are defined in a `[Script]` section with a name and parameters. ## Script Configuration Example script definitions: ``` [Script] script1 = type=http-response,pattern=^http://www.example.com/test,script-path=test.js,max-size=16384,debug=true script2 = type=cron,cronexp="* * * * *",script-path=fired.js script3 = type=http-request,pattern=^http://httpbin.org,script-path=http-request.js,requires-body=true script4 = type=dns,script-path=dns.js,debug=true ``` ## Common Parameters - **`type`**: Script category (http-request, http-response, cron, event, dns, rule, generic) - **`script-path`**: File location (relative/absolute path or URL) - **`script-update-interval`**: URL refresh interval in seconds - **`debug`**: Reloads from filesystem each execution; logs appear in request notes - **`timeout`**: Maximum execution time (default: 5s) - **`argument`**: Accessible via `$argument` - **`engine`**: JavaScript engine selection (see below) ## HTTP Request/Response Parameters - **`pattern`**: URL regex pattern matching - **`requires-body`**: Enable body modification (default: false) - **`max-size`**: Maximum body size in bytes (default: 131072) - **`binary-body-mode`**: Passes raw binary data as Uint8Array (iOS 15+, macOS+) ## Constraints & Performance Scripts support asynchronous operations. Call `$done(value)` to signal completion, even when results aren't required. Omitting this triggers timeout warnings. Performance is optimized; the JavaScript engine is efficient and shouldn't impact overall operation. ## Public API ### Environment Information - **`$network`**: Network environment details - **`$script.name`**, **`$script.startTime`**, **`$script.type`**: Current script metadata - **`$environment`**: System info (OS, build, version, language, device model) ### Data Persistence - **`$persistentStore.write(data, [key])`**: Save string data permanently - **`$persistentStore.read([key])`**: Retrieve saved data Scripts sharing a path automatically share storage. ### Control & HTTP Requests - **`$httpAPI(method, path, body, callback)`**: Call Surge's HTTP APIs - **`$httpClient.post/get/put/delete/head/options/patch(URL|options, callback)`**: HTTP requests with options for timeout, certificate verification, cookies, and redirects ### Utilities - **`console.log(message)`**: Log to Surge file - **`setTimeout(function, [delay])`**: Browser-like timer - **`$utils.geoip/ipasn/ipaso(ip)`**: IP lookup functions - **`$utils.ungzip(binary)`**: Decompress gzip data - **`$notification.post(title, subtitle, body, [options])`**: Send notifications with actions, media, and auto-dismiss ### Manual Triggering Long-press scripts in Surge iOS or use Shortcuts app. Shortcuts can pass parameters via `$intent.parameter`. ## JavaScript Engine Selection Two engines available (iOS 5.9.0+, Mac 5.5.0+): ### JavaScriptCore (JSC) - **Pros**: Fast initialization, low call overhead - **Cons**: Increases NE process memory; can trigger system termination ### WebView - **Pros**: Separate process isolation; JIT compilation for complex scripts; WebAPI support - **Cons**: Slightly higher initialization overhead; less efficient for large data transfers ### Recommendations Use JSC for small, frequently-called simple scripts (rule, DNS). Use WebView for complex or memory-intensive scripts (large JSON parsing). Add `engine=auto|jsc|webview` to configuration. Default is `auto` (prefers WebView when available). ### Availability - iOS: Both engines - macOS 10.15 and below: JSC only - macOS 11.0+: Both engines - tvOS: JSC only ### Cron # Cron ## Overview The cron function executes scripts at specified times using cron expressions. A cron expression is a string with five or six fields that define scheduling details. ## Cron Expression Format Common cron expression examples: - **Daily at 2 AM:** `0 2 *` - **Daily at 5 AM and 5 PM:** `0 5,17 *` - **Every minute:** `*` - **Every Sunday at 5 PM:** `0 17 sun` - **Every 10 minutes:** `*/10 * *` ## Implementation Scripts receive one parameter: `$cronexp`, which contains the cron expression string. Invoke `$done()` to complete execution. ## Example ```javascript // cron "0 2 * * *" script-path=cron.js $surge.setSelectGroupPolicy('Group', 'Proxy'); $done(); ``` This schedules a script to run daily at 2 AM, which sets a policy group selection and then completes. ## Available API - **`$cronexp`** — The cron expression string that triggered the script ### Dns # DNS Scripting Documentation ## Overview The `dns` function allows you to use a custom script as a DNS resolver in Surge. ## Usage Syntax ``` dns dnspod script-path=dnspod.js ``` Then add entries in the `[Host]` section: ``` [Host] example.com = script:dnspod *.example.com = script:dnspod ``` ## Script Parameters and Return Values The script receives `$domain` as the incoming parameter. The script must return one of the following: - `address`: A valid IPv4/IPv6 address as the result - `addresses`: Multiple IP addresses for the result - `server`: Instructs Surge to query a specified upstream DNS server - `servers`: Instructs Surge to query multiple upstream DNS servers When returning address or addresses, you can optionally include a `ttl` parameter (in seconds) to cache the result and prevent repeated lookups. ## Example Here's an implementation using DNSPod's public HTTP DNS API: ```javascript $httpClient.get('http://119.29.29.29/d?dn=' + $domain, function(error, response, data){ if (error) { $done({}); // Fallback to standard DNS query } else { $done({addresses: data.split(';'), ttl: 600}); } }); ``` ### Event # Event ## Overview The `event` directive evaluates a script when a specified event occurs. Currently, only one event type is supported. Scripts must invoke `$done()` to complete execution. ## Event Types ### network-changed Triggered when the system network changes. Example implementation: ```javascript // network-changed = script-path=network-changed.js,type=event,event-name=network-changed $notification.post('DNS Update', $network.dns.join(', ')); $done(); ``` This event fires whenever network conditions change on the system, allowing scripts to respond with notifications or other logic. ### notification Triggered when Surge shows a notification. The script can still get the message even if the notification's category is off. Example implementation: ```javascript // notification = script-path=notification.js,type=event,event-name=notification console.log($event.data); $done(); ``` This event enables scripts to intercept and process notifications generated by Surge, regardless of notification settings. ### Http request # HTTP Request ## Overview The `http-request` script allows modification of HTTP requests using regular expressions to match request URLs. ## Request Parameters The `$request` object contains: - **`$request.url`** (String): The request URL - **`$request.method`** (String): HTTP method - **`$request.headers`** (Object): HTTP headers - **`$request.body`** (String or Uint8Array): Request body (only with `requires-body = true`) - **`$request.id`** (String): Unique identifier for script continuity ## Response Object Scripts must invoke `$done()` with an object potentially containing: - **`url`** (String): Replacement URL (note: doesn't auto-update the Host header) - **`headers`** (Object): Replacement headers (some fields like Content-Length may be restricted) - **`body`** (String or Uint8Array): Replacement body (requires-body must be true) - **`response`** (Object): Returns an HTTP response without network operation: - `status` (Number): HTTP status code (default: 200) - `headers` (Object): Response headers - `body` (String or Uint8Array): Response body You may call `$done()` to abort or `$done({})` to leave the request unchanged. ## Example ```javascript let headers = $request.headers; headers['X-Modified-By'] = 'Surge'; $done({headers}); ``` ## Limitations - Request body cannot be overwritten with chunked encoding - Request body cannot be overwritten when 'Expect: 100-continue' header is present ### Http response # HTTP Response ## Overview The `http-response` script functionality allows modification of HTTP responses by matching request URLs with regular expressions. ## Available Parameters ### Request Object (`$request`) - `$request.url` (String): The request URL - `$request.method` (String): HTTP method used - `$request.id` (String): Unique identifier for script continuity - `$request.headers` (Object): Request HTTP headers ### Response Object (`$response`) - `$response.status` (Number): HTTP status code - `$response.headers` (Object): Response HTTP headers - `$response.body` (String or Uint8Array): Response body (UTF-8 decoded by default unless binary-mode is enabled; only available when `requires-body = true`) ## Response Modifications The `$done()` callback accepts an object with optional properties: - `body` (String or Uint8Array): Replace the response body (requires `requires-body = true`) - `headers` (Object): Replace all response headers (note: certain fields like 'Content-Length' cannot be modified) - `status` (Number): Replace the HTTP status code You may call `$done()` without arguments to abort, or `$done({})` to leave the response unchanged. ## Example ```javascript let headers = $response.headers; headers['X-Modified-By'] = 'Surge'; $done({headers}); ``` This example adds a custom header to all matching responses. ### Rule # Rule Scripting Documentation ## Overview Script-based rules allow dynamic matching logic using JavaScript. A script returns an object indicating whether a request matches the rule criteria. ## Basic Usage Define a script rule in your configuration: ``` rule ssid-rule script-path=ssid-rule.js ``` Then reference it in the `[Rule]` section: ``` SCRIPT,ssid-rule,DIRECT ``` ## Available Request Properties Scripts receive a `$request` object containing: - `hostname` (String) - `destPort` (Number) - `processPath` (String) - `userAgent` (String) - `url` (String) - `sourceIP` (String) - `listenPort` (Number) - `dnsResult` (Object) - `srcPort` (Number) - iOS 5.8.4+, Mac 5.4.4+ - `protocol` (Number) - iOS 5.8.4+, Mac 5.4.4+ ## DNS Resolution By default, SCRIPT rules skip DNS lookups. Enable resolution with the `requires-resolve` option: ``` SCRIPT,ssid-rule,DIRECT,requires-resolve ``` The DNS results appear in `$request.dnsResult`. ## Example Implementation ```javascript var hostnameMatched = ($request.hostname === 'home.com'); var ssidMatched = ($network.wifi.ssid === 'My Home'); $done({matched: (hostnameMatched && ssidMatched)}); ``` The script must return an object with a `matched` boolean property indicating the rule's result. --- ## Others ### Cli # Surge Mac CLI Surge Mac includes a command-line interface tool located at `/Applications/Surge.app/Contents/Applications/surge-cli`. Use the `--help` flag to access the complete manual. ## Available Commands **Profile Management:** - `reload` - Reload the main profile - `switch-profile ` - Switch to another profile **System Control:** - `stop` - Shutdown Surge - `unattended-upgrade` - Perform an unattended Surge upgrade if available **Diagnostic Commands:** - `dump active` - Show all active connections - `dump request` - Show recent connections - `dump rule` - Show all effective rules - `dump policy` - Show all proxies and policy groups - `dump dns` - Show DNS caches - `dump profile [original / effective]` - Display original or module-modified profiles - `dump event` - Show events - `watch request` - Keep tracing new requests **Testing Commands:** - `test-network` - Test the network delay - `test-policy ` - Test a proxy - `test-all-policies` - Test all proxies - `test-group ` - Immediately retest a policy group **Maintenance Commands:** - `kill ` - Kill an active connection - `flush dns` - Flush DNS cache - `diagnostics` - Run network diagnostics - `set-log-level ` - Change log level without writing to the profile **Environment & Scripting:** - `environment` - Show environment settings - `set ` - Modify environment settings - `script evaluate [mock-script-type] [timeout]` - Load and evaluate scripts ## Available Parameters - `--raw` - Output results in raw JSON format - `--remote/-r` - Connect to a remote Surge instance (e.g., `--remote password@192.168.2.2:6170`) ### Enhanced mode # Enhanced Mode ## Enhanced Mode (Surge Virtual Network Interface, VIF) Some applications don't respect system proxy settings. Surge's enhanced mode solves this by creating a virtual network interface (VIF) that intercepts all traffic. **How it works:** - Surge creates a virtual network interface (VIF) and registers it as the default route - DNS queries receive responses using virtual IPs from the 198.18.0.0/15 range - The VIF handles TCP, UDP, and ICMP traffic only - ICMP cannot be proxied, so responses return directly from the VIF **Important considerations:** - Enable only when necessary - Enabled by default on Surge for iOS - Must be manually started on Surge for Mac - Starting with Surge Mac 5.8.0, the Network Extension framework replaced the legacy utun driver (legacy parameters remain for compatibility) ## Surge VM Gateway ### UDP Fast Path (Mac 6.4.0+) High-volume UDP traffic can overwhelm the standard proxy engine. The UDP Fast Path feature automatically downgrades clients creating excessive short-lived UDP connections to lightweight L3 forwarding mode. **Activation thresholds:** - 10+ connections within 1 second, or - 30+ connections within 10 seconds **Key behaviors:** - Packets forwarded via the fast path bypass the proxy engine entirely and therefore cannot be matched by rules or MITM - Destination ports below 1024 remain in standard mode for service compatibility - Individual device behavior can be toggled via Dashboard/Device list ### Host list # Host List Parameter Type In Surge, many parameters use the Host List type to handle complex requirements, including `force-http-engine-hosts`, `always-raw-tcp-hosts`, and MITM's `hostname` parameter. ## Format Rules The Host List parameter is comma-separated and follows these conventions: - **Exclusions**: Prefix with `-` to exclude a hostname - **Wildcards**: Supports `*` and `?` characters - **Matching order**: Items are matched sequentially; first match wins. Exclusions should appear first for priority - **Default ports**: If no port is specified, Surge applies the standard port for that parameter (port 80 for `force-http-engine-hosts`, port 443 for MITM) - **Specific ports**: Use `:port` suffix to target other ports - **All ports**: Use `:0` suffix to match all ports - **IP addresses**: Use `` for IPv4/IPv6 matching - **IPv4 only**: Use `` for IPv4-specific matching - **IPv6 only**: Use `` for IPv6-specific matching ## Examples Using `force-http-engine-hosts`: - `-*.apple.com` — Excludes all requests to *.apple.com on port 80 - `www.google.com` — Forces HTTP processing for www.google.com on port 80 - `www.google.com:8080` — Forces HTTP processing for www.google.com on port 8080 - `www.google.com:0` — Forces HTTP processing across all ports - `*:0` — Applies to all hostnames on all ports - `-` — Excludes direct IP address requests ## MITM Configuration Example To decrypt all HTTPS while excluding certificate-pinned services: ``` [MITM] hostname = -*icloud*, -*.mzstatic.com, -*.facebook.com, -*.instagram.com, -*.twitter.com, -*dropbox*, -*apple*, -*.amazonaws.com, -, * ``` ### Http api # HTTP API Documentation ## Overview The HTTP API allows you to control Surge (iOS 4.4.0+, Mac 4.0.0+). ## Configuration ``` [General] http-api = examplekey@0.0.0.0:6171 http-api-tls = false ``` ## Authentication Include the API key in the `X-Key` header for all requests: ``` GET /v1/events X-Key: examplekey Accept: */* ``` Alternatively, pass the key via URL query for convenience (e.g., certificate downloads): ``` http://127.0.0.1:6171/v1/mitm/ca?x-key=examplekey ``` ## HTTPS/TLS Support Enable HTTPS by setting `http-api-tls = true`. Surge will use the MITM CA certificate to generate the server certificate. ## Basic Constraints - Only HTTP without TLS is currently supported - Uses GET and POST methods only - GET parameters via URL queries; POST uses JSON body - All responses are JSON ## API Endpoints ### Feature Toggles GET/POST endpoints for: `/v1/features/mitm`, `/v1/features/capture`, `/v1/features/rewrite`, `/v1/features/scripting`, and Mac-only: `system_proxy`, `enhanced_mode` ### Outbound Management - `GET/POST /v1/outbound` — retrieve/change outbound mode (direct, proxy, rule) - `GET/POST /v1/outbound/global` — manage default policy ### Policies & Groups - List policies: `GET /v1/policies` - Test policies: `POST /v1/policies/test` - List groups: `GET /v1/policy_groups` - Select group option: `GET/POST /v1/policy_groups/select` ### Requests - Recent requests: `GET /v1/requests/recent` - Active requests: `GET /v1/requests/active` - Kill request: `POST /v1/requests/kill` ### Profiles - Current profile: `GET /v1/profiles/current?sensitive=0` - Reload: `POST /v1/profiles/reload` - Switch (Mac): `POST /v1/profiles/switch` ### DNS - Flush cache: `POST /v1/dns/flush` - View cache: `GET /v1/dns` - Test delay: `POST /v1/test/dns_delay` ### Modules, Scripts, Devices, & Misc Additional endpoints for module management, scripting evaluation, device management (Mac), traffic monitoring, logging, and CA certificate retrieval. ### Managed profile # Managed Profile Surge can automatically update a profile from a URL. A managed profile begins with: ``` #!MANAGED-CONFIG http://test.com/surge.conf interval=60 strict=true ``` The remote profile must also include the `#!MANAGED-CONFIG` line, or it reverts to a standard profile. Updates only occur when the main Surge app is running. ## Parameters **interval** (Optional, seconds; default: 86400s) Sets the minimum time between update checks. Surge doesn't necessarily trigger immediately after this period expires. **strict** (true/false; default: false) When enabled, Surge requires a forced update after the interval. If updates fail with strict mode off, users can continue using outdated configurations. Users can still start Surge via widget or VPN settings regardless. ## REQUIREMENT Statement Limit configuration lines to specific environments using `!REQUIREMENT` at the line beginning or end: ``` #!REQUIREMENT CORE_VERSION>=22 Group = smart, policyA, policyB ``` Supported variables: `CORE_VERSION, SYSTEM, SYSTEM_VERSION, DEVICE_MODEL, LANGUAGE` Operators: `=, ==, >=, =>, <=, =<, >, <, !, <>, AND, &&, OR, ||, NOT, BEGINSWITH, CONTAINS, ENDSWITH, LIKE, MATCHES` Wrap strings in single quotes; expressions with spaces need double quotes: ``` #!REQUIREMENT "CORE_VERSION>=22 AND SYSTEM=='iOS'" ``` ## FORBIDDEN-AUTO-UPGRADE Statement Prevent automatic profile optimizations (Surge iOS 5.11.0+, Mac 5.7.0+): ``` #!FORBIDDEN-AUTO-UPGRADE smart-group ``` Available keywords: `smart-group` (upgrades url-test/load-balance groups to smart groups) ### Misc options # Misc Options ## Miscellaneous Options in [General] Section The options in this section change frequently. For the most current explanations, consult: - **Surge Mac**: Main Window Menu → Help → Profile Syntax - **Surge iOS**: More Tab → Help → Profile Syntax ### Core Options **loglevel** Sets verbosity: verbose, info, notify, or warning. Avoid verbose in daily use due to performance impact. **ipv6** Enables full IPv6 support, including AAAA record queries for domain access. **ipv6-vif** Controls IPv6 handling through Surge VIF: - `off`: Never set up IPv6 - `auto`: Only if local network has valid IPv6 - `always`: Always enabled **dns-server** Specifies upstream DNS server IP addresses. ### Network Routing **skip-proxy** Forces connections to specified domains/IPs to bypass the proxy. Supports domain names (apple.com), wildcards (*apple.com), and CIDR notation (192.168.2.0/24). **exclude-simple-hostnames** Similar to skip-proxy but for hostnames without dots. **tun-excluded-routes** Bypasses specific IP ranges from the Surge VIF for all traffic types. **tun-included-routes** Adds smaller routes to override default routing behavior. ### Control & API **external-controller-access** Enables external controllers (e.g., Surge Dashboard). Example: `key@0.0.0.0:6165` **http-api** Enables HTTP API control. Example: `key@0.0.0.0:6166` **http-api-tls** Uses HTTPS for API communication (requires MitM CA certificate). **http-api-web-dashboard** Enables web browser control interface. ### HTTP Processing **show-error-page** (Mac 5.8.0+) Controls whether Surge displays its built-in HTTP error page when a request fails (enabled by default). **show-error-page-for-reject** Displays error webpage for rejected plain HTTP requests. **full-header-mode** Exposes complete HTTP header arrays including duplicate fields to rewrite rules and scripts. ### DNS & Testing **internet-test-url** URL for connectivity testing and DIRECT policy tests. **proxy-test-url** Default testing URL for proxy policies. **test-timeout** Connectivity testing timeout duration. **always-real-ip** Returns real IP addresses instead of fake ones for DNS queries. Supports Host List parameter type. **hijack-dns** Hijacks DNS queries to return fake addresses. Use `hijack-dns = *:53` for all queries. **allow-dns-svcb** By default, SVCB record lookups are forbidden to force A record lookups (iOS system compatibility). ### Advanced Features **force-http-engine-hosts** Treats TCP connections as HTTP requests for advanced features (capturing, rewriting, scripting). Uses Host List parameter type. **use-local-host-item-for-proxy** Uses IP addresses from local DNS mapping instead of domain names for proxy connections. **always-raw-tcp-hosts** (iOS 5.8.0+, Mac 5.4.0+) Prevents protocol sniffing for specified hosts. Uses Host List parameter type. **always-raw-tcp-keywords** (Mac 5.5.0+) Skips protocol sniffing for hostnames containing specified substrings. ### Encrypted DNS **encrypted-dns-follow-outbound-mode** Makes DOH (DNS over HTTPS) follow outbound mode settings and rules. **encrypted-dns-server** Specifies encrypted DNS URLs: - DNS over HTTPS: `https://example.com` - DNS over HTTP/3: `h3://example.com` - DNS over QUIC: `quic://example.com` **encrypted-dns-skip-cert-verification** Skips certificate verification (insecure). ### Security & Restrictions **proxy-restricted-to-lan** (iOS 5.13.1+, Mac 5.8.1+) Restricts proxy services to current subnet (enabled by default). **gateway-restricted-to-lan** (iOS 5.13.1+, Mac 5.8.1+) Restricts gateway services to current subnet (enabled by default). **icmp-forwarding** (iOS 5.14.3+, Mac 5.10.0+) Directly forwards ICMP packets in enhanced mode (enabled by default). **block-quic** (iOS 5.14.6+, Mac 5.10.3+) Global QUIC blocking behavior: - `per-policy`: Policy-determined (default) - `all-proxy`: Block all except DIRECT - `all`: Block everything - `always-allow`: Allow all ### UDP & Performance **udp-policy-not-supported-behaviour** Fallback behavior when UDP matches unsupported policies: `DIRECT` or `REJECT` (default in Mac 6.0.0+). **proxy-test-udp** Default UDP test parameter. Example: `apple.com@8.8.8.8` **udp-priority** Prioritizes UDP packets under high system load (game mode). ### GeoIP **geoip-maxmind-url** URL for GeoIP database updates. **disable-geoip-db-auto-update** Disables automatic GeoIP database updates. --- ## Surge iOS Only Parameters **allow-wifi-access** Permits LAN access to Surge proxy services. **wifi-access-http-port** HTTP proxy service port number. **wifi-access-socks5-port** SOCKS5 proxy service port number. **wifi-access-http-auth** Requires authentication: `username:password` **wifi-assist** Enables Wi-Fi assist feature. **hide-vpn-icon** Hides VPN status bar icon. **all-hybrid** Simultaneously uses Wi-Fi and cellular data for connections and DNS (requires unlimited cellular plan). **allow-hotspot-access** Permits access to Surge proxy from tethered devices. **include-all-networks** Makes Surge VIF handle all requests without leakage (iOS 14.0+). Caution: May cause AirDrop, Xcode debugging, and Surge Dashboard USB issues. **include-local-networks** Handles LAN requests via Surge VIF (iOS 14.2+, requires `include-all-networks=true`). **include-apns** Handles Apple Push Notification service traffic (requires `include-all-networks=true`). **include-cellular-services** Handles cellular service traffic: VoLTE, Wi-Fi Calling, IMS, MMS, etc. (requires `include-all-networks=true`). **compatibility-mode** Controls Surge iOS working mode: - `0`: Auto - `1`: Proxy Takeover + VIF (best performance) - `2`: Proxy Takeover Only - `3`: VIF Takeover Only (default) - `4`: Proxy Takeover + VIF with VIF address - `5`: VIF Takeover with multiple smaller routes **auto-suspend** (iOS 5.11.0+) Automatically suspends Surge iOS when Surge Mac network detected (enabled by default). --- ## Surge Mac Only Parameters **use-default-policy-if-wifi-not-primary** When disabled, SSID/BSSID patterns match even when Wi-Fi isn't primary. **read-etc-hosts** Follows local DNS mapping from /etc/hosts. **http-listen** HTTP proxy service listen parameter. Example: `0.0.0.0:6152` **socks5-listen** SOCKS5 proxy service listen parameter. Example: `0.0.0.0:6153` **debug-cpu-usage** Enables CPU debug mode (performance impact). **debug-memory-usage** Enables memory debug mode (performance impact). ### Module # Module ## Overview A module functions as a patch to your current profile, with higher priority than existing profile settings. There are three module types: - **Internal Modules**: Built-in by Surge - **Local Modules**: `.sgmodule` files in the profile directory - **Installed Modules**: Modules installed via URL ## Use Cases Modules enable you to: - Modify settings in non-editable profiles (managed or enterprise) - Toggle specific settings temporarily with a single action - Apply community-created solutions for particular tasks - Customize settings per device without syncing changes across devices ## Module Syntax Module syntax mirrors profile syntax. Overridable sections include: **General & MITM sections** - Override: `key = value` - Append: `key = %APPEND% value` - Insert at front: `key = %INSERT% value` Only `hostname`, `skip-server-cert-verify`, and `tcp-connection` fields can be manipulated in MITM sections. **WireGuard sections** - Override or append keys within `[WireGuard *]` sections **Ruleset sections** - Patch inline rulesets defined within profiles **Rule, Script, URL Rewrite, Header Rewrite, Host** - New lines insert at the top of original content - Module rules limited to: DIRECT, REJECT, REJECT-TINYGIF ## Metadata Add metadata headers to modules: ``` #!name=Name Here #!desc=Description Here #!system=mac ``` ## Parameter Tables (Mac 5.5.0+) Enable user customization via `#!arguments`: ``` #!arguments=hostname=example.com&enable_mitm=true ``` Placeholders like `%hostname%` become available for text replacement. ## Requirements (iOS 5.10.0+ / Mac 5.6.0+) Restrict module usage with `#!requirement=`: ``` #!requirement=CORE_VERSION>=20 && (SYSTEM='iOS' || SYSTEM='tvOS') ``` Available variables: CORE_VERSION, SYSTEM, SYSTEM_VERSION, DEVICE_MODEL, LANGUAGE ### Panel # Information Panel ## Overview Surge iOS 4.9.3+ introduced an experimental feature for customizing information panels to display related information. This requires an active subscription expiring after September 22, 2021. If the subscription expires, panels won't display but other features remain unaffected. ## Basic Configuration ``` [Panel] PanelA = title="Panel Title",content="Panel Content\nSecondLine",style=info ``` The panel name (e.g., `PanelA`) gets passed to scripts in script mode. Supported style parameters include: good, info, alert, and error. ## Static Mode Panels created with basic configuration are static. This works well with managed or enterprise profiles to update content during profile updates and provide operational guidelines to end-users. ## Dynamic Mode Script-driven panels update their contents automatically: ``` [Panel] PanelB = title="Panel Title",content="Panel Content\nSecondLine",style=info,script-name=panel [Script] panel = script-path=panel.js,type=generic ``` When users tap refresh, scripts receive parameters: `$input: { purpose: "panel", position: "policy-selection", panelName: "PanelB" }` and `$trigger: "button"` or `"auto-interval"`. Scripts should return title, content, and style fields via `$done()`. Before first execution, static content displays. Surge caches results and displays the previous output before refreshing. ### Example Script ```javascript $httpClient.get("https://api.my-ip.io/ip", function(error, response, data){ $done({ title: "External IP Address", content: data, }); }); ``` ### Auto-Updating Panels ``` [Panel] PanelB = title="Panel Title",content="Panel Content\nSecondLine",style=info,script-name=panel,update-interval=60 ``` Auto-updates only occur when viewing the policy selection screen. ## Advanced Customization - Omitting the style field displays text-only cards without icons - Use the icon field with SF Symbol Names (e.g., `bolt.horizontal.circle.fill`) for custom icons - Use icon-color with HEX color codes to control icon appearance ### Port forwarding # Port Forwarding **Availability:** iOS 5.14.3+ | Mac 5.10.0+ ## Overview Surge has the capability to listen on a designated local port and direct TCP requests from that port to a specific destination host. This functionality operates independently, meaning it works even when Surge's standard request handling mechanisms (system proxy or enhanced mode) are disabled. ## Usage ### Configuration Syntax Add entries to the `[Port Forwarding]` section of your profile: ``` [Port Forwarding] 0.0.0.0:6841 localhost:3306 policy=SQL-Server-Proxy ``` ### Parameters - **Local address and port** (e.g., `0.0.0.0:6841`): The listening endpoint - **Target host and port** (e.g., `localhost:3306`): Where traffic gets forwarded - **policy parameter** (optional): Specifies which proxy policy to apply. When omitted, standard proxy matching rules determine the policy instead. ## Common Use Cases This feature proves particularly valuable for development and debugging workflows, such as establishing connections to database servers (like MariaDB) through SSH tunneling. ### Subnet settings # Subnet Settings You can use subnet expressions to match specified networks and apply particular settings. Note that subnet settings are named [SSID Setting] in profiles for compatibility. ## Suspend Temporarily suspend Surge on specified networks: ``` [SSID Setting] SSID:MyHome suspend=true ``` ## Cellular Fallback (iOS Only) Control Wi-Fi assist and Hybrid Network behavior for specific Wi-Fi networks: ``` [SSID Setting] SSID:MyHome cellular-fallback=off ``` Options: - `cellular-fallback=default` - Use global Wi-Fi assist and Hybrid Network settings - `cellular-fallback=off` - Disable Wi-Fi assist and Hybrid Network for the network - `cellular-fallback=hybrid` - Enable Hybrid Network for the network - `cellular-fallback=wifi-assist` - Enable Wi-Fi assist for the network ## TCP Fast Open Behaviour ``` [SSID Setting] SSID:MyHome tfo-behaviour=force-enabled ``` Options: - `tfo-behaviour=auto` - Use default TFO behavior - `tfo-behaviour=force-disabled` - Disable TFO completely for the network - `tfo-behaviour=force-enabled` - Enable TFO, overriding system blackhole detection ## DNS Override Override DNS settings for specified networks: ``` [SSID Setting] SSID:MyHome dns-server=8.8.8.8,encrypted-dns-server=https://1.1.1.1/ ``` When encrypted DNS is configured globally, explicitly use `off` to revert to traditional DNS: ``` [SSID Setting] SSID:MyHome dns-server=8.8.8.8,encrypted-dns-server=off ``` ### Url scheme # URL Scheme ## URL Scheme for Surge iOS Surge iOS supports 4 actions and one option. ### Actions - **surge:///start** — Start with selected configuration. - **surge:///stop** — Stop current session. - **surge:///toggle** — Start or stop with selected configuration. - **surge:///install-config?url=x** — Install a configuration from a URL. The URL should be encoded in percent encoding. ### Options - **autoclose=true** — Auto close Surge after action completed. (Cannot be used with install-config) Example: `surge:///toggle?autoclose=true` ## x-callback-url Surge supports x-callback-url specification from v3.4. The URL scheme is 'surge' and the available actions are 'start', 'stop' and 'toggle'. ---