# TLS - sing-box
The universal proxy platform.
Author: nekohasekai

Skip to content

# TLS

Changes in sing-box 1.14.0

certificate_provider
handshake_timeout
spoof
spoof_method
engine
acme

Changes in sing-box 1.13.0

kernel_tx
kernel_rx
curve_preferences
certificate_public_key_sha256
client_certificate
client_certificate_path
client_key
client_key_path
client_authentication
client_certificate_public_key_sha256
ech.query_server_name

Changes in sing-box 1.12.0

fragment
fragment_fallback_delay
record_fragment
ech.pq_signature_schemes_enabled
ech.dynamic_record_sizing_disabled

Changes in sing-box 1.10.0

utls

### Inbound

    {
      "enabled": true,
      "server_name": "",
      "alpn": [],
      "min_version": "",
      "max_version": "",
      "cipher_suites": [],
      "curve_preferences": [],
      "certificate": [],
      "certificate_path": "",
      "client_authentication": "",
      "client_certificate": [],
      "client_certificate_path": [],
      "client_certificate_public_key_sha256": [],
      "key": [],
      "key_path": "",
      "kernel_tx": false,
      "kernel_rx": false,
      "handshake_timeout": "",
      "certificate_provider": "",

      // Deprecated

      "acme": {
        "domain": [],
        "data_directory": "",
        "default_server_name": "",
        "email": "",
        "provider": "",
        "disable_http_challenge": false,
        "disable_tls_alpn_challenge": false,
        "alternative_http_port": 0,
        "alternative_tls_port": 0,
        "external_account": {
          "key_id": "",
          "mac_key": ""
        },
        "dns01_challenge": {}
      },
      "ech": {
        "enabled": false,
        "key": [],
        "key_path": "",

        // Deprecated

        "pq_signature_schemes_enabled": false,
        "dynamic_record_sizing_disabled": false
      },
      "reality": {
        "enabled": false,
        "handshake": {
          "server": "google.com",
          "server_port": 443,

          ... // Dial Fields
        },
        "private_key": "UuMBgl7MXTPx9inmQp2UC7Jcnwc6XYbwDNebonM-FCc",
        "short_id": [
          "0123456789abcdef"
        ],
        "max_time_difference": "1m"
      }
    }

### Outbound

    {
      "enabled": true,
      "engine": "",
      "disable_sni": false,
      "server_name": "",
      "insecure": false,
      "alpn": [],
      "min_version": "",
      "max_version": "",
      "cipher_suites": [],
      "curve_preferences": [],
      "certificate": "",
      "certificate_path": "",
      "certificate_public_key_sha256": [],
      "client_certificate": [],
      "client_certificate_path": "",
      "client_key": [],
      "client_key_path": "",
      "fragment": false,
      "fragment_fallback_delay": "",
      "record_fragment": false,
      "spoof": "",
      "spoof_method": "",
      "kernel_tx": false,
      "kernel_rx": false,
      "handshake_timeout": "",
      "ech": {
        "enabled": false,
        "config": [],
        "config_path": "",
        "query_server_name": "",

        // Deprecated
        "pq_signature_schemes_enabled": false,
        "dynamic_record_sizing_disabled": false
      },
      "utls": {
        "enabled": false,
        "fingerprint": ""
      },
      "reality": {
        "enabled": false,
        "public_key": "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0",
        "short_id": "0123456789abcdef"
      }
    }

TLS version values:

- `1.0`
- `1.1`
- `1.2`
- `1.3`

Cipher suite values:

- `TLS_RSA_WITH_AES_128_CBC_SHA`
- `TLS_RSA_WITH_AES_256_CBC_SHA`
- `TLS_RSA_WITH_AES_128_GCM_SHA256`
- `TLS_RSA_WITH_AES_256_GCM_SHA384`
- `TLS_AES_128_GCM_SHA256`
- `TLS_AES_256_GCM_SHA384`
- `TLS_CHACHA20_POLY1305_SHA256`
- `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA`
- `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA`
- `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`
- `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`
- `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`
- `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`
- `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`
- `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`
- `TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256`
- `TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256`

You can ignore the JSON Array [] tag when the content is only one item

### Fields

#### enabled

Enable TLS.

#### engine

Since sing-box 1.14.0

Client only

TLS engine to use.

Values:

