CIS126RH | RHEL System Administration 1
Mesa Community College
Know how SSH verifies server identity and protects against MITM attacks
Create Ed25519/RSA keys and deploy public keys to remote systems
Avoid repeated passphrase entry while maintaining security
Disable password auth, restrict access, configure client shortcuts
SSH creates an encrypted tunnel between client and server. Authentication and all data transfer happen inside this encrypted channel.
| Component | Location | Purpose |
|---|---|---|
ssh | Client | Client program — connects to remote servers |
sshd | Server | SSH daemon — listens for connections (port 22) |
~/.ssh/ | Client | Client configuration, keys, known hosts |
/etc/ssh/ | Server | Server configuration and host keys |
| Type | Key File | Notes |
|---|---|---|
Ed25519 | id_ed25519 | Recommended — fast, secure, modern |
RSA | id_rsa | Legacy — use 4096-bit minimum |
ECDSA | id_ecdsa | Elliptic curve — widely supported |
Authentication flow: Client presents public key → Server checks authorized_keys → Server sends a challenge → Client signs it with private key → Server verifies signature
Every SSH server has host keys — unique key pairs that identify the server. These prevent man-in-the-middle attacks by verifying you are connecting to the real server.
# Server host keys stored in /etc/ssh/
[root@server ~]# ls /etc/ssh/ssh_host_*
/etc/ssh/ssh_host_ed25519_key (private)
/etc/ssh/ssh_host_ed25519_key.pub (public)
/etc/ssh/ssh_host_rsa_key (private)
/etc/ssh/ssh_host_rsa_key.pub (public)
# View server's fingerprint
[root@server ~]# ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:XYZ123... root@server (ED25519)
[user@client ~]$ ssh user@server.example.com
The authenticity of host 'server.example.com (192.168.1.100)'
can't be established.
ED25519 key fingerprint is SHA256:AbCdEfGhIjKlMnOpQrStUv1234567890.
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' to the list of known hosts.
[user@server ~]$
# View known_hosts
[user@client ~]$ cat ~/.ssh/known_hosts
server.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBcd...
192.168.1.100 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBcd...
webserver.lab ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC...
# Show fingerprints for entries in known_hosts
[user@client ~]$ ssh-keygen -lf ~/.ssh/known_hosts
256 SHA256:AbCdEf... server.example.com (ED25519)
256 SHA256:AbCdEf... 192.168.1.100 (ED25519)
# Remove a specific host entry
[user@client ~]$ ssh-keygen -R server.example.com
# Host server.example.com found: line 1
/home/user/.ssh/known_hosts updated.
# System-wide known hosts (all users)
/etc/ssh/ssh_known_hosts
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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)!
The fingerprint for the ED25519 key sent by the remote host is
SHA256:NewFingerprint1234567890abcdef.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending key in /home/user/.ssh/known_hosts:1
Host key verification failed.
# Step 1: Verify the key change is legitimate
# (Check console, contact admin, verify through secure channel)
# Step 2: Remove the old key entry
[user@client ~]$ ssh-keygen -R server.example.com
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old
# Also remove by IP if you connected by IP
[user@client ~]$ ssh-keygen -R 192.168.1.100
# Step 3: Reconnect and verify new fingerprint
[user@client ~]$ ssh user@server.example.com
The authenticity of host 'server.example.com (192.168.1.100)' cannot be established.
ED25519 key fingerprint is SHA256:NewFingerprint1234567890abcdef.
Are you sure you want to continue connecting (yes/no)? yes
# Or manually edit known_hosts to remove the offending line
[user@client ~]$ vim ~/.ssh/known_hosts
Key-based authentication replaces passwords with a cryptographic key pair. The private key stays on your client (never shared). The public key is placed on servers you want to access.
~/.ssh/id_ed25519
Keep secret. Password-protected. Never leave your client.
~/.ssh/id_ed25519.pub
Safe to share. Goes into server's authorized_keys.
# Generate an Ed25519 key (recommended)
[user@client ~]$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519): [Enter]
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase): [Enter passphrase]
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:YourKeyFingerprint1234567890 user@client
# View your .ssh directory — check permissions!
[user@client ~]$ ls -la ~/.ssh/
drwx------. 2 user user 80 Jan 20 10:00 .
-rw-------. 1 user user 419 Jan 20 10:00 id_ed25519
-rw-r--r--. 1 user user 96 Jan 20 10:00 id_ed25519.pub
-rw-r--r--. 1 user user 442 Jan 20 10:00 known_hosts
# View public key (this is what you share)
[user@client ~]$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBcd... user@client
# View key fingerprint
[user@client ~]$ ssh-keygen -lf ~/.ssh/id_ed25519.pub
256 SHA256:YourKeyFingerprint1234567890 user@client (ED25519)
id_ed25519) must be 600 (rw-------). SSH will refuse to use keys with too-permissive permissions.
# Method 1: ssh-copy-id (recommended)
[user@client ~]$ ssh-copy-id user@server.example.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "~/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)
Number of key(s) added: 1
Now try logging into the machine with: "ssh 'user@server.example.com'"
and check to make sure that only the key(s) you wanted were added.
# Method 2: Manual copy (if ssh-copy-id unavailable)
[user@client ~]$ cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
ssh-copy-id automatically sets correct permissions on the server. Always prefer it over manual copying.
# Connect — key used automatically, passphrase prompted
[user@client ~]$ ssh user@server.example.com
Enter passphrase for key '/home/user/.ssh/id_ed25519':
Last login: Mon Jan 20 10:30:00 2024
[user@server ~]$
# Specify a different key file
[user@client ~]$ ssh -i ~/.ssh/work_key user@server
# Verbose mode to troubleshoot authentication
[user@client ~]$ ssh -v user@server
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/user/.ssh/id_ed25519 ED25519 SHA256:abc...
debug1: Server accepts key: /home/user/.ssh/id_ed25519 ED25519 SHA256:abc...
debug1: Authentication succeeded (publickey).
ssh-agent caches your decrypted private key in memory. You type the passphrase once; subsequent connections use the cached key automatically.
# Start ssh-agent (often already running in desktop env)
[user@client ~]$ eval $(ssh-agent)
Agent pid 12345
# Add your key — enter passphrase once
[user@client ~]$ ssh-add
Enter passphrase for /home/user/.ssh/id_ed25519:
Identity added: /home/user/.ssh/id_ed25519 (user@client)
# List loaded keys
[user@client ~]$ ssh-add -l
256 SHA256:YourFingerprint user@client (ED25519)
# Remove all keys from agent
[user@client ~]$ ssh-add -D
# View authorized_keys on the server
[user@server ~]$ cat ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBcd... user@client
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIXyz... user@laptop
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB... admin@workstation
# Add restrictions to limit a key's use
from="192.168.1.*",no-port-forwarding ssh-ed25519 AAAAC3... backup@client
# Common restrictions:
# from="pattern" — Only allow from specific IPs/hosts
# command="cmd" — Only run this one command when used
# no-port-forwarding — Disable port forwarding
# no-X11-forwarding — Disable X11 forwarding
# no-pty — Disable terminal allocation
[root@server ~]# vim /etc/ssh/sshd_config
# Key security settings:
PermitRootLogin no # Disable direct root login
PasswordAuthentication no # Require key-based auth only
PubkeyAuthentication yes # Enable key-based auth
AuthorizedKeysFile .ssh/authorized_keys
# Restrict who can SSH in
AllowUsers alice bob # Only these users can SSH
AllowGroups sshusers # Or only this group
# Other hardening
X11Forwarding no # Disable X11 forwarding
MaxAuthTries 3 # Limit auth attempts
ClientAliveInterval 300 # Timeout idle connections (seconds)
ClientAliveCountMax 2 # Disconnect after 2 missed keepalives
# After any changes, restart sshd
[root@server ~]# systemctl restart sshd
# Step 1: Verify key-based auth works FIRST
[user@client ~]$ ssh -o PasswordAuthentication=no user@server
# If this succeeds, you are safe to proceed
# Step 2: Edit sshd_config on server
[root@server ~]# vim /etc/ssh/sshd_config
PasswordAuthentication no
# Step 3: Restart sshd (keep current session open!)
[root@server ~]# systemctl restart sshd
# Step 4: Test from a NEW terminal — do not close current one yet
[user@client ~]$ ssh user@server
vim /etc/ssh/sshd_config → set PasswordAuthentication yes → systemctl restart sshd
[user@client ~]$ cat ~/.ssh/config
# Default settings for all hosts
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# Named shortcut for production server
Host prod
HostName production.example.com
User admin
IdentityFile ~/.ssh/prod_key
Port 2222
# Jump through a bastion host
Host internal
HostName 10.0.0.50
User developer
ProxyJump bastion.example.com
# Now use shortcuts
[user@client ~]$ ssh prod
# Instead of: ssh -i ~/.ssh/prod_key -p 2222 admin@production.example.com
SSH host keys verify server identity. The first connection fingerprint must be verified out-of-band. Stored in ~/.ssh/known_hosts.
Generate keys with ssh-keygen -t ed25519. Deploy with ssh-copy-id. Private key stays local; public key goes to server's authorized_keys.
Use ssh-agent + ssh-add to cache passphrases. Type once per session, connect without prompts.
Harden servers: PermitRootLogin no, PasswordAuthentication no. Always test key auth before disabling passwords.
Next: Secure File Transfer with scp and sftp