Proxies
Each [[proxy]] entry is one upstream server that you operate or are authorized to use. Rules, groups and global-proxy refer to it by name. Specola ships with no servers; the built-in targets DIRECT and REJECT always exist.
[[proxy]]
name = "office"
type = "http"
server = "proxy.example.com"
port = 8080Common fields
| Field | Required | Notes |
|---|---|---|
name | yes | unique; no commas, no ::; cannot be DIRECT or REJECT |
type | yes | one of the types below |
server | yes | host name or IP address |
port | yes | 1–65535 |
dialer-proxy | no | name of another proxy to connect through, see Proxy Chains |
[proxy.tls] | no | TLS settings, see TLS |
[proxy.transport] | no | WebSocket, gRPC or HTTP carrier, see Transports |
Names are case-sensitive everywhere they are referenced.
Types
type | Protocol | Required fields |
|---|---|---|
http | HTTP proxy (CONNECT), optionally over TLS | — |
socks5 | SOCKS5, optionally over TLS | — |
ss or shadowsocks | Shadowsocks | cipher, password |
trojan | Trojan (always TLS) | password |
vmess | VMess | uuid |
vless | VLESS | uuid |
hysteria2 | Hysteria 2 (always TLS, QUIC) | password |
tuic | TUIC v5 (always TLS, QUIC) | uuid, password |
anytls | AnyTLS (always TLS) | password |
ssh, mieru and sudoku are recognized but not included in the current build, and a profile that uses them is rejected.
HTTP
[[proxy]]
name = "office"
type = "http"
server = "proxy.example.com"
port = 8080
username = "me" # optional
password = "change-me" # optionalFor an HTTPS proxy, add a TLS block:
[[proxy]]
name = "office-tls"
type = "http"
server = "proxy.example.com"
port = 8443
username = "me"
password = "change-me"
[proxy.tls]
server-name = "proxy.example.com"Optional: path, headers (a table of extra request headers) and early-data (boolean).
SOCKS5
[[proxy]]
name = "lab"
type = "socks5"
server = "10.0.0.5"
port = 1080
username = "me" # optional
password = "change-me" # optional
udp = true # allow UDP ASSOCIATEA TLS block is also accepted, for SOCKS5 over TLS.
Shadowsocks
[[proxy]]
name = "ss-home"
type = "ss"
server = "home.example.com"
port = 8388
cipher = "2022-blake3-aes-128-gcm"
password = "base64-key-from-your-server"Supported ciphers: aes-128-gcm, aes-256-gcm, chacha20-ietf-poly1305, 2022-blake3-aes-128-gcm, 2022-blake3-aes-256-gcm. For the 2022-* ciphers the password is the base64 key from the server configuration. A TLS block is not allowed for Shadowsocks.
Trojan
[[proxy]]
name = "trojan-home"
type = "trojan"
server = "home.example.com"
port = 443
password = "change-me"
udp = true
[proxy.tls]
server-name = "home.example.com"TLS is always on. Without alpn, Trojan offers h2 and http/1.1.
VMess
[[proxy]]
name = "vmess-home"
type = "vmess"
server = "home.example.com"
port = 443
uuid = "00000000-0000-0000-0000-000000000000"
alterId = 0
cipher = "auto"
[proxy.tls]
server-name = "home.example.com"
[proxy.transport]
type = "ws"
path = "/ws"Optional: global-padding, authenticated-length, packet-encoding (packetaddr or xudp), udp.
VLESS
[[proxy]]
name = "vless-home"
type = "vless"
server = "home.example.com"
port = 443
uuid = "00000000-0000-0000-0000-000000000000"
flow = "xtls-rprx-vision"
[proxy.tls]
server-name = "www.example.com"
[proxy.tls.reality]
enabled = true
public-key = "public-key-from-your-server"
short-id = "0123abcd"flow and encryption are optional. Reality is supported for VLESS (and for HTTP and SOCKS5).
Hysteria2
[[proxy]]
name = "hy2-home"
type = "hysteria2"
server = "home.example.com"
port = 443
password = "change-me"
down = "100 mbps"
[proxy.tls]
server-name = "home.example.com"Optional: obfs with obfs-password for Salamander obfuscation.
TUIC
[[proxy]]
name = "tuic-home"
type = "tuic"
server = "home.example.com"
port = 443
uuid = "00000000-0000-0000-0000-000000000000"
password = "change-me"
congestion-control = "bbr"
udp-relay-mode = "native"
[proxy.tls]
server-name = "home.example.com"
alpn = ["h3"]Optional: heartbeat-interval, request-timeout, reduce-rtt, fast-open, disable-sni, max-open-streams, max-udp-relay-packet-size, ip.
AnyTLS
[[proxy]]
name = "anytls-home"
type = "anytls"
server = "home.example.com"
port = 443
password = "change-me"
[proxy.tls]
server-name = "home.example.com"Optional: idle_session_check_interval, idle_session_timeout (duration strings) and min_idle_session (integer).
TLS
Add [proxy.tls] directly after the [[proxy]] it belongs to. Its presence turns TLS on.
| Field | Notes |
|---|---|
enabled | defaults to true when the block exists; false turns TLS off for http, socks5, vmess, vless |
server-name (alias sni) | name sent in SNI and checked against the certificate |
alpn | list of protocols; only for vmess, vless, trojan, tuic |
certificate | list of PEM strings to trust |
certificate-path | path to a PEM file to trust |
skip-cert-verify (alias insecure) | disables certificate checks; only for testing |
Reality (VLESS, HTTP, SOCKS5):
| Field | Notes |
|---|---|
[proxy.tls.reality] enabled | true to use Reality |
public-key | required |
short-id | at most one value |
These TLS fields are recognized but rejected by the current build: min-version, max-version, cipher-suites, curve-preferences, fingerprint, client certificates and keys, ech, acme.
Transports
[proxy.transport] wraps the connection in another carrier. Set type and its fields:
type | Fields |
|---|---|
ws | path, host, headers, max-early-data, early-data-header-name |
httpupgrade | path, host, headers |
grpc | service-name, authority, multi-mode, user-agent |
http | path, host, method, headers |
[proxy.transport]
type = "grpc"
service-name = "tunnel"Checks before you continue
- Test a new proxy with
route-mode = "global"andglobal-proxy = "<name>"before writing rules for it. If Global fails, the problem is the proxy, not your rules. - Keep credentials out of shared repositories, logs and screenshots. If you keep your profile in dotfiles, keep that repository private.