TLS — sing-box
每个 sing-box 入站与出站都通过 InboundTLSOptionsContainer / OutboundTLSOptionsContainer 内嵌一个 tls: { ... } 块。同一个块以嵌套子块形式承载 REALITY、ECH 与 uTLS —— 它们不是独立的顶层功能。
入站 tls
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
enabled | bool | false | true | false | 总开关。为 false 时块内其他字段被忽略。 |
server_name | string | (inferred from SNI) | <hostname> | ACME 签发使用的期望服务器名。若设置了 acme 则必填。 |
insecure | bool | false | true | false | 跳过 TLS 校验。仅供测试。 |
alpn | badoption.Listable[string] | [] | <ALPN string> | 向客户端宣告的 ALPN 列表。 |
min_version | string | 1.2 | 1.0 | 1.1 | 1.2 | 1.3 | 可接受的最低 TLS 版本。 |
max_version | string | 1.3 | 1.0 | 1.1 | 1.2 | 1.3 | 可接受的最高 TLS 版本。 |
cipher_suites | badoption.Listable[string] | (library default) | <cipher> | 覆盖加密套件列表(仅 TLS 1.2)。 |
curve_preferences | badoption.Listable[CurvePreference] | (library default) | P256 | P384 | P521 | X25519 | X25519MLKEM768 | 密钥交换曲线偏好列表。 |
certificate | badoption.Listable[string] | [] | <PEM block> | 内联服务器证书 PEM。列表形式可承载完整证书链。 |
certificate_path | string | (unset) | <PEM file path> | 服务端证书文件路径。 |
client_authentication | ClientAuthType | no | no | request | require-any | verify-if-given | require-and-verify | mTLS 客户端鉴权策略。映射到 crypto/tls 的 ClientAuthType 值。 |
client_certificate | badoption.Listable[string] | [] | <PEM block> | 受信客户端证书根(mTLS)。 |
client_certificate_path | badoption.Listable[string] | [] | <PEM file path> | 客户端受信根的路径形式。 |
client_certificate_public_key_sha256 | badoption.Listable[[]byte] | [] | <SHA-256 bytes> | 按公钥 SHA-256 锚定客户端证书。用于一次性发放客户端证书的场景。 |
key | badoption.Listable[string] | [] | <PEM block> | 内联服务端私钥。 |
key_path | string | (unset) | <file path> | 服务端私钥文件路径。 |
kernel_tx | bool | false | true | false | Linux KTLS —— 把出站流量的 TLS 加密下沉到内核。需要内核 TLS 支持与对应的加密模块。 |
kernel_rx | bool | false | true | false | 入站流量的 Linux KTLS。 |
handshake_timeout | badoption.Duration | 15s | <duration> | TLS 握手超时(Go duration 格式)。 |
certificate_provider | *CertificateProviderOptions | (unset) | <provider tag> | CertificateProviderOptions | 由证书提供方管理的证书:可为顶层 certificate_providers 中某条目的 tag,或带 type(acme、tailscale、cloudflare-origin-ca)的内联提供方对象。设置后不会读取 certificate / key。与 acme 互斥;reality 下不可用。 |
acme | *InboundACMEOptions | (deprecated) | InboundACMEOptions | 已弃用:内联 ACME。请改用 type: acme 的 certificate_provider —— 字段可原样迁移。与 certificate_provider 互斥。 |
ech | *InboundECHOptions | (unset) | InboundECHOptions | Encrypted Client Hello 配置。 |
reality | *InboundRealityOptions | (unset) | InboundRealityOptions | REALITY 服务端配置。与普通 TLS 互斥 —— REALITY 替换 TLS 握手。 |
源码: option/tls.go:13-40 · 锚定版本 v1.14.2 (af6e64c)
出站 tls
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
enabled | bool | false | true | false | 总开关。 |
engine | string | go | go | apple | windows | 用于握手的 TLS 实现。apple 使用 Network.framework(启用 CGO 的 Apple 构建);windows 通过 SSPI 使用 Schannel(Windows build 17763+,仅 Windows 11 / Server 2022+ 支持 TLS 1.3)。非 go 引擎只接受 server_name、insecure、alpn、min_version、max_version、certificate(_path)、certificate_public_key_sha256 与 handshake_timeout;其他 TLS 选项会在启动时被拒绝。 |
disable_sni | bool | false | true | false | 完全省略 ClientHello 中的 SNI 扩展。 |
server_name | string | (server address) | <hostname> | 发送给服务器的 SNI,并据此校验 leaf 证书名称。 |
insecure | bool | false | true | false | 跳过服务端证书校验。 |
alpn | badoption.Listable[string] | [] | <ALPN string> | 向服务器宣告的 ALPN 列表。 |
min_version | string | 1.2 | 1.0 | 1.1 | 1.2 | 1.3 | 可接受的最低 TLS 版本。 |
max_version | string | 1.3 | 1.0 | 1.1 | 1.2 | 1.3 | 可接受的最高 TLS 版本。 |
cipher_suites | badoption.Listable[string] | (library default) | <cipher> | 覆盖加密套件列表。 |
curve_preferences | badoption.Listable[CurvePreference] | (library default) | <see inbound> | 密钥交换曲线偏好。 |
certificate | badoption.Listable[string] | [] | <PEM block> | 附加到系统根证书的受信 CA。配合 insecure: false 接受自签服务器。 |
certificate_path | string | (unset) | <file path> | 受信 CA 的路径形式。 |
certificate_public_key_sha256 | badoption.Listable[[]byte] | [] | <SHA-256 bytes> | 按公钥 SHA-256 锚定服务端证书。 |
client_certificate | badoption.Listable[string] | [] | <PEM block> | 客户端证书(mTLS)。 |
client_certificate_path | string | (unset) | <file path> | 客户端证书的路径形式。 |
client_key | badoption.Listable[string] | [] | <PEM block> | 客户端私钥。 |
client_key_path | string | (unset) | <file path> | 客户端私钥的路径形式。 |
fragment | bool | false | true | false | TCP 层握手分片。把 ClientHello 拆到多个包以规避 SNI DPI。 |
fragment_fallback_delay | badoption.Duration | 500ms | <duration> | 分片握手未在该期限内完成时,回退到不分片重试。 |
record_fragment | bool | false | true | false | TLS 记录层分片(比 fragment 更激进 —— 在 TLS 记录流内部拆,而不仅是 TCP 包)。 |
spoof | string | (unset) | <hostname> | 在真实 ClientHello 之前发送一份携带此 SNI 的伪造副本,以欺骗放行特定主机名的 SNI 过滤设备。必须与 server_name 不同。仅支持 Linux、macOS 与 Windows,需要原始套接字权限(Linux 上为 CAP_NET_RAW + CAP_NET_ADMIN,macOS 上为 root,Windows 上为管理员;不支持 Windows ARM64)。 |
spoof_method | string | wrong-sequence | wrong-sequence | wrong-checksum | wrong-ack | wrong-md5 | wrong-timestamp | 让真实服务端丢弃伪造分段的方式:窗口外的序列号(默认)、错误校验和、窗口外的 ACK、TCP-MD5 选项,或回拨的时间戳(wrong-timestamp 不支持 macOS)。 |
kernel_tx | bool | false | true | false | 出站流量的 Linux KTLS。 |
kernel_rx | bool | false | true | false | 入站流量的 Linux KTLS。 |
handshake_timeout | badoption.Duration | 15s | <duration> | TLS 握手超时(Go duration 格式)。 |
ech | *OutboundECHOptions | (unset) | OutboundECHOptions | ECH 配置。未设置时不使用(除非通过 HTTPS 记录自动发现)。 |
utls | *OutboundUTLSOptions | (unset) | OutboundUTLSOptions | uTLS ClientHello 模拟。 |
reality | *OutboundRealityOptions | (unset) | OutboundRealityOptions | REALITY 客户端配置。与普通 TLS 互斥。 |
源码: option/tls.go:107-136 · 锚定版本 v1.14.2 (af6e64c)
utls
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
enabled | bool | false | true | false | 启用 uTLS。 |
fingerprint | string | chrome | chrome | firefox | safari | ios | android | edge | 360 | qq | random | randomized | 要模拟的浏览器指纹。决定整个 ClientHello(加密套件、扩展、签名算法)。 |
源码: option/tls.go:247-250 · 锚定版本 v1.14.2 (af6e64c)
证书提供方
服务端证书可以来自证书提供方,而不是文件或内联的 acme 块。在顶层 certificate_providers 数组中定义提供方(每个带 type 与 tag),再在 tls.certificate_provider 中按 tag 引用,或直接在该处内联一个提供方对象。类型:acme(需要 with_acme 构建标签)、tailscale(复用一个 Tailscale 端点;需在 tailnet 中启用 MagicDNS 与 HTTPS)以及 cloudflare-origin-ca。完整选项参考:证书提供方。acme 提供方:
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
domain | badoption.Listable[string] | (required) | <domain> | … | 要申请证书的域名。必填。 |
data_directory | string | (certmagic default) | <dir path> | ACME 状态与证书的存放目录。默认:$XDG_DATA_HOME/certmagic 或 $HOME/.local/share/certmagic。 |
email | string | (unset) | <e-mail> | 用于创建或选择 ACME 账户的邮箱。 |
provider | string | letsencrypt | letsencrypt | zerossl | <https:// directory URL> | ACME CA。为 zerossl 时,若设置了 email 且 external_account 为空,会自动申请 EAB 凭据。 |
account_key | string | (unset) | <PEM key> | 已有 ACME 账户的 PEM 私钥。 |
dns01_challenge | *ACMEProviderDNS01ChallengeOptions | (unset) | ACMEProviderDNS01ChallengeOptions | DNS-01 质询设置(provider:alidns、cloudflare、acmedns,以及 ttl、propagation_delay、propagation_timeout、resolvers、override_domain)。设置后其他质询方式被禁用。 |
key_type | ACMEKeyType | (certmagic default) | ed25519 | p256 | p384 | rsa2048 | rsa4096 | 新签发证书的密钥类型。 |
profile | string | (unset) | <ACME profile> | 签发使用的 ACME profile。使用 Let's Encrypt 且任一域名为 IP 地址时,自动选用 shortlived。 |
http_client | *HTTPClientOptions | (default client) | <http_clients tag> | HTTPClientOptions | 所有 ACME 请求使用的 HTTP 客户端:内联对象,或 http_clients 中某条目的 tag。 |
源码: option/acme.go:15-31 · 锚定版本 v1.14.2 (af6e64c)
示例
使用内联 ACME 证书提供方的入站:
json
{
"inbounds": [{
"type": "vless",
"listen_port": 443,
"users": [{ "uuid": "..." }],
"tls": {
"enabled": true,
"server_name": "example.com",
"alpn": ["h2", "http/1.1"],
"certificate_provider": {
"type": "acme",
"domain": ["example.com"],
"email": "admin@example.com"
}
}
}]
}带 uTLS chrome 指纹与 TCP 分片 SNI 隐藏的出站:
json
{
"outbounds": [{
"type": "vless",
"server": "example.com",
"server_port": 443,
"uuid": "...",
"tls": {
"enabled": true,
"server_name": "example.com",
"utls": { "enabled": true, "fingerprint": "chrome" },
"fragment": true,
"fragment_fallback_delay": "500ms"
}
}]
}双向 TLS —— 服务端要求客户端证书:
json
{
"inbounds": [{
"type": "http",
"listen_port": 8443,
"tls": {
"enabled": true,
"certificate_path": "/etc/ssl/cert.pem",
"key_path": "/etc/ssl/key.pem",
"client_authentication": "require-and-verify",
"client_certificate_path": ["/etc/ssl/clients-ca.pem"]
}
}]
}说明
client_authentication的五个值直接映射到 Go 的crypto/tls.ClientAuthType:no—— 不要求客户端证书(默认)。request—— 请求一个,没有也接受。require-any—— 必须有但不校验。verify-if-given—— 提供则校验。require-and-verify—— 严格 mTLS。
fragment与record_fragment是两个不同层:fragment拆 TCP 包(承载 TLS 握手)。record_fragment拆 TLS 记录本身(Handshake 记录被切成多个小片)。先用fragment;仅当基于 SNI 的 DPI 仍能识别时再启用record_fragment。
kernel_tx/kernel_rx为 AES-GCM 与 CHACHA20-POLY1305 启用 Linux KTLS。内核需加载tls模块和正确的加密模块。- 内联
tls.acme已弃用。把其字段原样移入type: acme的certificate_provider(可如示例般内联,也可通过certificate_providers+ tag 共享)。certificate_provider与acme不能同时使用,REALITY 两者都不接受。 engine: apple/windows把握手交给操作系统的 TLS 栈。它们会在启动时拒绝 uTLS、REALITY、ECH、分片、KTLS、客户端证书、cipher_suites、curve_preferences、disable_sni与spoof。spoof(及spoof_method)也可按连接通过路由规则动作选项tls_spoof/tls_spoof_method启用。- REALITY(
reality子块)完全替换 TLS 握手 —— 见 REALITY — sing-box。 - ECH(
ech子块)挂在同一握手内 —— 见 ECH — sing-box。
跨内核说明
- Xray-core 使用
streamSettings.tlsSettings而非内嵌tls块。字段名为 camelCase(serverName、cipherSuites);uTLS 指纹是顶层字段而非子块。参见 TLS — Xray-core。 - mihomo 没有集中化 TLS 块 —— 每个 proxy 适配器把 TLS 字段直接内联(
tls、sni、alpn、skip-cert-verify等)。参见 TLS — mihomo。
源码: option/tls.go:13-250 · v1.14.2 (af6e64c)
