Skip to main content

Overview

TurkeyDPI uses TOML configuration files for advanced customization. While ISP presets work for most users, configuration files give you fine-grained control over bypass behavior.

Generating a Configuration File

The easiest way to start is by generating an example configuration:
turkeydpi gen-config --output config.toml
Creates a TOML file with all available options and comments.

Configuration Structure

A TurkeyDPI configuration file has five main sections:
[global]          # Global settings and master switches
[[rules]]         # Traffic matching and transform rules
[limits]          # Resource and safety limits
[transforms]      # Transform-specific parameters

Global Section

Top-level configuration and master switches.
[global]
enabled = true
enable_fragmentation = true
enable_jitter = false
enable_padding = true
enable_header_normalization = true
log_level = "info"
json_logging = false
Type: booleanDefault: trueDescription: Master switch for the entire engine. Set to false to disable all processing.
enabled = true
Type: booleanDefault: trueDescription: Global toggle for packet fragmentation. When false, no fragmentation occurs regardless of rules.
enable_fragmentation = true
Type: booleanDefault: falseDescription: Enable timing jitter (delays) between fragments. Useful against DPI systems that buffer packets.
enable_jitter = false  # Set true for aggressive bypass
Type: booleanDefault: trueDescription: Enable random padding to packets. Makes traffic analysis harder.
enable_padding = true
Type: booleanDefault: trueDescription: Normalize packet headers (randomize IP ID, etc.) to evade fingerprinting.
enable_header_normalization = true
Type: stringDefault: "info"Options: "trace", "debug", "info", "warn", "error"Description: Logging verbosity level.
log_level = "info"  # Use "debug" for troubleshooting
Type: booleanDefault: falseDescription: Output logs in JSON format for machine parsing.
json_logging = false

Rules Section

Rules define which traffic to transform and how. Rules are evaluated in priority order (highest first).

Basic Rule Structure

[[rules]]
name = "https-evasion"
enabled = true
priority = 100
transforms = ["fragment", "padding"]

[rules.match_criteria]
dst_ports = [443]
protocols = ["tcp"]

Rule Fields

Type: stringRequired: YesDescription: Human-readable rule identifier.
name = "https-evasion"
Type: booleanDefault: trueDescription: Enable or disable this rule.
enabled = true
Type: integerDefault: 0Description: Rule priority. Higher numbers are evaluated first.
priority = 100  # Evaluated before priority 90
Type: array of stringsRequired: YesOptions: "fragment", "resegment", "padding", "jitter", "decoy"Description: List of transforms to apply when this rule matches.
transforms = ["fragment", "padding"]
Type: table (key-value pairs)Optional: YesDescription: Per-rule parameter overrides.
# Override fragment max_size for this rule only
overrides = { "fragment.max_size" = 20 }

Match Criteria

Rules match traffic based on these criteria:
Type: array of integersDescription: Match packets to these destination ports.
[rules.match_criteria]
dst_ports = [443]  # HTTPS traffic
Example - Multiple ports:
dst_ports = [80, 8080, 8443]  # HTTP and alternate HTTPS ports
Type: array of stringsOptions: "tcp", "udp"Description: Match specific protocols.
[rules.match_criteria]
protocols = ["tcp"]
Type: array of stringsDescription: Match packets to specific IP addresses or CIDR ranges.
[rules.match_criteria]
dst_ip = ["104.16.0.0/12", "172.64.0.0/13"]  # Cloudflare IPs

Example Rules

[[rules]]
name = "https-evasion"
enabled = true
priority = 100
transforms = ["fragment", "padding"]

[rules.match_criteria]
dst_ports = [443]
protocols = ["tcp"]

Limits Section

Resource and safety limits prevent abuse and crashes.
[limits]
max_flows = 10000
max_queue_size = 1000
max_memory_mb = 128
max_jitter_ms = 500
flow_timeout_secs = 120
log_rate_limit = 100
Type: integerDefault: 10000Description: Maximum concurrent flows (connections) to track.
max_flows = 10000
Type: integerDefault: 1000Description: Maximum packets in processing queue.
max_queue_size = 1000
Type: integerDefault: 128Description: Maximum memory usage in megabytes.
max_memory_mb = 128
Type: integerDefault: 500Description: Maximum jitter delay in milliseconds.
max_jitter_ms = 500
Type: integerDefault: 120Description: Idle timeout for flows in seconds.
flow_timeout_secs = 120  # 2 minutes
Type: integerDefault: 100Description: Maximum log messages per second.
log_rate_limit = 100

