Tools: Complete Guide to Setting Up SSH Keys and Hardening SSH Access

Tools: Complete Guide to Setting Up SSH Keys and Hardening SSH Access

Why SSH Keys?

Generating Your SSH Key Pair

Copying Your Public Key to the Server

Testing Your Key-Based Login

Disabling Password Authentication

Hardening Your SSH Server

Changing the Default SSH Port

Disabling Root Login

Limiting User Access

Using Fail2Ban

Choosing a Hosting Provider

Conclusion Let's get your server access locked down tight and a bit more convenient. This guide will walk you through setting up SSH keys for secure logins and then hardening your SSH server to fend off unwanted guests. When you connect to a server using SSH (Secure Shell), you typically use a username and password. This is like using a key and a lock, but the key is something you have to remember and type, and it can be guessed or intercepted. SSH keys offer a more secure and convenient alternative. Instead of a password, you use a pair of cryptographic keys: a private key and a public key. Think of your private key as your physical house key – you keep it safe and secret. Your public key is like a special lock you put on your door that only your specific house key can open. When you try to log in, your computer uses your private key to prove it's you, and the server checks if it matches the public key it has on record. This process is much harder to break than guessing a password. It also means you don't have to type your password every time you connect. The first step is to create your unique SSH key pair. Most systems have the ssh-keygen command built-in. Open your terminal and run the following command: Here's what's happening: The command will then prompt you for a few things: After this, you'll see output indicating that your public and private key files have been created. Your private key (e.g., id_ed25519) should be kept secret. Your public key (e.g., id_ed25519.pub) is what you'll copy to your servers. Now that you have your key pair, you need to place your public key on the server you want to access. This tells the server to trust connections authenticated by your corresponding private key. The easiest way to do this is using the ssh-copy-id command: Replace username with your username on the server and your_server_ip with the server's IP address or hostname. When you run this command, it will ask for your server's password. After you enter it, ssh-copy-id will automatically append your public key to the ~/.ssh/authorized_keys file on the server. This file lists all the public keys that are allowed to log in without a password. If ssh-copy-id isn't available, you can do it manually. First, copy the content of your public key file: Then, SSH into your server using your password, and create the ~/.ssh directory if it doesn't exist, and then create or append to the authorized_keys file: Make sure to replace "PASTE_YOUR_PUBLIC_KEY_HERE" with the actual content of your id_ed25519.pub file. The chmod commands set the correct file permissions, which are essential for SSH security. After copying your public key, try logging into your server again: If everything is set up correctly, you should be logged in without being prompted for a password. If you set a passphrase for your private key, you will be prompted for that passphrase. Once you've confirmed that key-based login works, the next critical step is to disable password authentication entirely. This significantly reduces the risk of brute-force attacks. To do this, you need to edit the SSH server configuration file, typically located at /etc/ssh/sshd_config. You'll need root privileges to edit this file. Find the line that says PasswordAuthentication yes and change it to: If the line is commented out (starts with #), uncomment it by removing the # and then change yes to no. After saving the file, you must restart the SSH service for the changes to take effect. The command varies slightly depending on your Linux distribution: For systems using systemd (like Ubuntu 15.04+, Debian 8+, CentOS 7+): For older systems using SysVinit: Important: Before you disable password authentication, ensure you have successfully logged in with your SSH key and that you have a way to access the server if something goes wrong (e.g., a console access provided by your hosting provider). Beyond disabling password authentication, there are several other measures you can take to make your SSH server more secure. The default SSH port is 22. While not a foolproof security measure, changing it can reduce the number of automated bot attacks that scan port 22 for vulnerable servers. Edit /etc/ssh/sshd_config again: Find the line #Port 22 and change it to your desired port, for example, Port 2222. Make sure to choose a port that isn't already in use by another service. After changing the port, you'll need to restart the SSH service: When connecting from your client, you'll now need to specify the new port: Remember to update any firewall rules to allow traffic on your new SSH port. Directly logging in as the root user is generally discouraged. It's better to log in as a regular user and then use sudo to perform administrative tasks. In /etc/ssh/sshd_config, find or add the following line: Restart the SSH service after making this change. You can specify which users or groups are allowed to log in via SSH. This is useful for restricting access to specific personnel. In /etc/ssh/sshd_config, you can use AllowUsers or AllowGroups: To allow only specific users: To allow only users in a specific group: Remember to restart the SSH service after these changes. Fail2Ban is an intrusion prevention software framework that protects your server by monitoring log files (e.g., /var/log/auth.log) for malicious activity, such as repeated failed login attempts. When it detects suspicious patterns, it can automatically update firewall rules to block the offending IP addresses for a configurable amount of time. First, install Fail2Ban: Then, start and enable the service: Fail2Ban comes with default configurations. For customization, you should copy the main configuration file to a local version to avoid your changes being overwritten during updates: Now, edit jail.local to configure specific jails and settings. For SSH, the relevant section usually looks like this: After editing jail.local, restart Fail2Ban: You can check the status of Fail2Ban and its jails with: When setting up and managing servers, reliable hosting is key. I've had good experiences with providers like PowerVPS and Immers Cloud. Both offer a range of services suitable for developers, from basic VPS to more specialized solutions. For those looking to explore different server rental options and compare features, the Server Rental Guide is a fantastic resource that breaks down various providers and their offerings. Securing your SSH access with keys and hardening your SSH server configuration are fundamental steps for any server administrator or developer. By following these practices, you significantly reduce your server's attack surface, protect your data, and improve the overall security posture of your infrastructure. Remember to always test your changes thoroughly, especially after disabling password authentication, and keep your server software updated. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

