sysadmin · June 24, 2026 · 14 min read

SSH hardening.
keys only, no root, scoped access.

A pen test flagged SSH password auth as critical. Move to key-based auth, disable passwords and root login, scope access to named users and a group, without locking yourself out.

// what we’re getting into
  1. The ticket
  2. Concept review. Keys and the permissions that break them.
  3. Generate a key pair
  4. Distribute the public key
  5. Harden sshd with a drop-in
  6. Verify the restrictions
  7. Exam questions
  8. Final checklist: confirm everything works

The pen test report landed with one finding flagged critical and in red: SSH still accepts passwords. secadmin wants it closed before Friday. Key-based auth for the admin account, passwords off globally, root login over SSH off, and access narrowed to two named users plus the sysadmins group. The line in the ticket that matters most is the last one: test it twice before you drop the session you are working in.

Every step on this ticket can lock you out of the box, and root SSH is already off, so there is no side door if you do. The discipline is not optional: validate the config with sshd -t before you reload, and prove a brand new session works before you close the one you have.

warning: Keep a second SSH session open the entire time. Edit the config, validate with sshd -t, reload, then log in from a brand new session before you close the one you have. If the new one fails, you still have the old one to fix it.

The ticket

bash
systemctl is-active sshd
ss -tlnp | grep :22
id admin student
getent group sysadmins

Concept review. Keys and the permissions that break them.

bash
man ssh
man sshd_config
man ssh-keygen

Key auth uses a pair: a private key that never leaves your machine and a public key you place on the server. SSH is strict about permissions and will silently refuse keys if they are too loose. The directory must be 700, the private key and authorized_keys must be 600, and the public key can be 644.

required permissions
~/.ssh                    700   only the owner can enter
~/.ssh/authorized_keys    600   only the owner can read
~/.ssh/id_ed25519         600   the private key, critical
~/.ssh/id_ed25519.pub     644   public, fine to be readable

Generate a key pair

ed25519 is the modern default on RHEL 9: smaller and faster than RSA at equivalent strength.

bash
ssh-keygen -t ed25519 -C "admin@workstation" -f ~/.ssh/id_ed25519
# press enter for no passphrase, or set one (recommended)
ls -la ~/.ssh    # id_ed25519 (600) and id_ed25519.pub (644)

Distribute the public key

ssh-copy-id is the easy path and prompts for the password one final time. After that, login is passwordless.

bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@server1

# manual alternative:
cat ~/.ssh/id_ed25519.pub | ssh admin@server1 \
    'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

ssh admin@server1 hostname    # should connect with no password prompt

Harden sshd with a drop-in

Write a drop-in in /etc/ssh/sshd_config.d/ rather than editing the main file. Validate with sshd -t before you reload, and use reload not restart so existing sessions are not dropped.

bash
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)

sudo tee /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
AllowUsers admin student
AllowGroups sysadmins
EOF

sudo sshd -t              # no output means the config is valid
sudo systemctl reload sshd
systemctl is-active sshd
note: KbdInteractiveAuthentication no matters. Without it, password-style login can still sneak back in through PAM even after you disable PasswordAuthentication.

Verify the restrictions

From a new session, confirm who can and cannot get in.

bash
ssh admin@server1 hostname      # succeeds, key auth
ssh student@server1 hostname    # succeeds, key auth
ssh dev1@server1 hostname       # fails, not allowed
ssh root@server1 hostname       # fails, PermitRootLogin no

# force a password attempt to prove passwords are dead
ssh -o PreferredAuthentications=password dev1@server1
# dev1@server1: Permission denied (publickey,gssapi-with-mic).

sudo journalctl -u sshd -n 30 --no-pager
# sshd[2011]: User dev1 not allowed because not listed in AllowUsers

Exam questions

Write the command first.

Q1. Generate a new ed25519 key pair for the current user with no passphrase at ~/.ssh/id_ed25519.

Q2. Configure SSH so only dev1 and dev2 can log in, using a drop-in file.

Q3. Disable password auth and root login, validate before restarting, and show how to test that passwords are refused.

Answers.

bash
# A1
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
# A2
sudo tee /etc/ssh/sshd_config.d/10-allow-devs.conf << 'EOF'
AllowUsers dev1 dev2
EOF
sudo sshd -t && sudo systemctl reload sshd
# A3
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
PasswordAuthentication no
PermitRootLogin no
KbdInteractiveAuthentication no
EOF
sudo sshd -t && sudo systemctl reload sshd
ssh -o PreferredAuthentications=password dev1@server1    # Permission denied (publickey)

Final checklist: confirm everything works

If every check passes, the ticket is done.

bash
# 1. key pair generated, public key in the server's authorized_keys
ls -la ~/.ssh

# 2. drop-in created and validated
sudo sshd -t

# 3. passwords and root login refused, access scoped
# 4. tested in a NEW session before closing the old one
# 5. all three exam commands written from scratch
# 6. tracker entry checked off

Reply to secadmin: SSH is locked down. Key auth only, root login disabled, access scoped to admin, student, and the sysadmins group. Validated with sshd -t before reload. Pen-test ready.

next post
firewalld zones, services, and rich rules