SSH Configuration: Important Security Options in sshd_config

A precise guide to sshd_config security options with recommended values and the effect of each; from PermitRootLogin to AllowTcpForwarding, along with real errors and how to fix them.

6 min Updated 27 Sep 2026

You've just brought up a server, you log in with ssh root@IP and everything works. Then you open /var/log/auth.log and see that in the past 24 hours, 4,300 failed login attempts from 190 different IPs have been recorded. This is where you need to take /etc/ssh/sshd_config seriously. This article is a list of the options that actually affect the attack surface, the recommended value for each, and what actually breaks in practice.

Before any change: keep a backup session open

Every time you edit sshd_config, keep another terminal open and stay logged in there. If the configuration is wrong and the service is restarted, the current session won't be disconnected, but a new session may fail to establish. Before restarting, always test:

sshd -t
systemctl reload sshd

If the output of sshd -t is empty, the syntax is correct. If it has errors, stop right there. The reload command does not disconnect active connections; restart does. For sshd_config changes, reload is almost always sufficient.

Options that actually reduce the attack surface

PermitRootLogin

Recommended value: prohibit-password or no. The difference between these two matters. prohibit-password blocks root login with a password but accepts a public key. no blocks any login for root, and you must log in with a regular user and then use sudo. I prefer no, provided you already have a user with sudo access and an installed key. If you don't, create one first, then change this line.

PasswordAuthentication and ChallengeResponseAuthentication

Recommended value: no for both. As long as password login is open, a dictionary attack on SSH works and no firewall stops it, because traffic on port 22 is legitimate. By setting these two to no, password attacks become completely ineffective. The cost is that if you lose your private key, you lose access and must recover the server from the console or rescue mode. If that risk is not acceptable to you, at least set PasswordAuthentication no for root and keep it open for a specific user.

PubkeyAuthentication and AuthorizedKeysFile

Recommended value: PubkeyAuthentication yes and AuthorizedKeysFile .ssh/authorized_keys. Be strict about file permissions: chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys. If the permissions on authorized_keys are too open, sshd silently ignores it and you'll see something like Authentication refused: bad ownership or modes in the log. I've seen this error a lot, and it's almost always a permissions issue, not a key issue.

Port

Changing the default port from 22 to something else does not add real security; it only reduces the log volume from automated scanners. If you're behind a firewall or fail2ban, it's worth it. If not, you've just added complexity. I change the port, but I don't count on it as the primary security layer.

AllowUsers and DenyUsers

Recommended value: AllowUsers deploy admin. This option is a whitelist; any user not in it is rejected, even with a valid key. If the server has multiple users and you want to make sure service accounts like www-data or mysql never SSH in, add this line. Note that AllowUsers and AllowGroups are combined, not mutually exclusive.

MaxAuthTries and LoginGraceTime

Recommended value: MaxAuthTries 3 and LoginGraceTime 30. The default for MaxAuthTries is 6. With 3, each connection is closed after three failed attempts, and the cost of a dictionary attack goes up. The default LoginGraceTime is 120 seconds; 30 seconds is enough and reduces the number of half-open connections.

X11Forwarding and AllowTcpForwarding

Recommended value: X11Forwarding no and AllowTcpForwarding no unless you actually need an SSH tunnel. If you use SSH as a proxy or for database tunneling, set AllowTcpForwarding to local rather than yes. This restriction prevents the server from being abused as a relay.

ClientAliveInterval and ClientAliveCountMax

Recommended value: ClientAliveInterval 300 and ClientAliveCountMax 2. Together these mean that if the client doesn't respond for 10 minutes, the connection is closed. This is useful for servers that have many abandoned sessions. If you work on a poor-quality connection, increase this number, otherwise you'll get disconnected mid-work.

This is where people make mistakes

The most common mistake I've seen is this: the user adds PasswordAuthentication no at the end of the file, but higher up in the same file there's already a PasswordAuthentication yes line. In sshd_config, the first value read for each key wins, not the last. The result is that the service is restarted, the log shows no errors, but password login still works and the user thinks the setting has been applied. The correct way: comment out or delete the old line, then add the new line. To be sure, check the effective output:

sshd -T | grep -i passwordauth

The sshd -T command prints the final configuration after all rules are applied. If you see passwordauthentication no there, the setting has actually been applied.

Comparison of default and recommended values

OptionDefaultRecommendedEffect
PermitRootLoginprohibit-passwordnoCompletely block root login
PasswordAuthenticationyesnoRender password attacks ineffective
MaxAuthTries63Reduce attempts per connection
LoginGraceTime12030Reduce half-open connections
X11ForwardingyesnoRemove an unused attack surface
AllowTcpForwardingyesno or localPrevent the server from becoming a relay

After closing SSH, what's next

Once password login is closed, fail2ban no longer has much to do, because there's nothing left to guess. But if you have other services on the same server, take MySQL security seriously; removing anonymous users and restricting access to localhost is part of the same work. For servers that act as web hosts, installing an SSL certificate is also a logical next step. If you're on a cloud server or dedicated server from ServerNet, these settings apply the same on both, and from the management console you can also use rescue mode if access gets locked out.

One practical tip: before applying changes, take a backup of the file and keep it somewhere off the server. cp /etc/ssh/sshd_config /root/sshd_config.bak is enough, but if the server becomes unreachable, that backup becomes unreachable too. Transferring files with scp and rsync is the quick way to pull a backup to your local machine.

Frequently asked questions

Why do I still log in with a password after PasswordAuthentication no?

Because there's probably a PasswordAuthentication yes line higher up in the same file, and sshd reads the first value. Check the effective value with sshd -T | grep -i passwordauth. If it's yes, delete or comment out the old line and reload the service.

What's the difference between prohibit-password and no in PermitRootLogin?

prohibit-password blocks root login with a password but accepts a public key. no blocks every login method for root, and you must log in with a regular user and then use sudo. If you have a sudo user with an installed key, no is the safer choice.

Does changing the SSH port increase security?

Not really. Changing the port only reduces the volume of automated scanning and makes the log look cleaner. Real security comes from closing password login, restricting allowed users, and using keys. If you're behind a firewall, changing the port is an extra layer, not a replacement.

What happens if I lose my SSH key?

If you've closed password login, you lose SSH access. In this case, you must use the server management console or rescue mode to fix the authorized_keys file or temporarily re-enable the password. That's why you should always keep a second user with a separate key as a backup path.

Was this page helpful?