How to use the sshd_config Analyzer
- Paste /etc/ssh/sshd_config, together with the files in /etc/ssh/sshd_config.d/ if it includes them, or open the file.
- Read the findings, most severe first, each with its line number and the line to write.
- Apply the hardened lines, where the tool says they go, from a session you keep open.
- Run sudo sshd -t, reload ssh, and log in again from a second terminal before closing the first.
How do I check an sshd_config for security problems?
Read it the way sshd does: keywords are case-insensitive, the first value sshd reads for a keyword is the one it uses, a Match block lasts until the next Match line, and any keyword you leave out takes the OpenSSH default. This analyzer applies those rules to the file you paste, so it reports what the server actually does, not what a line further down appears to say.
On the server itself, sudo sshd -T prints the values sshd resolved, includes and defaults applied. Use it to confirm the result after a change.
How sshd reads the file
The rules below come from sshd_config(5) and were checked against sshd -T from OpenSSH 9.6p1, the version in Ubuntu 24.04:
- The first value wins. If line 10 says
PermitRootLogin yesand line 40 saysPermitRootLogin no, root can log in. The analyzer reports each ignored duplicate. A few keywords differ:Port,ListenAddress,HostKey,AllowUsers,DenyUsers,AllowGroups,DenyGroupsandAcceptEnvadd up, andMaxStartupskeeps the last value. - Match blocks. Lines after
Match User backupapply only to connections that match, until the nextMatchline or the end of the file, whatever the indentation. A global setting added at the bottom of a file that ends in aMatchblock silently becomes part of it.Match allends a block. - Include.
Include /etc/ssh/sshd_config.d/*.confreads those files at that point. Debian and Ubuntu put it on the first line, so a drop-in's value beats the same keyword anywhere in the main file. This tool cannot open those files; paste them in place of the Include line. - Syntax.
Keyword valueandKeyword=valueare equal, a#after a space ends the line, CRLF line endings are fine. A typo, an unknown value such astrue, a keyword not allowed insideMatch, or a byte-order mark from a Windows editor makessshd -tfail, and sshd will not restart.
Defaults: what an absent line means
Absent keywords are judged by OpenSSH 9.x defaults: PermitRootLogin prohibit-password, PasswordAuthentication yes, KbdInteractiveAuthentication yes, PubkeyAuthentication yes, PermitEmptyPasswords no, MaxAuthTries 6, LoginGraceTime 120, X11Forwarding no, AllowTcpForwarding yes, AllowAgentForwarding yes, UsePAM no and ClientAliveInterval 0.
Distributions change some of them in the file they ship. Ubuntu 24.04's stock sshd_config sets KbdInteractiveAuthentication no, UsePAM yes and X11Forwarding yes, and leaves password login at the default, yes. Ubuntu cloud images add /etc/ssh/sshd_config.d/60-cloudimg-settings.conf with PasswordAuthentication no, but cloud-init can write 50-cloud-init.conf with PasswordAuthentication yes, which sorts first and wins.
What it checks
| Area | Keywords |
|---|---|
| Who can log in | PermitRootLogin, AllowUsers, AllowGroups, DenyUsers |
| How | PasswordAuthentication, KbdInteractiveAuthentication with UsePAM, PubkeyAuthentication, PermitEmptyPasswords, AuthenticationMethods, HostbasedAuthentication, IgnoreRhosts |
| Brute force and idle sessions | MaxAuthTries, LoginGraceTime, ClientAliveInterval |
| Forwarding | X11Forwarding, AllowTcpForwarding, AllowAgentForwarding, PermitUserEnvironment, StrictModes |
| Cryptography | Ciphers, MACs, KexAlgorithms and signature lists, naming each weak entry; DSA host keys; Protocol 1 |
One pairing catches people out: PasswordAuthentication no does not cover keyboard-interactive login, and with UsePAM yes that method asks for the account password. Turn both off. Weak algorithms are named exactly, for example 3des-cbc, the aes*-cbc modes, hmac-md5, hmac-sha1-96, diffie-hellman-group1-sha1 and ssh-dss; arcfour, blowfish-cbc and cast128-cbc are gone from OpenSSH entirely, so a line naming them stops sshd from starting.
Applying the fixes without locking yourself out
# Keep this session open until a new login works.
sudo nano /etc/ssh/sshd_config.d/00-hardening.conf
sudo sshd -t # prints nothing when the files are valid
sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication)'
sudo systemctl reload ssh # the unit is sshd on RHEL, Fedora and Arch
ssh -o PreferredAuthentications=publickey deploy@your-server # from a second terminalThe 00- file name only wins when the main file includes sshd_config.d before its own settings; otherwise put the lines at the top of sshd_config, above any Match. Before turning off passwords, copy your key with ssh-copy-id and log in with it once. After changing Port on Ubuntu 22.10 or later, also run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket, and allow the new port in the firewall first.
Common errors and how to fix them
- Bad configuration option. A misspelt keyword, such as
PasswordAuthentcation; the analyzer suggests the keyword you meant. - Directive is not allowed within a Match block. A global keyword such as
PortorCipherssits under aMatchline. Move it above the first one. - unsupported option. A value sshd does not take, such as
true, orno#comment, where the missing space makes the comment part of the value. - The change has no effect. An earlier line or an included drop-in sets the same keyword first. Check with
sudo sshd -T.
Shipown and SSH access
Shipown creates dedicated deploy users on a server, each with its own SSH key and scoped sudo rules, so nobody needs to log in as root. Its fail2ban setup bans addresses that keep failing to log in, and always keeps the address your own session comes from in the ignore list.
Frequently asked questions
If sshd_config has the same keyword twice, which one wins?
For most keywords the first one sshd reads wins and later lines are ignored. Port, ListenAddress, HostKey, AllowUsers and a few others add up instead, and MaxStartups keeps the last value.
Is PermitRootLogin prohibit-password safe?
It refuses root passwords and allows only key logins, which is OpenSSH’s default. PermitRootLogin no is stricter once a normal user with sudo can log in with a key.
Why can I still log in with a password after setting PasswordAuthentication no?
Keyboard-interactive login is separate, and with UsePAM yes it asks for the account password. Set KbdInteractiveAuthentication no too, and check that no file in sshd_config.d sets PasswordAuthentication yes first.
How do I test sshd_config before restarting?
Run sudo sshd -t, which prints nothing when the configuration is valid. sudo sshd -T prints the values sshd will use, with includes and defaults resolved.
Does this tool read my sshd_config.d files?
It cannot open files on your server. Paste their contents in place of the Include line, in the order sshd reads them, or run sudo sshd -T on the server.
Which OpenSSH defaults does the analyzer assume?
OpenSSH 9.x defaults, checked against sshd -T from 9.6p1. Debian and Ubuntu change a few of them in their stock file, which the analyzer reads when you paste it.