3.7.3. SSH security basics
Table of Contents
Why SSH Security Matters
SSH (Secure Shell) is usually the primary way to remotely administer Linux systems. If SSH is compromised, an attacker effectively gets a shell on your machine with your privileges (or root, if they can escalate). This chapter focuses on practical, baseline measures to harden SSH on typical Linux servers.
You’ll use:
- The SSH server config:
/etc/ssh/sshd_config - The SSH client config:
/etc/ssh/ssh_configand~/.ssh/config - The
ssh,sshd, andsshd-keygentools - Systemd commands like
systemctl restart sshd(name may besshon some distros)
Assume SSH is already installed and working; here we focus on making it safer.
Understanding SSH Keys vs Passwords
SSH supports two common authentication methods:
- Password authentication
- You type a username and password.
- Vulnerable to brute-force guessing if SSH is exposed to the internet.
- Reuse of passwords across services is especially dangerous.
- Public key authentication
- You generate a key pair: private key (kept secret) and public key (shared).
- Server stores your public key in
~/.ssh/authorized_keys. - When you connect, the server challenges your client to prove it has the private key.
- More resistant to brute-force attacks, especially if keys are protected with a passphrase.
For most servers, public key authentication should be the default, and password logins should be disabled once keys are in place.
Generating and Using SSH Keys Securely
Creating a key pair
Run this on the client machine (your laptop/workstation):
ssh-keygen -t ed25519 -C "you@example.com"-t ed25519: uses a modern, strong key type.-Cis an arbitrary comment (e.g., email or purpose).- Default file is
~/.ssh/id_ed25519(private) and~/.ssh/id_ed25519.pub(public).
When prompted:
- Choose a strong passphrase. This encrypts your private key at rest.
- Don’t share the private key file with anyone.
To see your public key:
cat ~/.ssh/id_ed25519.pub
Never share the private key (id_ed25519); you may share the .pub file.
Installing your public key on the server
On the client, you can copy your key to a server:
ssh-copy-id user@server.example.comThis:
- Appends your public key to
~user/.ssh/authorized_keyson the server. - Sets basic permissions correctly.
If ssh-copy-id is unavailable, do it manually:
- On client:
cat ~/.ssh/id_ed25519.pub- On server (logged in as
useror viasudo su - user):
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA... your-comment" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysNow test login from client:
ssh user@server.example.comIf it logs in without asking for the account’s password (but maybe asking for key passphrase), key auth is working.
Hardening `sshd_config`
The SSH daemon configuration file is usually /etc/ssh/sshd_config.
Before editing, backup it:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bakAfter changes, test config for syntax errors:
sudo sshd -tIf there’s no output, configuration syntax is OK. Then restart:
sudo systemctl restart sshd
# or, on some systems:
sudo systemctl restart sshDisable root login
Logging in directly as root over SSH is risky. Use a regular user and sudo instead.
In /etc/ssh/sshd_config:
PermitRootLogin noOr, more permissive but still safer than full root logins:
PermitRootLogin prohibit-password
This allows only key-based root logins (not recommended for beginners; prefer no).
Enforce key-based authentication
Once keys are set up and tested, disable password auth:
In /etc/ssh/sshd_config:
PasswordAuthentication no
KbdInteractiveAuthentication no
UsePAM yesNotes:
- Only do this after confirming that your keys work, or you can lock yourself out.
- Keep console/physical access or out-of-band access (e.g., cloud provider console) for recovery.
Restrict SSH protocol and algorithms
Modern OpenSSH only supports protocol 2; ensure it:
Protocol 2Algorithms:
- Old/weak ciphers and MACs should be disabled, but default modern OpenSSH configs are generally sane.
- For most beginners, rely on the distro defaults; aggressive tuning belongs in more advanced chapters.
Limiting Who and How People Can Log In
Restrict which users can SSH
You can explicitly allow only certain users or groups:
In /etc/ssh/sshd_config:
AllowUsers alice backupuser
# or
AllowGroups sshusers
If you use AllowUsers or AllowGroups, only those listed will be allowed.
Alternatively, you can deny specific accounts:
DenyUsers test temp
DenyGroups nogroup
Don’t use both Allow and Deny in complex ways unless you understand the precedence rules; for simple setups, stick to one approach.
Use non-default port (with care)
Changing the SSH port from 22 to another (e.g., 2222) does not add real cryptographic security, but it:
- Reduces noise from automated bots scanning the internet.
- Makes logs less cluttered with generic brute-force attempts.
In /etc/ssh/sshd_config:
Port 2222Then update firewall rules and connect with:
ssh -p 2222 user@server.example.comThis is “security through obscurity” and should supplement, not replace, proper hardening.
Protecting SSH with Firewalls
Basic idea: only allow SSH from networks or IPs that should reach it.
Examples:
Using UFW (commonly on Ubuntu)
Allow SSH on the default port:
sudo ufw allow sshIf you changed the SSH port (e.g., to 2222):
sudo ufw allow 2222/tcpRestrict to a specific IP:
sudo ufw allow from 203.0.113.10 to any port 22 proto tcpCheck rules:
sudo ufw status verboseUsing firewalld (Fedora/RHEL family)
Allow SSH in the active zone:
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadIf using a custom port:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
For tighter restrictions (e.g., only from a specific subnet), use --add-rich-rule or rich rules as appropriate for your environment.
Using Fail2ban (Brute-Force Protection)
Fail2ban monitors logs and bans IP addresses with repeated failed login attempts.
Install (example on Debian/Ubuntu):
sudo apt install fail2banBasic SSH protection is often enabled by default. To enable or tune it:
- Copy default config:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local- Edit
/etc/fail2ban/jail.local, look for[sshd]:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 600maxretry: number of failed attempts before ban.bantime: ban duration in seconds.
- Restart Fail2ban:
sudo systemctl restart fail2banCheck banned IPs:
sudo fail2ban-client status sshdFail2ban configuration can be more advanced, but this baseline cuts down on brute-force noise.
Securing SSH Client-Side
Use `~/.ssh/config` for safer defaults
Create or edit ~/.ssh/config on your client:
Host server-example
HostName server.example.com
User alice
Port 2222
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yesNow connect with:
ssh server-exampleThis helps avoid mistakes like specifying the wrong port or user, and enforces use of your key.
Protect your private keys
- Set proper permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519- Never email or upload private keys.
- Use an SSH agent so you don’t type your passphrase every connection:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519Many desktop environments start an agent automatically.
Verifying Host Keys and Avoiding MITM
When you first connect to a host, SSH shows a message like:
The authenticity of host 'server.example.com (203.0.113.5)' can't be established.
ED25519 key fingerprint is SHA256:....
Are you sure you want to continue connecting (yes/no/[fingerprint])?- SSH stores the server’s host key fingerprint in
~/.ssh/known_hosts. - On later connections, it checks if the key changed; if it did, you’ll get a warning (possible man-in-the-middle attack or server reinstall).
Basic practices:
- For important servers, verify the fingerprint out-of-band (e.g., from your provider’s web console or documentation) before accepting.
- If you see a warning about a changed host key, don’t blindly accept it. Confirm why it changed (e.g., server rebuilt) before proceeding.
You can inspect a known host entry:
ssh-keygen -lf ~/.ssh/known_hostsOr from a host key file on the server:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubPractical Hardening Checklist
For a typical internet-facing server:
- Generate an
ed25519SSH key on your client; protect it with a passphrase. - Install your public key on the server (
ssh-copy-id). - Confirm you can log in using the key.
- On the server, edit
/etc/ssh/sshd_config: Protocol 2PermitRootLogin noPasswordAuthentication no(after confirming key works)- Optionally change
Portfrom22to a non-standard value. - Optionally add
AllowUsers yourusername. - Test SSH config:
sudo sshd -t. - Restart SSH service.
- Configure firewall (UFW or firewalld) to:
- Allow SSH only from networks that need it.
- Use the correct port.
- Install and enable Fail2ban (or equivalent) to limit brute-force attempts.
- Keep SSH server and system packages up to date with your distro’s package manager.
- Periodically review
/var/log/auth.logor equivalent for unusual SSH activity.
These steps provide a solid baseline of SSH security for most beginner-to-intermediate Linux administrators.
Views: 330
KAHIBARO