# 简介

Surge 官方手册的汉化

本项目开源在 [GitHub](https://github.com/FlintyLemming/SurgeHandbook)，如果对文章内容有疑问，请发 Issue（不解答技术问题）。如果内容有错误和不恰当，也可以 Fork 后修改。


# 总览

Surge 是为开发者设计的网络开发和代理工具，因此需要专业知识才能使用。

Surge 的核心工作流由四项主要能力组成：

* 接管：Surge 允许用户接管设备发送的网络连接。支持代理服务和虚拟网卡接管。
* 处理：该软件允许用户修改被接管的网络请求和响应。包括 URL 重定向、本地文件映射、使用 JavaScript 进行自定义修改等多种方法。
* 转发：网络请求被接管后，用户可以将其转发到其他代理服务器。转发可以是全局的，也可以使用灵活的规则系统来确定出站策略。
* 截获：用户可以截获并保存网络请求和响应中的特定数据。此外，用户还可以通过 MITM 解密 HTTPS 流量。

## 特性

* 高性能、稳定、高效：Surge 能够以工业级稳定性，占用最少的系统资源，流畅处理所有网络流量。
* 灵活的规则系统：你可以基于域名、IP CIDR、GeoIP 等编写转发规则。Surge 可以自动使用 HTTP/HTTPS/SOCKS5/SOCKS5-TLS/Shadowsocks 协议将请求代理到其他服务器。
* HTTPS 解密：通过中间人攻击解密 HTTPS 流量。证书生成器将帮助你生成受操作系统信任的 CA 证书，以便用于调试。
* 本地 DNS 映射：Surge 支持本地自定义 DNS 映射。它的多个功能模块，包括通配符、别名和自定义 DNS 服务器，能够满足各种需求。
* 策略组：你可以将多个代理归为一组，并根据分组采用相应的策略。策略组可以配置为自动测速（基于访问目标 URL 的速度选择策略）、SSID（基于 Wi-Fi SSID 选择策略）和手动选择。
* HTTP 重写：你可以使用自定义规则将 HTTP/HTTPS 请求重写到另一个 URL，或者阻止这些请求；
* 远程面板：Surge Dashboard 可以通过 USB 或网络连接到远程的 Surge iOS 或 Surge Mac 实例。
* 完整的 IPv6 支持：所有功能都可在 IPv6 环境下工作。

### Surge Mac 独占特性

* 增强模式：对于未显式支持 Web 代理的应用程序，Surge 可以设置一个虚拟网络接口来处理所有网络流量。
* 计费网络模式：你可以控制允许哪些应用程序/进程访问互联网，这在使用计费连接（如蜂窝网络）时非常有用。
* 网关模式：Surge Mac 可以配置为三层网关，以处理同一网络中其他设备的网络流量。

### Surge iOS 独占特性

* 所有功能均可在蜂窝网络上使用。
* 捕获设备上任何应用的所有 HTTP/HTTPS/TCP 流量，并根据高度可配置的规则将其重定向到 HTTP/HTTPS/SOCKS5/Shadowsocks 代理服务器，即使应用程序不遵循系统代理设置也能生效。
* 即使在蜂窝网络下也能覆盖系统 DNS 设置，并通过同时查询所有 DNS 服务器来提升性能。
* 通过 Wi-Fi 或 USB 线缆将 Surge Dashboard 连接到 Surge iOS，监控和分析 iOS 设备上的网络请求。通过 USB 连接时，你甚至可以检查蜂窝网络请求。

### 深入理解 Surge

我们发布了一本官方指南以帮助你了解 Surge。

* 英文版：<https://manual.nssurge.com/book/understanding-surge/en/>
* 中文版：<https://manual.nssurge.com/book/understanding-surge/cn/>


# 组件

Surge 包含几个组件。

### Surge 代理服务器

这是 Surge 的核心部分。它是一个全功能的 HTTP/SOCKS5 代理服务器，具有极高的性能和稳定性，使用 Objective-C 编写，并针对 macOS 和 iOS 进行了优化。

### Surge 虚拟网卡 (Surge VIF)

一些应用不遵循系统代理设置（如 Mail.app），因为它们需要使用原始 TCP 套接字。这类流量可以由 Surge VIF 处理。

Surge VIF 在 Surge iOS 上默认启用。你可以通过打开增强模式在 Surge Mac 上启用 Surge VIF。

这是 Surge iOS 的架构：

### Surge Dashboard (仅限 Mac 版)

Surge Dashboard 是一个图形用户界面，用于审查和检查请求，并列出 DNS 缓存。它可以连接到本地 Surge 实例，或者在配置了外部控制器访问权限时连接到远程实例。


# 配置文件

Surge 的核心功能由配置文件控制。基本上，配置文件的所有内容都可以通过用户界面进行调整。但部分实验性功能可能尚未提供配置视图。当你遇到一些特殊需求时，可能需要手动编辑配置文件来实现。

### 配置文件内容

配置文件的格式遵循 INI 文件的格式，带有 `[Section]` 段落，用于划分不同的段落并分隔设置。

每个段落的配置行都有其特定的语法，例如 `[General]` 和 `[MITM]` 段落仅仅是 `key = value` 的形式：

```ini
[General]
key = value
```

在这些段落中，配置行的顺序没有任何影响。但是，在诸如 `[Rule]` 这样的段落中，配置行的顺序非常重要。

### 配置文件分类

配置文件分为三类：

1. 普通配置文件：手动创建或默认使用的配置。
2. 托管配置文件：通常由企业管理员或服务提供商提供。托管配置文件无法在本地修改，因为它可以被远程更新。如果你想进行更改，应先创建一个副本，将其转换为普通配置。
3. 企业配置文件：仅限企业版，不能被修改或查看，也不能被复制。

### 分离的配置段落 (Detached Profile Section)

为了满足各种复杂的使用场景，Surge 支持将配置文件中的某个段落分离到另一个文件中。

例如：

Main.conf

```ini
[Proxy]
#!include Proxy.dconf
```

其中引用的另一个文件必须包含对应段落的 `[]` 声明。因此，该文件可以是仅包含部分段落（一个或多个）的文件，也可以是一个完整的配置文件。

Proxy.dconf

```ini
[Proxy]
ProxyA = http, 1.2.3.4, 80
```

使用此功能，你可以：

1. 引用托管配置的 `[Proxy]`、`[Proxy Group]`、`[Rule]` 段落，并自行编写其他段落。这使你可以享受托管配置中代理相关内容的更新，而不会影响通过 UI 调整的其他功能。
2. 在多个配置之间共享特定段落的内容。例如，在 iOS 和 macOS 上同时使用 Surge 时，`[Proxy]`、`[Proxy Group]`、`[Rule]` 等段落的内容往往是相同的，但 `[General]` 的内容可能差异很大。你可以创建两个配置 iOS.conf 和 macOS.conf，并将重复的段落放在另一个文件中。

```ini
[Proxy]
#!include Forwarding.dconf

[Proxy Group]
#!include Forwarding.dconf

[Rule]
#!include Forwarding.dconf
```

这样，在 iOS 上调整 `[General]` 段落时，就不会影响 macOS，并避免了维护两套代理配置的麻烦。这也完全不会干扰使用 UI 的配置过程。

一些额外说明：

* 通过 UI 修改配置后，配置会根据 include 语句写入到对应的分离配置文件中。如果文件中包含未被引用的其他段落，写入操作将只会修改被引用的段落。
* 如果引用的是托管配置文件，则该段落相关的配置无法被编辑，但不影响调整其他段落。
* 文件名的后缀没有硬性要求，如果它是一个完整的配置文件，你可以继续使用 conf 后缀；如果不是完整的配置文件，建议使用其他后缀以避免在配置列表中显示。
* 从 Surge iOS 4.12.0 和 Surge Mac 4.5.0 开始，你可以在一个段落中包含多个分离的配置文件。但该段落会被标记为只读，无法使用 UI 编辑。

  ```ini
  [Proxy]
  #!include A.dconf, B.dconf
  ```

#### 链接配置 (Linked Profiles) Mac 6.0.0+

`#!include` 也可以直接引用远程托管配置文件（一个 URL）。这让你可以构建一个本地的“覆盖 (overlay)”配置，该配置将保持追踪上游配置的更新。

```ini
[Rule]
#!include https://example.com/managed.conf
```

当引用的内容是只读的时，如果你尝试编辑这些段落，Surge 会提示创建一个链接层 (linked layer)。本地层仅存储你的覆盖设置，而远程托管配置文件则自动接收更新。

### 模块 (Modules)

分离的配置段落功能用于将单个配置文件拆分为多个文件，而模块是配置文件的补丁，每个模块文件用于调整配置文件的各个部分，以实现特定任务。

模块可以：

* 灵活地开启和关闭。
* 调整同一文件中的多个段落。
* 通过 URL 安装并保持更新。

但是：

* 模块不能调整 `[Proxy]`、`[Proxy Group]`、`[Rule]` 段落的内容。
* 模块不能调整 MITM 的 CA 证书。
* 模块的设置会覆盖主配置，因此无法通过 UI 进行调整。

模块的详细说明见：[https://manual.nssurge.com/others/module.html](/others/module)

### 注释 (Comment)

Surge 配置文件支持注释行，以 `#`、`;` 和 `//` 开头。也支持行内注释。

```ini
# 这是一个注释行
; 这是一个注释行
// 这是一个注释行
```

```ini
dns-server = 8.8.8.8 // 这是一个行内注释
dns-server = 8.8.8.8 # 这是一个行内注释
dns-server = 8.8.8.8 ; 这是一个行内注释
```

请注意，使用行内注释时，分隔符前必须至少有一个空格。

### 行条件 (Line Requirement) iOS 5.11.0+ Mac 5.7.0+

你可以设置约束，使得某一行配置仅在满足特定条件时生效。

```ini
Group = url, policyA, policyB #!REQUIREMENT CORE_VERSION<22
```

对于原生支持开启/关闭状态配置的项，不满足条件的配置行将等同于处于禁用状态。对于其他行，它们将等同于行注释。

`#!REQUIREMENT` 表达式也可以在行首使用。由于以前的版本不支持此表达式，因此提供了行首和行尾两种格式。你可以灵活利用这一机制来兼容旧版本。例如，如果希望支持智能组 (Smart groups) 的客户端使用智能组，你可以这样写：

```ini
#!REQUIREMENT CORE_VERSION>=22 Group = smart, policyA, policyB
Group = url, policyA, policyB //!REQUIREMENT CORE_VERSION<22
```

由于在旧版本中第一行将被视为简单的注释，因此不会有任何效果，而第二行的行尾注释也只会作为常规注释处理。

#### REQUIREMENT 表达式

可用于判断的变量包括 `CORE_VERSION`、`SYSTEM`、`SYSTEM_VERSION`、`DEVICE_MODEL`、`LANGUAGE`。

可以使用的运算符有 `=,==,>=,=>,<=,=<,>,<,!=,<>,AND,&&,OR,||,NOT,!,BEGINSWITH,CONTAINS,ENDSWITH,LIKE,MATCHES`。

变量值的典型示例：

```
CORE_VERSION: 22
SYSTEM: iOS
SYSTEM_VERSION: System Version 17.4.1 (Build 21E236)
DEVICE_MODEL: iPhone16,1
LANGUAGE: en-US
```

表达式中的字符串应使用 `''` 括起来，例如 `#!REQUIREMENT SYSTEM=='macOS'`

**简写标记 iOS 5.14.3+ Mac 5.10.0+**

为了方便，提供了三种简写标记：`#!IOS-ONLY`、`#!MACOS-ONLY`、`#!TVOS-ONLY`。

例如：

```ini
DOMAIN,reject.com,REJECT #!MACOS-ONLY
```


# 代理规则

Surge 可以根据自定义规则将请求转发到另一个代理服务器，或直接连接到主机。

### 优先级 (Priority)

规则从第一条到最后一条按顺序匹配，顺序即它们在配置文件中出现的顺序。换句话说，列表顶部的规则比后面的规则具有更高的优先级。

### 组成部分 (Composition)

每条规则由 3 部分组成：规则类型、匹配器（FINAL 规则除外）和代理策略：

```ini
           类型(TYPE),  值(VALUE),       策略(POLICY)
例如:       DOMAIN-SUFFIX,apple.com,     DIRECT
           IP-CIDR,      192.168.0.0/16,ProxyA
```

Surge 支持多种类型的规则，请参阅此类别下特定规则的介绍。策略可以是内置策略、代理策略或策略组。有关详细信息，请参阅策略部分的说明。规则列表必须以一条 `FINAL` 规则结尾，以定义默认行为。

示例：

```ini
[Rule]
DOMAIN-SUFFIX,company.com,ProxyA
DOMAIN-KEYWORD,google,DIRECT
GEOIP,US,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT
FINAL,ProxyB
```

`DOMAIN`、`DOMAIN-SUFFIX` 和 `DOMAIN-KEYWORD` 属于基于域名的规则 (domain based rules)。`IP-CIDR` 和 `GEOIP` 属于基于 IP 的规则 (IP based rules)。


# 域名规则

共有三种基于域名的规则类型。

#### DOMAIN

`DOMAIN,www.apple.com,Proxy`

如果请求的域名完全匹配，则触发该规则。

#### DOMAIN-SUFFIX

`DOMAIN-SUFFIX,apple.com,Proxy`

如果请求的域名匹配该后缀，则触发该规则。例如：'google.com' 会匹配 '[www.google.com'、'mail.google.com](http://www.google.com'、'mail.google.com)' 和 'google.com'，但**不**匹配 'content-google.com'。

#### DOMAIN-KEYWORD

`DOMAIN-KEYWORD,google,Proxy`

如果请求的域名包含该关键字，则触发该规则。

#### DOMAIN-SET

专为大量域名设计，支持数千条记录的快速搜索。文件中的每一行都是一个域名，如果一行以 `.` 开头，则匹配所有子域名以及该域名本身。这可用于广告过滤。

### 基于域名的规则参数

#### extended-matching iOS 5.8.0+ Mac 5.4.0+

当启用此参数时，规则将尝试同时匹配 SNI 和 HTTP Host 请求头 (或 `:authority`)。

此参数仅适用于 `DOMAIN`、`DOMAIN-SUFFIX`、`DOMAIN-KEYWORD` 规则，你可以通过将该参数追加到相应的 `RULE-SET`/`DOMAIN-SET` 规则行，将其传播到 `DOMAIN-SET` 的条目中。


# IP 地址规则

共有 3 种基于 IP 的规则类型。如果请求的主机名是域名，基于 IP 的规则将触发 DNS 查询。如果 DNS 查询失败，Surge 将中止规则测试并报告错误。

#### IP-CIDR

```ini
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
```

如果请求的 IP 地址匹配指定的范围，则触发该规则。

从 Surge Mac 6.0.0 开始，你也可以提供一个不带 `/` 掩码的单一 IPv4 地址，它将被视为 `/32`。

#### IP-CIDR6

```ini
IP-CIDR6,2001:db8:abcd:8000::/50,DIRECT
```

如果请求的 IPv6 地址匹配指定的范围，则触发该规则。

也支持单一 IPv6 地址——例如，写入 `IP-CIDR6,2404:6800::` 等同于 `/128`。

#### GEOIP

`GEOIP,US,DIRECT`

如果 GeoIP 测试结果匹配指定的国家/地区代码，则触发该规则。

#### IP-ASN

`IP-ASN,1234,DIRECT`

如果远程 IP 地址的自治系统编号 (ASN) 匹配，则触发该规则。

### 基于 IP 的规则参数

#### no-resolve

```ini
GEOIP,US,DIRECT,no-resolve
IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
```

当遇到 `GEOIP` 或 `IP-CIDR` 规则时，Surge 将发送 DNS 查询以检查请求的主机名是否为域名。你可以选择 `no-resolve` 选项，让带有域名的请求跳过该规则。

> 注意：如果某些域名无法被本地 DNS 服务器解析，请确保在匹配该域名的规则之前没有基于 IP 的规则。否则，规则测试将由于 DNS 错误而失败。你也可以使用 `no-resolve` 来解决此问题。


# HTTP 规则

共有两种 HTTP 规则类型。HTTP 规则适用于 HTTP 请求或 HTTPS 请求。它不会影响 TCP 连接。

#### USER-AGENT

```ini
USER-AGENT,Instagram*,DIRECT
```

如果请求的 User-Agent 匹配，则触发该规则。支持通配符 `*` 和 `?`。

#### URL-REGEX

`URL-REGEX,^http://google\.com,DIRECT`

如果 URL 匹配该正则表达式，则触发该规则。

你可以追加 `extended-matching` 参数以同时测试 HTTP Host 请求头（或 `:authority`）和 SNI，这在需要 TLS 握手信息时非常有用：

```ini
URL-REGEX,^https://example\.com,Proxy,extended-matching
```


# 进程规则

你可以为指定的进程分配策略。进程规则仅适用于 Surge Mac，Surge iOS 会忽略这些规则。

#### PROCESS-NAME (仅限 Mac)

```ini
PROCESS-NAME,Telegram,Proxy
```

如果请求的进程名称匹配，则触发该规则。支持通配符 `*` 和 `?`。

> 你可以指定可执行文件的文件名或完整路径。对于 macOS 应用程序包，它位于 `.app/Contents/MacOS` 路径下。


# 逻辑规则

使用逻辑操作符规则将多个规则组合起来以应对复杂场景。你可以将逻辑规则嵌套在另一个逻辑规则中。

#### AND 规则

如果所有子规则都匹配，则触发该规则。

```ini
AND,((#Rule1), (#Rule2), (#Rule3)...),Policy
```

示例：

```ini
AND,((SRC-IP,192.168.1.110), (DOMAIN, example.com)),DIRECT
```

#### OR 规则

如果任意子规则匹配，则触发该规则。

`OR,((#Rule1), (#Rule2), (#Rule3)...),Policy`

示例：

```ini
OR,((SRC-IP,192.168.1.110), (SRC-IP,192.168.1.111)),DIRECT
```

#### NOT 规则

反转原始规则的评估结果。

```ini
NOT,((#Rule1)),Policy
```

示例：

```ini
AND,((NOT,((SRC-IP,192.168.1.110))),(DOMAIN, example.com)),DIRECT
```


# 子网表达式与规则

### 子网表达式 (Subnet Expression)

子网表达式可以是以下之一：

* 使用 `SSID:value` 匹配 Wi-Fi SSID，允许使用通配符。
* 使用 `BSSID:value` 匹配 Wi-Fi BSSID，允许使用通配符。
* 使用 `ROUTER:value` 匹配路由器 IP 地址。
* 使用 `TYPE:WIFI` 匹配所有 Wi-Fi 网络。
* 使用 `TYPE:WIRED` 匹配所有有线网络。
* 使用 `TYPE:CELLULAR` 匹配所有蜂窝网络。
* 如果未提供前缀，它将尝试匹配 SSID/BSSID/Router，以保持旧版本兼容性。

#### SUBNET

如果子网表达式匹配，则触发该规则。

```ini
SUBNET,TYPE:WIRED,DIRECT
SUBNET,SSID:MyHome,Proxy
```


# 杂项规则

### 端口号规则

端口号规则支持三种表达式：

* 直接写端口号，例如 `IN-PORT,6153`
* 端口号闭区间：例如 `DEST-PORT,10000-20000`
* 使用 `>`、`<`、`<=`、`>=` 运算符，例如 `SRC-PORT,>=50000` (iOS 5.8.4+ Mac 5.4.4+)

#### DEST-PORT

如果请求的目标端口匹配，则触发该规则。

```ini
DEST-PORT,80-81,DIRECT
```

#### IN-PORT

如果请求的传入端口匹配，则触发该规则。在 Surge 监听多个端口时很有用。

```ini
IN-PORT,6152,DIRECT
```

#### SRC-PORT iOS 5.8.4+ Mac 5.4.4+

如果请求的客户端端口号匹配，则触发该规则。

```ini
SRC-PORT,>=50000,DIRECT
```

### 其他

#### SRC-IP

如果请求的客户端 IP 地址匹配，则触发该规则。仅适用于远程机器。

```ini
SRC-IP,192.168.20.100,DIRECT
```

`SRC-IP` 规则也支持 CIDR 表示法。

```ini
SRC-IP,192.168.20.0/24,DIRECT
```

#### PROTOCOL

如果请求的协议匹配，则触发该规则。可能的值为 HTTP、HTTPS、TCP、UDP、DOH、DOH3、DOQ、QUIC、STUN。

```ini
PROTOCOL,HTTP,DIRECT
```

1. 由于 QUIC 存在多个草案版本，并非所有的 QUIC 流量都能被 Surge 识别。
2. 出于兼容性原因，`PROTOCOL,UDP` 也可以匹配 QUIC 流量。
3. `PROTOCOL,TCP` 现在涵盖了 HTTP 和 HTTPS 连接，因此你可以为基于 TCP 的网络流量编写一条规则即可。
4. 协议关键字 `DOH`、`DOH3` 和 `DOQ` 仅用于匹配 Surge 自身发送的加密 DNS 请求。此功能需要与 `encrypted-dns-follow-outbound-mode=true` 结合使用。
5. STUN 检测可用于过滤 P2P 流量；`PROTOCOL,STUN` 将专门拦截或转发 STUN 数据包。

#### SCRIPT

使用 Javascript 脚本来确定是否匹配。

```ini
SCRIPT,ScriptName,DIRECT
```

#### CELLULAR-RADIO (仅限 iOS)

如果当前网络的蜂窝无线电技术匹配，则触发该规则。可能的值有 GPRS, Edge, WCDMA, HSDPA, HSUPA, CDMA1x, CDMAEVDORev0, CDMAEVDORevA, CDMAEVDORevB, eHRPD, HRPD, LTE, NRNSA, NR

```ini
CELLULAR-RADIO,LTE,DIRECT
```

#### DEVICE-NAME

如果客户端的设备名称匹配，则触发该规则。

* 对于 Surge Ponte 访问，设备名称为客户端设备系统设置中的设备名称。
* 如果启用了 Surge DHCP，对于局域网设备访问，可以使用在设备视图上找到的自定义设备名称。

#### MAC-ADDRESS Mac 6.1.0+

可以匹配访问设备的 MAC 地址。请注意，这仅对同一局域网内的设备有效；如果请求是由网关转发的，则无法获取 MAC 地址。

#### HOSTNAME-TYPE Mac 5.7.3+

匹配请求中主机名的形式。支持的关键字有：

* `IPv4`: 主机名是字面量 IPv4 地址。
* `IPv6`: 主机名是字面量 IPv6 地址。
* `DOMAIN`: 主机名包含点且是常规域名。
* `SIMPLE`: 不包含点的主机名，例如 `localhost`。

示例：

```ini
HOSTNAME-TYPE,IPv6,REJECT
HOSTNAME-TYPE,SIMPLE,DIRECT
```


# 规则集

你可以使用来自文件或 URL 的一系列规则。Surge 也提供了两个内部规则集。

## 内部规则集 (Internal Ruleset)

内部规则集的内容可能会随着 Surge 版本更新而改变。请前往规则集设置查看最新的子规则。

### SYSTEM

`RULE-SET,SYSTEM,DIRECT`

包含 macOS 和 iOS 自身发送的大多数请求的规则。不包含由 App Store、iTunes 和其他内容服务发送的请求。

```ini
USER-AGENT,*com.apple.mobileme.fmip1
USER-AGENT,*WeatherFoundation*
USER-AGENT,%E5%9C%B0%E5%9B%BE*
USER-AGENT,%E8%AE%BE%E7%BD%AE*
USER-AGENT,com.apple.geod*
USER-AGENT,com.apple.Maps
USER-AGENT,FindMyFriends*
USER-AGENT,FindMyiPhone*
USER-AGENT,FMDClient*
USER-AGENT,FMFD*
USER-AGENT,fmflocatord*
USER-AGENT,geod*
USER-AGENT,locationd*
USER-AGENT,Maps*
DOMAIN,api.smoot.apple.com
DOMAIN,captive.apple.com
DOMAIN,configuration.apple.com
DOMAIN,guzzoni.apple.com
DOMAIN,smp-device-content.apple.com
DOMAIN,xp.apple.com
DOMAIN-SUFFIX,ess.apple.com
DOMAIN-SUFFIX,push-apple.com.akadns.net
DOMAIN-SUFFIX,push.apple.com
DOMAIN,aod.itunes.apple.com
DOMAIN,mesu.apple.com
DOMAIN,api.smoot.apple.cn
DOMAIN,gs-loc.apple.com
DOMAIN,mvod.itunes.apple.com
DOMAIN,streamingaudio.itunes.apple.com
DOMAIN-SUFFIX,lcdn-locator.apple.com
DOMAIN-SUFFIX,lcdn-registration.apple.com
DOMAIN-SUFFIX,ls.apple.com
PROCESS-NAME,trustd
```

> 这些规则可能会随着 Surge 的更新而更新。请参阅软件中的说明以获取最新的子规则。

### LAN

`RULE-SET,LAN,DIRECT`

包含针对局域网 IP 地址和 `.local` 后缀的规则。请注意，此规则集将触发 DNS 查询。

```ini
DOMAIN-SUFFIX,local
IP-CIDR,192.168.0.0/16
IP-CIDR,10.0.0.0/8
IP-CIDR,172.16.0.0/12
IP-CIDR,127.0.0.0/8
IP-CIDR,100.64.0.0/10
IP-CIDR6,fe80::/10
```

## 外部规则集 (External Ruleset)

来自 URL 或本地文件的规则集。规则集文件应为文本文件。每行包含一个不带策略的规则声明。

示例：

```ini
DOMAIN,exampleA.com
DOMAIN,exampleB.com
```

`[Rule]` 中的 `RULE-SET` 规则行接受应用于每个子规则的可选参数：

* `no-resolve`: 在匹配该集合时跳过 DNS 解析。
* `extended-matching`: 允许集合内的域名规则同时匹配 SNI 和 HTTP Host 请求头。

示例：

```ini
RULE-SET,https://example.com/social.list,Proxy,no-resolve,extended-matching
```

## 内联规则集 (Inline Ruleset) Mac 5.3.1+

你无需将列表托管在外部，而是可以将规则直接嵌入配置内部。

```ini
[Ruleset Streaming]
DOMAIN-SUFFIX,netflix.com
DOMAIN-SUFFIX,netflix.net
DOMAIN,netflixdnstest0.com

[Rule]
RULE-SET,Streaming,StreamingProxy
```

内联规则集与独立文件共享相同的语法，并受益于相同的预处理/索引优化。


# 最终规则

`FINAL` 规则必须写在所有其他规则之后。它为未匹配任何其他规则的请求定义了默认策略。

示例：

```ini
[Rule]
DOMAIN-SUFFIX,company.com,ProxyA
DOMAIN-KEYWORD,google,DIRECT
GEOIP,US,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT
FINAL,ProxyB
```

### 选项

#### 选项: dns-failed

如果在规则评估期间 DNS 查询失败，则使用 `FINAL` 规则。此选项仅在与非 `DIRECT` 策略结合使用时才有意义。


# 代理策略

根据自定义的规则，Surge 可以将请求转发给另一个代理服务器，或直接连接到目标主机。策略决定了 Surge 将如何处理这些请求。

共有三种类型的策略：[代理 (proxy)](/policy/proxy)、[策略组 (policy group)](/policy-group) 和[内置策略 (built-in policy)](/policy/built-in)。


# 内置策略

Surge 包含几种内置策略，其中最重要的是 `DIRECT` 和 `REJECT`。`DIRECT` 表示请求应当直接发送给主机，而 `REJECT` 表示该请求应当被拒绝。

### 内置策略

#### DIRECT

将请求直接发送给主机。

#### CELLULAR 仅限 iOS

优先使用蜂窝网络而非 Wi-Fi 网络。

#### CELLULAR-ONLY 仅限 iOS

仅使用蜂窝网络。如果蜂窝网络不可用，则连接失败。

#### HYBRID 仅限 iOS

尝试同时通过 Wi-Fi 和蜂窝网络建立连接。仅在未开启“All Hybrid”选项时有意义。

#### NO-HYBRID 仅限 iOS

如果 Wi-Fi 可用，则永远不尝试通过蜂窝网络建立连接。仅在开启了“All Hybrid”或“Wi-Fi Assist”选项时有意义。

关于 REJECT/REJECT-DROP/REJECT-NO-DROP，请查看 [REJECT 策略](/policy/reject) 页面。

### 别名 (Alias)

内置策略可以直接在规则和策略组中使用。你也可以在 `[Proxy]` 段落中定义别名。

```ini
[Proxy]
On = direct
Off = reject
```

然后，你可以在规则和策略组中使用 `On` 和 `Off` 作为策略名称。


# REJECT 策略

为了满足不同的需求，Surge 有多个内置的 REJECT 策略。在大多数情况下，直接使用 `REJECT` 已经足够。如果存在特殊需求，可以考虑使用派生策略。

#### REJECT

拒绝请求，如果该请求是 HTTP 类型，则将返回一个错误页面。此行为可以通过 `show-error-page-for-reject` 参数进行控制。

#### REJECT-DROP

拒绝请求。与 REJECT 不同，此策略将静默丢弃连接。某些应用程序具有非常激进的重试逻辑，当它们在连接失败后立即重试时，会导致请求风暴。使用此策略可以缓解该问题。

#### REJECT-NO-DROP

如果在短时间内对某个主机名的大量请求触发了 `REJECT/REJECT-TINYGIF` 策略（当前版本中的阈值为 30 秒内 50 次），Surge 将自动把策略升级为 `REJECT-DROP` 以避免浪费大量资源。

你可以使用 `REJECT-NO-DROP` 策略来避免这种行为。

#### REJECT-TINYGIF

拒绝请求，如果该请求是 HTTP 类型，则返回一个 1 像素的透明 GIF，用于广告拦截。

### 预匹配拒绝 (Pre-matching Reject) iOS 5.14.0+ Mac 5.9.0+

由于 Surge 规则系统可以评估的属性范围很广，因此规则的判定只能在接收到第一个 TCP 数据包后进行。这在处理风暴请求或广告拦截需求时会导致产生过多的不必要开销。

在新版本中，Surge 添加了预匹配 (Pre-matching) 功能，以低开销快速拒绝请求。对于使用 REJECT 策略的规则，可以通过 `pre-matching` 标记启用此功能。

```ini
[Rule]
DOMAIN,ad.com,REJECT,pre-matching
```

标记为 `pre-matching` 的规则将在正常的规则匹配过程之前生效，因此具有最高优先级。

所有标记为 `pre-matching` 的规则都将被提取以进行优先匹配，并在 DNS 解析和 TCP SYN 阶段执行。如果匹配了 DNS 域名，则直接返回无记录 (No Record)；如果在 TCP SYN 阶段匹配，则立即生成 TCP RST 响应。在大量请求的情况下，它会升级为丢包，UDP 的处理方式也类似。

此外，每条规则每 5 分钟只会在最近请求列表中出现一次，以避免因大量请求而导致列表泛滥。

可以标记为 `pre-matching` 的规则类型包括：

* DOMAIN 类型：DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD、DOMAIN-SET、DOMAIN-WILDCARD。
* IP 类型：IP-CIDR、IP-CIDR6、GEOIP、IP-ASN。
* 逻辑规则：AND、OR、NOT
* 其他：SUBNET、DEST-PORT、SRC-PORT、SRC-IP

`RULE-SET` 也可以被使用，但其内容同样受上述限制。

### 预匹配技术细节

为了获得最佳的用户体验，拒绝在预匹配阶段进行，并在使用不同的派生规则时会存在一些细节上的差异。

#### 对于 DNS 查询

* 如果匹配了 REJECT 策略，Surge 将返回一个无记录的 DNS 响应。如果触发了内置于 REJECT 策略的频率限制，DNS 查询将被直接丢弃而不产生响应。
* 如果匹配了 REJECT-DROP 策略，DNS 查询将被直接丢弃而不产生响应。
* 如果匹配了 REJECT-NO-DROP 策略，它将返回一个特殊的 IP 地址 198.18.0.244；Surge 将为所有访问该地址的 TCP 连接生成 TCP RST 响应。

#### 对于使用 IP 的 TCP 请求

* 如果匹配了 REJECT 策略，将直接生成 TCP RST 响应；如果触发了内置于 REJECT 策略的频率限制，它将丢弃相应的 TCP SYN 握手数据包。
* 如果匹配了 REJECT-DROP 策略，将直接丢弃 TCP SYN 握手数据包。
* 如果匹配了 REJECT-NO-DROP 策略，将直接生成 TCP RST 响应。

请注意，由于某些软件可能具有激进的重试逻辑，在请求失败后立即重试从而导致异常的 CPU 占用，因此即使对于 REJECT-NO-DROP 策略，当 Surge 在短时间内产生大量的 TCP RST 数据包时（当前版本的阈值为 3 秒内 100 次），也会触发保护机制，暂停返回 TCP RST 而直接执行丢包处理。

#### 对于 UDP 数据包

由于 UDP 数据包没有握手开销，因此不存在预匹配阶段；它们使用主规则集进行直接匹配：

* 如果匹配了 REJECT 策略，将生成 ICMP Administratively Prohibited (管理上被禁止) 的响应；如果触发了内置于 REJECT 策略的频率限制，数据包将被直接丢弃。
* 如果匹配了 REJECT-DROP 策略，数据包将被直接丢弃。
* 如果匹配了 REJECT-NO-DROP 策略，将生成 ICMP Administratively Prohibited 的响应。


# 代理策略

代理策略指示将请求转发到另一个代理服务器。Surge 支持 HTTP/HTTPS/SOCKS5/SOCKS5-TLS 以及更多代理协议。

`[Proxy]` 段落用于声明代理策略。你可以为不同的规则创建多个代理。

配置行示例：

```ini
[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
```

## 代理类型

Surge 支持大多数常见的标准代理协议。

* HTTP 代理: `ProxyHTTP = http, 1.2.3.4, 443, username, password`
* HTTPS 代理 (基于 TLS 的 HTTP 代理): `ProxyHTTPS = https, 1.2.3.4, 443, username, password`
* SOCKS5: `ProxySOCKS5 = socks5, 1.2.3.4, 443, username, password`
* SOCKS5 over TLS: `ProxySOCKS5TLS = socks5-tls, 1.2.3.4, 443, username, password`
* SSH
* WireGuard (作为代理的 L3 层 VPN)

Surge 也支持几种流行的社区代理协议。

* Snell: `Proxy-Snell = snell, 1.2.3.4, 8000, psk=password, version=4`
* Shadowsocks: `Proxy-SS = ss, 1.2.3.4, 8000, encrypt-method=chacha20-ietf-poly1305, password=abcd1234`
* VMess: `Proxy-VMess = vmess, 1.2.3.4, 8000, username=0233d11c-15a4-47d3-ade3-48ffca0ce119`
* Trojan: `Proxy-Trojan = trojan, 192.168.20.6, 443, password=password1`
* TUIC: `Proxy-TUIC = tuic, 192.168.20.6, 443, token=pwd, alpn=h3`
* Hysteria 2: `Proxy-Hysteria = hysteria2, 192.168.20.6, 443, password=pwd, download-bandwidth=100` iOS 5.8.0+ Mac 5.4.0+
* AnyTLS: `Proxy-AnyTLS = anytls, 192.168.20.6, 443, password=pwd` iOS 5.17.0+ Mac 6.4.3+

### UDP 转发

Surge 支持 SOCKS5、Snell v4/v5、Shadowsocks、Trojan、WireGuard、Hysteria 2 和 TUIC 协议的 UDP 转发。由于服务器并不总是支持 UDP 转发，Shadowsocks 和 SOCKS5 代理的 UDP 转发支持应通过添加参数 `udp-relay=true` 手动开启。

## 参数

#### 代理链 (Proxy Chain)

* `underlying-proxy`

  使用一个代理来连接另一个代理，也称为代理链。它可以是另一个代理策略或策略组的名称。

#### 基于 TLS 的代理的通用参数 (HTTP, SOCKS5-TLS, VMess, Trojan, TUIC, Hysteria 2, AnyTLS)

* `skip-cert-verify`: 可选，"true" 或 "false"（默认值：false）。

  如果启用此选项，Surge 将不验证服务器的证书。
* `sni`: 默认值为代理的主机名

  你可以自定义 TLS 握手期间的 SNI (Server Name Indication)。使用 `sni=off` 可完全关闭 SNI。默认情况下，Surge 像大多数浏览器一样发送使用主机名的 SNI。
* `server-cert-fingerprint-sha256`: 可选。

  使用固定的服务器证书，而不是标准的 X.509 验证。

#### HTTP/HTTPS 协议参数

* `always-use-connect`: 可选。

  始终使用 HTTP CONNECT 方法来中继请求，即使是纯 HTTP 请求也是如此。

#### SOCKS5 协议参数

* `udp-relay`: 可选。由于 SOCKS5 服务器的 UDP 转发是可选的，因此你必须明确启用 UDP 转发。

#### Snell 协议参数

有关更多信息，请参阅知识库 [Snell](https://kb.nssurge.com/surge-knowledge-base/release-notes/snell)。

* `psk`: 必填。
* `version`: 必填。
* `reuse`: 可选。连接复用是 Snell V4 的一个可选功能。
* `obfs`: 可选。`http` 是 Snell V4 唯一支持的混淆选项。
* `obfs-host`: 可选。
* `obfs-uri`: 可选。

#### Shadowsocks 协议参数

* `udp-relay`: 可选。由于 Shadowsocks 服务器的 UDP 转发是可选的，因此你必须明确启用 UDP 转发。
* `obfs`: 可选。`http` 或 `tls`。
* `obfs-host`: 可选。
* `obfs-uri`: 可选。
* `udp-port`: 可选。进行 UDP 转发时，使用另一个服务器端口号。这可以在服务器的 TCP 和 UDP 服务不监听同一个端口时使用（例如配置了 ShadowTLS）。iOS 5.14.0+ Mac 5.9.0+

#### VMess 协议参数

* `ws`: 可选。使用 WebSocket 传输层。
* `ws-path`: 可选。
* `ws-headers`: 可选。
* `encrypt-method`: 可选。可能的值：`chacha20-ietf-poly1305` 或 `aes-128-gcm`。
* `vmess-aead`: 可选。

#### Trojan 协议参数

* `ws`: 可选。使用 WebSocket 传输层。
* `ws-path`: 可选。
* `ws-headers`: 可选。

#### TUIC 参数

* `token`: 必填。
* `alpn`: 可选。它必须匹配服务器的 ALPN 设置。
* `port-hopping`: 可选。配置一个端口或端口范围的列表（例如 `1234;5000-6000`）。Surge 将在它们之间定期轮换，而不是使用主端口。
* `port-hopping-interval`: 可选。轮换的间隔（秒），默认为 30。设置此字段时，声明中的主端口将被忽略。

#### Hysteria 2 参数 iOS 5.8.0+ Mac 5.4.0+

* `download-bandwidth`: 可选，单位为 Mbps。
* `port-hopping`: 可选。以分号分隔的显式端口或范围列表。启用发行说明中描述的端口跳跃模式。
* `port-hopping-interval`: 可选。间隔（秒），默认为 30。启用端口跳跃后，前导的端口参数不再被使用。

#### AnyTLS v2 参数 iOS 5.17.0+ Mac 6.4.3+

* `reuse`: 可选。根据 AnyTLS 规范，默认启用连接复用。你可以通过将 `reuse` 设置为 false 来禁用它。

## 用于 TLS 代理的客户端证书

Surge 支持对基于 TLS 的代理进行客户端证书验证。

示例：

```ini
[Proxy]
Proxy = https, example.com, 443, client-cert=cert1

[Keystore]
cert1 = base64=<此处为 P12 的 base64 字符串>, password=123456
```

## Shadow TLS

Shadow TLS 是一种代理混淆器，可与任何基于 TCP 的代理一起使用。(<https://github.com/ihciah/shadow-tls>)

从 Surge iOS 5.2.0 和 Surge Mac 4.10.0 开始，Surge 支持 Shadow TLS v2 协议。将 `shadow-tls-password` 附加到任何代理声明中即可使用它。

示例：

```ini
[Proxy]
STLS-SNELL = snell, 1.2.3.4, 443, psk=pwd1, version=4, reuse=true, shadow-tls-password=pwd2
```

从 Surge iOS 5.5.0 和 Surge Mac 5.0.3 开始，Surge 支持 Shadow TLS v3 协议。

示例：

```ini
STLS-SNELL = snell, 1.2.3.4, 443, psk=pwd1, version=4, reuse=true, shadow-tls-password=pwd2, shadow-tls-version=3
```

#### 参数

* `shadow-tls-password`: 必填。它必须与服务器的设置匹配。
* `shadow-tls-sni`: 可选。SNI 将在 TLS 握手期间以明文形式发送到服务器。如果未设置，将不发送任何 SNI。
* `shadow-tls-version`: 可选。可能的值：2 或 3。默认值：2。


# WireGuard

你可以将 Surge 作为 WireGuard 客户端使用，把 L3 VPN 转换为出站代理策略。

```ini
[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)
```

配置注意事项：

1. 所有密钥均可以使用 Base64 或 HEX 形式。
2. 你可以同时配置 `self-ip` 和 `self-ip-v6` 以利用 IPv4 & IPv6 双栈，或仅配置其中之一以使用单栈。
3. 请注意，每个设备的 `self-ip` 和 `self-ip-v6` 必须不同，否则可能导致 IP 抢占。
4. 如果 `prefer-ipv6` 为 true，在启用 IPv4 & IPv6 双栈并且域名同时配置了 A 和 AAAA 记录时，将优先使用 IPv6。
5. `peer` 字段可以配置多个节点，使用逗号分隔，并以 `()` 表示一个节点。如果通过 UI 配置，则只允许配置单个节点。
6. `preshared-key` 和 `keepalive` 是对端 (peer) 的可选参数。
7. 对端的 `endpoint` 可以使用域名。请注意，端点的解析由 `[General]` 段落配置的 DNS 解析器完成，并且与该段落中的 `dns-server` 参数无关。
8. `0.0.0.0/0` 的 `allowed-ips` 意味着该策略可以用来访问任何地址，或者也可以配置为特定的内网地址。
9. 如果你需要通过此策略使用域名访问主机，你必须配置 `dns-server`，Surge 将通过 WireGuard VPN 隧道向该服务器进行 DNS 解析。可以配置多个 DNS 地址，使用逗号分隔。
10. `[WireGuard NAME]` 段落可以拆分到分离的配置段落文件 (Detached Profile Section file) 中。
11. 可以同时配置并使用多个 Wireguard 实例。

使用注意事项：

1. WireGuard 是一种 L3 VPN，因此在处理期间的开销明显高于其他通用代理协议。它适用于带宽要求较低的场景。
2. 隧道仅支持 TCP 和 UDP 协议。此外，还提供了一种非常简单的 ICMP/ICMPv6 响应机制。WireGuard 握手成功时，可以从服务器端 ping 客户端隧道的 IP，以测试连通性。
3. 由于 WireGuard 协议没有报错机制，在大多数情况下，WireGuard 错误均表现为超时（例如密钥错误、防火墙拦截、服务端未配置 NAT 等），因此请自行抓包分析原因。

按照 WireGuard 协议标准的建议，WireGuard 握手数据包将被打上 0x88 (AF41) DSCP 标记，以提高成功率。

#### 自定义保留位 (Customize Reserved Bits) iOS 5.3.1+ Mac 4.10.3+

Surge 支持自定义 WireGuard 的保留位。它可能会被某些实现用作客户端 ID 或路由 ID，例如 Cloudflare WARP。

示例：

`peer = (public-key = <key>, allowed-ips = "0.0.0.0/0, ::/0", endpoint = example.com:51820, client-id = 83/12/235)`

#### ECN 支持 iOS 5.8.0+ Mac 5.4.0+

当通过 WireGuard 转发 UDP 数据包时，支持保留隧道内数据包的 TOS (DSCP/ECN) 标记。

根据 WireGuard 协议标准的建议，Surge 会将 ECN 标记从隧道内的数据包复制到外部数据包中。在接收带有 ECN 标记的数据包时，将根据 RFC6040 严格合并。（必须为 WireGuard 策略设置 `ecn=true`）。


# SSH

你可以使用 SSH 协议作为代理策略，相当于 `ssh -D`。

配置文件语法：

* 密码认证

```ini
[Proxy]
proxy = ssh, 1.2.3.4, 22, username=root, password=pw
```

* 公钥认证

```ini
[Proxy]
proxy = ssh, 1.2.3.4, 22, username=root, private-key=key1

[Keystore]
key1 = type=openssh-private-key, base64=[私钥文件的 Base64 编码内容]
```

* 请注意，你必须对整个私钥文件再次进行 Base64 编码，即使私钥文件本身就是 Base64 编码的。
* 支持全部四种类型的私钥：RSA/ECDSA/ED25519/DSA。
* Surge 仅支持 `curve25519-sha256` 作为密钥交换 (kex) 算法，并仅支持 `aes128-gcm` 作为加密算法。这意味着 SSH 服务器必须使用 OpenSSH v7.3 或更高版本。（这应该不是问题，因为 OpenSSH 7.3 已于 2016-08-01 发布。）
* 你现在可以指定空闲超时参数。默认值为 180 秒。

```ini
[Proxy]
proxy = ssh, 1.2.3.4, 22, username=root, password=pw, idle-timeout=180
```

## 服务器指纹 (Server Fingerprint)

为了防范 MITM 攻击，你可以使用 `server-fingerprint` 参数指定服务器的公钥指纹，这能确保只连接到合法的服务器。

```ini
[Proxy]
proxy = ssh, 1.2.3.4, 22, username=root, password=pw, idle-timeout=180, server-fingerprint = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBk2No6KBq2m9VTCcHXXJBX4/A3RNr+L+yDBl5+TF9qz"
```

由于一台服务器可能拥有多个公钥，`server-fingerprint` 参数支持配置多个指纹。

```ini
server-fingerprint = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBk2No6KBq2m9VTCcHXXJBX4/A3RNr+L+yDBl5+TF9qz,ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD7aoFCymj8NJL+xMqYzRLGpIfVd2sebgtnD3cplG7/lrvPGYIpRAOkKqdUBOkRd2x68JFe0u+gBHQxFkv8o81Saqr6qxcrq4mPiyqxOTRkvDMtYrjJ4AJZE26nCzHRCC7Ji6Mq2OtepTJcC9uk2LLcRrF3G05qu6ToeK1LgXgqc+b2RLOQJ1AXEeNgn0NIXWlBv4AhQRJ6fFQi4HO/jkxpFNfzKY+dPDx6P3VAazYa2nl8wpLbXt+tq6SBv8RctwDuYszAbjSCPPJq7ToX/Svqqbl82qtOLOofcQ8/f8809i4RQ0yuEpVLnVVWd7cZx5h45vt+/I1Ifr2pS7BqhLL/,ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLdhR3D2BvyD7FTXfx0CrjZF2tVgoVRFi1poGKoX0eXc9OlpiaqNos4niiN0GWyoT4mL724cgvaL+vHW8sTZE5A="
```

如果服务器的 sshd 支持 ed25519，则只需要 ssh-ed25519 的指纹。

你可以从 `~/.ssh/known_hosts` 文件中获取服务器指纹。或者你可以在受信任的网络环境中使用 `ssh-keyscan example.com` 命令来获取。在将其复制到 Surge 之前，请移除行首的主机名。


# 通用策略参数

### 出站参数

以下所有参数对内置策略和代理策略均可用。

#### `interface` (默认值: 自动)

强制使用指定的出站网络接口。

```ini
ProxyHTTP = http, 1.2.3.4, 443, username, password, interface = en2
```

Direct 策略的别名也像代理策略一样支持 `interface` 参数。

```ini
[Proxy]
Corp-VPN = direct, interface = utun0
WiFi = direct, interface = en2, allow-other-interface=true
```

请确保该接口具有目标地址的有效路由表。

#### `allow-other-interface` (布尔值, 默认值: false)

当此选项为 true 时，如果所需的接口不可用，Surge 允许使用默认接口来绑定连接。否则，连接将直接失败。

```ini
ProxyHTTP = http, 1.2.3.4, 443, username, password, interface = en2, allow-other-interface=true
```

#### `dns-follow-interface` (布尔值, 默认值: false) iOS 5.15.2+ Mac 5.2.0+

让策略的 `interface` 参数对 DNS 查询也生效；匹配该策略的 DNS 请求将使用此接口进行查询。（如果在规则匹配阶段触发了 DNS 解析，则不会使用特定接口。）

#### `no-error-alert` (布尔值, 默认值: false)

不显示该策略的错误警告。

#### `ip-version`

选择在 IPv4 和 IPv6 协议之间的行为。此选项仅影响到代理服务器的连接。因此，只有当代理服务器的主机名是一个域名时，它才有意义。如果配置了底层代理，该选项无效，因为 DNS 解析发生在远程服务器上。

* `dual` (默认，使用最快的链路)
* `v4-only`
* `v6-only`
* `prefer-v4`
* `prefer-v6`

#### `hybrid` (布尔值, 仅限 iOS, 默认值: false)

同时建立蜂窝数据和 Wi-Fi 连接，然后使用较快的链路。

#### `tfo` (布尔值, 默认值: false)

开启 TCP Fast Open。

#### `tos` (十进制或十六进制, 默认值: 0)

自定义 IP TOS 值。

#### `ecn` (布尔值, 默认值: false) iOS 5.8.0+ Mac 5.4.0+

开启 ECN (显式拥塞通知) 支持。它可以提高高丢包率环境下的带宽性能，但在不支持的网络环境中开启可能会导致连接失败。

#### `block-quic` iOS 5.8.0+ Mac 5.4.0+

通过代理转发 QUIC 流量可能会导致性能问题。开启此选项将阻断 QUIC 流量，使客户端回退到传统的 HTTPS/TCP 协议。

* `auto`: 根据代理是否适合转发 QUIC 流量自动开启。
* `on`: 阻断 QUIC 流量。
* `off`: 不阻断 QUIC 流量。

### 测试

#### `test-url`

示例：`test-url=http://google.com`

覆盖全局的测试 URL。该 URL 用于可用性和延迟测试。Surge 通过向该 URL 发送 HTTP HEAD 请求来测试代理并进行基准测试。

#### `test-timeout` (单位：秒)

覆盖全局的测试超时时间。

#### `test-udp`

示例：`test-udp=google.com@1.1.1.1`

覆盖代理的全局 `proxy-test-udp` 设置。Surge 通过执行 DNS 查询来测试和基准测试 UDP 中继。


# 外部代理程序

Surge Mac 支持外部代理程序策略，这使得 Surge 能够更容易地与其他代理软件协同工作。

以下是一个 ssh 的例子。

首先，策略的关键字类型为 `external`。

```ini
[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
```

`args` 和 `addresses` 参数是可选的，`exec` 和 `local-port` 是必填的。`args` 和 `addresses` 字段可以重复使用以进行追加。

Surge 将执行以下操作：

1. 当该策略被使用时，Surge 会使用 `exec` 和 `args` 参数启动外部进程，随后将请求转发到 SOCKS5 `127.0.0.1:[local-port]`。
2. 如果外部进程被终止，在下次使用该策略时它将自动重启。
3. 当开启增强模式时，Surge 会自动将 `addresses` 参数中的地址从 VIF 路由中排除。（因此请在此字段中填写代理服务器的 IP 地址。不支持主机名和域名。）
4. Surge 总是对来自外部进程的请求使用 `DIRECT` 策略。（为了应对类似 obfs-local 的插件程序，外部进程的子进程也同样处理。）
5. Surge 退出时自动关闭所有外部进程，并在增强模式关闭时自动清理路由表项。

一些注意事项：

1. 上述第 3 点和第 4 点的功能有重叠，请使用 `addresses` 声明来排除 VIF 处理，这可以降低处理开销，第 4 点的功能是作为额外的保护措施。
2. 外部进程的 stdout 和 stderr 被重定向到 `/tmp/Surge-External-xxxxxx.log` 以便于排错。
3. 由于外部进程启动可能需要一点时间。如果在转发到 `127.0.0.1:[local-port]` 时遇到连接拒绝 (connection refused) 错误，Surge 将会在 500ms 后自动重试，每个请求最多重试 6 次。
4. Surge iOS 将会把 `external` 策略视为 `REJECT`，因为它不支持此功能。


# 策略组

策略组可以包含多个策略。它可以是代理策略、另一个策略组，或者是内置策略。

策略组的存在是为了在应用代理规则时，能够灵活地调整具体使用的策略，而不需要修改规则本身。

有几种策略组类型：`select`、`url-test`、`fallback`、`load-balance` 和 `subnet`。策略组应在 `[Proxy Group]` 段落中声明。


# 手动选择组

在用户界面上选择要使用的策略。

`SelectGroup = select, ProxyHTTP, ProxyHTTPS, DIRECT, REJECT`

在 Surge iOS 中，你可以使用小组件为手动选择组快速切换策略。 在 Surge Mac 中，你可以在菜单栏菜单中切换策略。


# 自动测试组

通过测试到测试 URL 的延迟，自动选择要使用的策略。你可以在通用设置中更改测试 URL，或者覆盖某个策略的测试 URL。

`AutoTestGroup = url-test, ProxySOCKS5, ProxySOCKS5TLS`

### 临时覆盖 (Temporary Override)

你可以通过手动选择策略来临时覆盖自动测试的结果。

* 在 Surge Mac 中，你可以在主菜单中对应的组里找到覆盖选项。
* 在 Surge iOS 中，你可以在策略组视图中长按对应策略的菜单找到覆盖选项。

### 参数

#### interval: 可选，单位为秒，默认值：600（秒）

基准测试结果将在该间隔时间后被丢弃。如果该策略组被使用，将会发生重新测试。

#### tolerance: 可选，单位为毫秒，默认值：100（毫秒）

仅当新的获胜者的得分高于旧的获胜者的得分加上容差时，才会更改策略。

此选项可防止得分相似的策略不断交替。

#### timeout: 可选，单位为秒，默认值：5（秒）

如果在超时时间内未完成，则放弃该策略。

#### evaluate-before-use: 可选，布尔值，默认值：false

默认情况下，第一次使用自动测试策略组时，为了不影响请求，它会首先使用策略组中的第一个策略进行访问，同时触发该策略组的测试。

如果启用了此选项，那么在第一次使用自动测试策略组时，它将触发策略组的测试并等待测试完成，然后再使用所选结果发出请求。


# 可用性测试组

根据优先级和可用性选择一个可用的策略。可用性通过访问一个 URL 来测试，就像自动测试组一样。区别在于降级组只关心可用性，而不关心具体的延迟。定义在前面的策略具有高优先级。

`FallbackGroup = fallback, ProxySOCKS5, ProxySOCKS5TLS`

### 临时覆盖 (Temporary Override)

你可以通过手动选择策略来临时覆盖自动测试的结果。

* 在 Surge Mac 中，你可以在主菜单中对应的组里找到覆盖选项。
* 在 Surge iOS 中，你可以在策略组视图中长按对应策略的菜单找到覆盖选项。

### 参数

#### `interval`: 可选，单位为秒，默认值：600（秒）

决定多久之后丢弃基准测试结果。

#### `timeout`: 可选，单位为秒，默认值：5（秒）

如果在超时时间内未完成，则放弃该策略。


# 子网组

使用子网策略组，你可以根据当前的网络环境自动选择一个策略。你可以使用[子网表达式 (subnet expression)](/rule/subnet)作为条件。

`Subnet Group = subnet, default = ProxyHTTP, TYPE:WIFI = ProxyHTTP, SSID:MyHome = ProxySOCKS5`

从 Surge iOS 4.12.0 & Surge Mac 4.5.0 开始，SSID 组现更名为子网组 (Subnet Group)。依然支持 SSID 组的旧语法。你可以使用组类型关键字 `subnet` 或 `ssid` 以保持兼容。

### 参数

#### `default`: 必填

当没有匹配任何子网表达式时的策略。

#### `cellular`: 可选 (已弃用，请改用 `TYPE:CELLULAR`)

蜂窝网络的策略。如果不提供，则将使用默认策略。


# 负载均衡组

负载均衡组从可用的子策略中随机选择一个策略来使用。

### 参数

#### `persistent`: 可选

当 `persistent=true` 时，对于相同的目标主机名将使用相同的策略。这可以避免由于出口 IP 不同而触发目标站点的风控。然而，当可用性发生变化时，可能会发生策略变更。


# 引入策略群组

## 包含外部策略

策略组可以导入在外部文件或从 URL 中定义的策略。

`egroup = select, policy-path=proxies.txt`

该文件包含策略列表，就像主配置文件中的定义行一样。

```ini
Proxy-A = https, example1.com, 443
Proxy-B = https, example2.com, 443
```

#### `update-interval`: 可选，单位为秒

更新间隔。仅当路径是 URL 时有意义。

#### `policy-regex-filter`: 可选

仅使用策略名称与正则表达式匹配的策略。

#### `external-policy-modifier`: 可选

你可以使用此参数修改外部策略的参数。

例如，开启 TFO 并更改测试 URL：

```ini
external-policy-modifier="test-url=http://apple.com/,tfo=true"
```

### `external-policy-name-prefix`: 可选

为这个外部策略组中子策略的策略名增加前缀，以便于同时使用多个不同的外部策略组时区分。

## 包含现有策略 iOS 4.12.0+ Mac 4.5.0+

你可以使用 `include-all-proxies` 和 `include-other-group` 来包含所有代理，或者重用来自另一个组的现有定义。

#### `include-all-proxies`

参数 `include-all-proxies=true` 包含 `[Proxy]` 段落中定义的所有代理策略，并可以与 `policy-regex-filter` 参数一起使用来进行过滤。

#### `include-other-group`

参数 `include-other-group="group1,group2"` 包含来自另一个策略组的策略，并且可以包含多个以逗号分隔的策略组。它也可以与 `policy-regex-filter` 参数一起使用来进行过滤。

* 允许在一个策略组中同时使用 `include-all-proxies`、`include-other-group` 和 `policy-path` 参数。`policy-regex-filter` 参数适用于这三者。
* 对于 `include-other-group` 参数引入的策略组之间存在优先级顺序，但在 `include-all-proxies`、`include-other-group` 和 `policy-path` 之间不存在优先级顺序。对于子策略顺序有意义的场景（如 fallback 组），请使用包含 `include-other-group` 的策略组嵌套。


# 通用参数

#### `no-alert`

不显示该策略组的策略变更通知。

#### `hidden`

不在菜单（Surge Mac）和策略选择视图（Surge iOS）中显示该组。


# DNS

*由系统自动生成的章节目录，因原始网站中没有该章节的单独页面。*

* [DNS 服务器](/dns/dns-override)
* [本地 DNS 映射](/dns/local-dns-mapping)
* [加密 DNS](/dns/doh)


# DNS 服务器

Surge 使用自定义的 DNS 客户端来支持高级功能。它的行为可能与操作系统的 DNS 客户端不同。

### 上游 DNS 服务器

Surge 默认使用操作系统的 DNS 服务器地址。你可以使用 `dns-server` 参数来覆盖它们。

```ini
[General]
dns-server = 8.8.8.8, 8.8.4.4
```

使用关键字 `system` 可以将操作系统的 DNS 服务器追加到列表中。（重复的服务器将被忽略）

```ini
[General]
dns-server = system, 8.8.8.8, 8.8.4.4
```

### 技术细节

Surge 会同时向所有的 DNS 服务器发起查询以提高性能，类似于 dnsmasq 配合 `--all-servers` 参数。最先返回的响应将被使用。Surge iOS 应用和 Surge Dashboard 会显示是哪个服务器最先响应的。如果 Surge 在 2 秒内没有收到任何响应，它会再次查询所有服务器。重试四次后，Surge 将放弃并报告 DNS 错误。

部分域名的权威名称服务器可能性能不佳，导致上游 DNS 服务器由于服务器端超时或其他连接问题返回空响应。如果**所有**上游 DNS 服务器显式返回空 DNS 响应，或者部分服务器返回空响应且其余服务器在 2 秒内没有响应，Surge 将报告空 DNS 错误。

当 IPv6 可用并开启时，Surge DNS 客户端将同时向上游 DNS 服务器发送 A 和 AAAA 请求。最先返回的 A 或 AAAA 响应将被使用。


# 本地 DNS 映射

Surge 支持本地自定义的 DNS 映射。它相当于 `/etc/hosts`，但具有更强大的功能，包括通配符、别名以及分配 DNS 服务器。

```ini
[Host]
abc.com = 1.2.3.4
*.dev = 6.7.8.9
foo.com = bar.com
bar.com = server:8.8.8.8
```

## 通配符

你可以使用 `*` 前缀通配所有子域名。请注意 Surge 使用的是简单的字符串匹配。例如，`*google.com` 会匹配 `google.com`、`foo.google.com` 以及 `bargoogle.com`。而 `*.google.com` **不会**匹配 `google.com`。

```ini
[Host]
*.dev = 6.7.8.9
```

## 别名

就像 CNAME 记录一样。

```ini
[Host]
foo.com = bar.com
```

## 分配 DNS 服务器

你可以为单个或多个域名分配指定的 DNS 服务器。

```ini
[Host]
bar.com = server:8.8.8.8
```

由于 Surge 拥有自己的 DNS 客户端实现，某些主机名可能会解析失败。你可以使用 `server:system` 交由系统进行解析。

```ini
[Host]
Macbook = server:system
```

`server:syslib` 的工作原理类似，但它会将查询保留在 Surge 内部，同时将其转发给 macOS 当前正在使用的任何 DNS 服务器。这在增强模式下特别有用，因为在该模式下传统的系统解析器可能会被绕过。

默认情况下，所有带有 `.local` 后缀的主机名都将由系统解析。

## 引用规则集 Mac 5.10.0+

当你已经维护了大型的规则集或域名集时，在 `[Host]` 中重现相同的列表是很繁琐的。Surge 允许将整个 `DOMAIN-SET` 或 `RULE-SET` 绑定到一个 DNS 映射条目，以便自动共享上游服务器或 IP 映射。

```ini
[Host]
DOMAIN-SET:https://example.com/domains.txt = server:https://doh.example.com/dns-query
RULE-SET:https://example.com/rules.txt = 10.0.0.10
```

`DOMAIN-SET:` 期望一个域名列表，而 `RULE-SET:` 可以包含混合的规则类型（DOMAIN、DOMAIN-SUFFIX、IP 范围等）。该语法遵循与[规则集 (Ruleset)](/rule/ruleset)中描述的相同的远程文件格式，并且特别有助于将 DOH/DOQ 的分配与受管列表保持一致。

## 代理请求也使用本地 DNS 记录

```ini
[General]
use-local-host-item-for-proxy=true
```

默认情况下，由于 Surge 总是使用域名发送代理请求，因此 DNS 解析总是在远程代理服务器上进行。

启用该选项后，对于符合本地 DNS 映射记录的请求，Surge 会使用本地的 IP 地址而不是原始域名发送代理请求。

该选项仅对使用 IP 地址的本地 DNS 映射记录有效。


# 加密 DNS

如果配置了加密 DNS，传统 DNS 将仅用于测试连通性以及解析加密 DNS URL 中的域名。

支持的协议：

* DNS over HTTPS: `https://example.com`
* DNS over HTTP/3: `h3://example.com`
* DNS over QUIC: `quic://example.com`

### 为所有域名使用加密 DNS

```ini
[General]
encrypted-dns-server = https://8.8.8.8/dns-query
```

你可以在此处指定多个加密服务器，以逗号分隔。

### 为指定域名使用加密 DNS

```ini
[Host]
example.com = server:https://cloudflare-dns.com/dns-query
```

### 通过代理使用加密 DNS

如果你希望通过代理查询 DoH 服务器，可以将 `encrypted-dns-follow-outbound-mode` 设为 true。

```ini
[General]
encrypted-dns-follow-outbound-mode=true
```

所有的加密 DNS 连接将遵循出站模式设置。然后可以为 DoH 的主机名配置一条规则以使用代理。

或者，使用 `PROTOCOL,DOH`、`PROTOCOL,DOH3` 或 `PROTOCOL,DOQ` 规则来匹配所有加密 DNS 连接。


# HTTP 处理

Surge 包含了多个用于修改 HTTP 请求和响应的功能，其处理管线 (pipeline) 的顺序如下：

1. URL 重写 (URL Rewrite)
2. 请求头重写 (Header Rewrite)
3. 请求体重写 (Body Rewrite)
4. 脚本处理 (Script Processing)

其中，脚本处理只能被一个脚本修改，而如果匹配到多个其他重写规则，它们将按顺序生效。


# HTTPS 解密

Surge 可以通过 MitM 来解密 HTTPS 流量。有关更多信息，请参阅[维基百科的文章](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)。

证书生成器可帮助你生成用于调试的新的 CA 证书，并使该证书被系统信任。它可在 Surge Dashboard（Mac 版）和 Surge iOS 配置编辑器中使用。此证书是在本地生成的，仅保存在你的配置文件和系统钥匙串中。新证书的密钥是使用 OpenSSL 随机生成的。

你也可以使用现有的 CA 证书。将证书导出为带有密码短语的 PKCS#12 格式 (`.p12`)。请注意，由于系统限制，密码短语不能为空。使用 `base64` 命令将其编码为 base64 字符串，并将以下设置追加到你的配置文件中。

```ini
[MITM]
ca-p12 = MIIJtQ.........
ca-passphrase = password
hostname = *google.com
h2 = true
```

Surge 仅对在此声明的主机解密流量。一个通用的配置可能如下所示：

`hostname = -*.apple.com, -*.icloud.com, *`

> 某些应用程序拥有使用固定证书 (pinned certificates) 或 CA 的严格安全策略。对这些主机启用解密可能会导致问题。

此参数属于 Host List 类型，有关详细规则请参见：[Host List 参数类型](/others/host-list)

## 选项

### skip-server-cert-verify (布尔值, 默认值: false)

在执行 MITM 时不验证远程主机的证书。

### h2 (布尔值, 默认值: false)

MITM over HTTP/2：通过 HTTP/2 协议执行 MITM 以解密 HTTPS 流量，这可以提高并发请求的性能。

### client-source-address

使用此参数可以仅在某些设备上启用 MITM 功能。

* 它是一个使用逗号作为分隔符的列表参数。
* 你可以指定单个 IP 地址，也可以使用 CIDR 块。同时支持 IPv4 和 IPv6。
* 你可以使用 `-` 前缀来排除某些客户端，例如：`client-source-address = -192.168.1.2, 0.0.0.0/0`
* 如果未设置此参数，则将对所有客户端启用 MITM。相当于 `client-source-address = 0.0.0.0/0, ::/0`
* 如果你希望对当前设备启用 MITM，则应包含 `127.0.0.1`。
* 从 Surge Mac 版本 6.1.0 开始，此参数可以使用 MAC 地址来匹配特定的客户端。

### auto-quic-block (布尔值, 默认值: true) iOS 5.8.0+ Mac 5.4.0+

当 QUIC 连接（即 HTTP/3）匹配 MITM 主机名列表时，将自动阻断该 QUIC 连接，迫使连接回退至 HTTP/2 或 HTTP/1.1，从而能够被 MITM 拦截。


# URL 重写

Surge 可以使用 2 种不同的方法重写请求的 URL，或者根据 URL 拒绝某些请求。

示例：

```ini
[URL Rewrite]
^http://www\.google\.cn http://www.google.com header
^http://yachen\.com https://yach.me 302
^http://ad\.com/ad\.png _ reject
```

重写规则由三个部分组成：正则表达式、替换内容和类型。

### Header 模式

Surge 会修改请求头，并在必要时将请求重定向到另一个主机。客户端不会感知到这个重写操作。

请求头中的 `Host` 字段将被修改以匹配新的 URL。

```ini
[URL Rewrite]
^http://www\.google\.cn http://www.google.com header
```

### 302 模式

Surge 将直接返回一个 302 重定向响应。如果为主机名启用了 MitM，HTTPS 请求也可以被重定向。

```ini
[URL Rewrite]
^http://yachen\.com https://yach.me 302
```

### Reject 模式

如果模式匹配，则拒绝该请求。替换参数将被忽略。如果为主机名启用了 MitM，HTTPS 请求将被拒绝。

```ini
[URL Rewrite]
^http://ad\.com/ad\.png _ reject
```


# 请求头重写

Surge 可以在客户端发送的请求头或响应头被转发给服务器之前对其进行重写。

示例：

```ini
[Header Rewrite]
http-request ^http://example.com header-add DNT 1
http-request ^http://example.com header-del Cookie
http-request ^http://example.com header-replace User-Agent Unknown
http-response ^http://example.com header-replace-regex Date 2022 2023
```

重写规则由几个部分组成：

1. HTTP 走向：`http-request` 或 `http-response`。旧版本仅支持修改请求，因此这部分可以省略，如下所示：

   ```ini
    [Header Rewrite]
    ^http://example.com header-add DNT 1
   ```
2. URL 正则表达式
3. 动作类型
4. 请求头字段名 (Header field)
5. 值 (不适用于 header-del)
6. 替换模板 (仅适用于 header-replace-regex)

### header-add

向请求头中追加一个新的标头行，即使该标头字段已经存在。

示例：

```ini
[Header Rewrite]
http-request ^http://example.com header-add DNT 1

修改前:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate

修改后:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
DNT: 1
```

### header-del

从请求头中删除某一行。

示例：

```ini
[Header Rewrite]
http-request ^http://example.com header-del DNT

修改前:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
DNT: 1

修改后:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
```

### header-replace

替换请求头中的值。如果该标头字段不存在，则不执行任何操作。

示例：

```ini
[Header Rewrite]
http-request ^http://example.com header-replace DNT 1

修改前:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
DNT: 0

修改后:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
DNT: 1
```

如果你希望在字段存在时添加或替换一条标头行，你可以同时使用 header-add 和 header-del。

```ini
[Header Rewrite]
^http://example.com header-del DNT
^http://example.com header-add DNT 1
```

### header-replace-regex

使用正则表达式和模板替换请求头中的值。如果该标头字段不存在，则不执行任何操作。

```ini
[Header Rewrite]
http-request ^http://example.com header-replace-regex User-Agent Safari Chrome

修改前:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
DNT: 0

修改后:
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Chrome/603.1.30
Accept-Language: en-us
Accept-Encoding: gzip, deflate
DNT: 0
```


# 请求体重写

Surge 可以重写 HTTP 请求或响应的请求体，使用正则表达式替换原始内容。示例：

```ini
[Body Rewrite]
http-request ^http(s)?://example\.com value abc
http-response ^http(s)?://example\.com documents Surge
```

### 语法

每行包含一条重写规则，参数之间以空格分隔，并以 `http-request` 或 `http-response` 开头。第二个参数是用于匹配生效 URL 的正则表达式。第三个参数是用于替换的正则表达式，第四个参数是替换的内容。

`http-response ^https?://example\.com/ regex replacement`

允许在后面继续添加正则表达式和替换内容，以进行连续替换。

```ini
http-response ^https?://example\.com/ regex1 replacement1 regex2 replacement2
http-response ^https?://example\.com/ regex1 replacement1 regex2 replacement2 regex3 replacement3
…
```

1. 如果一个请求匹配到多个请求体重写规则，它们将被按顺序执行。
2. 即使原始请求不包含请求体，仍然可以通过请求体重写生成新内容，例如使用 `^$` 表达式。

### JQ 请求体重写 iOS 5.14.0+ Mac 5.9.0+

你可以使用 JQ 表达式来操作 JSON 请求体。

```ini
http-request-jq url-pattern jq-expexpression
http-response-jq url-pattern jq-expexpression
```

例如：

```ini
http-response-jq ^http://httpbingo.org/anything '.headers |= with_entries(select(.key | test("^X-") | not))'
```


# Mock (本地映射)

你可以模拟 HTTP 服务器并返回静态响应。此功能也可以被称为 Map Local 或 API Mocking。如果你想动态返回响应，请尝试使用脚本 (scripting)。

示例：

```ini
[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
```

### 参数

#### URL 匹配模式 (URL Pattern)

每行通过以空格分隔的多个参数进行定义，其中第一个参数是用于匹配 URL 的正则表达式。如果某个 HTTP 请求（或解密后的 HTTPS 请求）与此表达式匹配，则应用该规则。

#### `data-type`

Surge 目前支持四种数据类型：

* `file`: 返回特定文件或 URL 的内容。
* `text`: 返回数据字段的文本，使用 UTF-8 编码。iOS 5.9.1+ Mac 5.5.1+
* `tiny-gif`: 返回一个 1 像素的 GIF。iOS 5.9.1+ Mac 5.5.1+
* `base64`: 返回使用 Base64 编码的二进制数据。iOS 5.9.1+ Mac 5.5.1+

#### `data`

* 对于 `file` 类型，此字段应为数据文件的路径，相对路径是相对于配置文件的目录。在 macOS 中，也可以使用绝对路径。
* 对于 `text` 类型，此字段即内容本身。
* 对于 `tiny-gif` 类型，此字段没有意义。
* 对于 `base64` 类型，此字段应包含有效的 Base64 数据。

你可以使用 `data-type=text data=""` 来返回空结果。

#### `header`

此参数允许你自定义返回结果的 HTTP 请求头。使用 `|` 来分隔多个键值对。

### 关于 Content-Type

你可以使用 `header` 字段来控制返回结果的 Content-Type。如果未提供，Surge 将会尽可能地补全。

* 对于 `file` 类型，它将尝试把文件扩展名转换为 MIME 类型。如果失败，将使用 `application/octet-stream`。
* 对于 `text` 类型，默认使用 `plain\text`。
* 对于 `tiny-gif` 类型，默认使用 `image/gif`。
* 对于 `base64` 类型，默认使用 `application/octet-stream`。


# 脚本

*由系统自动生成的章节目录，因原始网站中没有该章节的单独页面。*

* [基础 (Basic)](/scripting/common)
* [HTTP 请求 (HTTP Request)](/scripting/http-request)
* [HTTP 响应 (HTTP Response)](/scripting/http-response)
* [规则 (Rule)](/scripting/rule)
* [事件 (Event)](/scripting/event)
* [DNS](/scripting/dns)
* [计划任务 (Cron)](/scripting/cron)


# 基础

*脚本功能需要 Surge iOS 4 或 Surge Mac 3.3.0*

## 脚本 (Scripting)

你可以使用 JavaScript 按照你的意愿扩展 Surge 的能力。

### 脚本段落 (Script Section)

```ini
[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,max-size=16384,debug=true,requires-body=true
script4 = type=dns,script-path=dns.js,debug=true
```

每一行包含两个组成部分：脚本名称和参数。公共参数：

* `type`: 脚本的类型：`http-request`、`http-response`、`cron`、`event`、`dns`、`rule`、`generic`。
* `script-path`: 脚本的路径，可以是相对于配置文件的相对路径、绝对路径或 URL。
* `script-update-interval`: 当为 script-path 使用 URL 时的更新间隔，单位为秒。
* `debug`: 开启调试模式，具有以下效果：
  1. 每次执行脚本前，都会从文件系统重新加载脚本。（仅限 Surge Mac）
  2. 对于 `http-request` 和 `http-response` 脚本，当你使用 `console.log()` 输出日志时，这些消息也会显示在请求的注释 (notes) 中。
* `timeout`: 脚本的最长运行时间。默认值为 5 秒。
* `argument`: 脚本可以通过 `$argument` 获取该值。
* `engine`: 参见本文后半部分。

`http-request` 和 `http-response` 的参数：

* `pattern`: 用于匹配 URL 的正则表达式。
* `requires-body`: 允许脚本修改请求/响应体。默认值为 false。此行为开销很大。仅在必要时开启。
* `max-size`: 允许的请求/响应体的最大大小。默认值为 131072 (128KB)。
* `binary-body-mode`: 仅在 iOS 15 和 macOS 中可用。原始二进制数据将以 `Uint8Array` 而不是字符串值的形式传递给脚本。

脚本功能要求 Surge 将整个响应体数据加载到内存中。巨大的响应体可能会导致 Surge iOS 崩溃，因为 iOS 系统限制了 Network Extension 可以占用的最大内存量。

请仅为必要的 URL 启用脚本。

如果响应体大小超过 `max-size` 的值，Surge 将回退到直通 (passthrough) 模式，并跳过对该请求的脚本处理。

### 基本限制 (Basic Constraints)

脚本允许异步操作。应该调用 `$done(value)` 来表示完成，即使对于不需要结果的脚本也是如此。否则，脚本会因为超时而收到警告。

### 性能 (Performances)

你无需担心脚本的性能。JavaScript 核心非常高效。

### 公共 API (Public API)

#### 基本信息

* **`$network`**

该对象包含网络环境的详细信息。

* **`$script`**
  * `$script.name<String>`: 正在执行的脚本名称。
  * `$script.startTime<Date>`: 当前脚本开始的时间。
  * `$script.type<String>`: 当前脚本的类型。
* **`$environment`**
  * `$environment.system<String>`: iOS 或 macOS。
  * `$environment.surge-build<String>`: Surge 的构建号。
  * `$environment.surge-version<String>`: Surge 的简短版本号。
  * `$environment.language<String>`: 当前 Surge 的 UI 语言。
  * `$environment.device-model<String>`: 当前设备型号。iOS 5.9.0+ Mac 5.5.0+

#### 持久化存储 (Persistent Store)

* **`$persistentStore.write(data<String>, [key<String>])`**

永久保存数据。只允许字符串。如果成功则返回 true。

* **`$persistentStore.read([key<String>])`**

获取保存的数据。返回字符串或 Null。

如果 key 为 undefined，具有相同 script-path 的脚本将共享存储池。使用 key 可以在不同脚本之间共享数据。

提示：Surge Mac 将 `$persistentStore` 数据写入目录 `~/Library/Application Support/com.nssurge.surge-mac/SGJSVMPersistentStore/`。你可以直接在此处编辑文件以进行调试。

#### 控制 Surge

* **`$httpAPI(method<String>, path<String>, body<Object>, callback<Function>(result<Object>))`**

你可以使用 `$httpAPI` 调用所有的 HTTP API 来控制 Surge 的功能。不需要身份验证参数。请参阅 HTTP API 部分以了解可用功能。

#### $httpClient

* **`$httpClient.post(URL<String> 或 options<Object>, callback<Function>)`**

发起 HTTP POST 请求。第一个参数可以是 URL 或选项对象。选项对象示例如下：

```json
{
  url: "http://www.example.com/",
  headers: {
    Content-Type: "application/json"
    },
  body: "{}",
  timeout: 5
}
```

当使用对象作为选项列表时，`url` 是必需的。如果存在 `headers` 字段，它将覆盖所有现有的标头字段。`body` 可以是字符串或对象。如果提供的是对象，它将被编码为 JSON 字符串，并且 'Content-Type' 将设置为 `application/json`。

**callback**

callback: `callback(error, response, data)`

成功时，error 为 null，response 对象包含 `status` 和 `headers` 属性。

相似函数：**`$httpClient.get`**, **`$httpClient.put`**, **`$httpClient.delete`**, **`$httpClient.head`**, **`$httpClient.options`**, **`$httpClient.patch`**。

**选项 (Options)**

* `timeout`: 默认超时时间为 5 秒。你可以使用此选项覆盖它。
* `insecure`: 如果将此选项设置为 true，https 请求将不验证服务器证书。iOS 5.9.0+ Mac 5.5.0+
* `auto-cookie`: 控制是否自动处理 Cookie 相关字段并存储，默认启用。如果关闭，Cookie 标头将作为普通字段传递。iOS 5.9.0+ Mac 5.5.0+
* `auto-redirect`: 控制当遇到 30x HTTP 状态码时是否自动重定向请求，默认启用。iOS 5.9.0+ Mac 5.5.0+

**策略 (Policy)**

你可以指定一个策略来执行请求：

* `policy`: 使用现有的策略名称。
* `policy-descriptor`: 使用带有完整描述符的临时策略。

**二进制数据 (Binary Data) iOS 5.4.1+ Mac 5.0.1+**

你可以将 `TypedArray` 对象作为 body 传递。

此外，你可以使用 `binary-mode` 参数让 Surge 以 `TypedArray` 而不是字符串形式返回响应数据。

```json
{
  url: "http://www.example.com/",
  binary-mode: true
}
```

#### 实用工具 (Utilities)

* **`console.log(message<String>)`**

打印到 Surge 日志文件。

* **`setTimeout(function[, delay])`**

与浏览器中的 setTimeout 相同。

* **`$utils.geoip(ip<String>)`**

执行 GeoIP 查询。结果采用 ISO 3166 代码。

* **`$utils.ipasn(ip<String>)`**

查找 IP 地址的 ASN。

* **`$utils.ipaso(ip<String>)`**

查找 IP 地址的 ASO。

* **`$utils.ungzip(binary<Uint8Array>)`**

解压 gzip 数据。结果也是一个 `Uint8Array`。

* **`$notification.post(title<String>, subtitle<String>, body<String>[, options<Object>])`**

发送通知。

可用选项：iOS 5.11.0+ Mac 5.7.0+

* `action`: 点击通知打开 Surge 后的操作。
  * `open-url`: 打开一个 URL，特定的 URL 由 `url` 参数提供。
  * `clipboard`: 复制内容到剪贴板（需要用户确认），内容通过 `text` 参数提供。
* `media-url`: 为通知提供媒体内容，例如图片。内容应该是一个有效的 URL。
* `media-base64`: 功能同上，但内容直接通过 base64 提供。需要通过 `media-base64-mime` 参数提供内容的 MIME 类型。
* `auto-dismiss`: 布尔值，指示是否在一段时间（通常是 10 秒）后自动关闭通知。
* `sound`: 弹出通知时使用默认推送消息声音。

#### 手动触发 (Manually Trigger)

你可以在 Surge iOS 上长按脚本或使用系统的快捷指令 (Shortcuts) 应用来手动触发脚本。

如果你使用快捷指令触发脚本，你可以选择向脚本传递一个参数，并使用 `$intent.parameter` 来获取它。

### 脚本引擎 (Script Engine) iOS 5.9.0+ Mac 5.5.0+

Surge 目前包含两个 JavaScript 脚本执行引擎。

#### JavaScriptCore (`engine=jsc`)

* 优点：
  1. 引擎初始化快，调用时开销低（低延迟）。
* 缺点：
  1. 由于 JSC 运行在 NE 进程内部，会导致 Surge NE 进程的内存占用显著增加，可能导致系统因超出内存限制而终止。

#### WebView (`engine=webview`)

* 优点：
  1. 由于 WebView 的实际运行环境在另一个独立的进程，脚本的执行对 NE 进程的内存使用几乎没有影响，不会导致 Surge NE 进程因内存占用问题被终止。
  2. WebView 的 JS 执行环境可以使用 JIT，大大提升了复杂或 CPU 密集型脚本的执行效率。
  3. 可以使用 WebAPI。
* 缺点：
  1. 引擎的初始化时间开销略高。
  2. 当脚本与 Surge 之间需要传输大量数据时，由于跨进程通信，效率较低，这在使用 `binary-body-mode` 处理较大请求时尤为明显。

#### 使用建议

1. 对于小型、频繁调用、简单的脚本，如 Rule、DNS 类型的脚本，建议使用 JSC。
2. 对于复杂、高内存消耗的脚本（例如解析 MB 级别 HTTP body 的 JSON），建议使用 WebView。

#### 配置方法

在脚本配置行添加参数：`engine`，可配置为 `auto`、`jsc`、`webview`。

* 默认值为 `auto`，在可用的情况下始终使用 WebView。
* 如果脚本中使用了 WebAPI，应显式配置为 `webview`，以便脚本在不支持 WebView 的环境中执行时提示用户。

#### 引擎可用性

* iOS: JSC 和 WebView
* macOS
  * macOS 10.15 及以下版本: 仅限 JSC
  * macOS 11.0 及以上版本: JSC 和 WebView
* tvOS: 仅限 JSC


# HTTP 请求

使用脚本修改 HTTP 请求。value 字段是一个正则表达式，用于匹配请求的 URL。

传入的参数包含在 `$request` 中：

* `$request.url<String>`: 请求的 URL。
* `$request.method<String>`：请求的 HTTP 方法。
* `$request.headers<Object>`：请求的 HTTP 标头。
* `$request.body<String or Uint8Array>`：请求的 body。仅在 `requires-body = true` 时有效。
* `$request.id<String>`: 用于在不同脚本间保持连续性的唯一 ID。

脚本必须调用 `$done()` 并传入一个对象。该对象可以包含：

* `url<String>`: 使用新的 URL 覆盖旧的 URL。请注意，它不会像 URL Rewrite 那样更新请求头中的 'Host' 字段。如果需要，您必须通过返回修改后的 header 对象来手动更改它。
* `headers<Object>`: 使用新的 headers 覆盖所有旧的 headers。请注意，某些字段（例如 'Content-Length'）可能无法修改。
* `body<String or Uint8Array>`: 使用新的 body 覆盖旧的 body。仅在 `requires-body = true` 时有效。
* `response<Object>`：如果该对象存在，Surge 将直接返回 HTTP 响应，而无需进行真正的网络操作。该对象可以包含：
  * `status<Number>`: 响应的 HTTP 状态码。（可选。默认值：200）
  * `headers<Object>`: 响应的 HTTP 标头。（可选）
  * `body<String or Uint8Array>`: 响应的 HTTP Body。（可选）

您可以调用 `$done();` 来中止请求而不返回任何内容。或者使用 `$done({});` 保持请求不变。

当前版本的一些限制：

* 使用 chunked 编码时，请求的 body 可能无法被覆盖。
* 当请求头中存在 'Expect: 100-continue' 时，请求的 body 可能无法被覆盖。

一个简单的示例：

```javascript
let headers = $request.headers;
headers['X-Modified-By'] = 'Surge';

$done({headers});
```


# HTTP 响应

使用脚本修改 HTTP 响应。value 字段是一个正则表达式，用于匹配请求的 URL。

传入的参数包含 `$request` 和 `$response`：

* `$request.url<String>`: 请求的 URL。
* `$request.method<String>`：请求的 HTTP 方法。
* `$request.id<String>`: 用于在不同脚本间保持连续性的唯一 ID。
* `$request.headers<Object>`：请求的 HTTP 标头。
* `$response.status<Number>`: 响应的 HTTP 状态码。
* `$response.headers<Object>`: 响应的 HTTP 标头。
* `$response.body<String or Uint8Array>`: 响应的 HTTP body，如果未设置 `binary-mode`，则会使用 UTF-8 解码为字符串。仅在 `requires-body = true` 时存在。

脚本必须调用 `$done()` 并传入一个对象。该对象可以包含：

* `body<String or Uint8Array>`: 使用新的 body 覆盖旧的 body。仅在 `requires-body = true` 时有效。
* `headers<Object>`: 使用新的 headers 覆盖所有旧的 headers。请注意，某些字段（例如 'Content-Length'）可能无法修改。
* `status<Number>`: 使用新的状态码覆盖旧的状态码。

您可以调用 `$done();` 来中止请求而不返回任何内容。或者使用 `$done({});` 保持响应不变。

一个简单的示例：

```javascript
let headers = $response.headers;
headers['X-Modified-By'] = 'Surge';

$done({headers});
```


# 规则

使用脚本作为规则。value 字段将被用作规则名称。

`rule ssid-rule script-path=ssid-rule.js`

然后在 `[Rule]` 段落中添加一行：

`SCRIPT,ssid-rule,DIRECT`

脚本应该返回一个带有 `matched` 属性的对象，以指示是否匹配。

传入的参数包括：

* `$request.hostname<String>`
* `$request.destPort<Number>`
* `$request.processPath<String>`
* `$request.userAgent<String>`
* `$request.url<String>`
* `$request.sourceIP<String>`
* `$request.listenPort<Number>`
* `$request.dnsResult<Object>`
* `$request.srcPort<Number>` iOS 5.8.4+ Mac 5.4.4+
* `$request.protocol<Number>` iOS 5.8.4+ Mac 5.4.4+

默认情况下，`SCRIPT` 规则不会触发 DNS 查询。您可以使用 `requires-resolve` 选项来更改此行为。

`SCRIPT,ssid-rule,DIRECT,requires-resolve`

DNS 结果包含在 `$request.dnsResult` 中。

一个简单的示例：

```javascript
var hostnameMatched = ($request.hostname === 'home.com');
var ssidMatched = ($network.wifi.ssid === 'My Home');

$done({matched: (hostnameMatched && ssidMatched)});
```


# 事件

在指定事件发生时执行脚本。value 是事件的名称。目前仅支持一个事件：`network-changed`。

请调用 `$done()` 以完成执行。

## 事件类型 (Event Types)

* `network-changed`: 当系统网络发生变化时触发。

```javascript
// network-changed = script-path=network-changed.js,type=event,event-name=network-changed

$notification.post('DNS Update', $network.dns.join(', '));

$done();
```

* `notification`: 当 Surge 显示通知时触发。即使通知所属的分类被关闭，脚本仍然可以获取该消息。

```javascript
// notification = script-path=notification.js,type=event,event-name=notification

console.log($event.data);

$done();
```


# DNS

使用脚本作为 DNS 解析器。value 字段将被用作名称。

`dns dnspod script-path=dnspod.js`

然后在 `[Host]` 段落中添加一行：

```ini
[Host]
example.com = script:dnspod
*.example.com = script:dnspod
```

传入的参数为 `$domain`。

脚本应该返回以下内容**之一**：

* `address<String>`: 使用此 IP 地址作为结果。它必须是字符串格式的有效 IPv4/IPv6 地址。
* `addresses<Array>`: 使用多个 IP 地址作为结果。
* `server<String>`: 要求 Surge 通过指定的上游 DNS 服务器解析该域名。它必须是字符串格式的有效 IPv4/IPv6 地址。
* `servers<Array>`: 要求 Surge 通过多个指定的上游 DNS 服务器解析该域名。

当返回 `address<String>` 或 `addresses<Array>` 时，还可以返回一个额外的 `ttl`，以将结果添加到缓存中并避免重复查询。单位是秒。

以下是一个示例，使用 DNSPod 的公共 HTTP DNS API 作为 Surge 的解析器：

```javascript
$httpClient.get('http://119.29.29.29/d?dn=' + $domain, function(error, response, data){
  if (error) {
    $done({}); // 回退到标准 DNS 查询
  } else {
    $done({addresses: data.split(';'), ttl: 600});
  }
});
```


# 计划任务

#### 计划任务 (cron)

在指定的时间执行脚本。该值应为 cron 表达式，这是一个由五或六个子表达式（字段）组成的字符串，用于描述排程的具体细节。

一些 cron 表达式示例：

* 每天凌晨 2 点: `0 2 * * *`
* 每天早上 5 点和下午 5 点: `0 5,17 * * *`
* 每分钟: `* * * * *`
* 每秒: `* * * * * *`
* 每个星期日下午 5 点: `0 17 * * sun`
* 每 10 分钟: `*/10 * * * *`

只有一个传入参数：`$cronexp`。

请调用 `$done()` 以完成执行。

一个简单的例子：

```javascript
// cron "0 2 * * *" script-path=cron.js
$surge.setSelectGroupPolicy('Group', 'Proxy');
$done();
```

#### 附加 API (Additional API)

* `$cronexp`: cron 表达式字符串。


# 其他

*由系统自动生成的章节目录，因原始网站中没有该章节的单独页面。*

* [杂项选项 (Misc Options)](/others/misc-options)
* [托管配置 (Managed Profile)](/others/managed-profile)
* [增强模式 (Enhanced Mode)](/others/enhanced-mode)
* [子网设置 (Subnet Settings)](/others/subnet-settings)
* [Host List 参数类型 (Host List Parameter Type)](/others/host-list)
* [URL Scheme](/others/url-scheme)
* [模块 (Module)](/others/module)
* [HTTP API](/others/http-api)
* [信息面板 (Information Panel)](/others/panel)
* [端口转发 (Port Forwarding)](/others/port-forwarding)
* [Surge Mac 命令行 (Surge Mac CLI)](/others/cli)


# 杂项选项

由于选项经常变化，你可以在应用内查找关于 `[General]` 段落选项的最新解释。

* Surge Mac: 主窗口菜单 -> 帮助 -> 配置语法 (Profile Syntax)
* Surge iOS: 更多选项卡 -> 帮助 -> 配置语法 (Profile Syntax)

### loglevel

日志级别。可选值为：`verbose`、`info`、`notify` 或 `warning`。不建议在日常使用中启用 `verbose`，因为这会显着降低性能。

### ipv6

启用完整的 IPv6 支持。具体来说，启用此选项后，在访问域名时将查询域名的 AAAA 记录。即使未启用此选项，你也可以通过直接访问 IPv6 地址来访问 IPv6 站点。

### ipv6-vif

允许 IPv6 流量通过 Surge VIF。当你想让 Surge 处理连接到 IPv6 地址的原始 TCP 连接时非常有用。

* `off`：从不在 Surge VIF 上设置 IPv6。
* `auto`：仅当本地网络具有有效的 IPv6 网络时，才在 Surge VIF 上设置 IPv6。
* `always`：始终在 Surge VIF 上设置 IPv6。

### dns-server

上游 DNS 服务器的 IP 地址。

### skip-proxy

在 iOS 版本中，此选项强制由 Surge VIF 处理对这些域名/IP 范围的连接，而不是由 Surge 代理引擎处理。在 macOS 版本中，当启用“设置为系统代理 (Set as System Proxy)”时，这些设置将应用于系统。此选项用于修复某些应用的兼容性问题。

* 要指定单个域名，请输入该域名 - 例如，apple.com。
* 要指定某个域上的所有网站，请在域名前使用星号 - 例如，\*apple.com。
* 要指定域名的特定部分，请分别指定每个部分 - 例如，store.apple.com。
* 要通过 IP 地址指定主机或网络，请输入特定的 IP 地址，如 192.168.2.11，或地址范围，如 192.168.2.\* 或 192.168.2.0/24。

注意：如果你输入的是 IP 地址或地址范围，你只能在使用该 IP 地址连接到该主机时绕过代理，而不能在通过解析为该地址的域名连接主机时绕过代理。

### exclude-simple-hostnames

与 skip-proxy 参数类似。此选项让直接使用简单主机名（不含点 `.` ）的请求由 Surge VIF 处理，而不是 Surge 代理引擎。

### external-controller-access

此选项允许外部控制器控制 Surge，例如 Surge Dashboard (macOS) 和 Surge iOS Remote Controller (iOS)。例如：`key@0.0.0.0:6165`

### http-api

此选项允许使用 HTTP API 控制 Surge。例如：`key@0.0.0.0:6166`

### http-api-tls

使用 HTTPS 协议代替 HTTP。必须首先配置 MitM CA 证书。你需要手动将证书安装到客户端设备上。

### http-api-web-dashboard

启用此功能后，你可以通过 Web 浏览器控制 Surge。

### show-error-page Mac 5.8.0+

控制当请求失败时（例如因为被策略拒绝或代理无法连接）Surge 是否显示其内置的 HTTP 错误页面。该参数默认启用；如果你更希望客户端收到原始的网络错误而不是 Surge 错误页面，请将其设置为 `false`。

### show-error-page-for-reject

如果请求是纯 HTTP 请求，则为 REJECT 策略显示错误网页。

### full-header-mode

启用后，Surge 会将完整的 HTTP 标头数组（包括重复的标头字段）暴露给请求头重写规则、脚本和抓包。这有助于依赖多个相同标头名称的场景。默认模式为了兼容性仅保留最后一个值。

### tun-excluded-routes

Surge VIF 只能处理 TCP 和 UDP 协议。使用此选项来绕过特定的 IP 范围，允许所有流量通过。

注意：此选项仅适用于 Surge VIF。由 Surge 代理服务器 (Surge Proxy Server) 处理的请求不受影响。将 `skip-proxy` 和 `tun-excluded-routes` 结合使用，可以确保特定的 HTTP 流量绕过 Surge。

当启用 IPv6 VIF 时，支持 IPv6 CIDR 块。

### tun-included-routes

默认情况下，Surge VIF 接口将其自身声明为默认路由。然而，由于 Wi-Fi 接口拥有更小的路由，某些流量可能不会通过 Surge VIF 接口。使用此选项可添加更小的路由。

当启用 IPv6 VIF 时，支持 IPv6 CIDR 块。

### internet-test-url

用于测试互联网连通性的 URL。同时也是 DIRECT 策略的测试 URL。

### proxy-test-url

代理策略的默认测试 URL。

### test-timeout

连通性测试超时时间。

### always-real-ip

此选项要求 Surge 在 Surge VIF 处理 DNS 查询时返回真实 IP 地址，而不是虚假 IP 地址。

DNS 数据包将被转发至上游 DNS 服务器。

此参数属于 Host List 类型，详细规则请见：[Host List 参数类型](/others/host-list)

### hijack-dns

默认情况下，Surge 仅对发送至 Surge DNS 地址 (198.18.0.2) 的 DNS 查询返回虚假 IP 地址。发送至标准 DNS 的查询将被转发。

某些设备或软件总是使用硬编码的 DNS 服务器。（例如，Google Speakers 总是使用 8.8.8.8）。你可以使用此选项劫持该查询以返回虚假地址。

你可以使用 `hijack-dns = *:53` 来劫持所有的 DNS 查询。

虚假 DNS 响应器监听在 `198.18.0.2` (IPv4) 和 `fd00:6152::2` (IPv6)，因此即使是纯 IPv6 网络也可以将其客户端指向 Surge。

### force-http-engine-hosts

让 Surge 将 TCP 连接视为 HTTP 请求。Surge 的 HTTP 引擎将处理这些请求，并且所有高级功能都将可用，例如抓包、重写和脚本。

此参数属于 Host List 类型，详细规则请见：[Host List 参数类型](/others/host-list)

### encrypted-dns-follow-outbound-mode

默认情况下，加密 DNS 查询使用 DIRECT 出站。启用此选项可使 DOH 遵循出站模式设置和规则。

### encrypted-dns-server

加密 DNS 服务器的 URL。如果配置了加密 DNS，传统 DNS 将仅用于测试连通性和解析加密 DNS URL 中的域名。

支持的协议：

* DNS over HTTPS: `https://example.com`
* DNS over HTTP/3: `h3://example.com`
* DNS over QUIC: `quic://example.com`

### encrypted-dns-skip-cert-verification

跳过加密 DNS 服务器证书验证，这并不安全。

### use-local-host-item-for-proxy

默认情况下，如果使用了代理策略，则始终在远程服务器上执行 DNS 查询。启用此选项后，如果目标域名的本地 DNS 映射结果存在，Surge 将使用该 IP 地址而不是域名来建立代理连接。

### geoip-maxmind-url

用于更新的 GeoIP 数据库的 URL。

### disable-geoip-db-auto-update

禁用 GeoIP 数据库的自动更新。

### allow-dns-svcb

iOS 系统可能会执行 SVCB 记录的 DNS 查询，而不是标准的 A 记录查询。这会导致 Surge 无法返回虚拟 IP 地址。因此，默认情况下，禁止进行 SVCB 记录查询，强制系统执行 A 记录查询。

### udp-policy-not-supported-behaviour

当 UDP 流量匹配到一个不支持 UDP 转发的策略时的回退行为。可选值为：`DIRECT`，`REJECT`。从 Surge Mac 6.0.0 开始，默认值为 `REJECT`，以避免在不知情的情况下泄漏流量。

### proxy-test-udp

代理的默认 UDP 测试参数。例如：`apple.com@8.8.8.8`

### udp-priority

启用后，在系统负载非常高且数据包处理出现延迟时，将优先处理 UDP 数据包。又称为游戏模式。

### always-raw-tcp-hosts iOS 5.8.0+ Mac 5.4.0+

Surge 将自动嗅探发送至端口 80 和 443 的 TCP 请求的协议，以启用高级 HTTP/HTTPS 功能，同时优化性能。然而，这可能会导致某些兼容性问题。如果你遇到问题，可以在此处添加主机名，Surge 将不会嗅探这些请求的协议。

此参数属于 Host List 类型，详细规则请见：[Host List 参数类型](/others/host-list)

### always-raw-tcp-keywords Mac 5.5.0+

行为类似于 `always-raw-tcp-hosts`，但通过子串进行匹配而不是使用 Host List。任何包含其中一个关键字的主机名都将跳过协议嗅探并保持在原始 TCP 模式，这在精确主机名不可预测时非常有帮助。

### proxy-restricted-to-lan iOS 5.13.1+ Mac 5.8.1+

### gateway-restricted-to-lan iOS 5.13.1+ Mac 5.8.1+

发现有些用户由于缺乏网络安全知识，意外地将代理和网关服务暴露在互联网上（例如配置了 DMZ）。因此，添加了这两个参数，限制代理和网关服务仅接受来自当前子网设备的访问。这两个参数默认处于开启状态。

### icmp-forwarding iOS 5.14.3+ Mac 5.10.0+

在开启了增强模式后，为了减少对用户的干扰，Surge 会直接转发所有 ICMP 的包，从而不影响 ping 等工具的使用。

但这可能对于部分极度关注隐私的用户来说，会导致 IP 泄漏。所以新增了 icmp-forwarding 选项可以关闭该行为。

默认开启。

### block-quic iOS 5.14.6+ Mac 5.10.3+

该参数用于全局覆盖是否阻断 QUIC 流量的行为，可设置为：

* `per-policy`：由 policy 的 `block-quic` 参数决定。这是默认值，与目前版本的行为一致。
* `all-proxy`：覆盖代理策略的 `block-quic` 参数，全部阻断。
* `all`：覆盖所有策略的 `block-quic` 参数，包括 DIRECT 策略也全部阻断。
* `always-allow`：覆盖代理策略的 `block-quic` 参数，全部放行。

## 仅限 Surge iOS 参数

### allow-wifi-access

允许局域网内的其他设备访问 Surge 代理服务。

### wifi-access-http-port

Surge HTTP 代理服务的端口号。

### wifi-access-socks5-port

Surge SOCKS5 代理服务的端口号。

### wifi-access-http-auth

要求 Surge HTTP 代理服务进行身份验证。例如：`username:password`

### wifi-assist

启用 Wi-Fi 助理。

### hide-vpn-icon

隐藏状态栏中的 VPN 图标。

### all-hybrid

当 Wi-Fi 网络状况不佳时，不只是切换为使用蜂窝数据建立连接，而是始终同时使用 Wi-Fi 和蜂窝数据建立连接。

此选项可以在较差的 Wi-Fi 网络环境下或 Wi-Fi 网络正在切换时显着提升网络体验。

该功能将应用于所有 TCP 连接和 DNS 查询。仅当你的蜂窝数据套餐无限制时才启用此选项。

### allow-hotspot-access

当个人热点开启时，允许其他设备访问 Surge 代理服务。

### include-all-networks

默认情况下，某些请求可能不会被 Surge 接管。例如，应用可以绑定到物理网络接口以绕过 Surge VIF。启用包含所有网络 (Include All Networks) 选项可确保所有请求都由 Surge 处理且不会发生泄漏。当你将 Surge 用作防火墙时，此选项非常有用。（需要 iOS 14.0 或更高版本）

启用此选项可能会导致 AirDrop 和 Xcode 调试问题、通过 USB 连接的 Surge Dashboard 无法工作，以及其他意想不到的副作用。请谨慎使用。

### include-local-networks

启用此选项以使 Surge VIF 能够接管发送至局域网的请求。（需要 iOS 14.2 或更高版本）

启用此选项可能会导致 AirDrop 和 Xcode 调试问题、通过 USB 连接的 Surge Dashboard 无法工作，以及其他意想不到的副作用。请谨慎使用。

必须与 `include-all-networks=true` 结合使用。

### include-apns

启用此选项以使 Surge VIF 处理 Apple Push Notification service (APNs) 的网络流量。

必须与 `include-all-networks=true` 结合使用。

### include-cellular-services

启用此选项以使 Surge VIF 处理蜂窝服务的可路由到互联网的网络流量。（VoLTE、Wi-Fi 通话、IMS、MMS、可视化语音信箱等）

请注意，某些移动运营商直接将蜂窝服务流量路由至运营商网络，绕过了互联网。此类蜂窝服务流量始终被排除在隧道之外。

必须与 `include-all-networks=true` 结合使用。

### compatibility-mode

此选项用于控制 Surge iOS 的工作模式。

* 0: 自动，在低于 5.8.0 版本的 Surge iOS 中等效于 1，从 5.8.0 开始等效于 3。
* 1: Proxy Takeover + VIF，在该模式下，代理接管的优先级高于 VIF 接管，提供了最佳的性能，但有些应用程序可能会检查代理设置并拒绝工作。
* 2: 仅 Proxy Takeover
* 3: 仅 VIF Takeover：最新版本的默认工作模式。
* 4: Proxy Takeover + VIF，但代理使用 VIF 地址而不是回环地址。
* 5: 仅 VIF Takeover，但 VIF 路由使用多个较小的路由进行接管，不配置默认路由，可以用来绕过一些特殊问题。（例如：HomeKit 安防摄像头）

### auto-suspend iOS 5.11.0+

当检测到被 Surge Mac 接管的网络时，自动暂停 Surge iOS。默认开启。

## 仅限 Surge Mac 参数

### use-default-policy-if-wifi-not-primary

如果禁用此项，即使 Wi-Fi 不是主网络接口，SSID/BSSID 模式仍可匹配。

### read-etc-hosts

遵循 `/etc/hosts` 中的本地 DNS 映射项。

### http-listen

HTTP 代理服务监听参数。例如：`0.0.0.0:6152`

### socks5-listen

SOCKS5 代理服务监听参数。例如：`0.0.0.0:6153`

### debug-cpu-usage

启用 CPU 调试模式。这可能会降低性能。

### debug-memory-usage

启用内存调试模式。这可能会降低性能。


# 托管配置

Surge 可以从一个 URL 自动更新配置。如果配置文本以如下行开头：

`#!MANAGED-CONFIG http://test.com/surge.conf interval=60 strict=true`

配置只能在 Surge 主应用运行时进行更新。

请确保新的远程配置也包含 `#!MANAGED-CONFIG` 行。如果没有，该配置将恢复为标准配置。

### 参数

#### interval: 可选，单位为秒 (默认值: 86400秒)

设置配置的更新间隔。请注意，这是触发更新的最短时间；Surge 不一定在达到此时间后立即触发更新。

#### strict: true 或 false (默认值: false)

如果 strict 为 true，Surge 将在间隔时间到达后强制要求更新。否则，如果更新失败，用户仍然可以使用过时的配置。

> 注意：即使 strict 为 true，用户仍然可以通过小组件或系统设置中的 VPN 开关启动 Surge。

### REQUIREMENT 语句

`!REQUIREMENT` 语句可以用在配置行的开头或结尾，以限制该行仅在特定环境下生效，例如：

`#!REQUIREMENT CORE_VERSION>=22 Group = smart, policyA, policyB`

或者

`Group = url, policyA, policyB //!REQUIREMENT CORE_VERSION<22`

可用于条件的变量包括 `CORE_VERSION, SYSTEM, SYSTEM_VERSION, DEVICE_MODEL, LANGUAGE`。

可用的运算符有 `=,==,>=,=>,<=,=<,>,<,!,<>,AND,&&,OR,||,NOT,!,BEGINSWITH,CONTAINS,ENDSWITH,LIKE,MATCHES`。

一个典型的变量值示例：

```yaml
CORE_VERSION: 22
SYSTEM: iOS
SYSTEM_VERSION: System Version 17.4.1 (Build 21E236)
DEVICE_MODEL: iPhone16,1
LANGUAGE: en-US
```

#### Core Version

当 Surge 发布新功能时，通常会向配置中引入新语法，相应的 Core Version 也会增加。这个版本可以用来判断某个功能是否可用，版本号及主要变更如下：

* 22: Surge Mac 5.7.0, Surge iOS 5.11.0, Smart Group (智能组)
* 20: Surge Mac 5.6.0, Surge iOS 5.10.0, Body Rewrite (请求体重写), Inline Map Local (内联映射本地)

在表达式中使用字符串时，字符串应用 `'` 包裹。当表达式包含空格时，应使用 `""` 包裹。

`#!REQUIREMENT "CORE_VERSION>=22 AND SYSTEM=='iOS'" Group = smart, policyA, policyB`

在 UI 中修改配置时会丢失表达式，因此此功能主要用于托管配置和企业配置。

由于早于 Surge iOS 5.11.0 和 Mac 5.7.0 的版本不支持此表达式，因此提供了行首和行尾两种注释方法，允许灵活地支持旧版本。例如，如果您想为支持 Smart Group 的客户端使用它，你可以写：

```ini
#!REQUIREMENT CORE_VERSION>=22 Group = smart, policyA, policyB
Group = url-test, policyA, policyB //!REQUIREMENT CORE_VERSION<22
```

由于第一行在旧版本中被视为纯注释，因此不会生效，第二行的行尾注释也将被视为普通注释。只有第二行会生效。

### FORBIDDEN-AUTO-UPGRADE 语句

从 Surge iOS 5.11.0 和 Mac 5.7.0 版本开始，Surge 可以自动为升级优化配置，以避免因托管配置未及时调整而无法使用最新功能。

如果出于某些特殊原因，你不希望配置应用某些自动优化，可以使用 `FORBIDDEN-AUTO-UPGRADE` 表达式，例如：

`#!FORBIDDEN-AUTO-UPGRADE smart-group`

目前可用的优化关键字包括：

* `smart-group`：自动将 `url-test/load-balance` 组升级为 `smart` 组。


# 增强模式

## 增强模式 (Enhanced Mode - Surge Virtual Network Interface, VIF)

某些应用程序可能不遵循系统代理设置。在 Surge 中使用增强模式可以确保所有应用程序的流量都被处理。

为了实现这一点，Surge 创建了一个虚拟网络接口 (VIF) 并将其注册为默认路由。所有的 DNS 查询都会返回一个 198.18.0.0/15 网段中的虚拟 IP 作为响应。

需要注意的是，Surge VIF 只能处理 TCP、UDP 和 ICMP 流量。因此，仅在必要时启用此功能。此外，由于无法代理 ICMP 流量，Surge VIF 会直接返回响应。

增强模式在 Surge iOS 上默认启用，而在 Surge Mac 上，必须手动启动。

从 Surge Mac 5.8.0 开始，增强模式由 Apple 的 Network Extension 框架驱动，取代了旧版的 utun 驱动。配置文件中的旧参数（如 `vif-mode`）保留用于向后兼容，但不再影响运行时的行为。

## Surge VM 网关 (Surge VM Gateway)

#### UDP 快速路径 (UDP Fast Path) Mac 6.4.0+

当 Surge Mac 运行在网关虚拟机 (Gateway VM) 模式时，创建数千个短生命周期 UDP 流的设备（如 P2P 下载器或网络游戏）可能会耗尽标准的四层代理引擎。UDP 快速路径功能会在这些高连接数客户端超过阈值（1 秒内 10 个连接或 10 秒内 30 个连接）时，自动将其降级为轻量级的 L3 转发模式。

* 通过快速路径转发的数据包完全绕过了代理引擎，因此无法被规则或 MITM 匹配。
* 低于 1024 的目标端口保持在正常模式，以保留与常用服务的兼容性。
* 如果你需要将客户端固定在某一种行为，可以从 Dashboard/设备列表中为每个客户端设备切换快速路径设置。


# 子网设置

你可以使用[子网表达式 (subnet expression)](/rule/subnet)来匹配指定的网络并应用特定设置。

> 出于兼容性原因，子网设置在配置中被命名为 `[SSID Setting]`。

### 挂起 (Suspend)

在指定的网络下临时挂起 Surge。

```ini
[SSID Setting]
SSID:MyHome suspend=true
```

### 蜂窝网络回退 (Cellular Fallback) (仅限 iOS)

控制指定 Wi-Fi 网络的 Wi-Fi 助理 (Wi-Fi assist) 和混合网络 (Hybrid Network) 行为。

```ini
[SSID Setting]
SSID:MyHome cellular-fallback=off
```

* `cellular-fallback=default` 使用全局的 Wi-Fi 助理和混合网络设置。
* `cellular-fallback=off` 为该网络关闭 Wi-Fi 助理和混合网络。
* `cellular-fallback=hybrid` 为该网络开启混合网络。
* `cellular-fallback=wifi-assist` 为该网络开启 Wi-Fi 助理。

### TCP Fast Open 行为 (TCP Fast Open Behaviour)

```ini
[SSID Setting]
SSID:MyHome tfo-behaviour=force-enabled
```

* `tfo-behaviour=auto` 使用默认的 TFO 行为。
* `tfo-behaviour=force-disabled` 完全为该网络禁用 TFO。
* `tfo-behaviour=force-enabled` 强制为该网络开启 TFO。此选项会使 Surge 忽略系统的 TFO 黑洞检测机制。

### DNS 覆盖 (DNS Override)

覆盖指定网络的 DNS 设置。

```ini
[SSID Setting]
SSID:MyHome dns-server=8.8.8.8,encrypted-dns-server=https://1.1.1.1/
```

如果加密 DNS 是在全局 DNS 设置中配置的，你必须在下面显式输入关键字 `off` 以使用传统 DNS。

```ini
[SSID Setting]
SSID:MyHome dns-server=8.8.8.8,encrypted-dns-server=off
```


# Host List 参数类型

在 Surge 中，许多参数使用 Host List 类型来适应各种复杂的需求，例如 `force-http-engine-hosts`、`always-raw-tcp-hosts`、`[MITM]` 的 `hostname` 等。

Host List 类型的参数是一个由 `,` 分隔的列表，并遵循以下规则：

* 使用前缀 `-` 来排除一个主机名。
* 支持通配符 `*` 和 `?`。
* 列表中的项目将按顺序匹配，一旦匹配成功，就会结束匹配过程。因此，排在前面的项目具有更高的优先级。特别是当使用 `-` 前缀时，你应该把需要排除的主机名写在前面。
* 如果未提供端口号，Surge 会自动追加该参数的标准端口号，例如对于 `force-http-engine-hosts` 参数，如果仅配置了主机名，它将仅对 80 端口生效。对于 MITM 功能，它将仅对 443 端口生效。
* 使用后缀 `:port` 来匹配其他端口。
* 使用后缀 `:0` 来匹配所有端口。
* 使用 `<ip-address>` 直接匹配所有使用 IPv4/IPv6 地址而不是域名的主机名。
* 使用 `<ipv4-address>` 直接匹配所有使用 IPv4 地址而不是域名的主机名。
* 使用 `<ipv6-address>` 直接匹配所有使用 IPv6 地址而不是域名的主机名。

以 `force-http-engine-hosts` 参数为例：

* `-*.apple.com`：排除所有发往 `*.apple.com` 的 80 端口请求。
* `www.google.com`：对 `www.google.com` 的 80 端口使用强制 HTTP 处理。
* `www.google.com:8080`：对 `www.google.com` 的 8080 端口使用强制 HTTP 处理。
* `www.google.com:0`：对 `www.google.com` 的所有端口使用强制 HTTP 处理。
* `*:0`：对所有主机名的所有端口使用强制 HTTP 处理。
* `-<ip-address>`：排除所有直接使用 IPv4/IPv6 地址的请求。

### 示例

在为 MITM 配置 hostname 时，如果你想解密所有的 HTTPS 连接，但排除那些由于证书固定 (certificate pinning) 而无法解密的知名主机名，你可以这样写：

```ini
[MITM]
hostname = -*icloud*, -*.mzstatic.com, -*.facebook.com, -*.instagram.com, -*.twitter.com, -*dropbox*, -*apple*, -*.amazonaws.com, -<ip-address>, *
```


# URL Scheme

### Surge iOS 的 URL Scheme

Surge iOS 支持 4 种动作和 1 个选项。

动作 (Action):

* `surge:///start`

  使用选定的配置启动。
* `surge:///stop`

  停止当前会话。
* `surge:///toggle`

  使用选定的配置启动或停止。
* `surge:///install-config?url=x`

  从 URL 安装配置。该 URL 应使用百分号编码。

选项 (Option):

* `autoclose=true`

  动作完成后自动关闭 Surge。（不能与 `install-config` 一起使用）

  示例：`surge:///toggle?autoclose=true`

### x-callback-url

Surge 从 v3.4 开始支持 `x-callback-url` 规范。URL Scheme 为 `surge`，可用的动作为 `start`、`stop` 和 `toggle`。


# 模块

模块是一组用于覆盖当前配置的设置。你可以使用模块来：

* 调整不可编辑配置（如托管配置和企业配置）中的设置。
* 一键更改部分设置。例如，你可以使用模块为所有主机名开启 MitM，并临时调整过滤器。
* 使用别人编写的模块来完成特定任务。例如，你的同事可能与你分享了一个将 API 请求重写为测试服务器的模块。
* 当你在多台设备之间共享同一个配置时，针对不同的场景可能需要修改某些设置。模块的启用状态不会同步到其他设备，因此你可以使用模块来满足这一需求。

### 基本概念

模块就像是对当前配置的补丁 (patch)。模块中的设置优先级高于配置中的设置。

共有 3 种类型的模块：

* 内部模块 (Internal Modules)：由 Surge 本身提供。
* 本地模块 (Local Modules)：放置在配置目录中的 `.sgmodule` 文件。
* 已安装模块 (Installed Modules)：通过 URL 安装的模块。

### 编写模块

模块的语法与配置相同。允许你覆盖以下段落：

* `[General]`, `[MITM]`
  * 覆盖：`key = value`
  * 追加至原始值：`key = %APPEND% value`
  * 在原始值最前面插入：`key = %INSERT% value`

    你只能在 `[MITM]` 段落中操作 `hostname`、`skip-server-cert-verify` 和 `tcp-connection` 字段。

    > 用于 HTTP 抓包功能的旧版 `[Replica]` 段落在 Surge Mac 5.4.0 中已被移除，因此模块不再需要对其进行补丁。
* `[WireGuard *]` 段落

  WireGuard 策略存在于名称以 `WireGuard` 开头的段落中。模块可以像覆盖主配置一样，覆盖或追加这些段落内部的键值。
* `[Ruleset *]` 段落

  当你定义内联规则集 (inline rulesets) 时，模块现在也可以对它们进行补丁，这对于提供内联列表的托管配置非常有用。
* Rule, Script, URL Rewrite, Header Rewrite, Host

  新行将插入到原始内容的顶部。

  模块中的规则只能使用内部策略：`DIRECT`、`REJECT` 和 `REJECT-TINYGIF`。
* Metadata (元数据)

  你可以在模块文件中添加元数据：

  ```ini
    #!name=模块名称
    #!desc=模块的描述
  ```

  你可以将模块限制为仅在指定平台生效。（可选）

  ```ini
    #!system=mac
  ```

### 示例：

```ini
#!name=MitM All Hostnames
#!desc=对所有 443 端口的主机名执行 MitM，排除苹果和其他无法被检查的常见站点。你仍然需要配置 CA 证书并打开 MitM 的总开关。

[MITM]
hostname = -*.apple.com, -*.icloud.com, -*.mzstatic.com, -*.crashlytics.com, -*.facebook.com, -*.instagram.com, *
```

```ini
#!name=Game Console SNAT
#!desc=让 Surge 正确处理 PlayStation、Xbox 和 Nintendo Switch 的 SNAT 对话。仅当 Surge Mac 作为这些设备的路由器时才有用。
#!system=mac
[General]
always-real-ip = %APPEND% *.srv.nintendo.net, *.stun.playstation.net, xbox.*.microsoft.com, *.xboxlive.com
```

### 参数表 Mac 5.5.0+

使用 `#!arguments` 元数据来声明用户在启用模块时可以自定义的参数。其语法遵循标准的查询字符串 (query-string)：

```ini
#!arguments=hostname=example.com&enable_mitm=true
```

每个键 (key) 会成为可用的占位符，如 `%hostname%`、`%enable_mitm%` 等，Surge 会在应用模块之前进行简单的文本替换。在 `#!arguments` 中定义的默认值会在 UI 中显示，并与该模块实例一起保存。

> 请保持占位符为字母数字组合（例如，`%SERVER_HOST%`），以避免与配置语法发生冲突。删除参数时请移除未使用的占位符。

### 运行环境要求 (Requirements) iOS 5.10.0+ Mac 5.6.0+

模块添加了 `#!requirement=` 声明，以支持更复杂的使用条件限制。例如，如果模块使用了新加的 Body Rewrite 功能，它需要限制 Surge 核心版本。

`#!requirement=CORE_VERSION>=20`

它也支持逻辑表达式，例如：`CORE_VERSION>=20 && (SYSTEM = 'iOS' || SYSTEM = 'tvOS')`。

可用于判断的变量如下：

* CORE\_VERSION: 数字，例如 `20`
* SYSTEM: 字符串，例如 `macOS`、`iOS`、`tvOS`
* SYSTEM\_VERSION: 字符串，例如 `Version 17.4.1 (Build 21E236)`
* DEVICE\_MODEL: 字符串，例如 `Mac15,8`
* LANGUAGE: 字符串，例如 `zh-Hans`


# HTTP API

你可以使用 HTTP API 来控制 Surge。

## 配置

```ini
[General]
http-api = examplekey@0.0.0.0:6171
http-api-tls = false
```

## 身份验证

所有请求的 'X-Key' 请求头中必须填入 API 密钥。

```http
GET /v1/events
X-Key: examplekey
Accept: */*
```

在某些特定情况下，如果不方便设置请求头，你也可以通过 URL 参数进行传递。例如，直接通过浏览器下载 CA 证书。

```
http://127.0.0.1:6171/v1/mitm/ca?x-key=examplekey
```

## HTTPS(TLS)

设置 `http-api-tls = true` 可以为 HTTP API 服务启用 HTTPS 支持。Surge 将使用 MITM 的 CA 证书为相应的访问地址生成服务器证书。

## 基本限制

目前仅支持不带 TLS 的 HTTP。Surge 仅使用 GET 和 POST 方法。

* 对于 GET 方法，你应该使用 URL 参数发送参数。
* 对于 POST 方法，你应该使用 JSON 请求体发送参数。

Surge 将始终返回一个 JSON 请求体作为响应。

## 路径 (Paths)

### 切换功能状态 (Toggle capabilities)

* GET /v1/features/mitm
* POST /v1/features/mitm
* GET /v1/features/capture
* POST /v1/features/capture
* GET /v1/features/rewrite
* POST /v1/features/rewrite
* GET /v1/features/scripting
* POST /v1/features/scripting
* GET /v1/features/system\_proxy (仅限 Surge Mac)
* POST /v1/features/system\_proxy (仅限 Surge Mac)
* GET /v1/features/enhanced\_mode (仅限 Surge Mac)
* POST /v1/features/enhanced\_mode (仅限 Surge Mac)

使用 GET 方法获取某个功能的状态。

GET 响应示例：

```json
{"enabled":true}
```

使用 POST 方法调整某个功能的状态。

POST 请求示例：

```json
{"enabled":true}
```

### 出站模式 (Outbound Mode)

* GET /v1/outbound
* POST /v1/outbound

使用 GET 获取出站模式，使用 POST 更改它。

GET 响应示例：

```json
{"mode":"rule"}
```

POST 请求示例：

```json
{"mode":"rule"}
```

可能的模式：direct, proxy, rule

* GET /v1/outbound/global
* POST /v1/outbound/global

获取或更改全局出站模式的默认策略。

GET 响应示例：

```json
{"policy":"ProxyA"}
```

POST 请求示例：

```json
{"policy":"ProxyB"}
```

### 代理策略 (Proxy Policy)

* GET /v1/policies

列出所有策略。

* GET /v1/policies/detail?policy\_name=ProxyNameHere

获取策略的详细信息。

* POST /v1/policies/test

使用 URL 测试策略。

请求示例：

```json
{"policy_names": ["ProxyA", "ProxyB"], "url": "http://bing.com"}
```

* GET /v1/policy\_groups

列出所有策略组及其选项。

* GET /v1/policy\_groups/test\_results

获取 url-test/fallback/load-balance 组的测试结果。

* GET /v1/policy\_groups/select?group\_name=GroupNameHere

获取手动选择组 (select group) 的选项。

响应示例：

```json
{"policy": "ProxyA"}
```

* POST /v1/policy\_groups/select

更改手动选择组 (select group) 的选项。

请求示例：

```json
{"group_name": "GroupA", "policy": "ProxyA"}
```

* POST /v1/policy\_groups/test

立即测试一个策略组。

请求示例：

```json
{"group_name": "GroupA"}
```

响应示例：

```json
{
    "available": [
        "ProxyA",
        "ProxyB"
    ]
}
```

### 请求 (Requests)

* GET /v1/requests/recent

列出最近的请求。

* GET /v1/requests/active

列出所有活动的请求。

* POST /v1/requests/kill

终止一个活动的请求。

请求示例：

```json
{"id": 100}
```

### 配置 (Profiles)

* GET /v1/profiles/current?sensitive=0

获取当前配置的文本内容。如果 'sensitive' 为 false，则所有密码字段都将被掩码隐藏。

* POST /v1/profiles/reload

立即执行配置重新加载。

* POST /v1/profiles/switch (仅限 Surge Mac)

请求示例：

```json
{"name": "Profile2"}
```

切换到另一个配置。

* GET /v1/profiles (仅限 Mac 4.0.6+)

获取所有可用的配置名称。

* POST /v1/profiles/check (仅限 Mac 4.0.6+)

请求示例：

```json
{"name": "Profile2"}
```

检查配置。如果配置无效，将返回一个错误。否则 "error" 字段将为 null。

### DNS

* POST /v1/dns/flush

清除 DNS 缓存。

* GET /v1/dns

获取当前的 DNS 缓存内容。

* POST /v1/test/dns\_delay

测试 DNS 延迟。

## 模块 (Modules)

* GET /v1/modules

列出可用和启用的模块。

响应示例：

```json
{
    "enabled": [
        "router.com"
    ],
    "available": [
        "Game Console SNAT",
        "Google Home Devices",
        "router.com",
        "MitM All Hostnames"
    ]
}
```

* POST /v1/modules

启用或禁用模块。

请求示例：

```json
{
    "router.com": false,
    "Google Home Devices": true
}
```

### 脚本 (Scripting)

* GET /v1/scripting

列出所有脚本。

* POST /v1/scripting/evaluate

在模拟环境中执行脚本。

请求示例：

```json
{
    "script_text": "The content of JS script",
    "mock_type": "cron",
    "timeout": 5
}
```

* POST /v1/scripting/cron/evaluate

立即执行一个 cron 脚本。

请求示例：

```json
{
    "script_name": "script1"
}
```

### 设备管理 (Device Management) (仅限 Mac 4.0.6+)

* GET /v1/devices

获取当前活动的和已保存的设备列表。

* GET /v1/devices/icon?id={iconID}

获取设备的图标。你可以从 `device.dhcpDevice.icon` 中获取 iconID。

* POST /v1/devices

更改设备属性。`physicalAddress` 字段为必填。你可以调整 `name`、`address` 和 `shouldHandledBySurge` 中的一个或多个属性。

请求示例：

```json
{
    "physicalAddress":"F0:9F:C2:00:00:00",
    "name": "Computer",
    "address": "192.168.1.200",
    "shouldHandledBySurge": true
}
```

### 杂项 (Misc)

* POST /v1/stop

关闭 Surge 引擎。如果在 Surge iOS 上启用了 Always On，Surge 引擎将会重新启动。

* GET /v1/events

获取事件中心的内容。

* GET /v1/rules

获取规则列表。

* GET /v1/traffic

获取流量信息。

* POST /v1/log/level

更改当前会话的日志级别。

请求示例：

```json
{"level": "verbose"}
```

* GET /v1/mitm/ca

获取 MITM 的 CA 证书，采用 DER 二进制格式。（仅包含证书，不包含私钥）


# 信息面板

Surge iOS 4.9.3 增加了一项实验性功能，允许用户自定义一个或多个信息面板以显示相关信息。

要访问此功能，用户需要拥有在 2021 年 9 月 22 日之后到期的有效订阅。如果订阅已过期且配置中仍有 Panel 字段，该面板将不会显示，但不会影响其他功能的正常使用。示例：

```ini
[Panel]
PanelA = title="Panel Title",content="Panel Content\nSecondLine",style=info
```

支持的 `style` 参数有 `good`、`info`、`alert`、`error`。

`PanelA` 是信息面板的名称，此参数将在脚本模式下传递给脚本。

### 静态模式 (Static mode)

上述配置生成的面板是静态的，它可以与托管配置或企业配置结合使用，以便在更新配置时更新面板内容，并为最终用户提供操作指南。

### 动态模式 (Dynamic Mode)

面板的内容可以通过脚本进行更新。

```ini
[Panel]
PanelB = title="Panel Title",content="Panel Content\nSecondLine",style=info,script-name=panel

[Script]
panel = script-path=panel.js,type=generic
```

新版本还引入了 `generic` 类型的脚本。当用户点击刷新按钮时，脚本将使用以下参数执行：

`$input : { purpose: "panel", position: "policy-selection", panelName: "PanelB" }, $trigger: "button" // 或 "auto-interval"`

脚本应在 `$done()` 中返回 `title`、`content` 和 `style` 字段。

在脚本首次执行之前，面板使用定义行中的静态内容。运行后，Surge 将自动缓存最后一次脚本的返回结果，并在执行刷新前始终显示最后一次脚本的结果。

脚本示例：

```javascript
$httpClient.get("https://api.my-ip.io/ip", function(error, response, data){
    $done({
        title: "External IP Address",
        content: data,
    });
});
```

此外，你还可以指定 `update-interval` 参数使面板自动更新。

```ini
[Panel]
PanelB = title="Panel Title",content="Panel Content\nSecondLine",style=info,script-name=panel,update-interval=60
```

自动更新仅在用户切换到策略选择视图时发生。因此，你可以在这里指定一个较小的时间（例如 1），使面板每次都自动更新。

## 更多自定义 (More customization)

* 当不传入 `style` 字段时，卡片将不显示图标，仅显示文本。
* 当不传入 `style` 字段时，可以传入 `icon` 字段以使用任何有效的 SF Symbol Name 自定义图标，例如 `bolt.horizontal.circle.fill`。
* 使用 `icon` 字段时，传入 `icon-color` 字段以控制图标的颜色，该值为颜色的 HEX 代码。


# 端口转发

Surge 可以监听特定的本地端口，并将来自该端口的 TCP 请求转发到特定的主机。当 Surge 的请求处理（系统代理或增强模式）未启用时，此功能可以独立使用。

配置示例：

```ini
[Port Forwarding]
0.0.0.0:6841 localhost:3306 policy=SQL-Server-Proxy
```

`policy` 参数是可选的；如果未指定，将使用标准的代理匹配来决定策略。

此功能通常用于开发和调试场景，例如使用 SSH 连接到像 MariaDB 这样的服务器。


# Surge Mac CLI

Surge Mac 提供了一个简单的 CLI 程序，以便于控制。你可以在 `/Applications/Surge.app/Contents/Applications/surge-cli` 找到它。

使用 `--help` 可以获取最新的手册。

```
可用命令：
  reload - 重新加载主配置
  switch-profile <profile-name> - 切换到另一个配置

  stop - 关闭 Surge
  unattended-upgrade - 如果有可用更新，则执行无人值守的 Surge 升级

  dump active - 显示所有活动连接
  dump request - 显示最近的连接
  dump rule - 显示所有生效的规则
  dump policy - 显示所有代理和策略组
  dump dns - 显示 DNS 缓存
  dump profile [original / effective] - 显示原始配置和被模块修改后的有效配置
  dump event - 显示事件

  watch request - 持续跟踪新请求

  environment - 显示环境变量设置
  set <key-path> <value> - 修改环境变量设置

  test-network - 测试网络延迟
  test-policy <policy-name> - 测试一个代理
  test-all-policies - 测试所有代理
  test-group <group-name> - 立即重新测试一个策略组

  kill <connection-id> - 终止一个活动连接
  flush dns - 清除 DNS 缓存
  diagnostics - 运行网络诊断
  set-log-level <log-level> - 更改日志级别而不写入配置文件

  script evaluate <script-js-path> [mock-script-type] [timeout] - 从文件加载脚本并执行

可用参数：
  --raw - 以原始 JSON 格式输出结果
  --remote/-r - 连接到远程 Surge 实例而不是本地。例如：--remote password@192.168.2.2:6170
```


# 更新日志

由于内容过多，而且很多就是老信息，所以随缘更新，可能只会翻译后来更新的内容


# Surge Mac

### **Version 4.1.0**

#### **脚本**

你现在可以通过 UI 界面配置脚本了。

#### **配置文件**

你现在可以把配置文件中的部分段落用单独的一个文件写。详情参考：<https://surge.mitsea.com/overview/configuration。>

#### **HTTP API**

1. 添加了关于配置文件的 HTTP API，包括 GET /profiles 和 POST /profiles/check。
2. 添加了关于设备管理的 HTTP API，包括 GET /devices、POST /devices 和 GET /devices/icon。
3. HTTP API、代理服务、外部控制器（external controller）现在都支持监听 IPv6 地址了（UI 界面尚无，需要手动在配置文件里配置）。
4. 你可以用 http-api-tls=true 来为 HTTP API 启用 TLS（HTTPS-API）。

#### **自动化改进**

外部资源在 Surge 启动时就会更新，并且当应用一个配置文件时会自动下载其中引用的外部资源。

#### **其他改进**

1. 新的规则类型：SUBNET，可以用通配符匹配 SSID、BSSID 和 路由IP地址。
2. 当处理大量请求的时候，Dashboard 性能有显著提升。

#### **下载地址**

<https://dl.nssurge.com/mac/v4/Surge-4.1.0-1298-f07b1b8713b2397518f4b252b5786452.zip>

### **Version 4.0.5**

#### **Policy Group**

In this release, we completely refactored the policy group functionality, bringing the following changes:

1. The url-test/fallback/load-balance policy group can no longer be configured with a specific testing URL but with a global testing URL or a policy-configured testing URL. The policy's test results can be used directly in all policy group decisions, eliminating the need to retest each policy group individually.
2. All types of policy groups support mixed nesting. The only requirement is that no circular references can be used.
3. When a group policy is used as a sub-policy of the url-test/fallback/load-balance group.
   * The latency of the select/url-test/fallback/ssid group is the latency of the selected policy.
   * The latency of the load-balance group is the average of the latencies of all available policies.
4. The timeout parameter of a policy group marks policies with latency exceeding this parameter as unavailable when making decisions for the group. But the maximum time taken to test the policy group is controlled by the global test-timeout parameter. (Default is 5s)
5. When testing a group due to decision making, all sub-policies that the group may use are tested, including sub-policies of the sub-policy group.
6. You may use no-alert=true parameter to suppress notifications for particular groups.

#### **Cloud Notification**

You can receive the notifications on iOS devices. Enable this option first and then configure it on Surge iOS. The two device must use a same iCloud account.

#### **Minor Changes**

* Bug fixes.

<https://dl.nssurge.com/mac/v4/Surge-4.0.5-1262-db70f680cd0f15236c8415ec7b804c3a.zip>

### **Version 4.0.4**

* Bug fixes.

<https://dl.nssurge.com/mac/v4/Surge-4.0.4-1227-9acb8b9e3f39e9048fc82e427184a4af.zip>

### **Version 4.0.3**

* You may override the testing URL of a policy for network diagnostics and activity cards.
* The GeoIP database can be updated automatically in the background.
* Bug fixes.

<https://dl.nssurge.com/mac/v4/Surge-4.0.3-1224-4ef8ae10c8a74c395bb4b6c3f6af6af6.zip>

### **Version 4.0.2**

* You may now customize the GeoIP database updating URL.
* tun-excluded-routes and tun-included-routes are now available for Surge Mac.
* Bug fixes.

<https://dl.nssurge.com/mac/v4/Surge-4.0.2-1219-dbd08724b90aa8b444cd6d0679a245b5.zip>

### **Version 4.0.1**

* You may configure the proxy chain with the UI now.
* Fixed some visual inconsistency under reducing transparency mode.
* Bug fixes.

<https://dl.nssurge.com/mac/v4/Surge-4.0.1-1207-ee7bea1b244950c82a6f90e060fa2d89.zip>

### **Version 4.0.0**

* The first version of 4.0.0.

<https://dl.nssurge.com/mac/v4/Surge-4.0.0-1191-d8140b0084223fd3fc4335e4414c0884.zip>

## **Surge Mac V3**

### **Version 3.5.8**

* Bug fixes

<https://dl.nssurge.com/mac/v3/Surge-3.5.8-1130.zip>

### **Version 3.5.7**

* Bug fixes

<https://dl.nssurge.com/mac/v3/Surge-3.5.7-1129.zip>

### **Version 3.5.5**

#### **Minor Changes**

* All URL resources now support URLs with a username and password (e.g. [https://user:pass@example.com](https://user:pass@example.com/)), including managed profile, external resources, and importing profile form URL.
* You may switch among the main views with shortcut keys.
* Bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.5.5-1123.zip>

### **Version 3.5.4**

#### **Changes in Policy Group**

* New parameter: policy-regex-filter. If the parameter is configured, only matched policy line will be used.

#### **Minor Changes**

* Provides more details for the TLS handshake error.
* Increases the file description limitation alert threshold.

<https://dl.nssurge.com/mac/v3/Surge-3.5.4-1119.zip>

### **Version 3.5.3**

#### **New Parameter: use-local-host-item-for-proxy**

`[General]`

`use-local-host-item-for-proxy = true`

If use-local-host-item-for-proxy is true, Surge sends the proxy request with the IP address defined in the \[Host] section, instead of the original domain.

#### **Changes in Load Balance Group**

* load-balance group now supports connectivity testing before being used. Add 'url' parameter to enable it.
* Parameters 'timeout', 'interval' and 'evaluate-before-use' are also available.

#### **Minor Changes**

* Surge will send an ICMP port unreachable message if UDP forwarding fails.
* Eliminate unnecessary local DNS lookup while forwarding UDP traffic to a proxy server.
* Fixed a bug that connecting to Surge iOS via USB is not working in Surge Dashboard.

<https://dl.nssurge.com/mac/v3/Surge-3.5.3-1094.zip>

### **Version 3.5.2**

#### **SSID Suspend**

* Surge Mac supports SSID suspend now. The system proxy and enhanced mode will be temporarily suspended under specified SSIDs.
* The name of WiFi can be an SSID, a BSSID, or a gateway IP address.
* No UI configuration in the current version.

#### **REJECT-DROP**

* REJECT-DROP policy is now effective to proxy connections. The connections matched with a REJECT-DROP policy will be closed in 60-120s later without any data returned.

#### **Global Proxy**

* You may now select and view sub-policy for policy groups while using the global proxy mode.

<https://dl.nssurge.com/mac/v3/Surge-3.5.2-1082.zip>

### **Version 3.5.1**

#### **New rule type: DOMAIN-SET**

* DOMAIN-SET is just like RULE-SET. But it is designed a large number of rules and highly efficient.
* Unlike RULE-SET, you can only write hostnames (domain or IP address) in it. One hostname per line.
* You may use "." prefix to include all sub-domains.

#### **Changes in SRC-IP**

* SRC-IP rule now supports IP-CIDR for both IPv4 and IPv6.

#### **Changes in DNS over HTTPS**

* From this version, if DNS-over-HTTPS is configured, the traditional DNS will only be used to test the connectivity and resolve the domain in the DOH URL.
* The DNS over HTTPS now has a separate parameter: doh-server. The DOH servers in 'dns-server' will be moved to the new parameter after saving.
* The legacy DNS is always required now.
* DOH can be matched with rule 'PROTOCOL,DOH' now.
* Added a new parameter 'doh-follow-outbound-mode'. In the previous version, the DOH client follows the system proxy settings. From this version, all DOH requests will use DIRECT policy by default. If 'doh-follow-outbound-mode' is set, the DOH requests will follow the outbound mode settings regardless of the system proxy settings.
* We are refactoring the HTTP client for DOH and scripting. Please feedback if you encounter any issue.

#### **Changes in Scripting**

* Added a simple view to test the script. You may find it in the Window menu.

#### **Minor Changes**

* Fixed a crash in Dashboard while using search.
* Bug fixes.

#### **Known Issues**

* You may not configure DOH with UI in this version temporarily.

<https://dl.nssurge.com/mac/v3/Surge-3.5.1-1069.zip>

### **Version 3.5.0**

* New feature: Module, which can override the current profile with a set of settings. Highly flexible for diverse purposes. See the post in the community for more information: <https://community.nssurge.com/d/225-module>.
* You may enable modules in the menu now.
* You may view the detail of a module by double clicking.
* Supports pattern filter for Dashboard requests.
* Added a new rule type: PROTOCOL. The possible values are HTTP, HTTPS, SOCKS, SNELL, TCP, UDP.
* You may now use UI to add and edit load-balance group.
  * DNS over HTTP (DoH) now uses DNS wireformat by default. You may configure doh-format=json in \[General] to continue using JSON format.
  * TCP connection setup optimizations.
  * Bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.5.0-1039.zip>

### **Version 3.4.0**

* Snell protocol now upgrade to version 2, supporting to reuse TCP connections to improve performance. <https://github.com/surge-networks/snell/releases>
* Supports a new proxy protocol: Trojan.
* Remote Dashboard now upgraded to Remote Controller. You may use Surge iOS to select policy group, toggle HTTP capture/MitM, and switch outbound mode remotely.
* The comment lines in the text config won't lost after editing with UI.
* You may open the new connection window of Dashboard by holding the Option key while clicking the Dashboard item in the main menu.
* Supports to use OpenSSL as TLS provider. See the post in the community for more information: <https://community.nssurge.com/d/196-surge-ios-mac-tls-provider>.
* Fixed a bug that Surge may not be able to process DNS answer packets which is longer than 512 bytes.

<https://dl.nssurge.com/mac/v3/Surge-3.4.0-989.zip>

### **Version 3.3.3**

* Fixed a bug which causes TFO failed.
* You may use a profile which stores in a subdirectory of the profile directory.
* Added Traditional Chinese localizations.
* Fixed a bug that the menu might be unresponsive.
* Fixed crashs on macOS 10.11.

<https://dl.nssurge.com/mac/v3/Surge-3.3.3-939.zip>

### **Version 3.3.2**

* Supports MITM on non-standard port for TCP mode.
* Proxy editing view now supports VMess protocol and all misc options.
* A new option 'persistent' has been added to the load-balance group. (aka PCC, per connection classifier) When 'persistent=true' is set, a same hostname will always get the same policy.
* Bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.3.2-925.zip>

### **Version 3.3.1**

* Supports VMess proxy protocol.
  * vmess-proxy= vmess, example.com, 443, username = 12345678-abcd-1234-1234-47ffca0ce229, ws=true, tls=true, ws-path=/v2, ws-headers=X-Header-1:value|X-Header-2:value
  * All proxy options for TLS proxy are available.
  * Web-socket and TLS options would degrade performance. Only enable when necessary.
  * Surge only supports chacha20-poly1305 encryption algorithm. Please make sure the server supports it. We have no plan to implement other ciphers.

<https://dl.nssurge.com/mac/v3/Surge-3.3.1-906.zip>

### **Version 3.3.0**

* The scripting has been rewritten totally. The old scripts are not compatible with this version. See <https://community.nssurge.com/d/33-scripting/3>
* Added support for TLS 1.3. Append 'tls13=true' to the proxy line to enable it. (Requires macOS 10.14 or above)
* Supports to use 'X-Surge-Policy' to force policy for HTTP/HTTPS requests.
* SSID group now supports to use the IP address of default router as an identifier.
* New policy group type: load-balance, which will use a random sub-policy for every request.
* Supports DNS over HTTPS. More information in community: <https://community.nssurge.com/d/48-dns-over-http>
* IN-PORT and DEST-PORT rule now supports port range expression: `DEST-PORT,8000-8999,DIRECT`
* Provides compatibility for Surge iOS 4.
* Surge Mac software package is now notarized by Apple.
* A new standalone view to manage all external resources.

<https://dl.nssurge.com/mac/v3/Surge-3.3.0-893.zip>

### **Version 3.2.1**

* Fixed a bug that Handoff doesn't work between Surge iOS and Dashboard.
* Fixed a bug that 'Update All Remote Resources' may not work.

<https://dl.nssurge.com/mac/v3/Surge-3.2.1-863.zip>

### **Version 3.2.0**

**Scripting**

* New major feature: scripting. You may use JavaScript to modify the response as you wish. See the manual for more information: <https://manual.nssurge.com/http-processing/scripting.html>
* You can now use a script to modify the response headers and status code.

**Dashboard**

* USB module has been refactored to improve stability. Also, you may choose the device from multiple USB devices now.

**MitM**

* HTTP and MitM engine has been refactored. Please report if you encounter any issues.
* You can now use URL-REGEX rule for MitM connections.
* You may use prefix '-' to exclude domains for MitM. Example:

  ```
    [MITM]
    hostname = -*.apple.com, -*.icloud.com, *
  ```
* MitM hostname list now supports port number. By default only the connections to port 443 will be decrypted. Use suffix :port to enable MitM for other ports. Use suffix :0 to enable MitM for all ports on the hostname.
* URL rewrite type 'header' is now available for MitM connections. You may also use it to rewrite a plain HTTP request to an HTTPS request.

**Misc**

* You can now enable/disable a rule.
* Added a small indicator in the menu icon for Metered Network Mode.\</lo>
* Added main switches for rewrite and scripting.
* Supports TCP SACKs for Surge VIF.
* New general option: force-http-engine-hosts. You can force Surge to treat a raw TCP connection as an HTTP connection, to enable high-level functions such as URL-REGEX rules, rewrite and scripting. This option uses the same format as \[MITM] hostname option.
* New option for url-test/fallback group: evaluate-before-use. By default, the requests before a connection evaluation will use the first policy in the list and trigger the evaluate. Enable the option to delay the requests until the evaluation completed.

<https://dl.nssurge.com/mac/v3/Surge-3.2.0-860.zip>

### **Version 3.1.1**

* Bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.1.1-811.zip>

### **Version 3.1.0**

* Added more feature to the main menu.
* Dashboard now supports to export all requests to an archive file for opening later or sharing.
* Supports a new proxy protocol: Snell. (<https://github.com/surge-networks/snell>)
* Surge Mac can work as a Snell proxy server now. See <https://manual.nssurge.com/others/snell-server.html> for more information.
* A new option to automatically reload if the profile was modified externally/remotely.
* Fixed a compatibility issue with some FTP clients.
* Added a new option to disable automatically notification dismissing.
* The update notification is now shown as a banner instead of an alert window.
* Bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.1.0-807.zip>

### **Version 3.0.6**

* Optimizations for no network error handling.
* Reduces CPU usage on idle.
* Fixed a bug while enabling MitM with a new certificate.
* Fixed crashes on macOS 10.11.

<https://dl.nssurge.com/mac/v3/Surge-3.0.6-781.zip>

### **Version 3.0.5**

* CPU usage optimizations (50% reduced for high throughout).
* Enabled Hardened Runtime to get enhanced security protections in macOS Mojave.
* Add more notes for rule evaluating stage.
* WeChat.app may flood ping when network is unstable, which causes a high CPU usage of Surge. We added a mechanism to limit ICMP throughput in this version.

<https://dl.nssurge.com/mac/v3/Surge-3.0.5-773.zip>

### **Version 3.0.4**

* Added a new option 'hijack-dns' to hijack DNS queries to other DNS servers with fake IP addresses. See manual for more information: <https://manual.nssurge.com/others/misc-options.html>.
* Bug fixes

<https://dl.nssurge.com/mac/v3/Surge-3.0.4-759.zip>

### **Version 3.0.3**

* Supports new iCloud container for Surge iOS migration.
* The MitM feature is now compatible with Android system. Please regenerate an new CA certificate before using with Android.
* Fixed some UI issues in Dashboard.
* Fixed a bug that MitM may refuse to enable after modifying settings.
* Fixed a bug that br decompress may fail.
* Fixed a bug that the menu item may use a wrong color if the accent color of system isn't blue.
* Fixed the JSON viewer color issue in the Dark Mode.
* Minor bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.0.3-754.zip>

### **Version 3.0.2**

* Allows import the profile from a URL.
* Fixed an issue that the HTTP capture button may show wrong state in Dashboard.
* Fixed an issue that Dashboard doesn't show User-Agent as the process name while connecting to iOS device.
* Fixed an issue that the bandwidth of processes may be inaccurate.
* Fixed an issue that the DEST-PORT rule may not be parsed.
* Fixed an issue that ruleset can't be used with logical type rule.

<https://dl.nssurge.com/mac/v3/Surge-3.0.2-736.zip>

### **Version 3.0.1**

* Fixed an issue that TFO option will not be saved.
* Fixed an issue that UDP relay option shows wrong state.
* Fixed some i18n issues.
* Fixed crashs on macOS 10.11.
* Save proxy declarations with legacy style (custom) if the proxy is written in legacy style in the text file.
* Other minor bug fixes.

<https://dl.nssurge.com/mac/v3/Surge-3.0.1-711.zip>

### **Version 3.0.0**

<https://dl.nssurge.com/mac/v3/Surge-3.0.0-702.zip>

## **Surge Mac V2**

### **Version 2.6.7**

* Fixed a compatibility issue with 304 response.
* Fixed a Dashboard crash.

<https://dl.nssurge.com/mac/Surge-2.6.7-656.zip>

### **Version 2.6.6**

* Fixed a compatibility issue with 304 response.
* Fixed an issue that Dashboard may not use the correct encoding to decode text body.

<https://dl.nssurge.com/mac/Surge-2.6.6-654.zip>

### **Version 2.6.5**

* Bug fixes.

<https://nssurge.com/mac/Surge-2.6.5-652.zip>

### **Version 2.6.4**

* Bug fixes.

<https://nssurge.com/mac/Surge-2.6.4-647.zip>

### **Version 2.6.3**

* New Features: External Proxy Provider. See <https://medium.com/@Blankwonder/surge-mac-new-features-external-proxy-provider-375e0e9ea660> for more information.
* Surge will automatically track system proxy settings now. When Surge is no longer the default proxy, the status icon will turn grey and a notification will raise.
* Fixed a compatibility issue with Docker.

<https://nssurge.com/mac/Surge-2.6.3-637.zip>

### **Version 2.6.2**

* Fixed an issue that the UDP mode with AEAD ciphers doesn't work.
* Bug fixes.

<https://nssurge.com/mac/Surge-2.6.2-618.zip>

### **Version 2.6.1**

* Surge now allows expired DNS answers for performance reasons. See 'Optimistic DNS' section in <https://developer.apple.com/videos/play/wwdc2018/714/> for more information.
* Performance improvements.
* Fixed an issue that UDP traffics are not included in the real-time speed.
* Supports hardware acceleration for AES-GCM encryption.
* Supports NAT64 in a pure IPv6 network. (Previous versions already supported DNS64)

<https://nssurge.com/mac/Surge-2.6.1-612.zip>

### **Version 2.6.0**

* Supports using Surge Mac as a gateway.
* A new setup guide view.
* A new config panel for traffic capture options.
* Fixed an issue which Dashboard may disconnect unexpectedly under huge pressure.
* The status bar icon will be red while traffic capture is enabled.
* Improved TUN interface performance.
* Enabling TCP Fast Open in macOS 10.14.

<https://nssurge.com/mac/Surge-2.6.0-596.zip>

### **Version 2.5.3**

* Supports UDP relay for shadowsocks protocol. A brief introduction in Chinese: <https://trello.com/c/ugOMxD3u>.
* You may use Dashboard to view UDP conversations.
* Dashboard now can save multiple remote machine profiles.
* Improved the JSON viewer in Dashboard.
* Added an UI switch for the dns-failed option in FINAL rule.
* Bug fixes.

<https://nssurge.com/mac/Surge-2.5.3-563.zip>

### **Version 2.5.2**

* You may toggle the hidden state of columns in Dashboard now.
* Supports to export selected rows to csv file.
* Added a connection duration column in Dashboard.
* Supports obfs-uri parameter.
* Improved the benchmark view.
* Fixed a serious bug in the SOCKS5 proxy implementation.
* Bug fixes.

<https://nssurge.com/mac/Surge-2.5.2-544.zip>

### **Version 2.5.1**

* The MitM enabling switch has been moved to the main menu and isolated from profile.
* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.5.1-528.zip>

### **Version 2.5.0**

* Added Outbound Mode options: Direct Outbound, Global Proxy and By Rule.
* Added options for all policy to specify outgoing interface: 'interface' and 'allow-other-interface'.
* Added all\_proxy environment variable for 'Copy Shell Export Command'
* Supports client-side SSL/TLS certificate validation for HTTPS and SOCKS5-TLS proxy. A config example is here: <https://gist.github.com/Blankwonder/cd9fa1987e41cf1a1f1df50583ba1d9c> (DO NOT support editing with UI in this version.)
* Refined MitM.
* Concurrently setup connection to host with Round-robin DNS to boost performance.
* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.5.0-520.zip>

### **Version 2.4.6**

* Supports xchacha20-ietf-poly1305.
* Bug fixes.
* HTTP request header and response header can be extracted from TCP connection now. (SOCKS5 and TUN)
* Enhanced mode can handle all connections now, even for connections initialized with IP address directly.
* Surge TUN now supports forwarding ICMP packets.

**From this version, the minimum system version requirement was raised to macOS 10.11. If you are still using macOS 10.10, please use version 2.4.5.**

<http://dl.nssurge.com/mac/Surge-2.4.6-490.zip>

### **Version 2.4.5**

* Bug fixes.
* Improved performance for high concurrency.
* TCP fast open has been disabled temporarily since there is a serious problem in macOS/iOS kernel.
* Dashboard will display decoded URL query now.

<http://dl.nssurge.com/mac/Surge-2.4.5-468.zip>

### **Version 2.4.4**

* Supports obfs=tls for shadowsocks protocol.
* Refined the proxy edit panel.
* Added Simplified Chinese language.

<http://dl.nssurge.com/mac/Surge-2.4.4-459.zip>

### **Version 2.4.3**

* Supports obfs=tls for shadowsocks protocol.
* Refined the proxy edit panel.
* Added Simplified Chinese language.

<http://dl.nssurge.com/mac/Surge-2.4.3-457.zip>

### **Version 2.4.2**

* Fixed an issue that enhanced mode may not be closed properly when switching to a profile without dns-server.
* Fixed an issue that managed profile updating and license info are unavailable while enhanced mode enabled.
* When the necessary port is used by another process, the error alert will show which process is using the port.
* Fixed an issue that map local items can't be edited with UI.
* Fixed an issue that system proxy settings may not be reset properly.
* Auto URL test group will execute a retest immediately after the selected policy has failed.

<http://dl.nssurge.com/mac/Surge-2.4.2-445.zip>

### **Version 2.4.1**

* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.4.1-439.zip>

### **Version 2.4.0**

* Supports enterprise license and profile management.
* Fixed a bug that some fields are unavailable in the configuration panel in some cases.
* Fixed a bug that the FINAL rule can't be edited.
* Fixed a bug that you may not be able to use custom storage path for profiles.
* The interface related options are no longer controlled by profile. Sorry for the repetitive changes.
* You may use $1, $2 to use the matched string in the value while using header rewrite.
* Added an option for HTTP/HTTPS proxy: always-use-connect. When it is true, Surge will use CONNECT method for plain HTTP requests.

<http://dl.nssurge.com/mac/Surge-2.4.0-429.zip>

### **Version 2.3.2**

* Added a option to control whether show proxy error notification.
* Fixed a problem that Dashboard show data doesn't exist error.

<http://dl.nssurge.com/mac/Surge-2.3.2-421.zip>

### **Version 2.3.1**

* Added a wizard to install CA’s root certificate for iOS simulator.
* Connectivity quality is now an option. (Not show by default)
* Line comments in \[Rule] section in profile file is now presented in UI.
* You may add proxy rule with Dashboard by right-clicking the request or process.
* Dashboard will always open a new window for local machine, instead of asking. You may use "File" menu to connect to a remote machine.
* Added a patch mechanism for adjusting settings for managed config. See manual for more information: <https://manual.nssurge.com/others/managed-configuration.html>

<http://dl.nssurge.com/mac/Surge-2.3.1-420.zip>

### **Version 2.3.0**

* Completely redesign the configure interface. You may configure every function with UI now.
* Proxy benchmark is now moved to main application from Dashboard.
* New feature: Header rewrite. See manual for more information: <https://manual.nssurge.com/header-rewrite.html>.
* You may switch profile with command line now: surge-cli switch-profile profilename.

<http://dl.nssurge.com/mac/Surge-2.3.0-416.zip>

### **Version 2.2.4**

* Notifications presented by Surge will be removed from Notification Center automatically.
* The interval of attempts to refresh managed config changes to one hour from one minute. (After config expired)
* Supports new encryption methods for shadowsocks-libev 3.0.
* Optimized Dashboard performance.
* Supports TCP Fast Open for shadowsocks proxy. You need add "tfo=true" flag in \[Proxy] section to enable the feature. You may use benchmark to confirm TFO is working.
* You can sort benchmark results now.
* You may choose to reload config after managed config updated.

<http://dl.nssurge.com/mac/Surge-2.2.4-394.zip>

### **Version 2.2.2**

* Fixed a bug when using SOCKS5 without authorization.

<http://dl.nssurge.com/mac/Surge-2.2.2-375.zip>

### **Version 2.2.1**

* You may use Dashboard to benchmark proxies now.
* Fixed "Too many open files" error by raising limit to 2048.
* Fixed a bug in SOCKS5 with authorization.
* Fixed a bug that managed config may refresh continuously.

<http://dl.nssurge.com/mac/Surge-2.2.1-374.zip>

### **Version 2.2.0**

* Map local function is now available.
* Adds notifications when proxy encounters errors.
* Network changed notification will show service name instead of BSD name now.
* Fixed a bug that Dashboard may show the incorrect state of body dump.
* Changes for HTTPS and SOCK5-TLS proxy:
  * Option 'skip-common-name-verify' is deprecated.
  * Add a new option 'skip-cert-verify' to skip certificate verify completely.
  * Add a new option 'sni' to customize SNI field while handshaking. You may use 'sni=off' to disable SNI.
* New rule type: PROCESS-NAME, USER-AGENT and URL-REGEX.
* You can use simple wildcard matching (? and \*) for PROCESS-NAME rule, local DNS mapping and MitM hosts.
* Dashboard supports display POST form data in a table view.
* You may let Surge reload config by sending SIGHUP. You can use command 'killall -HUP Surge' or 'surge-cli reload'.
* Managed configuration is supported now.
* Add a new option 'skip-server-cert-verify' for MitM.

<http://dl.nssurge.com/mac/Surge-2.2.0-368.zip>

### **Version 2.1.4**

* Fixed a bug that helper may crash on macOS 10.10.
* Add a option to remove Surge helper for troubleshooting.
* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.1.4-362.zip>

### **Version 2.1.3**

* Fixed a bug that helper may crash on macOS 10.10.
* Add a option to remove Surge helper for troubleshooting.
* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.1.3-337.zip>

### **Version 2.1.2**

* New option: Collapse policy group items in menu
* Fixed a bug that enhanced mode DNS settings may not be reverted.
* Hold option key to click 'Copy Shell Export Command' to get a command with primary interface IP instead of 127.0.0.1.
* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.1.2-327.zip>

### **Version 2.1.0**

* New feature: Enhanced Mode

  Some applications may not obey the system proxy settings. Using enhanced mode can make all applications handled by Surge.
* New rule type: IP-CIDR6

  Example: IP-CIDR6,2005::/16,DIRECT,no-resolve
* The /etc/hosts file will be reloaded automatically if it has changes.

<http://dl.nssurge.com/mac/Surge-2.1.0-318.zip>

### **Version 2.0.13**

* Dashboard supports to use ⌘ + 1,2,3,4 to switch panel.
* Dashboard Supports handoff with Surge iOS.
* Fixed a bug that Dashboard may show incorrect process name.

<http://dl.nssurge.com/mac/Surge-2.0.13-304.zip>

### **Version 2.0.12**

* Bug fixes.
* Supported SNI while performing MitM.
* The original certificate will be resigned and used while performing MitM, instead of generating a new certificate.

<http://dl.nssurge.com/mac/Surge-2.0.12-295.zip>

### **Version 2.0.11**

* Rule test cache will be flushed after network switching now.
* Added a option 'Grey icon if set as system proxy is disabled'.
* Bug fixes and performance improvements.

<http://dl.nssurge.com/mac/Surge-2.0.11-289.zip>

### **Version 2.0.10**

* Surge talks to HTTP proxies with a plain HTTP method for non-HTTPS requests now, instead of CONNECT.
* Improved compatibility with some HTTP server.
* Improved compatibility with some DNS server.

<http://dl.nssurge.com/mac/Surge-2.0.10-280.zip>

### **Version 2.0.9**

* Dashborad: The height of the detail panel will not change now while switching pages.
* A notification will show when proxy client access from other machine.
* Used SF Mono as monospaced font for header and body data display.
* Supported TCP half-open mechanism.

<http://dl.nssurge.com/mac/Surge-2.0.9-273.zip>

### **Version 2.0.8**

* Add a new option 'exclude-simple-hostnames' in the gereral section.
* Dashborad: Selected row will not be lost while the filter or sort column changed.
* Dashborad: Fixes some issues in the active panel.

<http://dl.nssurge.com/mac/Surge-2.0.8-260.zip>

### **Version 2.0.5**

* Bug fixes.

<http://dl.nssurge.com/mac/Surge-2.0.5-255.zip>

### **Version 2.0.3**

* New feature: Show connectivity quality in menu.

  Surge will send a DNS question to all DNS servers concurrently to test physical network connectivity while opening the menu.
* Fixes a problem that Surge may freeze while opening the menu.
* Fixes a problem that if a policy group contains duplicate policies, Surge may crash.

<http://dl.nssurge.com/mac/Surge-2.0.3-250.zip>

### **Version 2.0.2**

* Dashboard will no longer display process icon in remote mode.
* Fixes a bug: "Set as System Proxy" option does not work properly if only SOCKS service is enabled.
* Fixes a bug: Dashboard can't add a rule with no-resolve option on and comment not empty.
* Minor bug fixes.

### **Version 2.0.1**

* Bug fixes


