Kahibaro
Discord Login Register

3.7.3 SSH security basics

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:

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:

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"

When prompted:

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.com

This:

If ssh-copy-id is unavailable, do it manually:

  1. On client:
   cat ~/.ssh/id_ed25519.pub
  1. On server (logged in as user or via sudo su - user):
   mkdir -p ~/.ssh
   chmod 700 ~/.ssh
   echo "ssh-ed25519 AAAA... your-comment" >> ~/.ssh/authorized_keys
   chmod 600 ~/.ssh/authorized_keys

Now test login from client:

ssh user@server.example.com

If 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.bak

After changes, test config for syntax errors:

sudo sshd -t

If there’s no output, configuration syntax is OK. Then restart:

sudo systemctl restart sshd
# or, on some systems:
sudo systemctl restart ssh

Disable root login

Logging in directly as root over SSH is risky. Use a regular user and sudo instead.

In /etc/ssh/sshd_config:

PermitRootLogin no

Or, 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 yes

Notes:

Restrict SSH protocol and algorithms

Modern OpenSSH only supports protocol 2; ensure it:

Protocol 2

Algorithms:

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:

In /etc/ssh/sshd_config:

Port 2222

Then update firewall rules and connect with:

ssh -p 2222 user@server.example.com

This 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 ssh

If you changed the SSH port (e.g., to 2222):

sudo ufw allow 2222/tcp

Restrict to a specific IP:

sudo ufw allow from 203.0.113.10 to any port 22 proto tcp

Check rules:

sudo ufw status verbose

Using firewalld (Fedora/RHEL family)

Allow SSH in the active zone:

sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

If 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 fail2ban

Basic SSH protection is often enabled by default. To enable or tune it:

  1. Copy default config:
   sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
  1. Edit /etc/fail2ban/jail.local, look for [sshd]:
   [sshd]
   enabled  = true
   port     = ssh
   filter   = sshd
   logpath  = /var/log/auth.log
   maxretry = 5
   bantime  = 600
  1. Restart Fail2ban:
   sudo systemctl restart fail2ban

Check banned IPs:

sudo fail2ban-client status sshd

Fail2ban 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 yes

Now connect with:

ssh server-example

This helps avoid mistakes like specifying the wrong port or user, and enforces use of your key.

Protect your private keys

  chmod 700 ~/.ssh
  chmod 600 ~/.ssh/id_ed25519
  eval "$(ssh-agent -s)"
  ssh-add ~/.ssh/id_ed25519

Many 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])?

Basic practices:

You can inspect a known host entry:

ssh-keygen -lf ~/.ssh/known_hosts

Or from a host key file on the server:

sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Practical Hardening Checklist

For a typical internet-facing server:

  1. Generate an ed25519 SSH key on your client; protect it with a passphrase.
  2. Install your public key on the server (ssh-copy-id).
  3. Confirm you can log in using the key.
  4. On the server, edit /etc/ssh/sshd_config:
    • Protocol 2
    • PermitRootLogin no
    • PasswordAuthentication no (after confirming key works)
    • Optionally change Port from 22 to a non-standard value.
    • Optionally add AllowUsers yourusername.
  5. Test SSH config: sudo sshd -t.
  6. Restart SSH service.
  7. Configure firewall (UFW or firewalld) to:
    • Allow SSH only from networks that need it.
    • Use the correct port.
  8. Install and enable Fail2ban (or equivalent) to limit brute-force attempts.
  9. Keep SSH server and system packages up to date with your distro’s package manager.
  10. Periodically review /var/log/auth.log or equivalent for unusual SSH activity.

These steps provide a solid baseline of SSH security for most beginner-to-intermediate Linux administrators.

Views: 92

Comments

Please login to add a comment.

Don't have an account? Register now!