SSH — sing-box
sing-box ships an SSH client outbound. The standard SSH features — password auth, key auth with passphrase, host-key pinning, banner override — are all exposed.
Outbound
type: "ssh":
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
user | string | (server-dependent) | <username> | SSH login name. |
password | string | (unset) | <string> | Password authentication. Mutually used with key auth — sing-box tries password first if both are set. |
private_key | badoption.Listable[string] | [] | <PEM block> | Inline private key(s). Accepts a single PEM string or a list of PEM strings. |
private_key_path | string | (unset) | <file path> | Path to a private-key file. Overrides private_key if both are set. |
private_key_passphrase | string | (unset) | <string> | Passphrase used to unlock encrypted private keys. |
host_key | badoption.Listable[string] | [] | <key string> | Expected host keys (authorized_keys format). Empty disables verification — useful only for testing. |
host_key_algorithms | badoption.Listable[string] | (library default) | <algo> | Restrict the host-key algorithms the client accepts. Useful for old servers. |
client_version | string | (library default) | <SSH version string> | Client version banner. Override to mimic OpenSSH or a specific build. |
cipher | badoption.Listable[string] | (library default) | <algo> | Allowed ciphers, in preference order (e.g. aes128-ctr, chacha20-poly1305@openssh.com). Empty uses the SSH library defaults. Useful for old servers. |
mac | badoption.Listable[string] | (library default) | <algo> | Allowed MAC algorithms (e.g. hmac-sha2-256-etm@openssh.com). Empty uses the SSH library defaults. |
kex_algorithm | badoption.Listable[string] | (library default) | <algo> | Allowed key-exchange algorithms (e.g. curve25519-sha256). Empty uses the SSH library defaults. |
Source: option/ssh.go:5-19 · pinned at v1.14.2 (af6e64c)
Embeds DialerOptions and ServerOptions (server, server_port).
Examples
Key-based auth, pinned host key:
json
{
"outbounds": [
{
"type": "ssh",
"tag": "ssh-out",
"server": "ssh.example.com",
"server_port": 22,
"user": "alice",
"private_key_path": "/etc/sing-box/id_ed25519",
"private_key_passphrase": "<passphrase>",
"host_key": ["ssh.example.com ssh-ed25519 AAAA..."]
}
]
}Password auth with banner spoofing:
json
{
"outbounds": [
{
"type": "ssh",
"tag": "ssh-spoof",
"server": "ssh.example.com",
"server_port": 22,
"user": "alice",
"password": "<password>",
"client_version": "SSH-2.0-OpenSSH_9.6"
}
]
}Notes
- The SSH outbound is client-only — sing-box does not implement an SSH-server inbound. (The Tailscale endpoint's
ssh_serverserves SSH only on the tailnet.) host_keyis in OpenSSHknown_hosts-style format. Emptyhost_keymeans "trust any host key" — not safe for production.private_keyaccepts a list because a host may rotate keys; sing-box tries them in order until one is accepted.
Cross-core notes
- Xray-core does not implement SSH. See SSH — Xray-core.
- mihomo uses
username(notuser), kebab-case for the rest (private-key-passphrase,host-key-algorithms), and takes the private key as a single string rather than a list. See SSH — mihomo.
Source: option/ssh.go:5-19 · v1.14.2 (af6e64c)