- `go` (default)
- `apple`
- `windows`

Supported fields:

- `server_name`
- `insecure`
- `alpn`
- `min_version`
- `max_version`
- `certificate` / `certificate_path`
- `certificate_public_key_sha256`
- `handshake_timeout`

Unsupported fields:

- `disable_sni`
- `cipher_suites`
- `curve_preferences`
- `client_certificate` / `client_certificate_path` / `client_key` / `client_key_path`
- `fragment` / `record_fragment`
- `kernel_tx` / `kernel_rx`
- `ech`
- `utls`
- `reality`

`windows` uses Schannel via SSPI. Only available on Windows build 17763 or later (Windows 10 version 1809, Windows Server 2019, or newer).

TLS 1.3 is only negotiated on Windows 11 or Windows Server 2022 and newer. On older Windows versions, Schannel caps the connection at TLS 1.2 even when `max_version` is `1.3`.

The default version range is TLS 1.2 to TLS 1.3, matching the `go` engine.

Supported fields:

- `server_name`
- `insecure`
- `alpn`
- `min_version`
- `max_version`
- `certificate` / `certificate_path`
- `certificate_public_key_sha256`
- `handshake_timeout`

Unsupported fields:

- `disable_sni`
- `cipher_suites`
- `curve_preferences`
- `client_certificate` / `client_certificate_path` / `client_key` / `client_key_path`
- `fragment` / `record_fragment`
- `kernel_tx` / `kernel_rx`
- `ech`
- `utls`
- `reality`

#### disable_sni

Client only

Do not send server name in ClientHello.

#### server_name

Used to verify the hostname on the returned certificates unless insecure is given.

It is also included in the client's handshake to support virtual hosting unless it is an IP address.

#### insecure

Client only

Accepts any server certificate.

#### alpn

List of supported application level protocols, in order of preference.

If both peers support ALPN, the selected protocol will be one from this list, and the connection will fail if there is no mutually supported protocol.

See Application-Layer Protocol Negotiation.

#### min_version

The minimum TLS version that is acceptable.

By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server.

#### max_version

The maximum TLS version that is acceptable.

By default, the maximum version is currently TLS 1.3.

#### cipher_suites

List of enabled TLS 1.0–1.2 cipher suites. The order of the list is ignored. Note that TLS 1.3 cipher suites are not configurable.

If empty, a safe default list is used. The default cipher suites might change over time.

#### curve_preferences

Since sing-box 1.13.0

Set of supported key exchange mechanisms. The order of the list is ignored, and key exchange mechanisms are chosen from this list using an internal preference order by Golang.

Available values, also the default list:

- `P256`
- `P384`
- `P521`
- `X25519`
- `X25519MLKEM768`

#### certificate

Server certificates chain line array, in PEM format.

#### certificate_path

Will be automatically reloaded if file modified.

The path to server certificate chain, in PEM format.

#### certificate_public_key_sha256

Since sing-box 1.13.0

Client only

List of SHA-256 hashes of server certificate public keys, in base64 format.

To generate the SHA-256 hash for a certificate's public key, use the following commands:

    # For a certificate file
    openssl x509 -in certificate.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

    # For a certificate from a remote server
    echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

#### client_certificate

Since sing-box 1.13.0

Client only

Client certificate chain line array, in PEM format.

#### client_certificate_path

Since sing-box 1.13.0

Client only

The path to client certificate chain, in PEM format.

#### client_key

Since sing-box 1.13.0

Client only

Client private key line array, in PEM format.

#### client_key_path

Since sing-box 1.13.0

Client only

The path to client private key, in PEM format.

#### key

Server only

The server private key line array, in PEM format.

#### key_path

Server only

Will be automatically reloaded if file modified.

The path to the server private key, in PEM format.

#### client_authentication

Since sing-box 1.13.0

Server only

The type of client authentication to use.

Available values:

- `no` (default)
- `request`
- `require-any`
- `verify-if-given`
- `require-and-verify`

One of `client_certificate`, `client_certificate_path`, or `client_certificate_public_key_sha256` is required if this option is set to `verify-if-given`, or `require-and-verify`.

#### client_certificate

Since sing-box 1.13.0

Server only

Client certificate chain line array, in PEM format.

#### client_certificate_path

Since sing-box 1.13.0

Server only

