Skip to content

SSH keys with KeePassXC

Introduction

KeePassXC is a password manager to securely store passwords in encrypted database. KeePassXC also enables securing SSH keys by storing private keys within its encrypted database while only public keys are present on disk. With such setup in order to connect to remote host, KeePassXC database should be opened and keys will be loaded to ssh-agent. Then connection to remote host using SSH will be possible. After closing KeePassXC database keys will be removed from ssh-agent. In this post I will demonstrate how to achieve such setup.

OS used: Debian 12
Software used: KeePassXC 2.7.4

KeePassXC installation

Install KeePassXC package:

$ sudo apt install keepassxc

KeePassXC configuration

Enabling SSH Agent in KeePassXC

Enable this options in KeePassXC settings:

  • Tools > Settings > SSH Agent > check Enable SSH Agent integration

Creating new Entry in KeePassXC

  • Create new Entry in KeePassXC. It will be used for storing SSH keys (private and public key).
    • Entries > New Entry...
  • Create password for Entry. This password will be used as SSH private key password. I recommended generating strong password with entropy above 128 bits (KeePassXC shows entropy value when generating password).

Creation of SSH keys

Key generation on client computer

Create SSH public and private keys using elliptic curves algorithm (which is currently recommended algorithm):

$ ssh-keygen -a 100 -t ed25519 -f ~/.ssh/id_ed25519_myname -C "[email protected]"
  • -a - number of KDF rounds (Key Derivation Function). Higher number means slower verification of key password (if password for private key was set). This slows down number of brute force attempts to guess password for private key.
  • -t - key algorithm type, more info about ed25519 and SSH can be found in this article "Upgrade Your SSH Key to Ed25519" on medium.com
  • -f - location and name of key to be generated (private and public keys will be generated)
  • -C - comment for key, can be user name, date or other for example: "$(whoami)@$(hostname)@$(date +'%Y-%m-%d')" this will create comment with username, hostname and date when keys were generated. If comment option will be omitted than username@hostname will be used as comment.

After above command you will need to enter password for private key in terminal. Use password from Entry created in KeePassXC.

Hardening public key

You can harden permissions for public key so only your user have access to it. This is optional as public key doesn't contain sensitive information.

$ chmod 600 ~/.ssh/id_ed25519_myname.pub

Config on client computer

To assign different keys to various remote hosts use SSH config file.

$ vim ~/.ssh/config
~/.ssh/config
Host hostname
HostName ip-address or hostname.domainname
User username
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519_myname.pub

# Example:
Host homelab-server
HostName 192.168.0.11 or homelab-server.localdomain
User john
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519_homelab-server.pub

  • Host - name of host, it will be used when connecting with ssh command
  • HostName - ip address or hostname
  • User - username with which you log in to the host
  • IdentitiesOnly yes - use key specified in IdentityFile, otherwise SSH picks 5 first keys in its list (in ssh-agent) and tries them for the host
  • IdentityFile - file path to public key

Adding keys to KeePassXC

Edit Entry and:

  • add SSH keys (public and private) as attachments:
    • Edit Entry > Advanced > Attachments > Add > select generated SSH keys on your disk (private key: ~/.ssh/id_ed25519_myname and public key: ~/.ssh/id_ed25519_myname.pub)
  • enable SSH Agent for Entry:
    • Edit Entry > SSH Agent > check following options:
      • Add key to agent when database is opened/unlocked - adds keys to ssh-agent when opening KeePassXC database
      • Remove key from agent when database is closed/locked - removes keys from ssh-agent when closing KeePassXC database
      • Require user confirmation when this key is used - (optional setting) before using SSH key window will open with question to allow use of SSH key
  • select Private Key for Entry in SSH Agent:
    • Edit Entry > SSH Agent > Attachment > select private key added in Attachments

After setting above options close and reopen KeePassXC database. Keys will be loaded to ssh-agent. You can view loaded keys with command:

$ ssh-add -l

Copying SSH key to remote host

In order for SSH keys to work you need to copy public key to remote host. Use following command to do that:

$ ssh-copy-id -i ~/.ssh/id_ed25519_myname.pub -o PubkeyAuthentication=no [email protected]
  • -o PubkeyAuthentication=no - use password login (SSH might attempt to use other keys for this host and after 5 tries it will fail because the key isn't set yet)

After running this command SSH will ask you to add key fingerprint. Type yes. Then enter password for username with which you log in to the host.

Deleting private key after adding to KeePassXC

After copying public key to remote host and adding public and private key to KeePassXC the private key can be deleted from disk. As mentioned earlier, the private key will be loaded upon opening the KeePassXC database.

Testing

To test SSH connection with key use this command:

$ ssh hostname
  • hostname - hostname that was set in ~/.ssh/config

Example:

$ ssh homelab-server

Basic hardening of remote host SSH server

Last step is to harden SSH server on remote host by disabling root login and password login. For this purpose create new config file in /etc/ssh/sshd_config.d/ folder. You could change /etc/ssh/sshd_config file as shown in many tutorials, but when SSH package updates this file (for example during Debian upgrade to newer version), you'll need to decide how to merge changes from your modified file with the new one.

# vim /etc/ssh/sshd_config.d/no-root_no-pass.conf
/etc/ssh/sshd_config.d/no-root_no-pass.conf
PermitRootLogin no
PasswordAuthentication no

After this change restart SSH service:

# systemctl restart sshd.service

With root login disabled you login as normal user and if needed you change user to root with su - command. This is valid for hosts that have user and root account, for hosts without active root account you use sudo.