CIS126RH | RHEL System Administration 1 Mesa Community College
Learning Objectives
1
Understand SSH host keys
Explain how host keys verify server identity and prevent MITM attacks
2
Manage known hosts
Handle host key verification, updates, and the known_hosts file
3
Generate SSH key pairs
Create secure RSA and Ed25519 keys with appropriate passphrases
4
Configure key-based authentication
Deploy public keys and optionally disable password authentication
SSH Security Overview
SSH (Secure Shell) provides encrypted communication between systems. Security depends on verifying both the server (host keys) and the user (authentication).
Encryption
All traffic is encrypted, protecting data from eavesdropping
Host Verification
Host keys prove server identity, preventing MITM attacks
User Authentication
Passwords or keys verify the user's identity
Integrity
MACs detect any tampering with transmitted data
⚠ Critical: Encryption alone isn't enough. Without host verification, an attacker could intercept your connection and decrypt everything.
Understanding Host Keys
Every SSH server has host key pairs that uniquely identify it. When you connect, the server proves its identity using these keys.
# Server's host keys are stored in /etc/ssh/[root@server ~]# ls -la /etc/ssh/ssh_host_*
-rw-r-----. 1 root ssh_keys 480 Jan 15 10:30 /etc/ssh/ssh_host_ecdsa_key
-rw-r--r--. 1 root root 162 Jan 15 10:30 /etc/ssh/ssh_host_ecdsa_key.pub
-rw-r-----. 1 root ssh_keys 387 Jan 15 10:30 /etc/ssh/ssh_host_ed25519_key
-rw-r--r--. 1 root root 82 Jan 15 10:30 /etc/ssh/ssh_host_ed25519_key.pub
-rw-r-----. 1 root ssh_keys 2578 Jan 15 10:30 /etc/ssh/ssh_host_rsa_key
-rw-r--r--. 1 root root 550 Jan 15 10:30 /etc/ssh/ssh_host_rsa_key.pub
Key Type
Files
Notes
Ed25519
ssh_host_ed25519_key[.pub]
Modern, fast, recommended
ECDSA
ssh_host_ecdsa_key[.pub]
Elliptic curve, widely supported
RSA
ssh_host_rsa_key[.pub]
Legacy compatibility, use 3072+ bits
First Connection: Verification
[student@workstation ~]$ ssh student@server.example.com
The authenticity of host 'server.example.com (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:xH7vK9mPqL2nR4wY8sT6uB3fJ5aD1eG9hC0iZ2kM7nQ.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'server.example.com' (ED25519) to the list of known hosts.
student@server.example.com's password:
⚠ Security Decision: Don't blindly type "yes"! In secure environments, verify the fingerprint through an out-of-band channel (phone call, secure document, physical access).
The known_hosts File
# Client stores known host keys in ~/.ssh/known_hosts[student@workstation ~]$ cat ~/.ssh/known_hosts
server.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
192.168.1.100 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
webserver.lab.local ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNo...# View fingerprints of known hosts[student@workstation ~]$ ssh-keygen -l -f ~/.ssh/known_hosts
256 SHA256:xH7vK9mPqL2nR4wY8sT6uB3fJ5aD1eG9hC0iZ2kM7nQ server.example.com (ED25519)
256 SHA256:xH7vK9mPqL2nR4wY8sT6uB3fJ5aD1eG9hC0iZ2kM7nQ 192.168.1.100 (ED25519)
256 SHA256:aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ5aB6c webserver.lab.local (ECDSA)# Remove a specific host entry[student@workstation ~]$ ssh-keygen -R server.example.com
Host server.example.com found: line 1
/home/student/.ssh/known_hosts updated.
Format: Each line contains: hostname[,IP] key-type public-key. A host may have multiple entries for different key types or names.
Host Key Changed Warning
[student@workstation ~]$ ssh student@server.example.com
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:nEwKeY9fInGeRpRiNt8xYz7AbCdEfGhIjKlMnOpQrSt.
Please contact your system administrator.
Add correct host key in /home/student/.ssh/known_hosts to get rid of this message.
Offending key in /home/student/.ssh/known_hosts:1
Host key for server.example.com has changed and you have requested strict checking.
Host key verification failed.
STOP! This warning means the server's key doesn't match what you expect. Either the server was reinstalled/changed, or you're being attacked.
Verifying Host Key Fingerprints
# On the SERVER, view host key fingerprints[root@server ~]# ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:xH7vK9mPqL2nR4wY8sT6uB3fJ5aD1eG9hC0iZ2kM7nQ root@server (ED25519)# View all host key fingerprints[root@server ~]# for key in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -lf "$key"; done
256 SHA256:eC2dSa... root@server (ECDSA)
256 SHA256:xH7vK9... root@server (ED25519)
3072 SHA256:rS4aKe... root@server (RSA)# Show fingerprint in different format (legacy MD5)[root@server ~]# ssh-keygen -E md5 -lf /etc/ssh/ssh_host_ed25519_key.pub
256 MD5:a1:b2:c3:d4:e5:f6:a7:b8:c9:d0:e1:f2:a3:b4:c5:d6 root@server (ED25519)# On the CLIENT, compare when connecting[student@workstation ~]$ ssh -o FingerprintHash=sha256 server.example.com
Verification Process: Get the fingerprint from the server through a trusted channel (console, documentation, phone) and compare it with what SSH displays when connecting.
Public Key Cryptography
🔐
Private Key
id_ed25519
Secret! Never share. Used to prove identity.
↔
🔓
Public Key
id_ed25519.pub
Safe to share. Place on servers.
How it works: Data encrypted with the public key can only be decrypted with the private key. The server sends a challenge encrypted with your public key. Only you can decrypt it with your private key, proving your identity without transmitting secrets.
Generating SSH Key Pairs
# Generate Ed25519 key pair (recommended)[student@workstation ~]$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/student/.ssh/id_ed25519):[Enter for default]Enter passphrase (empty for no passphrase):[Enter strong passphrase]Enter same passphrase again:Your identification has been saved in /home/student/.ssh/id_ed25519
Your public key has been saved in /home/student/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:yOuRkEyFiNgErPrInT1234567890AbCdEfGhIjKlMn student@workstation
The key's randomart image is:
+--[ED25519 256]--+
| .+o.o.=+ |
| ..+.o.+ .. |
...# Generate RSA key (for legacy compatibility, use 4096 bits)[student@workstation ~]$ ssh-keygen -t rsa -b 4096
# Generate with specific filename and comment[student@workstation ~]$ ssh-keygen -t ed25519 -f ~/.ssh/work_key -C "work laptop 2024"
SSH will refuse to use keys with wrong permissions! Private keys must be readable only by the owner. This prevents other users from stealing your keys.
Deploying Public Keys: ssh-copy-id
# Copy public key to remote server (easiest method)[student@workstation ~]$ ssh-copy-id student@server.example.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/student/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
student@server.example.com's password:[Enter password]
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'student@server.example.com'"
and check to make sure that only the key(s) you wanted were added.# Test key-based authentication[student@workstation ~]$ ssh student@server.example.com
Enter passphrase for key '/home/student/.ssh/id_ed25519':[Key passphrase, not password][student@server ~]$# Copy specific key file[student@workstation ~]$ ssh-copy-id -i ~/.ssh/work_key.pub student@server.example.com
Manual Key Deployment
# View your public key[student@workstation ~]$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... student@workstation# Method 1: Pipe through SSH[student@workstation ~]$ cat ~/.ssh/id_ed25519.pub | ssh student@server \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# Method 2: Copy and paste manually# 1. Display the public key[student@workstation ~]$ cat ~/.ssh/id_ed25519.pub
# 2. On the server, create the authorized_keys file[student@server ~]$ mkdir -p ~/.ssh
[student@server ~]$ chmod 700 ~/.ssh
[student@server ~]$ vim ~/.ssh/authorized_keys # Paste the key[student@server ~]$ chmod 600 ~/.ssh/authorized_keys
# Verify the authorized_keys file[student@server ~]$ cat ~/.ssh/authorized_keys
⚠ Key Format: Each key must be on a single line. Don't add line breaks! The entire key from "ssh-ed25519" to the comment is one line.
The authorized_keys File
# Located at ~/.ssh/authorized_keys on the SERVER[student@server ~]$ cat ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... student@workstation
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB... student@laptop
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@management# Keys can have options prependedfrom="192.168.1.*" ssh-ed25519 AAAAC3... restricted-user
command="/usr/bin/backup.sh" ssh-ed25519 AAAAC3... backup-key
no-pty,no-port-forwarding ssh-ed25519 AAAAC3... limited-key
Option
Purpose
from="pattern"
Only allow connections from matching hosts
command="cmd"
Force specific command, ignore client request
no-pty
Prevent terminal allocation
no-port-forwarding
Disable port forwarding
no-agent-forwarding
Disable agent forwarding
SSH Authentication Flow
1
Client connects - TCP connection to server port 22
Client offers public key - "I want to authenticate with this key"
4
Server checks authorized_keys - Is this key allowed?
5
Server sends challenge - Random data encrypted with public key
6
Client decrypts and responds - Using private key (may need passphrase)
7
Server verifies response - Correct? Grant access!
Key Point: The private key never leaves the client. The server verifies identity through challenge-response, not by receiving the private key.
SSH Agent: Passphrase Caching
ssh-agent holds your decrypted private keys in memory, so you only enter the passphrase once per session instead of every connection.
# Start ssh-agent (usually automatic in desktop environments)[student@workstation ~]$ eval $(ssh-agent)
Agent pid 12345# Add your key to the agent[student@workstation ~]$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/student/.ssh/id_ed25519:Identity added: /home/student/.ssh/id_ed25519 (student@workstation)# List keys in agent[student@workstation ~]$ ssh-add -l
256 SHA256:yOuRkEyFiNgErPrInT... student@workstation (ED25519)# Now connections don't prompt for passphrase[student@workstation ~]$ ssh server.example.com
[student@server ~]$# Connected without passphrase prompt!# Remove all keys from agent (security)[student@workstation ~]$ ssh-add -D
Configuring sshd for Security
# /etc/ssh/sshd_config - Server configuration# Disable root login (recommended)PermitRootLoginno# Disable password authentication (keys only)PasswordAuthenticationno# Enable public key authentication (usually default)PubkeyAuthenticationyes# Specify allowed users or groupsAllowUsersstudent adminAllowGroupssshusers wheel# Disable empty passwordsPermitEmptyPasswordsno# Use only SSH protocol 2Protocol2
# After editing, validate and restart[root@server ~]# sshd -t # Test config syntax[root@server ~]# systemctl restart sshd
Disabling Password Authentication
Generate keys on your workstation: ssh-keygen -t ed25519
Deploy public key to server: ssh-copy-id user@server
Test key authentication - Verify you can connect without password
Keep current session open - Your safety net!
Edit sshd_config: Set PasswordAuthentication no
Test and restart: sshd -t && systemctl restart sshd
Test from new terminal - Verify key auth still works
⚠ CRITICAL: Do NOT close your existing session until you've verified key authentication works after the change. If something goes wrong, you need that session to fix it!
SSH Client Configuration
# ~/.ssh/config - Per-user client configurationHost webserver
HostName webserver.example.com
User admin
Port 22
IdentityFile ~/.ssh/work_key
Host database
HostName 192.168.1.50
User dbadmin
IdentityFile ~/.ssh/db_key
Host *.internal.example.com
User developer
IdentityFile ~/.ssh/internal_key
StrictHostKeyChecking yes
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# Now connect using the alias[student@workstation ~]$ ssh webserver # Expands to full connection[student@workstation ~]$ ssh database # Uses the defined settings
Benefit: Define complex connection settings once, then use simple aliases. Different keys for different purposes, different usernames per host.