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
- OpenSSH 8.0 or later (for Ed25519 host keys and modern defaults)
- A generated set of host keys
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.comrequires 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+:
ChallengeResponseAuthenticationwas renamed toKbdInteractiveAuthentication. On 8.7+, useKbdInteractiveAuthentication noinstead. 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