LinuxDojo

Secure & Efficient SSH: A Comprehensive Guide

SSH (Secure Shell) is the backbone of remote server management. This guide will walk you through hardening your SSH server (sshd) for improved security and optimizing your SSH client for a more efficient workflow. We'll cover key-based authentication, disabling passwords, changing the default port, and using SSH aliases.

Step 1: Generate SSH Keys (Client Side)

The first and most crucial step for SSH security is to ditch password authentication in favor of SSH keys. This creates a cryptographic pair: a private key (kept secret on your local machine) and a public key (placed on the remote server).

Generating an Ed25519 Key

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "your_email@example.com"
                

When prompted, **always set a strong passphrase** for your private key. This encrypts the private key on your disk, adding an extra layer of security in case your local machine is compromised. The `-C` flag adds a comment for easy identification.

Step 2: Copy Your Public Key to the Server

Once your key pair is generated, you need to copy the public key (`~/.ssh/id_ed25519.pub`) to the remote server. The `ssh-copy-id` utility is the safest and easiest way to do this.

Copying Public Key

ssh-copy-id -i ~/.ssh/id_ed25519.pub username@remote_server_ip
                

You'll be prompted for the remote user's password. After successful execution, you should be able to log in using your SSH key. Test it:

Testing Key-Based Login

ssh username@remote_server_ip
                

Step 3: Harden Your SSH Server (sshd_config)

Now that you're using key-based authentication, it's time to secure the SSH server (`sshd`) itself. **Always make a backup of your `sshd_config` file before making changes.**

Backup sshd_config

# On Linux (Arch)
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# On FreeBSD
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
                

Edit `sshd_config` for Hardening:

Open `sshd_config` with your preferred editor (like `nano`):

Open sshd_config

# On Linux (Arch)
sudo nano /etc/ssh/sshd_config

# On FreeBSD
sudo nano /etc/ssh/sshd_config
                

Find and modify/add the following lines:

sshd_config recommended settings

Port 2222
PasswordAuthentication no
PermitRootLogin no
PermitEmptyPasswords no
# ChallengeResponseAuthentication no # Often default, but ensure it's not "yes"
UsePAM yes # Keep this for many Linux systems, often `no` on FreeBSD if not using PAM
X11Forwarding no # Disable if not needed
MaxAuthAttempts 3
# AllowUsers joe admin # Uncomment and add your allowed users
# AllowGroups sshusers # Uncomment and add your allowed groups
                

**Important:** If you change the `Port`, make sure to update your firewall rules (e.g., `ufw`, `iptables` on Linux, `pf`, `ipfw` on FreeBSD) to allow traffic on the new port. Test the new port with a separate SSH session before closing your current one!

Firewall Rules Example (FreeBSD pf)

# In /etc/pf.conf:
# ... other rules ...
pass in quick on em0 proto tcp to any port 2222 keep state
# ... other rules ...

# To reload pf rules after editing:
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
                
Firewall Rules Example (Linux ufw)

sudo ufw allow 2222/tcp
sudo ufw enable # if not already enabled
sudo ufw status
                

After making changes to `sshd_config` and your firewall, restart the SSH service:

Restart SSH Service

# On Linux (Arch)
sudo systemctl restart sshd

# On FreeBSD
sudo service sshd restart
                

Step 4: Configure Your SSH Client (`~/.ssh/config`)

The SSH client configuration file (`~/.ssh/config` on your local machine) allows you to set up aliases and specific settings for your connections, making them more efficient and user-friendly. Create this file if it doesn't exist.

Create/Edit ~/.ssh/config

nano ~/.ssh/config
                

Here's an example of how to configure an alias for your `remote_server_ip` machine:

Example ~/.ssh/config

Host mercury # Your preferred alias name (e.g., your machine name)
    Hostname remote_server_ip_or_hostname
    User joe
    Port 2222 # The new port you configured
    IdentityFile ~/.ssh/id_ed25519 # Path to your private key
    IdentitiesOnly yes # Only use keys specified by IdentityFile
    ForwardAgent yes # Useful for forwarding your SSH agent to jump hosts
    ServerAliveInterval 60 # Keep connection alive every 60 seconds
    ServerAliveCountMax 3 # Disconnect after 3 unanswered intervals
                

Now, you can connect to your server simply by typing:

Connecting with Alias

ssh mercury
                

Step 5: Use `ssh-agent` for Passphrase Management

If you set a passphrase for your SSH key (which you should!), `ssh-agent` allows you to unlock it once per session (or boot) instead of for every connection.

Start ssh-agent & Add Key

eval "$(ssh-agent -s)" # Start the agent (often automatic in modern desktops)
ssh-add ~/.ssh/id_ed25519 # Add your private key, you'll be prompted for passphrase
                

You can add `eval "$(ssh-agent -s)"` to your `~/.bashrc` or `~/.zshrc` (or `~/.profile` for `sh`/`ksh` users like yourself on FreeBSD) to automatically start the agent when your shell starts. `ssh-add` can also be added, though some prefer to run it manually or use a graphical agent.

Further Hardening & Tips: