Configuration Reference
Complete reference for all trojan-rs configuration options
trojan-rs supports TOML, YAML, JSON, and JSONC configuration formats. This page documents every available option.
Server Configuration
[server]
listen = "0.0.0.0:443" # Listening address (required)
fallback = "127.0.0.1:80" # Fallback address for non-Trojan traffic (required)
tcp_idle_timeout_secs = 600 # TCP idle timeout (default: 600)
udp_timeout_secs = 60 # UDP association timeout (default: 60)
max_udp_payload = 8192 # Maximum UDP payload size (default: 8192)
max_udp_buffer_bytes = 8192 # Maximum UDP buffer size (default: 8192)
max_header_bytes = 8192 # Maximum Trojan header size (default: 8192)
max_connections = 10000 # Max concurrent connections (optional, unlimited by default)TCP Socket Options
[server.tcp]
no_delay = true # Disable Nagle's algorithm (default: true)
keepalive_secs = 300 # TCP Keep-Alive interval, 0 = disabled (default: 300)
reuse_port = false # SO_REUSEPORT for multi-process (default: false)
fast_open = false # TCP Fast Open (default: false)
fast_open_qlen = 5 # TFO queue length (default: 5)
prefer_ipv4 = false # Prefer IPv4 for outbound DNS resolution (default: false)Rate Limiting
[server.rate_limit]
max_connections_per_ip = 100 # Max new connections per IP per window (default: 100)
window_secs = 60 # Time window in seconds (default: 60)
cleanup_interval_secs = 300 # Expired entry cleanup interval (default: 300)Fallback Connection Pool
Pre-connects to the fallback server to reduce latency for non-Trojan traffic.
[server.fallback_pool]
max_idle = 10 # Maximum idle connections (default: 10)
max_age_secs = 30 # Maximum connection age (default: 30)
fill_batch = 5 # Connections to open per cycle (default: 5)
fill_delay_ms = 100 # Delay between connection attempts (default: 100)Resource Limits
[server.resource_limits]
relay_buffer_size = 8192 # Buffer size for TCP relay (default: 8192)
tcp_send_buffer = 0 # SO_SNDBUF size, 0 = OS default (default: 0)
tcp_recv_buffer = 0 # SO_RCVBUF size, 0 = OS default (default: 0)
connection_backlog = 1024 # TCP listener backlog (default: 1024)TLS Configuration
[tls]
cert = "/etc/trojan/cert.pem" # Certificate file path, PEM format (required)
key = "/etc/trojan/key.pem" # Private key file path, PEM format (required)
alpn = ["http/1.1"] # ALPN protocols (default: [])
min_version = "tls12" # Minimum TLS version (default: "tls12")
max_version = "tls13" # Maximum TLS version (default: "tls13")
client_ca = "/path/to/ca.pem" # CA cert for mTLS client verification (optional)
cipher_suites = [] # Custom cipher suites (default: rustls defaults)Cipher Suites
When cipher_suites is empty, rustls defaults are used. Available suites:
TLS13_AES_256_GCM_SHA384TLS13_AES_128_GCM_SHA256TLS13_CHACHA20_POLY1305_SHA256TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
Authentication
In-Memory Passwords
[auth]
passwords = ["password1", "password2"]Passwords are stored as plaintext in the config and hashed (SHA-224) at runtime. The 56-byte hex hash is used for protocol authentication.
Named Users
Users can have explicit IDs for identification in logs and analytics:
[[auth.users]]
id = "alice"
password = "secret1"
[[auth.users]]
id = "bob"
password = "secret2"Both passwords and users can be used together. The id field is used for logging and traffic tracking.
SQL Database
For SQL-based auth, omit the [auth] section and use the CLI to manage users against a database. See Authentication and User Management.
WebSocket Configuration
[websocket]
enabled = true # Enable WebSocket transport (default: false)
mode = "mixed" # "mixed" or "only" (default: "mixed")
path = "/ws" # WebSocket endpoint path (default: "/ws")
host = "cdn.example.com" # Expected Host header (optional)
listen = "0.0.0.0:8080" # Separate WebSocket listen address (optional)
max_frame_bytes = 16384 # Maximum WebSocket frame size (default: 16384)Modes
mixed— Accept both raw TLS and WebSocket connections on the same portonly— Accept only WebSocket connections
See WebSocket Transport for details.
Metrics
[metrics]
listen = "127.0.0.1:9100" # Prometheus metrics endpoint (optional)When configured, exposes /metrics, /health, and /ready HTTP endpoints. See Metrics.
Logging
[logging]
level = "info" # Log level: trace, debug, info, warn, error
format = "pretty" # Format: json, pretty, compact (default: pretty)
output = "stderr" # Output: stdout, stderr (default: stderr)
[logging.filters]
trojan_auth = "debug" # Per-module log level overrides
rustls = "warn"See Logging.
Analytics
[analytics]
enabled = true
[analytics.clickhouse]
url = "http://localhost:8123"
database = "trojan"
table = "connection_events"
username = "default"
password = ""
[analytics.buffer]
max_events = 1000
flush_interval_secs = 10
[analytics.sampling]
rate = 1.0 # 0.0 to 1.0
allowed_users = [] # Always sample these users
[analytics.privacy]
record_ip = true
mask_user_id = false
record_sni = trueSee Analytics.
Rule-Based Routing
Route connections to different outbound connectors based on domain, IP, GeoIP, or rule providers.
Outbound Connectors
[server.outbounds.proxy-jp]
type = "trojan" # "trojan", "direct", or "reject"
addr = "jp-server.example.com:443"
password = "proxy-password"
sni = "jp-server.example.com"
[server.outbounds.direct-out]
type = "direct"
bind = "0.0.0.0" # Bind to specific local IP (optional)Routing Rules
Rules are evaluated in order (first match wins):
[[server.rules]]
type = "DOMAIN-SUFFIX" # Rule type
value = ".cn" # Rule value
outbound = "direct-out" # Action: outbound name, "DIRECT", or "REJECT"
[[server.rules]]
type = "GEOIP"
value = "CN"
outbound = "DIRECT"
[[server.rules]]
rule-set = "blocked-domains" # Reference a rule provider
outbound = "REJECT"
[[server.rules]]
type = "FINAL" # Default action (must be last)
outbound = "proxy-jp"Supported rule types: DOMAIN, DOMAIN-SUFFIX, DOMAIN-KEYWORD, IP-CIDR, IP-CIDR6, GEOIP, DST-PORT, SRC-IP-CIDR, RULE-SET, FINAL.
Rule Providers
Load external rule sets from files or URLs:
[server.rule-providers.blocked-domains]
format = "surge" # "surge" or "clash"
source = "file" # "file" or "http"
path = "/etc/trojan/rules/blocked.list"
[server.rule-providers.gfw-list]
format = "clash"
behavior = "domain" # "domain", "ipcidr", "classical", "domain-set"
source = "http"
url = "https://example.com/rules.yaml"
interval = 86400 # Update interval in seconds (for http)
path = "/tmp/cache/gfw-list.yaml" # Local cache pathGeoIP Database
[server.geoip]
source = "geolite2-country" # Built-in source name (default)
# path = "/path/to/GeoLite2-Country.mmdb" # Local file (highest priority)
# url = "https://example.com/geo.mmdb" # Custom download URL
auto_update = true # Auto-update in background (default: true)
interval = 604800 # Update interval in seconds (default: 7 days)
cache_path = "/tmp/trojan-geoip.mmdb" # Cache file for downloadsBuilt-in sources: geolite2-country, geolite2-city, dbip-country, dbip-city, iptoasn-country, and more. Databases are auto-downloaded from CDN.
See Rule-Based Routing for a complete guide.
Complete Example
[server]
listen = "0.0.0.0:443"
fallback = "127.0.0.1:80"
tcp_idle_timeout_secs = 600
udp_timeout_secs = 60
[server.tcp]
no_delay = true
keepalive_secs = 300
reuse_port = false
fast_open = false
[server.rate_limit]
max_connections_per_ip = 100
window_secs = 60
[tls]
cert = "/etc/trojan/cert.pem"
key = "/etc/trojan/key.pem"
alpn = ["http/1.1"]
[auth]
passwords = ["password1", "password2"]
[websocket]
enabled = true
mode = "mixed"
path = "/ws"
[metrics]
listen = "127.0.0.1:9100"
[logging]
level = "info"
format = "pretty"