Will be automatically reloaded if file modified.

List of path to client certificate chain, in PEM format.

#### client_certificate_public_key_sha256

Since sing-box 1.13.0

Server only

List of SHA-256 hashes of client certificate public keys, in base64 format.

To generate the SHA-256 hash for a certificate's public key, use the following commands:

    # For a certificate file
    openssl x509 -in certificate.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

    # For a certificate from a remote server
    echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

#### kernel_tx

Since sing-box 1.13.0

Only supported on Linux 5.1+, use a newer kernel if possible.

Only TLS 1.3 is supported.

kTLS TX may only improve performance when `splice(2)` is available (both ends must be TCP or TLS without additional protocols after handshake); otherwise, it will definitely degrade performance.

Enable kernel TLS transmit support.

#### kernel_rx

Since sing-box 1.13.0

Only supported on Linux 5.1+, use a newer kernel if possible.

Only TLS 1.3 is supported.

kTLS RX will definitely degrade performance even if `splice(2)` is in use, so enabling it is not recommended.

Enable kernel TLS receive support.

#### handshake_timeout

Since sing-box 1.14.0

TLS handshake timeout, in golang's Duration format.

`15s` is used by default.

#### certificate_provider

Since sing-box 1.14.0

Server only

A string or an object.

When string, the tag of a shared Certificate Provider.

When object, an inline certificate provider. See Certificate Provider for available types and fields.

## Custom TLS support

QUIC support

Only ECH is supported in QUIC.

#### utls

Client only

Not Recommended

uTLS has had repeated fingerprinting vulnerabilities discovered by researchers.

uTLS is a Go library that attempts to imitate browser TLS fingerprints by copying ClientHello structure. However, browsers use completely different TLS stacks (Chrome uses BoringSSL, Firefox uses NSS) with distinct implementation behaviors that cannot be replicated by simply copying the handshake format, making detection possible. Additionally, the library lacks active maintenance and has poor code quality, making it unsuitable for censorship circumvention.

For TLS fingerprint resistance, use NaiveProxy instead.

uTLS is a fork of "crypto/tls", which provides ClientHello fingerprinting resistance.

Available fingerprint values:

Removed since sing-box 1.10.0

Some legacy chrome fingerprints have been removed and will fallback to chrome:

chrome_psk
chrome_psk_shuffle
chrome_padding_psk_shuffle
chrome_pq
chrome_pq_psk

- chrome
- firefox
- edge
- safari
- 360
- qq
- ios
- android
- random
- randomized

Chrome fingerprint will be used if empty.

### ECH Fields

ECH (Encrypted Client Hello) is a TLS extension that allows a client to encrypt the first part of its ClientHello message.

The ECH key and configuration can be generated by `sing-box generate ech-keypair`.

#### pq_signature_schemes_enabled

Deprecated in sing-box 1.12.0

`pq_signature_schemes_enabled` is deprecated in sing-box 1.12.0 and removed in sing-box 1.13.0.

Enable support for post-quantum peer certificate signature schemes.

#### dynamic_record_sizing_disabled

Deprecated in sing-box 1.12.0

`dynamic_record_sizing_disabled` is deprecated in sing-box 1.12.0 and removed in sing-box 1.13.0.

Disables adaptive sizing of TLS records.

When true, the largest possible TLS record size is always used.
When false, the size of TLS records may be adjusted in an attempt to improve latency.

#### key

Server only

ECH key line array, in PEM format.

#### key_path

Server only

Will be automatically reloaded if file modified.

The path to ECH key, in PEM format.

#### config

Client only

ECH configuration line array, in PEM format.

If empty, load from DNS will be attempted.

#### config_path

Client only

The path to ECH configuration, in PEM format.

If empty, load from DNS will be attempted.

#### query_server_name

Since sing-box 1.13.0

Client only

Overrides the domain name used for ECH HTTPS record queries.

If empty, `server_name` is used for queries.

#### fragment

Since sing-box 1.12.0

Client only

Fragment TLS handshakes to bypass firewalls.

This feature is intended to circumvent simple firewalls based on plaintext packet matching, and should not be used to circumvent real censorship.

Due to poor performance, try `record_fragment` first, and only apply to server names known to be blocked.