Transforms Section

Parameters for each transform type.

Fragment Transform

Splits packets into smaller fragments.
[transforms.fragment]
min_size = 1
max_size = 40
split_at_offset = null
randomize = true
ParameterTypeDefaultDescription
min_sizeinteger1Minimum fragment size in bytes
max_sizeinteger40Maximum fragment size in bytes
split_at_offsetinteger or nullnullFixed split offset (null = dynamic)
randomizebooleantrueRandomize fragment sizes
Example - Aggressive fragmentation:
[transforms.fragment]
min_size = 1
max_size = 5  # Very small fragments
randomize = true
Example - Fixed split:
[transforms.fragment]
min_size = 1
max_size = 40
split_at_offset = 2  # Always split at byte 2
randomize = false

Resegment Transform

Resegments TCP streams into different sizes.
[transforms.resegment]
segment_size = 16
max_segments = 8
ParameterTypeDefaultDescription
segment_sizeinteger16Target segment size in bytes
max_segmentsinteger8Maximum segments per packet

Padding Transform

Adds random padding to packets.
[transforms.padding]
min_bytes = 0
max_bytes = 64
fill_byte = null
ParameterTypeDefaultDescription
min_bytesinteger0Minimum padding bytes
max_bytesinteger64Maximum padding bytes
fill_byteinteger or nullnullFill byte (null = random)
Example - Fixed padding:
[transforms.padding]
min_bytes = 32
max_bytes = 32  # Always 32 bytes
fill_byte = 0   # Fill with zeros

Jitter Transform

Adds timing delays between fragments.
[transforms.jitter]
min_ms = 0
max_ms = 50
ParameterTypeDefaultDescription
min_msinteger0Minimum delay in milliseconds
max_msinteger50Maximum delay in milliseconds
Example - Fixed delay:
[transforms.jitter]
min_ms = 10
max_ms = 10  # Always 10ms

Header Transform

Modifies packet headers.
[transforms.header]
normalize_ttl = false
ttl_value = 64
normalize_window = false
randomize_ip_id = true
ParameterTypeDefaultDescription
normalize_ttlbooleanfalseSet fixed TTL value
ttl_valueinteger64TTL value if normalized
normalize_windowbooleanfalseSet fixed TCP window size
randomize_ip_idbooleantrueRandomize IP ID field

Decoy Transform

Sends fake packets with low TTL.
[transforms.decoy]
send_before = false
send_after = false
ttl = 1
probability = 0.0
ParameterTypeDefaultDescription
send_beforebooleanfalseSend decoy before real packet
send_afterbooleanfalseSend decoy after real packet
ttlinteger1TTL for decoy packets
probabilityfloat0.0Probability of sending decoys (0.0-1.0)

Complete Example

Here’s a complete configuration file combining all sections:
# Global settings
[global]
enabled = true
enable_fragmentation = true
enable_jitter = false
enable_padding = true
enable_header_normalization = true
log_level = "info"
json_logging = false

# HTTPS bypass rule
[[rules]]
name = "https-evasion"
enabled = true
priority = 100
transforms = ["fragment", "padding"]

[rules.match_criteria]
dst_ports = [443]
protocols = ["tcp"]

# HTTP bypass rule
[[rules]]
name = "http-evasion"
enabled = true
priority = 90
transforms = ["resegment", "padding"]

[rules.match_criteria]
dst_ports = [80, 8080]
protocols = ["tcp"]

# DNS protection rule
[[rules]]
name = "dns-protection"
enabled = true
priority = 80
transforms = ["padding"]

[rules.match_criteria]
dst_ports = [53]
protocols = ["udp"]

# Resource limits
[limits]
max_flows = 10000
max_queue_size = 1000
max_memory_mb = 128
max_jitter_ms = 500
flow_timeout_secs = 120
log_rate_limit = 100

# Transform parameters
[transforms.fragment]
min_size = 1
max_size = 40
randomize = true

[transforms.resegment]
min_segment_size = 1
max_segment_size = 100
max_segments = 10

[transforms.padding]
min_bytes = 0
max_bytes = 64
fill = "random"

