Tech Verse Logo
Enable dark mode
Hardening a Linux VPS with Custom Port and Keys

Hardening a Linux VPS with Custom Port and Keys

Md. Mostafijur RahmanMMd. Mostafijur Rahman

Md. Mostafijur Rahman

•4 min read

You spin up a fresh virtual private server, and within minutes, the authentication logs start filling with automated login attempts. Bots scan every public IP address for open SSH ports, cycling through common usernames and weak passwords until they find a gap. Leaving SSH on port twenty-two with password authentication enabled is an open invitation for compromise. Fixing this requires two straightforward configuration changes: moving the daemon to a non-standard port and enforcing cryptographic key pairs while shutting down passwords altogether. It isn't complicated, but it's easy to miss a detail that'll lock you out.

Most administrators skip these steps on development boxes, and that's a mistake. Automated scanners don't care if your app isn't launched yet. They just want an entry point. If you don't secure the perimeter right away, you'll spend hours cleaning up a compromised container or burning cycles trying to figure out how a crypto miner got installed. Let's walk through the exact steps to lock down the daemon before you deploy any code.

Generating and Copying Your SSH Key Pair

Before you lock down the server, you need a reliable way to get back in. Password authentication goes away permanently in a later step, so generating an Ed25519 key pair on your local machine is the mandatory first move. Run the key generator in your local terminal and accept the default file path. Don't skip the passphrase unless you enjoy living dangerously.

ssh-keygen -t ed25519 -C "admin@example.com"

That command writes a private key and a public key to your local ~/.ssh directory. Next, copy that public key to your remote server using the standard copy utility. You'll need your temporary root password for this single operation.

ssh-copy-id -i ~/.ssh/id_ed25519.pub root@your_server_ip

Log in once to confirm the key works without prompting for a password. If the server lets you straight through to the shell, you're ready to modify the daemon configuration. If it still asks for a password, stop here and fix your key permissions before touching any configuration files, or you'll lock yourself out of the box for good.

You should also verify that your local SSH agent has the identity loaded. Run ssh-add -l to check. If it doesn't return your key, add it manually with ssh-add ~/.ssh/id_ed25519. Skipping this will cause authentication to fail once the remote server rejects standard password fallbacks, even if the public key file is sitting in the right directory on the remote host.

Modifying the SSH Daemon Configuration

The main SSH configuration file lives at /etc/ssh/sshd_config on most distributions. Open this file with your preferred text editor. You need to adjust three distinct directives to secure the service. First, locate the port directive, uncomment it, and change the number to something outside the standard range. Pick an unprivileged port above ten thousand to avoid conflicts with common services.

Next, find the password authentication settings. You must disable plain text passwords entirely so that brute-force attempts fail instantly, regardless of how many guesses a bot tries. Finally, ensure root login is restricted or forced through keys only. Here is what those specific lines look like inside the configuration file once edited.

Port 49152
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes

Save the file and exit the editor. Don't close your current terminal session yet. You need to test the configuration syntax before restarting the service to ensure you didn't introduce a typo that breaks the daemon.

Check if your operating system uses drop-in configuration files inside an sshd_config.d directory. Modern Linux distributions often split configurations into separate files to make package upgrades cleaner. If you see an include directive pointing to that directory, you'll want to place your custom directives there instead of modifying the main file directly. It's a cleaner approach that won't get overwritten when OpenSSH gets patched by your package manager.

Testing the Configuration and Restarting the Service

Systemd manages the SSH service on modern Linux installations. Before applying the changes, run the SSH daemon validation flag to check for parsing errors. If this command prints anything other than an empty output, fix the reported line number immediately.

sshd -t

If the test passes, restart the SSH service to load the new port and authentication rules. On systemd distributions, the restart command targets the ssh service name. Some enterprise distributions use sshd instead, so check your specific service manager if the command fails.

sudo systemctl restart ssh

Open a second terminal window on your local machine and test the connection before closing your original session. You must specify the new port flag and point to your private key explicitly. If you forget the port flag, the client will time out trying to reach port twenty-two.

ssh -p 49152 -i ~/.ssh/id_ed25519 root@your_server_ip

Once you confirm successful entry through the new port, you can safely close your original terminal. If you run into firewall blocks, make sure to adjust your rules as outlined in Configuring Linux Deploy Users, Sudo, and SSH Keys to permit traffic on your chosen port before closing access. For long-running servers where you want to keep an eye on active resource usage and connection drops, pair this setup with the tips found in Self-Hosted Linux Server Monitoring Without SaaS Fees to track unauthorized access attempts.

Don't forget to configure your host firewall to block traffic on the old port once you're confident everything works. Leaving port twenty-two open in your firewall rules while closing it in the SSH daemon creates confusion down the road. Keep your rule set clean and minimal so you aren't guessing which ports are actually active when auditing your infrastructure later.

Md. Mostafijur RahmanMMd. Mostafijur Rahman

WRITTEN BY

Md. Mostafijur Rahman

    Latest Posts

    View All

    Hardening a Linux VPS with Custom Port and Keys

    Hardening a Linux VPS with Custom Port and Keys

    Mastering Next.js Streaming and Suspense

    Mastering Next.js Streaming and Suspense

    Preventing Race Conditions in Laravel Seeders

    Preventing Race Conditions in Laravel Seeders

    Linux Sysctl Tuning for High-Throughput Web Servers

    Linux Sysctl Tuning for High-Throughput Web Servers

    Local Embedding Models in Production RAG

    Local Embedding Models in Production RAG

    Preventing nextjs middleware cache poisoning

    Preventing nextjs middleware cache poisoning

    Fixing Async Python Memory Leaks from Unclosed Sessions

    Fixing Async Python Memory Leaks from Unclosed Sessions

    Optimizing Inertia SSR Performance in Production

    Optimizing Inertia SSR Performance in Production

    Cron vs Systemd Timers: Which to Use

    Cron vs Systemd Timers: Which to Use

    Configuring Linux Deploy Users, Sudo, and SSH Keys

    Configuring Linux Deploy Users, Sudo, and SSH Keys