Traversio

Connection Configuration

How to choose endpoint, trust, transport, and routing settings for an SSH connection.

SSHClientConfiguration is the complete description of one SSH connection attempt. It answers four practical questions:

  • where to connect
  • how to authenticate
  • how to trust the server
  • how the transport should behave once the session is up

If you use jump hosts, SSHProxyJumpHost repeats the same per-hop transport knobs on each SSH hop. The root SSHClientConfiguration continues to describe the final target and any outer connectionProxy used before the first SSH handshake starts.

Defaults At A Glance

FieldDefaultWhat it controls
hostrequiredFinal target host name or address
port22Final target port
usernamerequiredSSH username
authenticationrequiredUser authentication method
hostKeyPolicyrequiredHost trust policy
compressionPreference.disabledWhether to advertise transport compression
legacyAlgorithmOptions.disabledOptional legacy host-key and RSA auth compatibility controls
automaticRekeyPolicy.currentProfileDefaultAutomatic client-initiated rekey thresholds
keepalivePolicy.disabledPost-auth idle keepalive behavior
timeoutPolicy.disabledConnection-setup and prompt-reply timeout behavior
connectionProxynilOptional outer SOCKS5 or HTTP CONNECT hop before SSH starts
proxyJumpHosts[]Optional SSH jump-host chain before the final target

The matching SSHProxyJumpHost fields are:

  • host
  • port
  • username
  • authentication
  • hostKeyPolicy
  • compressionPreference
  • legacyAlgorithmOptions
  • automaticRekeyPolicy
  • keepalivePolicy
  • timeoutPolicy

Endpoint, Auth, And Trust

These are the required inputs:

  • host
  • username
  • authentication
  • hostKeyPolicy

Typical choices:

  • use a stable DNS name when you rely on known_hosts hostnames or certificate principals
  • keep hostKeyPolicy strict in production; .acceptAnyVerifiedHostKey is only appropriate for disposable test targets
  • choose the simplest auth method your deployment already manages well: password for controlled lab/testing, public-key auth for normal production automation

Transport Settings

compressionPreference

Default: .disabled

Supported values:

  • .disabled
  • .zlib
  • .delayedZlib

.zlib means RFC 4253 zlib: compression starts as soon as the encrypted transport is active after each key exchange.

.delayedZlib means OpenSSH [email protected]: compression stays off during handshake and user authentication, then turns on only after authentication succeeds.

Use it when:

  • bandwidth is scarce
  • you expect larger shell, exec, or SFTP payloads
  • the target server is already known to support either RFC 4253 zlib or the OpenSSH delayed-zlib path

Leave it off when:

  • connections are short-lived
  • payloads are small
  • CPU cost matters more than wire size

automaticRekeyPolicy

Default: .currentProfileDefault

currentProfileDefault currently means:

  • outboundPacketThreshold: 1_048_576
  • inboundPacketThreshold: 1_048_576
  • idleTimeInterval: nil

Use a custom policy when:

  • you want tighter packet budgets on long-lived connections
  • you need an idle timer which triggers a client rekey even when the connection is quiet
  • you are reproducing or validating server behavior under more aggressive rekey conditions

Use .disabled only when you intentionally want to turn off client-initiated automatic rekey.

legacyAlgorithmOptions

Default: .disabled

Supported values:

  • .disabled
  • .sshRSA

SSHLegacyAlgorithmOptions.sshRSA enables Traversio's explicit legacy RSA compatibility path for one connection or one jump-host hop.

When it is enabled:

  • the connection appends ssh-rsa to the advertised server-host-key preference list
  • RSA public-key authentication still prefers rsa-sha2-512 and rsa-sha2-256
  • if the server declines the SHA-2 attempt and still offers publickey, Traversio retries with ssh-rsa

Use it when:

  • you target older SSH appliances, routers, NAS devices, or embedded systems
  • the server only advertises ssh-rsa host keys
  • the server accepts RSA keys only through the legacy SHA-1 signature path