[transforms.jitter]
min_ms = 0
max_ms = 50
distribution = "uniform"

[transforms.header]
randomize_ip_id = true
strip_tcp_timestamps = false

[transforms.decoy]
probability = 0.1
send_before = false
send_after = true
max_per_flow = 3

Using Configuration Files

1

Create configuration

Generate or write your configuration file:
turkeydpi gen-config --output custom.toml
2

Edit configuration

Modify the file to suit your needs:
nano custom.toml
3

Validate configuration

Check for errors:
turkeydpi validate custom.toml
Output:
✓ Configuration is valid: custom.toml
4

Run with configuration

Start TurkeyDPI with your custom config:
turkeydpi run --proxy --config custom.toml

Reloading Configuration

You can reload configuration without restarting:
1

Start daemon

Run TurkeyDPI in daemon mode:
turkeydpi run --proxy --config config.toml
2

Edit configuration

Modify config.toml while the daemon is running.
3

Reload

Apply changes without downtime:
turkeydpi reload config.toml
Output:
Configuration reloaded
Configuration reloading applies changes to new connections. Existing connections continue using old settings until they close.

Common Configurations

Minimal Latency

Optimized for speed (works on Türk Telekom):
[global]
enabled = true
enable_fragmentation = true
enable_jitter = false  # No delays
enable_padding = false
log_level = "warn"

[[rules]]
name = "https-minimal"
enabled = true
priority = 100
transforms = ["fragment"]

[rules.match_criteria]
dst_ports = [443]
protocols = ["tcp"]

[transforms.fragment]
min_size = 1
max_size = 20
split_at_offset = 2  # Fixed split at byte 2
randomize = false

[transforms.jitter]
min_ms = 0
max_ms = 0  # No jitter

Maximum Bypass

Aggressive configuration for difficult networks:
[global]
enabled = true
enable_fragmentation = true
enable_jitter = true
enable_padding = true
enable_header_normalization = true
log_level = "info"

[[rules]]
name = "aggressive-bypass"
enabled = true
priority = 100
transforms = ["fragment", "jitter", "padding", "decoy"]

[rules.match_criteria]
dst_ports = [443, 80, 8080]
protocols = ["tcp"]

[transforms.fragment]
min_size = 1
max_size = 5  # Very small fragments
randomize = true

[transforms.jitter]
min_ms = 5
max_ms = 20  # Random delays

[transforms.padding]
min_bytes = 0
max_bytes = 64

[transforms.decoy]
probability = 0.2  # 20% chance of decoy packets
send_before = true
ttl = 1

DNS Only

Protect DNS queries without affecting other traffic:
[global]
enabled = true
enable_fragmentation = false
enable_padding = true
log_level = "info"

[[rules]]
name = "dns-only"
enabled = true
priority = 100
transforms = ["padding"]

[rules.match_criteria]
dst_ports = [53]
protocols = ["udp"]

[transforms.padding]
min_bytes = 32
max_bytes = 64

Troubleshooting

Configuration validation fails

Error: “Configuration error: …”
  1. Check TOML syntax:
    # Use a TOML validator
    cat config.toml | python3 -c "import sys, toml; toml.load(sys.stdin)"
    
  2. Check for typos: Common mistakes:
    • enable = true instead of enabled = true
    • port = [443] instead of dst_ports = [443]
    • Missing quotes: protocols = [tcp] instead of protocols = ["tcp"]
  3. Use generated config as base:
    turkeydpi gen-config > base.toml
    
    Compare with your config.

Rules not matching

If your rules don’t seem to work:
  1. Check rule priority: Higher priority rules are evaluated first.
  2. Enable debug logging:
    log_level = "debug"
    
    Look for “Rule matched” messages.
  3. Simplify match criteria: Start with just port matching:
    [rules.match_criteria]
    dst_ports = [443]
    

Performance issues

If TurkeyDPI is slow:
  1. Reduce fragment size:
    [transforms.fragment]
    max_size = 40  # Increase from 5
    
  2. Disable jitter:
    enable_jitter = false
    
  3. Reduce logging:
    log_level = "warn"  # Less verbose
    

Next Steps

Basic Usage

Return to basic CLI usage

ISP Presets

Learn about built-in presets

Build docs developers (and LLMs) love