SSH Key Setup Guide: Create Keys, Disable Root Password & Secure Your VPS
TUTORIAL 10 min read fordnox

SSH Key Setup Guide: Create Keys, Disable Root Password & Secure Your VPS

Learn how to create SSH keys, disable root password login, and check open ports on your VPS. Step-by-step guide to securing your server in minutes.


SSH Key Setup Guide: Create Keys, Disable Root Password & Secure Your VPS

Every VPS you spin up is immediately scanned by bots trying default passwords. Within minutes. If you’re still logging in with a root password, you’re one brute-force attack away from a compromised server.

SSH keys fix this. They’re stronger than any password, faster to use, and let you disable password login entirely. Here’s how to set it all up, plus how to check what ports are exposed on your server.

Step 1: Create an SSH Key Pair

Step 1: Create an SSH Key Pair

Step 1: Create an SSH Key Pair

SSH keys work in pairs — a private key (stays on your computer, never share it) and a public key (goes on the server).

On macOS or Linux

Open a terminal and run:

ssh-keygen -t ed25519 -C "your@email.com"

You’ll see:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519):

Press Enter to accept the default location. Then set a passphrase (recommended) or press Enter to skip.

This creates two files:

FileWhat it isShare it?
~/.ssh/id_ed25519Private keyNever
~/.ssh/id_ed25519.pubPublic keyYes — copy to servers

On Windows

Option A: Windows Terminal / PowerShell

ssh-keygen -t ed25519 -C "your@email.com"

Same process as above. Keys are saved to C:\Users\YourName\.ssh\.

Option B: PuTTYgen

  1. Download PuTTY
  2. Open PuTTYgen
  3. Select EdDSA (Ed25519)
  4. Click Generate and move your mouse around
  5. Save private key (.ppk) and copy the public key text

Why Ed25519?

AlgorithmKey SizeSecuritySpeed
RSA 40964096-bitGoodSlower
Ed25519256-bitExcellentFastest
ECDSA256-bitGoodFast

Ed25519 is the modern default — shorter keys, faster operations, strong security. Use it unless you need RSA compatibility with very old systems.

Step 2: Copy Your Public Key to the Server

Method 1: ssh-copy-id (Easiest)

ssh-copy-id root@your-server-ip

Enter your password one last time. Done. The tool appends your public key to ~/.ssh/authorized_keys on the server.

Method 2: Manual Copy

If ssh-copy-id isn’t available:

cat ~/.ssh/id_ed25519.pub | ssh root@your-server-ip \
  "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Method 3: During VPS Creation

Most providers let you add SSH keys when creating a server:

This is the best approach — the server is secured from the moment it boots.

Verify It Works

ssh root@your-server-ip

You should log in without being asked for a password (or only asked for your key passphrase if you set one).

Step 3: Disable Root Password Login

Once SSH key login works, disable password authentication entirely. This makes brute-force attacks impossible.

Edit the SSH Config

sudo nano /etc/ssh/sshd_config

