Skip to content

rofi based frontend for KeePassXC running on Qubes OS

Notifications You must be signed in to change notification settings

codewhitesec/qubes-keepass

Repository files navigation

Qubes Keepass


qubes-keepass is a rofi based frontend for KeePassXC which integrates nicely with the isolation and security features of Qubes OS. It enables you to easily copy credentials to the currently focused Qube, to define allow lists for credentials based on Qube names and to automatically clear the Qubes clipboard after a configurable amount of time.

qubes-keepass-example

qubes-keepass is inspired by rofi-pass which provides a rofi based frontend for the password manager pass.

Installation


qubes-keepass relies on Qubes qrexec mechanism and requires multiple installation steps in different Qubes. In the following, it is assumed that your KeePassXC database is contained within a Qube named vault, that your window manager is i3 and that you have an AppVM Qube called app-vm. In addition, make sure that rofi is installed in vault and xclip is installed in app-vm.

dom0

In dom0 create a policy file for the custom.QubesKeepass qrexec service. This service will be invoked by your vault Qube to copy credentials to other AppVMs:

[user@dom0 ~]$ cat /etc/qubes-rpc/policy/custom.QubesKeepass
vault @anyvm allow notify=yes

According to your preferences, you could also choose ask instead of the allow action or remove the notify=true option, if you do not want to be notified when something gets copied via qubes-keepass.

If you're using Qubes 4.1 and want to follow the new qrexec policy system:

[user@dom0 ~]$ cat /etc/qubes/policy.d/30-user.policy
...
custom.QubesKeepass * vault @anyvm allow notify=yes

Now copy the qubes-keepass-dom0.sh script to a location within your $PATH environment variable and make sure that it is executable.

Finally, set up a shortcut for invoking qubes-keepass-dom0.sh in your i3 configuration file and make sure that the window class Rofi is configured to floating:

[user@dom0 ~]$ cat /.config/i3/config
...
bindsym $mod+p exec --no-startup-id qubes-keepass-dom0.sh
for_window [class="Rofi"] floating enable

vault

In your vault VM you need to enable the Secret Service integration for KeePassXC. This can be configured within the database settings and requires that no other Secret Service Providers is running. By default, you probably have gnome-keyring-daemon as Secret Service Provider running in your vault VM. The recommended way to disable it is by modifying it's autostart entry. First, setup a binddir for your vault VM:

[user@vault ~]$ cat /rw/config/qubes-bind-dirs.d/50_user.conf
binds+=( '/etc/xdg/autostart/gnome-keyring-secrets.desktop' )

Now restart the vault VM and add Hidden=true to the /etc/xdg/autostart/gnome-keyring-secrets.desktop file and comment the line containing the Exec statement. According to the documentation creating a file ~/.config/autostart/gnome-keyring-secrets.desktop with contents Hidden=true would also be sufficient, but this did not work during our tests.

[user@vault ~]$ cat /etc/xdg/autostart/gnome-keyring-secrets.desktop
...
#Exec=/usr/bin/gnome-keyring-daemon --start --components=secrets
Hidden=true

After restarting the vault VM again, gnome-keyring-daemon should no longer start up and you can enable the Secret Service integration in the KeePassXC Tools settings. If gnome-keyring-daemon is still running, reboot your system and make sure that you start your vault VM by requesting it to execute KeePassXC directly. If this does also not work read the FAQ section.

Additionally, you need to expose the credentials you want to use with qubes-keepass to the Secret Service within the database specific security settings. If you simply want to use your entire database with qubes-keepass, allow access to the Root folder of your database.

Finally, copy the qubes-keepass.py script to your vault VM and make sure it is executable. Also make sure that the location specified in qubes-keepass-dom0.sh matches the location you copied the script to (default is /home/user/.local/bin/qubes-keepass.py). Also the configuration file qubes-keepass.ini needs to be copied to your vault VM. A good location for this one is /home/user/.config/qubes-keepass.ini.

app-vm

For each AppVM that is allowed to obtain credentials from qubes-keepass, you need to setup an qrexec service. This service is essentially just a pipe to xclip and looks like this:

[user@app-vm ~]$ cat /etc/qubes-rpc/custom.QubesKeepass
#!/usr/bin/sh

xclip -selection clipboard

Make sure that it is executable and that such a file exists on each AppVM you want to use qubes-keepass with. As the qrexec service is defined outside the persistent portions of an AppVM, you probably want to set it up within the AppVMs template.

Usage


After pressing the configured shortcut for qubes-keepass-dom0.sh, qubes-keepass determines your currently focused Qube and displays available credentials from your KeePassXC database in rofi. After you selected a credential, it is copied to previously determined focused Qube using the custom.QubesKeepass qrexec service.

Within rofi you can press the following keys to copy different attributes of the credential:

  • Return or Ctrl+c: Copy password
  • Ctrl+b: Copy username
  • Ctrl+Shift+u: Copy URL

All of those can be configured using the qubes-keepass configuration-file.

Configuration


