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.