Last updated:

To harden SSH on Debian 13 (Trixie) or Debian 12 (Bookworm), put your settings in a drop-in file under /etc/ssh/sshd_config.d/: turn off root login and password logins, allow only the users who need access, and lower the login limits. Then check the syntax with sudo sshd -t and reload the service. The one rule that prevents lockouts: set up key login for a normal user and confirm it works in a second terminal before you disable passwords.

Quick answer. Create /etc/ssh/sshd_config.d/00-hardening.conf with the settings below, run sudo sshd -t, then sudo systemctl reload ssh. Keep your current session open and test a new login before you close it.

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowUsers deploy

Replace deploy with your own user name. Package versions in the Debian archive (checked 6 Oct 2026): Debian 13 has openssh-server 1:10.0p1-7+deb13u4 and Debian 12 has 1:9.2p1-2+deb12u10. The screenshots in this guide were captured on Ubuntu 24.04 with OpenSSH 9.6p1, because the commands and directives are the same OpenSSH features; they were not captured on a Debian host, and exact default values can differ between releases, so check your own with sudo sshd -T (step 1). This is one step in our Debian server security checklist, which shows the order to apply them in.

What each setting does

Setting What it does Risk if misconfigured
PermitRootLogin no Blocks direct SSH logins as root; you log in as a normal user and use sudo Lockout if no other user can use sudo
PasswordAuthentication no Only SSH keys are accepted, so password guessing stops working Lockout if no working key is installed
KbdInteractiveAuthentication no Closes the keyboard-interactive path, which can otherwise still ask for a password through PAM None for key-only access
MaxAuthTries 3 Disconnects after 3 failed attempts in one connection Users with many keys in an agent may hit the limit
LoginGraceTime 30 Drops connections that do not authenticate within 30 seconds Very slow links may time out
X11Forwarding no Disables forwarding of graphical applications Breaks remote GUI apps over SSH
AllowUsers deploy Only the listed users may log in over SSH Lockout if the list is wrong or empty of valid users

Before you start

Make sure you have a way back in that does not use SSH: a provider web console, VNC or physical access. Also make sure you have a non-root account with sudo rights; if not, enable sudo for a user on Debian first. If a firewall is active, SSH must stay allowed in it; see the UFW setup guide for Debian 13 and 12.

Step 1: Check the version and your current settings

Run these on the server. sshd -T prints the settings the server is actually using after all configuration files are merged, which is more reliable than reading the files by eye.

ssh -V
sudo sshd -T | grep -E '^(permitroot|password|maxauth|x11f|logingr|pubkeyauthentication)'
Terminal showing ssh -V and the default sshd -T values: logingracetime 120, maxauthtries 6, permitrootlogin without-password, passwordauthentication yes, x11forwarding yes
Default sshd settings, captured on Ubuntu 24.04 with OpenSSH 9.6p1. Debian 13 ships OpenSSH 10.0p1 and Debian 12 ships 9.2p1, so exact defaults can differ.

On the Ubuntu test machine the defaults allowed password logins, allowed 6 attempts per connection and gave 120 seconds to log in. Your Debian values may differ, which is exactly why you check first.

Step 2: Create a key and install it

On your own computer (the client, not the server), create an Ed25519 key pair. Set a passphrase when asked, because the key file is the only thing protecting access once passwords are off.

ssh-keygen -t ed25519 -C "laptop-2026"
Terminal output of ssh-keygen -t ed25519 creating a key pair and printing its SHA256 fingerprint
Generating an Ed25519 key pair on the client, captured on Ubuntu 24.04 with OpenSSH 9.6p1. The key shown was a throwaway and has been deleted.

Copy the public key to the server user you will keep using (deploy here), then open a new terminal and confirm the key works without a password prompt for the account:

ssh-copy-id deploy@your-server-ip
ssh deploy@your-server-ip

If ssh-copy-id is not available on your client, append the contents of id_ed25519.pub to ~/.ssh/authorized_keys on the server, with ~/.ssh set to mode 700 and authorized_keys to mode 600. SSH ignores the key file when its permissions are too open. Do not continue until this login works.

Step 3: Write the hardening drop-in file

