Intermediate · SELinux and SSH · topic 33 of 57 · 35 min
SSH: keys, ssh-copy-id and hardening sshd
Explanation
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.
Making and installing a key
[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 ~]$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
$ 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 aboveHardening 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.
# /etc/ssh/sshd_config.d/01-hardening.conf
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowGroups sshusers# 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 oneOn 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.
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 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.
# 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)
Which file must NEVER leave your laptop?
Key login fails and /var/log/secure says "bad ownership or modes for directory /home/asha/.ssh". Fix?
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
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- SELinux booleans and port labelsSELinux and SSH · same module
- Contexts and file labels: ls -Z, semanage fcontext and restoreconSELinux and SSH · same module
- Linux security basicsCyber Security: from zero to SOC analyst · Systems and cryptography
- Securing device access: secrets and SSHComputer Networking (CCNA level) · Network security
- Linux basics for backend developersBackend Development · Deployment and scaling
- Users, groups and permissionsDevOps: Git, Docker, Kubernetes and CI/CD · Linux for DevOps
Questions people ask about this
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.
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.
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.
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.
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
- This is the last topic of “SELinux and SSH”. The module exam comes next.
- Module 6 exam: SELinux and SSH · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Automation basics: scheduling, archives and shell scripts. 57 topics left in the course before the final exam.