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).
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.
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:
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.**
# 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`):
# On Linux (Arch)
sudo nano /etc/ssh/sshd_config
# On FreeBSD
sudo nano /etc/ssh/sshd_config
Find and modify/add the following lines:
- Change Default Port: Change `Port 22` to a high, non-standard port (e.g., `Port 2222`). This reduces automated attacks.
- Disable Password Authentication: Set `PasswordAuthentication no`. This prevents login attempts using passwords entirely.
- Disable Root Login: Set `PermitRootLogin no`. Always log in as a regular user and use `sudo` for administrative tasks.
- Disable Empty Passwords: Ensure `PermitEmptyPasswords no`.
- Use Only SSH Protocol 2: Ensure `Protocol 2`. (This is usually default now, but good to check).
- Limit Authentication Attempts: Set `MaxAuthAttempts 3`.
- Restrict Users (Optional but Recommended): Use `AllowUsers username1 username2` or `AllowGroups sshusers` to explicitly list who can SSH in.
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!
# 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
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:
# 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.
nano ~/.ssh/config
Here's an example of how to configure an alias for your `remote_server_ip` machine:
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:
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.
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:
- Keep Software Updated: Regularly update your operating system and SSH packages.
- Firewall Best Practices: Only allow SSH access from trusted IP addresses if possible.
- Fail2Ban (Linux) / sshguard (FreeBSD): Install these tools to automatically ban IPs that attempt too many failed SSH logins.
- Disable X11 Forwarding: If you don't use graphical applications over SSH, disable `X11Forwarding` in `sshd_config`.
- Use Strong Ciphers and MACs: Modern SSH clients and servers automatically negotiate strong algorithms. You can explicitly restrict them in `sshd_config` or `~/.ssh/config` if needed, but for most users, defaults are fine if your software is up-to-date.