Skip to content

Intermediate · SELinux and SSH · topic 33 of 57 · 35 min

SSH: keys, ssh-copy-id and hardening sshd

Explanation

SSH gives you an encrypted remote shell. Log in with a key pair instead of a password: ssh-keygen makes it, ssh-copy-id installs the public key on the server. Harden the server in /etc/ssh/sshd_config (or a drop-in file): no root login, no passwords once keys work, test with sshd -t, and reload.

How key login works

A key pair is two linked files. The private key stays on your laptop and must never be shared. The public key can be given to anyone; you put it in ~/.ssh/authorized_keys on every server you want to log into. When you connect, the server sends a challenge that only the matching private key can answer. No password crosses the network, and a stolen public key is useless.

Think of it like this: The public key is a padlock you hand out; the private key is the only key that opens it. You can fix your padlocks on a hundred servers. Anyone can see them, but only you can open them.

Making and installing a key

bash
[asha@laptop ~]$ ssh-keygen -t ed25519 -C "asha@laptop"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/asha/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/asha/.ssh/id_ed25519
Your public key has been saved in /home/asha/.ssh/id_ed25519.pub
[asha@laptop ~]$ ssh-copy-id asha@web01.example.com
asha@web01.example.com's password:
Number of key(s) added: 1
[asha@laptop ~]$ ssh asha@web01.example.com
[asha@web01 ~]$
A passphrase encrypts the private key on disk. Use one; ssh-agent remembers it so you type it once per session.

ssh-copy-id appends your .pub file to ~/.ssh/authorized_keys on the server and sets safe permissions. Done by hand, the rules are strict: ~/.ssh must be 700 and authorized_keys 600, owned by the user, or sshd ignores the key. On RHEL the files also need the right SELinux label (ssh_home_t); restorecon -Rv ~/.ssh fixes that if you created them oddly.

Useful client features

bash
$ ssh -i ~/.ssh/deploy_key deploy@203.0.113.10      # a specific key
$ scp report.pdf asha@web01:/tmp/                      # copy a file over SSH
$ rsync -avz ./site/ asha@web01:/var/www/html/         # sync a folder (needs rsync on both sides)
$ cat ~/.ssh/config
Host web01
    HostName web01.example.com
    User asha
    IdentityFile ~/.ssh/id_ed25519
$ ssh web01                                            # uses the settings above

Hardening the server

The SSH server is sshd, configured in /etc/ssh/sshd_config. On RHEL 9 that file starts with Include /etc/ssh/sshd_config.d/*.conf, and for each setting sshd uses the FIRST value it reads. So the cleanest way to change settings is a drop-in file whose name sorts early, which wins over later lines.

ini
# /etc/ssh/sshd_config.d/01-hardening.conf
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowGroups sshusers
Only after you have confirmed key login works for your admin users!
bash
# sshd -t                         # syntax test; no output means OK
# sshd -T | grep -Ei 'permitrootlogin|passwordauthentication'
permitrootlogin no
passwordauthentication no
# systemctl reload sshd
$ ssh asha@web01                  # test in a NEW terminal before closing the old one
sshd -T prints the settings sshd will really use, after all includes.

On RHEL 9 the default already blocks root logins with a password (PermitRootLogin prohibit-password). Setting it to no blocks root over SSH entirely; admins log in as themselves and use sudo.

Careful: Never close your only working session after changing sshd. Open a second terminal, log in, and test sudo. If something is wrong, fix it from the first session. Changing the port also needs semanage port and a firewall rule (previous lessons).

Common mistakes

  • Wrong permissions on ~/.ssh or authorized_keys: the server falls back to asking for a password. Check /var/log/secure for "Authentication refused: bad ownership or modes".
  • Copying the PRIVATE key to the server. Only the .pub file goes there.
  • Editing sshd_config but a drop-in file read earlier sets the same option, so your change has no effect. Check with sshd -T.
  • Disabling passwords before keys work for all admins, and locking everyone out.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

SSH: keys, ssh-copy-id and hardening sshd · 1/7

ssh user@host

SSH gives you an encrypted shell on a remote server.

Prefer a video by a teacher? Find free videos on “ssh key authentication ssh-keygen ssh-copy-id sshd_config hardening rhel 9” on YouTube ↗

In real life: Stopping brute-force attacks on a fintech's servers

A Gurugram fintech saw thousands of password-guessing attempts per day on its SSH servers. The team rolled out SSH keys for all engineers with ssh-copy-id, then added a drop-in file with PermitRootLogin no and PasswordAuthentication no through Ansible. The guessing still happens, but it cannot succeed, and the auditors were satisfied that no shared root password exists any more.

bash
# grep -c "Failed password" /var/log/secure
0
# grep "Connection closed by authenticating user" /var/log/secure | tail -1
Oct 19 15:22:07 app02 sshd[7781]: Connection closed by authenticating user root 203.0.113.50 port 51122 [preauth]

Practice (0/3 done)

Task 1 · Question

Which file must NEVER leave your laptop?

Task 2 · Question

Key login fails and /var/log/secure says "bad ownership or modes for directory /home/asha/.ssh". Fix?

Task 3 · Practice

Between your host (or a second VM) and the lab VM: set up key login for a normal user, then harden sshd with a drop-in so root cannot log in over SSH and passwords are refused. Prove both.

Quick quiz

Question 1

1.What does ssh-copy-id do?

Question 2

2.On RHEL 9, sshd_config includes sshd_config.d/*.conf at the top. Which value wins if both set PasswordAuthentication?

Question 3

3.Which command checks sshd configuration syntax?

Question 4

4.Which key type is a good modern default for ssh-keygen?

Question 5

5.Why keep a session open while changing sshd?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does ssh-copy-id do?

Answer: Appends your public key to the server's authorized_keys

It installs the public key.

On RHEL 9, sshd_config includes sshd_config.d/*.conf at the top. Which value wins if both set PasswordAuthentication?

Answer: The first one read

sshd uses the first value it obtains.

Which command checks sshd configuration syntax?

Answer: sshd -t

sshd -t tests the config.

Which key type is a good modern default for ssh-keygen?

Answer: ed25519

Ed25519 is short, fast and strong. (RSA 3072+ is also fine.)

Why keep a session open while changing sshd?

Answer: So you can fix mistakes if new logins fail

A mistake could otherwise lock you out.

Which sshd_config line stops direct root logins over SSH?Related

Answer: PermitRootLogin no

PermitRootLogin no is the standard OpenSSH setting.

From Linux security basics

A switch has 16 VTY lines. Only line vty 0 4 has transport input ssh. What is the risk?Related

Answer: Lines 5 to 15 may still accept Telnet

Unconfigured lines keep their own settings; secure all of them with line vty 0 15.

From Securing device access: secrets and SSH

With SSH keys, which key stays only on your laptop?Related

Answer: The private key

The public key goes to the server. The private key never leaves your machine.

From Linux basics for backend developers

Which permissions should a private SSH key file have?Related

Answer: 600

Only the owner should read or write a private key. SSH rejects keys that others can read.

From Users, groups and permissions

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. This is the last topic of “SELinux and SSH”. The module exam comes next.
  2. Module 6 exam: SELinux and SSH · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Automation basics: scheduling, archives and shell scripts. 57 topics left in the course before the final exam.

← Previous: Troubleshooting SELinux denials