McGarrah Technical Blog

SSH Key-Based Access to a Proxmox Cluster

· 5 min read

Typing passwords every time you SSH into a Proxmox node gets old fast — especially when you have a six-node cluster and you’re bouncing between nodes all day. SSH key-based authentication eliminates the password prompts entirely, and Proxmox makes it even easier because the cluster shares authorized_keys across all nodes. Copy the key once, access every node.

I needed this set up so I could run the Ceph WAL vs DB performance benchmarks from my development machine — scripting SSH commands across multiple nodes to collect latency data, trigger scrubs, and restart OSDs is painful when every command demands a password. Getting passwordless SSH sorted first made the whole test workflow possible.

Prerequisites

My Cluster

My homelab cluster is named AlteredCarbon (yes, after the show). Six Dell OptiPlex 990 nodes:

Node IP Address
harlan 192.168.86.11
kovacs 192.168.86.12
poe 192.168.86.13
edgar 192.168.86.14
tanaka 192.168.86.15
quell 192.168.86.16

Step 1: Generate an SSH Key

If you already have a key at ~/.ssh/id_ed25519, skip this step. Check with:

ls ~/.ssh/id_ed25519.pub

If you don’t have one, generate it:

ssh-keygen -t ed25519 -C "yourname-dev"

Accept the default path (~/.ssh/id_ed25519). Adding a passphrase is optional but recommended — you can use ssh-agent to avoid retyping it every time.

Why ed25519? It’s faster, more secure, and produces shorter keys than RSA. There’s no reason to use RSA for new keys unless you’re dealing with ancient systems that don’t support it.

Step 2: Pre-load Host Key Fingerprints

The first time you SSH into a new host, you get the “authenticity can’t be established” prompt and have to type “yes” to accept the fingerprint. With six nodes, that’s six interactive prompts. Skip all of them by pulling the host keys in bulk with ssh-keyscan:

ssh-keyscan 192.168.86.{11..16} >> ~/.ssh/known_hosts 2>/dev/null

This grabs the ED25519 (and other) host keys from all six nodes and appends them to your known_hosts file. No interactive prompts, no typing “yes” six times.

If you’ve already set up your SSH config (Step 4 below), you can also scan by name to cover both hostname and IP lookups:

ssh-keyscan harlan kovacs poe edgar tanaka quell 192.168.86.{11..16} >> ~/.ssh/known_hosts 2>/dev/null

Step 3: Copy the Key to One Proxmox Node

Here’s the nice part about Proxmox clusters — the /etc/pve/ filesystem is shared across all nodes via pmxcfs (the Proxmox Cluster File System). This means authorized_keys for root is shared too. Copy your key to any single node and it’s available on all of them:

ssh-copy-id root@192.168.86.11

Enter the root password when prompted. That’s the last time you’ll need it.

Step 4: Create an SSH Config

Rather than typing ssh root@192.168.86.11 every time, create ~/.ssh/config so you can just type ssh harlan:

# AlteredCarbon Proxmox Cluster
Host harlan
    HostName 192.168.86.11
    User root

Host kovacs
    HostName 192.168.86.12
    User root

Host poe
    HostName 192.168.86.13
    User root

Host edgar
    HostName 192.168.86.14
    User root

Host tanaka
    HostName 192.168.86.15
    User root

Host quell
    HostName 192.168.86.16
    User root

Host harlan kovacs poe edgar tanaka quell
    IdentityFile ~/.ssh/id_ed25519
    StrictHostKeyChecking accept-new

Set the correct permissions (SSH will refuse to use a config file that’s too open):

chmod 600 ~/.ssh/config

The shared Host block at the bottom applies two settings to all cluster nodes:

Step 5: Test It

ssh harlan

You should drop straight into a root shell with no password prompt. Verify the other nodes work too:

for node in harlan kovacs poe edgar tanaka quell; do
    echo "--- $node ---"
    ssh $node "hostname && uptime"
done

If everything is working, you’ll see the hostname and uptime for all six nodes scroll by with no password prompts.

Optional: Use ssh-agent for Passphrase Keys

If you set a passphrase on your key (and you should consider it), you can avoid retyping it by loading the key into ssh-agent:

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

On Ubuntu 24.04, the GNOME Keyring typically handles this automatically — you’ll be prompted for the passphrase once after login and it’s cached for the session.

Optional: Harden SSH on the Cluster

Once you’ve confirmed key authentication works on all nodes, you can disable password authentication entirely on the Proxmox side. SSH into any node and run:

sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

Warning: Do this carefully. Keep a session open as a safety net, or use the Proxmox web UI console (which doesn’t go through SSH) in case something goes wrong. Since this is /etc/ssh/sshd_config (a local file, not shared via /etc/pve/), you’ll need to repeat this on each node individually.

Why This Works Across the Cluster

Proxmox clusters use pmxcfs to share configuration across nodes. The root user’s authorized_keys lives under this shared filesystem, so any key you add to one node is immediately available on all nodes in the cluster. This is the same mechanism that lets you manage all nodes from a single Proxmox web UI.

This is a Proxmox-specific convenience — on a non-clustered setup, you’d need to run ssh-copy-id against each host individually.

Wrapping Up

Four commands to go from password prompts to passwordless access across an entire Proxmox cluster:

  1. ssh-keygen -t ed25519 — generate the key
  2. ssh-keyscan 192.168.86.{11..16} >> ~/.ssh/known_hosts — pre-load host fingerprints
  3. ssh-copy-id root@<any-node> — copy it once
  4. Create ~/.ssh/config — name your nodes

It’s a small quality-of-life improvement that pays off every single day when you’re managing a homelab cluster. In my case, it was the prerequisite that made running Ceph WAL vs DB benchmarks across all six nodes practical — scripting ssh harlan 'ceph tell osd.0 bench' is a lot more pleasant than typing passwords six times per test run.

Categories: proxmox, homelab, security

About the Author: Michael McGarrah is a Cloud Architect with 25+ years in enterprise infrastructure, machine learning, and system administration. He holds an M.S. in Computer Science (AI/ML) from Georgia Tech and a B.S. in Computer Science from NC State University, and is currently pursuing an Executive MBA at UNC Wilmington. LinkedIn · GitHub · ORCID · Google Scholar · Resume