Debian and Ubuntu’s default /etc/ssh/sshd_config starts with Include /etc/ssh/sshd_config.d/*.conf, so files in that directory are read first. For each setting, the first value found wins. That is why this guide names the file 00-hardening.conf, and why editing only the main file can fail silently (see the precedence check in step 6).

sudo nano /etc/ssh/sshd_config.d/00-hardening.conf

Paste the settings from the quick answer, changing AllowUsers to your user:

Terminal showing the contents of a sshd_config.d drop-in file with PermitRootLogin no, PasswordAuthentication no, MaxAuthTries 3 and AllowUsers deploy
The drop-in file used in this guide. Captured on Ubuntu 24.04; the same directives exist in Debian 13 and 12.

Step 4: Test the syntax before touching the service

sshd -t checks the configuration without restarting anything. It prints nothing and exits 0 when the file is valid.

sudo sshd -t && echo "config OK"
sudo sshd -T | grep -E '^(permitroot|password|kbdinter|maxauth|x11f|logingr|pubkeyauthentication|allowusers)'
Terminal showing sshd -t printing config OK and sshd -T listing the effective hardened values
Syntax test and effective configuration after adding the drop-in. Captured on Ubuntu 24.04 with OpenSSH 9.6p1.

A typo is caught here instead of at restart time. With MaxAuthTries three in the file, sshd -t refuses it and names the file and line:

Terminal showing sshd -t reporting MaxAuthTries integer value invalid on line 5 and exit code 255
sshd -t rejecting a deliberate typo (MaxAuthTries three) before the service is touched. Captured on Ubuntu 24.04.

Step 5: Reload and test from a second terminal

sudo systemctl reload ssh

Use reload rather than restart. Existing sessions stay connected, so you keep a working shell if something is wrong. The service is named ssh on Debian and Ubuntu (sshd also works as an alias on current releases). Keep the old session open, then open a new terminal and log in as your normal user with the key. Also confirm that root and password logins are now refused:

ssh deploy@your-server-ip
ssh root@your-server-ip
ssh -o PubkeyAuthentication=no deploy@your-server-ip

The second and third commands should end with Permission denied. Only close your original session after the first command succeeds.

Step 6: Confirm nothing else overrides your settings

Some cloud images ship their own file in sshd_config.d, for example 50-cloud-init.conf setting PasswordAuthentication yes. Because the first value wins and files are read in alphabetical order, a lower-numbered name beats a higher-numbered one. In this test, the hardening file named 60- lost to a 50- file, and sshd -T showed password logins still enabled:

Terminal showing a 50-cloud-init.conf file that sets PasswordAuthentication yes overriding a later 60-hardening.conf, so sshd -T reports passwordauthentication yes
Files in sshd_config.d are read in alphabetical order and the first value wins, so a 50- file beats a 60- file. Captured on Ubuntu 24.04.

So always finish with sudo sshd -T | grep passwordauthentication, and rename or remove the conflicting setting if it does not say no.

Undo the change

If you can still reach the server, remove the file and reload:

sudo rm /etc/ssh/sshd_config.d/00-hardening.conf
sudo sshd -t && sudo systemctl reload ssh

If you are locked out, use the provider console or physical access, log in locally, and run the same commands.

Troubleshooting

What you see Likely cause What to check
Permission denied (publickey) The key is not installed for that user, wrong key offered, or bad permissions Check ~/.ssh (700) and authorized_keys (600); try ssh -v; read sudo journalctl -u ssh -n 50 on the server
A user can log in as root or with a password even after the change Another file in sshd_config.d set the value first Run sudo sshd -T and check file names with ls /etc/ssh/sshd_config.d/
Bad configuration option or integer value invalid Typo or wrong value in a directive sudo sshd -t prints the file and line
A listed user still cannot log in User missing from AllowUsers, or not spelled exactly Add the user (space-separated) and re-test
Connection refused after a restart The service failed to start, or the firewall blocks port 22 sudo systemctl status ssh, then your firewall rules

FAQ

Is it safe to disable password authentication?

Yes, as long as key login works first, you have console access as a fallback, and you protect the private key with a passphrase. The risk is lockout, not weaker security.

Should I change the SSH port?

Changing the port reduces noise in the logs but does not make SSH meaningfully safer, and it can interfere with firewall rules. This guide leaves it at 22; focus on keys and access limits first.

Does reloading SSH disconnect me?

No. Reloading re-reads the configuration for new connections while existing sessions stay open, which is why the guide tests in a second terminal.