Skip to content

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":

FieldTypeDefaultAllowed valuesDescription
userstring(server-dependent)<username>SSH login name.
passwordstring(unset)<string>Password authentication. Mutually used with key auth — sing-box tries password first if both are set.
private_keybadoption.Listable[string][]<PEM block>Inline private key(s). Accepts a single PEM string or a list of PEM strings.
private_key_pathstring(unset)<file path>Path to a private-key file. Overrides private_key if both are set.
private_key_passphrasestring(unset)<string>Passphrase used to unlock encrypted private keys.
host_keybadoption.Listable[string][]<key string>Expected host keys (authorized_keys format). Empty disables verification — useful only for testing.
host_key_algorithmsbadoption.Listable[string](library default)<algo>Restrict the host-key algorithms the client accepts. Useful for old servers.
client_versionstring(library default)<SSH version string>Client version banner. Override to mimic OpenSSH or a specific build.
cipherbadoption.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.
macbadoption.Listable[string](library default)<algo>Allowed MAC algorithms (e.g. hmac-sha2-256-etm@openssh.com). Empty uses the SSH library defaults.
kex_algorithmbadoption.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_server serves SSH only on the tailnet.)
  • host_key is in OpenSSH known_hosts-style format. Empty host_key means "trust any host key" — not safe for production.
  • private_key accepts 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 (not user), 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)

Core Tutorial by Argsment