On Linux, Apple platforms, (administrator privileges required) Windows, the wait time can be automatically detected. Otherwise, it will fall back to waiting for a fixed time specified by `fragment_fallback_delay`.

In addition, if the actual wait time is less than 20ms, it will also fall back to waiting for a fixed time, because the target is considered to be local or behind a transparent proxy.

#### fragment_fallback_delay

Since sing-box 1.12.0

Client only

The fallback value used when TLS segmentation cannot automatically determine the wait time.

`500ms` is used by default.

#### record_fragment

Since sing-box 1.12.0

Client only

Fragment TLS handshake into multiple TLS records to bypass firewalls.

#### spoof

Since sing-box 1.14.0

Client only, Linux/macOS/Windows only, requires elevated privileges

Inject a forged TLS ClientHello carrying a whitelisted SNI before the real one, to fool SNI-filtering middleboxes that permit specific hostnames.

The forged segment is a copy of the real ClientHello with only the SNI value replaced by the value of this field, so TLS fingerprinting cannot distinguish it from the real one. The receiving server drops the forged segment (see `spoof_method`) while the middlebox treats it as a legitimate session.

Requires raw-socket access (`CAP_NET_RAW` on Linux, root on macOS); on Linux, `CAP_NET_ADMIN` is additionally required because the send sequence number is read via `TCP_REPAIR`. On Windows, Administrator is required to install the embedded WinDivert kernel driver on first use. Windows on ARM64 is not supported.

#### spoof_method

Since sing-box 1.14.0

Client only

How the forged segment is rejected by the real server.

Value | Behavior
--- | ---
`wrong-sequence` (default) | The forged segment's TCP sequence number is placed before the server's receive window.
`wrong-checksum` | The forged segment's TCP checksum is deliberately invalid.
`wrong-ack` | The forged segment's TCP acknowledgment number is placed before the server's send window.
`wrong-md5` | The forged segment carries a TCP-MD5 signature option, which the server rejects since no MD5 key is negotiated.
`wrong-timestamp` | The forged segment carries a backdated TCP timestamp, which the server rejects as a PAWS replay. Linux/Windows only; not supported on macOS.

### ACME Fields

Deprecated in sing-box 1.14.0

Inline ACME options are deprecated in sing-box 1.14.0 and will be removed in sing-box 1.16.0, check Migration.

#### domain

List of domain.

ACME will be disabled if empty.

#### data_directory

The directory to store ACME data.

`$XDG_DATA_HOME/certmagic|$HOME/.local/share/certmagic` will be used if empty.

#### default_server_name

Server name to use when choosing a certificate if the ClientHello's ServerName field is empty.

#### email

The email address to use when creating or selecting an existing ACME server account

#### provider

The ACME CA provider to use.

Value | Provider
--- | ---
`letsencrypt (default)` | Let's Encrypt
`zerossl` | ZeroSSL
`https://...` | Custom

#### disable_http_challenge

Disable all HTTP challenges.

#### disable_tls_alpn_challenge

Disable all TLS-ALPN challenges

#### alternative_http_port

The alternate port to use for the ACME HTTP challenge; if non-empty, this port will be used instead of 80 to spin up a listener for the HTTP challenge.

#### alternative_tls_port

The alternate port to use for the ACME TLS-ALPN challenge; the system must forward 443 to this port for challenge to succeed.

#### external_account

EAB (External Account Binding) contains information necessary to bind or map an ACME account to some other account known by the CA.

External account bindings are "used to associate an ACME account with an existing account in a non-ACME system, such as a CA customer database.

To enable ACME account binding, the CA operating the ACME server needs to provide the ACME client with a MAC key and a key identifier, using some mechanism outside of ACME. §7.3.4

#### external_account.key_id

The key identifier.

#### external_account.mac_key

The MAC key.

#### dns01_challenge

ACME DNS01 challenge field. If configured, other challenge methods will be disabled.

See DNS01 Challenge Fields for details.

### Reality Fields

#### handshake

Server only

Required

Handshake server address and Dial Fields.

#### private_key

Server only

Required

Private key, generated by `sing-box generate reality-keypair`.

#### public_key

Client only

Required

Public key, generated by `sing-box generate reality-keypair`.

#### short_id

Required

A hexadecimal string with zero to eight digits.

#### max_time_difference

Server only

The maximum time difference between the server and the client.

Check disabled if empty.