$ ssh-keygen -t ed25519 -C "[email protected]" ssh-keygen -t ed25519 -C "[email protected]" ssh-keygen -t ed25519 -C "[email protected]" ssh-copy-id username@your_server_ip ssh-copy-id username@your_server_ip ssh-copy-id username@your_server_ip cat ~/.ssh/id_ed25519.pub cat ~/.ssh/id_ed25519.pub cat ~/.ssh/id_ed25519.pub mkdir -p ~/.ssh chmod 700 ~/.ssh echo "PASTE_YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys mkdir -p ~/.ssh chmod 700 ~/.ssh echo "PASTE_YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys mkdir -p ~/.ssh chmod 700 ~/.ssh echo "PASTE_YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys ssh username@your_server_ip ssh username@your_server_ip ssh username@your_server_ip -weight: 600;">sudo nano /etc/ssh/sshd_config -weight: 600;">sudo nano /etc/ssh/sshd_config -weight: 600;">sudo nano /etc/ssh/sshd_config PasswordAuthentication no PasswordAuthentication no PasswordAuthentication no -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd -weight: 600;">sudo -weight: 500;">service ssh -weight: 500;">restart -weight: 600;">sudo -weight: 500;">service ssh -weight: 500;">restart -weight: 600;">sudo -weight: 500;">service ssh -weight: 500;">restart -weight: 600;">sudo nano /etc/ssh/sshd_config -weight: 600;">sudo nano /etc/ssh/sshd_config -weight: 600;">sudo nano /etc/ssh/sshd_config -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd ssh -p 2222 username@your_server_ip ssh -p 2222 username@your_server_ip ssh -p 2222 username@your_server_ip PermitRootLogin no PermitRootLogin no PermitRootLogin no AllowUsers user1 user2 AllowUsers user1 user2 AllowUsers user1 user2 AllowGroups sshusers AllowGroups sshusers AllowGroups sshusers # For Debian/Ubuntu -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban # For CentOS/RHEL -weight: 600;">sudo -weight: 500;">yum -weight: 500;">install epel-release -weight: 600;">sudo -weight: 500;">yum -weight: 500;">install fail2ban # For Debian/Ubuntu -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban # For CentOS/RHEL -weight: 600;">sudo -weight: 500;">yum -weight: 500;">install epel-release -weight: 600;">sudo -weight: 500;">yum -weight: 500;">install fail2ban # For Debian/Ubuntu -weight: 600;">sudo -weight: 500;">apt -weight: 500;">update -weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban # For CentOS/RHEL -weight: 600;">sudo -weight: 500;">yum -weight: 500;">install epel-release -weight: 600;">sudo -weight: 500;">yum -weight: 500;">install fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban -weight: 600;">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local -weight: 600;">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local -weight: 600;">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local [sshd] enabled = true port = ssh # Replace 'ssh' with your custom SSH port if you changed it # port = 2222 filter = sshd logpath = %(sshd_log)s maxretry = 3 bantime = 1h findtime = 10m [sshd] enabled = true port = ssh # Replace 'ssh' with your custom SSH port if you changed it # port = 2222 filter = sshd logpath = %(sshd_log)s maxretry = 3 bantime = 1h findtime = 10m [sshd] enabled = true port = ssh # Replace 'ssh' with your custom SSH port if you changed it # port = 2222 filter = sshd logpath = %(sshd_log)s maxretry = 3 bantime = 1h findtime = 10m -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart fail2ban -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart fail2ban -weight: 600;">sudo fail2ban-client -weight: 500;">status -weight: 600;">sudo fail2ban-client -weight: 500;">status sshd -weight: 600;">sudo fail2ban-client -weight: 500;">status -weight: 600;">sudo fail2ban-client -weight: 500;">status sshd -weight: 600;">sudo fail2ban-client -weight: 500;">status -weight: 600;">sudo fail2ban-client -weight: 500;">status sshd - ssh-keygen: This is the command to generate SSH keys. - -t ed25519: This specifies the type of encryption. Ed25519 is a modern, secure, and fast algorithm. - -C "[email protected]": This adds a comment to your public key, which is helpful for identifying it later, especially if you manage keys for multiple servers or users. Replace "[email protected]" with your actual email address. - Enter a file in which to save the key: Press Enter to accept the default location (usually ~/.ssh/id_ed25519). If you already have a key, you might want to specify a different name to avoid overwriting it. - Enter passphrase (empty for no passphrase): This is crucial. A passphrase acts like a password for your private key. Even if someone gets your private key file, they can't use it without the passphrase. It's highly recommended to use a strong passphrase. You'll be asked to enter it twice. - enabled = true: Activates the SSH jail. - port: Specifies the SSH port. - maxretry: The number of failed attempts before an IP is banned. - bantime: How long an IP is banned (e.g., 1h for one hour). - findtime: The time window within which maxretry must occur for an IP to be banned.