Find and change these lines (some may be commented out with #):

# Disable password authentication
PasswordAuthentication no

# Disable empty passwords
PermitEmptyPasswords no

# Disable challenge-response (PAM)
KbdInteractiveAuthentication no

# Optional: disable root login entirely (use a regular user + sudo instead)
# PermitRootLogin no

# If you want root login but ONLY with keys:
PermitRootLogin prohibit-password

Apply the Changes

sudo systemctl restart sshd

⚠️ Warning: Before closing your current session, open a new terminal and test that you can still log in with your key. If you lock yourself out, you’ll need console access from your VPS provider’s dashboard.

Test It

From a different machine (or try with password explicitly):

ssh -o PreferredAuthentications=password root@your-server-ip

You should see:

Permission denied (publickey).

That means password login is disabled. Only your SSH key works now.

Step 4: Check Open Ports on Your VPS

Every open port is a potential attack surface. You should know exactly what’s exposed.

Check From Inside Your Server

List all listening ports:

ss -tlnp

Output looks like:

State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:22          0.0.0.0:*          users:(("sshd",pid=1234))
LISTEN  0       511     0.0.0.0:80          0.0.0.0:*          users:(("nginx",pid=5678))
LISTEN  0       511     0.0.0.0:443         0.0.0.0:*          users:(("nginx",pid=5678))
LISTEN  0       128     127.0.0.1:5432      0.0.0.0:*          users:(("postgres",pid=9012))

What each column tells you:

ColumnMeaning
0.0.0.0:22Listening on all interfaces (publicly accessible)
127.0.0.1:5432Listening only on localhost (not publicly accessible)
ProcessWhich program is using the port

Key takeaway: Anything on 0.0.0.0 or [::] is reachable from the internet. Anything on 127.0.0.1 is local only.

Check From Outside Your Server

This tells you what the internet actually sees.

Using nmap (most thorough):

# Install nmap on your local machine
# macOS: brew install nmap
# Ubuntu: sudo apt install nmap

# Scan common ports
nmap your-server-ip

# Scan ALL ports (takes longer)
nmap -p- your-server-ip

# Scan with service detection
nmap -sV your-server-ip

Using netcat (quick single port check):

nc -zv your-server-ip 22
nc -zv your-server-ip 3306

Using an online scanner:

Visit shodan.io and search for your server IP. It shows all publicly detected ports and services — exactly what attackers see.

What Ports Should Be Open?

For a typical web server:

PortServiceShould be open?
22SSH✅ Yes (consider changing to non-standard)
80HTTP✅ Yes (redirects to HTTPS)
443HTTPS✅ Yes
3306MySQL❌ No — bind to localhost
5432PostgreSQL❌ No — bind to localhost
6379Redis❌ No — bind to localhost
27017MongoDB❌ No — bind to localhost

Rule of thumb: If a service doesn’t need to be reached from the internet, bind it to 127.0.0.1.

Close Unnecessary Ports with UFW

UFW (Uncomplicated Firewall) is the simplest way to manage port access on Ubuntu/Debian:

# Enable UFW (allow SSH first!)
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

# Check status
sudo ufw status verbose

# Block a specific port
sudo ufw deny 3306

# Allow from specific IP only
sudo ufw allow from 203.0.113.50 to any port 22

⚠️ Always allow SSH before enabling UFW. Otherwise you’ll lock yourself out.

Bonus: Additional SSH Hardening

Change the Default SSH Port

Moving SSH off port 22 eliminates 99% of automated scans:

# /etc/ssh/sshd_config
Port 2222
sudo systemctl restart sshd
sudo ufw allow 2222/tcp
sudo ufw delete allow 22/tcp

Then connect with:

ssh -p 2222 root@your-server-ip

Set Up an SSH Config File

Stop typing long commands. Create ~/.ssh/config on your local machine:

Host myserver
    HostName 203.0.113.50
    User root
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Now just type:

ssh myserver

Enable Fail2Ban

Fail2Ban watches log files and temporarily bans IPs with too many failed login attempts:

sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Check banned IPs
sudo fail2ban-client status sshd

Quick Security Checklist

After setting up any new VPS, run through this:

FAQ

I lost my SSH key. How do I get back in?

Use your VPS provider’s web console (available in every provider’s dashboard). It gives you direct terminal access without SSH. From there, you can add a new public key or temporarily re-enable password auth.

Can I use multiple SSH keys?

Yes. Add each public key on its own line in ~/.ssh/authorized_keys on the server. Useful for team access or different devices.

Should I set a passphrase on my key?

Yes, especially on shared or portable devices. It adds a second layer — even if someone steals your key file, they can’t use it without the passphrase. Use ssh-agent to avoid typing it every time:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Is changing the SSH port actually useful?

It doesn’t improve security against targeted attacks, but it eliminates ~99% of automated bot traffic. Less noise in your logs, fewer resources wasted on failed attempts.

How do I know if someone is trying to break in?

Check your auth log:

# Ubuntu/Debian
sudo tail -100 /var/log/auth.log | grep "Failed password"

# CentOS/RHEL
sudo tail -100 /var/log/secure | grep "Failed password"

If you see thousands of entries from different IPs, that’s normal bot scanning. It’s exactly why you disable password auth.

What’s Next?

Now that SSH is locked down and you know which ports are open, you’ve covered the most critical attack vectors. For a deeper dive into VPS security, check out our VPS security guide and WireGuard setup guide for encrypted tunnels between servers.

Need a VPS to practice on? Hostinger’s KVM plans start at a few bucks a month and give you full root access — perfect for learning server security hands-on.

~/ssh-key-management-guide/get-started

Ready to get started?

Get the best VPS hosting deal today. Hostinger offers 4GB RAM VPS starting at just $4.99/mo.

Get Hostinger VPS — $4.99/mo

// up to 75% off + free domain included

// related topics

ssh key setup create ssh key disable root password ssh ssh key authentication check open ports vps vps security guide

// related guides

Andrius Putna

Andrius Putna

I am Andrius Putna. Geek. Since early 2000 in love tinkering with web technologies. Now AI. Bridging business and technology to drive meaningful impact. Combining expertise in customer experience, technology, and business strategy to deliver valuable insights. Father, open-source contributor, investor, 2xIronman, MBA graduate.

// last updated: March 14, 2026. Disclosure: This article may contain affiliate links.