Keep it disabled for current OpenSSH-family servers and other modern deployments.

keepalivePolicy

Default: .disabled

SSHKeepalivePolicy(interval: ...) sends a keepalive only after authentication succeeds and the connection has stayed idle for that interval.

Use it when:

  • the connection stays open for a long time
  • shells or forwarding sessions may sit idle between bursts
  • NAT or firewall devices may silently drop an otherwise idle TCP flow

Leave it disabled when:

  • the connection is short-lived
  • you mostly run one command or one SFTP transfer and then disconnect
  • extra background traffic is not desirable

Behavior:

  • keepalive applies to idle authenticated connections
  • timeoutPolicy remains the dedicated timeout control
  • long-running shell and exec reads keep their own streaming behavior

If you also set timeoutPolicy.responseTimeInterval, keepalive reply waits use the tighter of that reply timeout and the keepalive interval itself.

timeoutPolicy

Default: .disabled

SSHTimeoutPolicy has two independent knobs:

  • connectionSetupTimeInterval
  • responseTimeInterval

connectionSetupTimeInterval covers one connect attempt, including:

  • transport connection setup
  • identification exchange
  • key exchange
  • host-key trust evaluation
  • user authentication

responseTimeInterval covers waits where the peer should answer promptly, including:

  • channel-open replies
  • channel-request replies such as exec, pty-req, shell, and subsystem
  • global-request replies such as tcpip-forward
  • SFTP responses

responseTimeInterval covers prompt request or reply paths. Long-running streams continue independently, including:

  • long-running command output collection
  • interactive shell streams
  • remote-forward accept loops

Routing: Proxy Versus Jump Host

connectionProxy and proxyJumpHosts solve different problems.

Use connectionProxy when Traversio itself must first reach the SSH server through:

  • a SOCKS5 proxy
  • an HTTP CONNECT proxy

Use proxyJumpHosts when you want SSH hop chaining through one or more bastion hosts.

Important boundary:

  • connectionProxy is only for the outermost TCP hop before the first SSH handshake
  • proxyJumpHosts is the SSH-native hop chain after that

If you set both, the external proxy is used only for the first TCP connection. Later hops travel inside SSH direct-tcpip channels.

Rules Of Thumb

  • Start with the defaults and add only the knobs you actually need.
  • Add timeoutPolicy first for automation and background jobs. It usually gives more immediate value than keepalive.
  • Add keepalivePolicy for long-lived shells, tunnels, or idle monitoring connections.
  • Keep compression off unless you have a concrete bandwidth reason to turn it on.
  • Treat SSHProxyJumpHost as hop-specific transport policy. The final target still uses the root SSHClientConfiguration.

Example

let configuration = SSHClientConfiguration(
    host: "app.internal.example.com",
    username: "deploy",
    authentication: try .ed25519PrivateKey(
        contentsOfOpenSSHPrivateKeyFile: "/Users/me/.ssh/id_ed25519"
    ),
    hostKeyPolicy: .knownHostsFile("/Users/me/.ssh/known_hosts"),
    legacyAlgorithmOptions: .disabled,
    automaticRekeyPolicy: .currentProfileDefault,
    keepalivePolicy: .init(interval: 30),
    timeoutPolicy: .init(
        connectionSetupTimeInterval: 20,
        responseTimeInterval: 5
    ),
    proxyJumpHosts: [
        SSHProxyJumpHost(
            host: "bastion.example.com",
            username: "deploy",
            authentication: try .ed25519PrivateKey(
                contentsOfOpenSSHPrivateKeyFile: "/Users/me/.ssh/id_ed25519"
            ),
            hostKeyPolicy: .knownHostsFile("/Users/me/.ssh/known_hosts"),
            legacyAlgorithmOptions: .disabled,
            keepalivePolicy: .init(interval: 30),
            timeoutPolicy: .init(responseTimeInterval: 5)
        )
    ]
)

On this page