Skip to content

Last updated: 2026-02-11

OpenSSH Security Configuration Guide

This guide provides recommended cryptographic settings for OpenSSH servers and clients. OpenSSH uses its own protocol (not TLS), but the same principles apply: use strong key exchange algorithms, ciphers, and MACs, and disable weak or legacy options.

Prerequisites

Server Configuration

All server settings are configured in /etc/ssh/sshd_config.

Host Keys

Use only strong host key types. Remove or disable DSA and ECDSA keys if not needed:

HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

Generate a new Ed25519 host key if one does not exist:

ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""

Host Key Algorithms

Specify the order of host key algorithms offered to clients:

HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com

Key Exchange Algorithms

Restrict key exchange to strong algorithms:

KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512

The sntrup761x25519-sha512 hybrid algorithm provides post-quantum resistance. Remove it if compatibility with older clients is required.

Version note: sntrup761x25519-sha512@openssh.com requires OpenSSH 8.5+. On OpenSSH 8.0--8.4 (RHEL 8, Debian 11, SLES 15), remove this algorithm from the list and use: KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512

Ciphers

Allow only authenticated encryption (AEAD) ciphers:

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

The CTR-mode ciphers are included for compatibility. Prefer the AEAD ciphers (ChaCha20-Poly1305, AES-GCM) when possible.

MACs

For non-AEAD ciphers, use Encrypt-then-MAC variants:

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com

AEAD ciphers (ChaCha20-Poly1305, AES-GCM) handle integrity internally and ignore the MAC setting.

Authentication Hardening

Disable password authentication and enforce key-based login:

PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes

OpenSSH 8.7+: ChallengeResponseAuthentication was renamed to KbdInteractiveAuthentication. On 8.7+, use KbdInteractiveAuthentication no instead. The old name still works as an alias but may be removed in future versions.

Disable root login or restrict it to key-based only:

PermitRootLogin no

Access Restrictions

Limit which users and groups can connect:

AllowUsers deploy admin
AllowGroups ssh-users

Set brute-force protections:

MaxAuthTries 3
LoginGraceTime 30
MaxSessions 5
MaxStartups 10:30:60

Additional Hardening

# Disable unused authentication methods
KbdInteractiveAuthentication no    # Requires OpenSSH 8.7+; omit on older versions
GSSAPIAuthentication no

# Disable X11 and agent forwarding if not needed
X11Forwarding no
AllowAgentForwarding no

# Disable TCP forwarding if not needed
AllowTcpForwarding no

# Log more detail for auditing
LogLevel VERBOSE

# Disconnect idle sessions
ClientAliveInterval 300
ClientAliveCountMax 2

Client Configuration

Client settings go in ~/.ssh/config or /etc/ssh/ssh_config. Match the cryptographic settings to the server:

Host *
    # Key exchange (sntrup761 requires OpenSSH 8.5+; remove on 8.0-8.4)
    KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512

    # Ciphers
    Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

    # MACs
    MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com

    # Host key verification
    HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com

    # Strict host key checking
    StrictHostKeyChecking ask
    VerifyHostKeyDNS yes
    HashKnownHosts yes

    # Prefer Ed25519 keys for authentication
    IdentityFile ~/.ssh/id_ed25519
    IdentityFile ~/.ssh/id_rsa

    # Forward agent only to trusted hosts
    ForwardAgent no

Per-Host Configuration

Override settings for specific hosts:

Host bastion
    HostName bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_bastion
    ForwardAgent no

Host internal-*
    ProxyJump bastion
    User deploy
    StrictHostKeyChecking yes

Complete Server Configuration

# /etc/ssh/sshd_config

# Network
Port 22
AddressFamily inet
ListenAddress 0.0.0.0

# Host keys
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

# Cryptography
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com

# Authentication
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no    # Requires OpenSSH 8.7+; omit on older versions (ChallengeResponseAuthentication above covers the same functionality)
GSSAPIAuthentication no
MaxAuthTries 3
LoginGraceTime 30
AuthenticationMethods publickey

# Access control
AllowGroups ssh-users
MaxSessions 5
MaxStartups 10:30:60

# Security
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no

# Session management
ClientAliveInterval 300
ClientAliveCountMax 2
UsePAM yes

# Logging
LogLevel VERBOSE

# SFTP
# Path varies by distribution:
#   RHEL/CentOS: /usr/libexec/openssh/sftp-server
#   Debian/Ubuntu: /usr/lib/openssh/sftp-server
#   SLES: /usr/lib/ssh/sftp-server
Subsystem sftp /usr/libexec/openssh/sftp-server

Verification

Test the configuration before restarting:

sshd -t

If the syntax is valid, reload the SSH daemon:

systemctl reload sshd       # Debian/Ubuntu: systemctl reload ssh

View the active server configuration:

sshd -T

Test a connection with verbose output to see the negotiated algorithms:

ssh -vv user@server.example.com

Look for lines showing the negotiated key exchange, cipher, and MAC:

debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit>
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit>

Audit your server with ssh-audit for a comprehensive check:

ssh-audit server.example.com