TLS — sing-box
Every sing-box inbound and outbound embeds a tls: { ... } block via InboundTLSOptionsContainer / OutboundTLSOptionsContainer. The same block carries REALITY, ECH, and uTLS sub-blocks as nested options — they're not separate top-level features.
Inbound tls
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
enabled | bool | false | true | false | Master switch. When false, the rest of the block is ignored. |
server_name | string | (inferred from SNI) | <hostname> | Expected server name for ACME provisioning. Required if `acme` is set. |
insecure | bool | false | true | false | Skip TLS verification. Test only. |
alpn | badoption.Listable[string] | [] | <ALPN string> | ALPN list offered to clients. |
min_version | string | 1.2 | 1.0 | 1.1 | 1.2 | 1.3 | Minimum acceptable TLS version. |
max_version | string | 1.3 | 1.0 | 1.1 | 1.2 | 1.3 | Maximum acceptable TLS version. |
cipher_suites | badoption.Listable[string] | (library default) | <cipher> | Override the cipher suite list (TLS 1.2 only). |
curve_preferences | badoption.Listable[CurvePreference] | (library default) | P256 | P384 | P521 | X25519 | X25519MLKEM768 | Key-exchange curve preference list. |
certificate | badoption.Listable[string] | [] | <PEM block> | Inline server certificate PEM. List form supports the full chain. |
certificate_path | string | (unset) | <PEM file path> | Path to server certificate. |
client_authentication | ClientAuthType | no | no | request | require-any | verify-if-given | require-and-verify | Mutual-TLS client-auth policy. Maps to crypto/tls's ClientAuthType values. |
client_certificate | badoption.Listable[string] | [] | <PEM block> | Trusted client-certificate roots (mTLS). |
client_certificate_path | badoption.Listable[string] | [] | <PEM file path> | Path-form trusted client roots. |
client_certificate_public_key_sha256 | badoption.Listable[[]byte] | [] | <SHA-256 bytes> | Pin the client cert by public-key SHA-256. Useful when issuing throw-away client certs. |
key | badoption.Listable[string] | [] | <PEM block> | Inline server private key. |
key_path | string | (unset) | <file path> | Path to server private key. |
kernel_tx | bool | false | true | false | Linux KTLS — offload TLS encryption to the kernel for outgoing traffic. Requires kernel TLS support and the right crypto modules. |
kernel_rx | bool | false | true | false | Linux KTLS for incoming traffic. |
acme | *InboundACMEOptions | (unset) | InboundACMEOptions | Automatic Let's-Encrypt certificate provisioning. Mutually exclusive with explicit `certificate`/`key`. |
ech | *InboundECHOptions | (unset) | InboundECHOptions | Encrypted Client Hello configuration. |
reality | *InboundRealityOptions | (unset) | InboundRealityOptions | REALITY server configuration. Mutually exclusive with normal TLS — REALITY replaces the TLS handshake. |
Source: option/tls.go:12-34 · pinned at v1.13.11 (553cfa1)
Outbound tls
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
enabled | bool | false | true | false | Master switch. |
disable_sni | bool | false | true | false | Omit the SNI extension entirely from the ClientHello. |
server_name | string | (server address) | <hostname> | SNI sent to the server, and the name verified against the leaf certificate. |
insecure | bool | false | true | false | Skip server-certificate verification. |
alpn | badoption.Listable[string] | [] | <ALPN string> | ALPN list offered to the server. |
min_version | string | 1.2 | 1.0 | 1.1 | 1.2 | 1.3 | Minimum acceptable TLS version. |
max_version | string | 1.3 | 1.0 | 1.1 | 1.2 | 1.3 | Maximum acceptable TLS version. |
cipher_suites | badoption.Listable[string] | (library default) | <cipher> | Override cipher suite list. |
curve_preferences | badoption.Listable[CurvePreference] | (library default) | <see inbound> | Key-exchange curve preference. |
certificate | badoption.Listable[string] | [] | <PEM block> | Trusted CA certificates appended to the system root store. Use with `insecure: false` for self-signed servers. |
certificate_path | string | (unset) | <file path> | Path-form trusted CAs. |
certificate_public_key_sha256 | badoption.Listable[[]byte] | [] | <SHA-256 bytes> | Pin the server certificate by public-key SHA-256. |
client_certificate | badoption.Listable[string] | [] | <PEM block> | Client certificate (mTLS). |
client_certificate_path | string | (unset) | <file path> | Path-form client certificate. |
client_key | badoption.Listable[string] | [] | <PEM block> | Client private key. |
client_key_path | string | (unset) | <file path> | Path-form client private key. |
fragment | bool | false | true | false | TCP-level handshake fragmentation. Splits the ClientHello across packets to evade SNI-based DPI. |
fragment_fallback_delay | badoption.Duration | 500ms | <duration> | If the fragmented handshake doesn't complete by this deadline, retry without fragmentation. |
record_fragment | bool | false | true | false | TLS-record-layer fragmentation (more aggressive than `fragment` — splits inside the TLS record stream, not just TCP packets). |
kernel_tx | bool | false | true | false | Linux KTLS for outgoing traffic. |
kernel_rx | bool | false | true | false | Linux KTLS for incoming traffic. |
ech | *OutboundECHOptions | (unset) | OutboundECHOptions | ECH configuration. When unset, ECH is not used (unless auto-discovered via HTTPS records). |
utls | *OutboundUTLSOptions | (unset) | OutboundUTLSOptions | uTLS client-hello mimicry. |
reality | *OutboundRealityOptions | (unset) | OutboundRealityOptions | REALITY client configuration. Mutually exclusive with normal TLS. |
Source: option/tls.go:97-122 · pinned at v1.13.11 (553cfa1)
utls
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
enabled | bool | false | true | false | Turn uTLS on. |
fingerprint | string | chrome | chrome | firefox | safari | ios | android | edge | 360 | qq | random | randomized | Browser fingerprint to mimic. Drives the entire ClientHello (cipher suites, extensions, signatures). |
Source: option/tls.go:229-232 · pinned at v1.13.11 (553cfa1)
Examples
Inbound with ACME provisioning:
json
{
"inbounds": [{
"type": "vless",
"listen_port": 443,
"users": [{ "uuid": "..." }],
"tls": {
"enabled": true,
"server_name": "example.com",
"alpn": ["h2", "http/1.1"],
"acme": {
"domain": ["example.com"],
"email": "admin@example.com"
}
}
}]
}Outbound with uTLS chrome fingerprint and TCP-fragment SNI hiding:
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"
}
}]
}Mutual TLS — server requires client certificates:
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"]
}
}]
}Notes
- The five
client_authenticationvalues map directly to Go'scrypto/tls.ClientAuthType:no— no client cert (default).request— ask for one, accept without it.require-any— require but don't validate.verify-if-given— validate if provided.require-and-verify— strict mTLS.
fragmentandrecord_fragmentare two different layers:fragmentsplits the TCP packets carrying the TLS handshake.record_fragmentsplits the TLS records themselves (Handshakerecords sent in multiple smaller pieces). Usefragmentfirst; only enablerecord_fragmentif SNI-based DPI still classifies the connection.
kernel_tx/kernel_rxenable Linux KTLS for AES-GCM and CHACHA20- POLY1305. The kernel must have thetlsmodule loaded and the right crypto modules registered.acmeis mutually exclusive with explicitcertificate/key. With ACME, sing-box uses the embedded autocert client — see the upstream docs for ACME provider options.- REALITY (the
realitysub-block) replaces the TLS handshake entirely — see REALITY — sing-box. - ECH (the
echsub-block) plugs into the same handshake — see ECH — sing-box.
Cross-core notes
- Xray-core uses
streamSettings.tlsSettingsrather than an embeddedtlsblock. Field names are camelCase (serverName,cipherSuites). uTLS fingerprint is a top-level field, not a sub-block. See TLS — Xray-core. - mihomo has no consolidated TLS block — each proxy adapter carries TLS fields inline (
tls,sni,alpn,skip-cert-verify, …). See TLS — mihomo.
Source: option/tls.go:12-232 · v1.13.11 (553cfa1)
