Fragment
An outbound overlay that cuts the TLS ClientHello into pieces, so DPI that reads the server name (SNI) without reassembling never sees it whole. Only the ClientHello, sent in the clear, is cut; nothing is decrypted, and the server reassembles it unaware.
Put it directly below the layer that sends the ClientHello: under freedom, the user's own browser's; in a proxy outbound, below tls.
Structure
{
"type": "fragment",
"settings": {
"tls_records": true,
"tcp_packets": true,
"piece_sizes": ["3-5", "10-20"],
"piece_delays": ["10-20ms"],
"max_pieces": "4-8",
"split_sni": true
}
}These are the defaults, so { "type": "fragment" } behaves the same.
Fields
tls_records
booleanDefault: true
Cut the ClientHello into several TLS records. Beats DPI that parses only the first record.
tcp_packets
booleanDefault: true
Send the pieces as separate TCP packets. Beats DPI that inspects each packet alone. At least one of the two must be on.
piece_sizes
list of rangesDefault: ["3-5", "10-20"]
Piece sizes in bytes, such as "5" or "3-5", picked per connection. The n-th entry sizes the n-th piece; the last repeats.
piece_delays
list of duration rangesDefault: ["10-20ms"]
The wait after each piece, by the same rule, such as "10ms" or "10-20ms". Needs tcp_packets. The defaults add about 70 to 140 ms to the TLS handshake.
max_pieces
rangeDefault: "4-8"
The most pieces, at least 2. The last piece takes what remains.
split_sni
booleanDefault: true
Always cut once inside the server name, so no piece holds it whole.
It does not beat DPI that reassembles connections, blocking by IP, TLS fingerprinting, or SNI allow-lists.
From Xray or sing-box
| Xray | sing-box | Apranik |
|---|---|---|
packets: "tlshello" | tls_record_fragment | tls_records: true |
delays above 0 | tls_fragment | tcp_packets: true |
lengths | – | piece_sizes |
delays (ms) | – | piece_delays, with a unit: "10-20ms" |
maxSplit | – | max_pieces |