Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Reference

SSHD Config: The Right /etc/ssh/sshd_config for Production

Sean

Platform Writer

Jul 06, 2026
7 min read

The /etc/ssh/sshd_config file controls the SSH server. The right production config is key-only auth (PasswordAuthentication no), no root login (PermitRootLogin no), modern ciphers and KEX algorithms, and a non-default port. The team that locks this down has the right posture. The team that leaves the defaults has a brute-force magnet.

SSHD Config: The Right /etc/ssh/sshd_config for Production

Table of contents

The right base config

The right production sshd_config starts with the most important directives:

Port 22
AddressFamily inet
ListenAddress 0.0.0.0
ListenAddress ::

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
UsePAM yes

X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

The right answer is to read this file from top to bottom before changing anything. The wrong answer is to change lines without understanding what they do — sshd_config is permissive by default, and the defaults are not safe for production.

The most important security directives

PermitRootLogin no — disallows root SSH login. The right answer is to also set AllowUsers or AllowGroups to restrict which accounts can SSH in.

PasswordAuthentication no — disallows password-based auth. The right answer is to require key-based auth.

PermitEmptyPasswords no — disallows accounts with empty passwords.

ChallengeResponseAuthentication no — disallows keyboard-interactive auth (the right answer for production unless you use PAM for 2FA).

The right answer is to set all four.

Modern cipher and KEX configuration

The right answer for production is to use the modern cipher suite:

KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],[email protected]

The right answer is to use the Mozilla ‘modern’ or ‘intermediate’ configuration. The wrong answer is to allow SHA-1 or 3DES — both are deprecated.

Rate limiting with fail2ban

The right way to limit brute-force attempts is fail2ban. The right setup:

sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

The right fail2ban jail for sshd is in /etc/fail2ban/jail.d/sshd.conf:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600

The right answer is to verify with sudo fail2ban-client status sshd.

Testing the config before reload

The right way to test sshd_config before reload is:

sudo sshd -t

This is the SSH test mode — it reports syntax errors without actually starting sshd. The right answer is to run this after any change. The wrong answer is to reload sshd with a broken config — the wrong answer is to lock yourself out of the box.

Reloading vs restarting

The right way to apply a config change is sudo systemctl reload sshd. The wrong answer is to restart sshd, which drops all in-flight connections. A reload tells sshd to re-read the config without dropping connections.

Audit recommendations

The right answer is to run ssh-audit (https://github.com/jtesta/ssh-audit) against the server regularly. The right answer is to scan the server from a workstation:

git clone https://github.com/jtesta/ssh-audit.git
./ssh-audit.py server.example.com

The output grades the server’s SSH config and lists the algorithms it supports. The right answer is to fix any A or B grade down to an A+.

FAQ

What is the default Port?

  1. The right answer for a public-facing server is to change it to a non-standard port. The right answer for an internal server is to keep the default.

What is the default PermitRootLogin?

On Debian/Ubuntu, PermitRootLogin prohibit-password (key-based only, no password). The right answer is to change to no to disallow root SSH entirely.

What is the difference between PasswordAuthentication and ChallengeResponseAuthentication?

PasswordAuthentication is for plain password auth. ChallengeResponseAuthentication is for keyboard-interactive auth (PAM, 2FA). The right answer is to disable PasswordAuthentication but enable ChallengeResponseAuthentication if you use PAM for 2FA.

Can I have multiple ListenAddress lines?

Yes, one per IP. The right answer for a dual-stack server is to listen on both IPv4 and IPv6.

What is UseDNS?

UseDNS is for resolving the client’s hostname from the IP (for from in logs and Match Host directives). The right answer is UseDNS no to avoid the delay if DNS is slow.

What is MaxAuthTries?

The number of authentication attempts per connection. The default is 6. The right answer for production is 3 to limit brute-force attempts.

What is MaxSessions?

The number of sessions per network connection. The default is 10. The right answer for most servers is the default.

What is LoginGraceTime?

The time allowed for authentication. The default is 2 minutes. The right answer is to set it to 30 seconds for production to limit slow-loris-style attacks.

If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.

Useful related references:

#ssh#sshd#dev-infra#tutorial