qubes-keepass accepts configuration options from two different places. Global options that affect the behavior of qubes-keepass itself can be specified within the qubes-keepass.ini configuration file. During startup, such a configuration file is searched in the following locations:

  • ~/.config/qubes-keepass.ini
  • ~/.config/qubes-keepass/config.ini
  • ~/.config/qubes-keepass/qubes-keepass.ini
  • /etc/qubes-keepass.ini
  • /etc/qubes-keepass/config.ini
  • /etc/qubes-keepass/qubes-keepass.ini

Moreover, qubes-keepass also supports some credential specific configurations, that can be applied within the Notes section of a KeePassXC credential. The following listing shows an example for such a configuration:

[QubesKeepass]
qubes = work, personal
timeout = 5
trust = 4

Credential Specific Options

  • timeout - specifies a credential specific timeout before the clipboard gets cleared after the credential was copied
  • qubes - specifies an allow list of qubes for the credential. The credential can only be copied into the specified qubes
  • trust - specifies the minimum trust level that a qube needs to be able to receive this credential
  • meta - specifies a list of qubes that are only allowed to obtain meta information of the credential (username, url)
  • icon - specifies the icon for the credential. Can be a default icon name (e.g. firefox) or a file system path. To display icons within rofi, you also need to add the -show-icons rofi-option in your qubes-keepass.ini file

Global Options

  • regex - treat specified qube names like regular expressions. This also applies to credential specific options
  • timeout - default timeout the clipboard gets cleared after a credential was copied
  • smart_sort - sort credentials by their usage count. A credential accessed within the last 30 seconds is always displayed first
  • restricted - qubes listed in this configuration can only obtain credentials that are explicitly configured for them
  • unrestricted - when this configuration is not empty, all other qubes are treated as restricted
  • minimum_trust - only qubes with a trust level above the specified value are able to obtain credentials via qubes-keepass

When using the minimum_trust option, qubes-keepass uses the default numerical values of the Qubes OS trust levels:

Label Trust Level
red 1
orange 2
yellow 3
green 4
gray 5
blue 6
purple 7
black 8

When using your own ordering (e.g. treating red as fully trusted), you can assign different trust levels within the qubes-keepass.ini file.

Theme

If you want to setup the custom theme displayed within this README file, just copy the qubes-keepass.rasi theme and the associated background image to your ~/.config/rofi folder and add -theme qubes-keepass to the rofi.options section in your qubes-keepass.ini

FAQ


Q: Isn't exposing credentials via DBus insecure?
A: No. Despite Keepass attempts to protect your credentials in memory, you should assume that each process running on the same machine as your Keepass instance is able to access these credentials by dumping them from memory. DBus access makes the process of dumping credentials more comfortable, but it is not a requirement. Moreover, your vault VM is considered trusted and other VMs are not able to access your secrets. If you are really concerned about the DBus access, you can configure Keepass to display a prompt for each credential access via DBus.

Q: Should I configure custom.QubesKeepass using the ask or allow policy?
A: It depends. custom.QubesKeepass adds a communication channel from your vault VM to other VMs. This communication channel is only unidirectional, but it could still allow to exfiltrate data from your vault into an online VM. That being said, the same is true for other Qubes mechanisms like split-SSH. If having a malicious process in your vault VM that exfiltrates data using your clipboard is something you worry about, you should use ask. If you like things more comfortable, you should use allow instead.

Q: I don't know how to stop gnome-keyring-daemon!?
A: Apparently, no one knows. We observed several different behaviors on exactly the same template VMs. As the ultima ratio you can remove the executable bit from your gnome-keyring-daemon. This method is pretty rough and could potentially break other functionality, but it seemed to work quite reliably on our test systems. Just create a binddir for gnome-keyring-daemon and remove the executable bit by running chmod -x /usr/bin/gnome-keyring-daemon.

Q: rofi does not start up, what can I do?
A: For troubleshooting, you can try to launch qubes-keepass.py and qubes-keepass-dom0.sh manually. Just run python3 qubes-keepass.py office in a terminal on your vault VM and replace office by a qube name you configured credentials for. You should see rofi startup or get an error messaghe within the terminal that can help you debugging. If everything worked, open a dom0 terminal and execute something like sleep 5 && qubes-keepass-dom0.sh. Within the sleep timeout, move the cursor to a qube you configured credentials for. If something goes wrong, you should see an error message within the dom0 terminal.

Q: Credentials are not copied to the clipboard, what can I do?
A: Make sure that the qrexec service in /etc/qubes-rpc/custom.QubesKeepass is present and executable in the desired AppVM. Also make sure that xclip is installed. You can test whether the service is working by running echo -n test | /etc/qubes-rpc/custom.QubesKeepass. After executing this command, the clipboard of the AppVM should contain the string test.

Q: I tried to installed qubes-kepass and now everything is broken!
A: Keep calm, you probably have a typo within one of your policy files. When Qubes encounters a malformed policy, it blocks all RPC communication. Run sudo journalctl -b and check for error messages indicating a malformed policy file. If you do not find it this way, just check the policy files you have edited while installing qubes-keepass. Also make sure that you changed the qube names used in the example setup to the names used by your environment.