Password management: now HOWTO

Now I managed to make the whole thing together.
If you “keep all your passwords strictly offline”, just stop reading. For the rest of us.

First, I divided the passwords to 3 categories:

  1. high security”. The security requirement is defining, so we need to sacrifice some availability here.
  2. domain-specific”. These passwords are needed within a specific context and typically may reside there.
  3. accessible”. For these passwords, accessibility requirements are more important than security. JFYI, I see almost everything that is properly (properly means excluding SMS) protected by a second factor may fall into this category unless it is already classified as 1 or 2.

For high security passwords (and this may include not just passwords, but TOTP keys as well) I do not think KeepassXC is a good fit at all. Most of its features will remain unused, including GUI, and I would consider some of it even dangerous. pass + pass-otp looks like a better fit.

For domain-specific passwords again, there is no need in advanced solutions. The most obvious way to manage is to keep them in the browser keychain of the according Qube. Even it gets compromised, the impact is going to be limited.

Now, the interesting part. How to set up single KeepassXC backend to make “accessible” passwords available from any Qube (maybe not any any, but most of general purpose ones which are not strictly domain-specific or compartmentalized due to elevated threat).

  1. vault” setup. It is not exactly vault, because most likely you want it to be accessible not just from your Qubes system, but from your other devices as well, so it is going to be networked and synced (or not if you do not wish to, I do not insist). This is mostly typical passwdXC installation within a Qube, with one extra thing: we want to make the keepassXC socket available to remote clients. To get this, we need to make it sure that keepassXC set to autostart in desltop environment, and a service is created as /etc/qubes-rpc/qubes.keepassXC:
notify-send "[`qubesdb-read /name`] KeepassXC access from: $QREXEC_REMOTE_DOMAIN"
ncat -U /run/user/1000/org.keepassxc.KeePassXC.BrowserServer

Please note that in template-based installation the file does not presist over Qube restarts. You need to either put it on the template or re-create it every time with rc.local. Don’t forget to make it executable.

  1. dom0 setup. That’s easy, all you need is a regular polcy in /etc/qubes/policy.d/30-user.policy (whatever your vaultvm is, or you may replace “ask” with “allow” if you are confident enough):
qubes.keepassXC   *   @anyvm vaultvm  ask target=vaultvm
  1. client setup. First, you need keepassxc to be installed in all that templates as well, because you need a binary component named keepassxc-proxy. Then you need to define a few things: first. the extension itself. You may install it manually to each user, or just place the file to /usr/share/mozilla/firefox/extensions. Second, the messaging host reference to let the browser communicate to the proxy, the org.keepassxc.keepassxc_browser.json file.
    "allowed_extensions": [
    "description": "KeePassXC integration with native messaging support",
    "name": "org.keepassxc.keepassxc_browser",
    "path": "/usr/bin/keepassxc-proxy",
    "type": "stdio"

Put it either to .mozilla/native-messaging-hosts per user, or to /usr/lib64/mozilla template-wide. Third, the forwarder service. You need to run

/usr/bin/ncat -k -l -U /run/user/1000/org.keepassxc.KeePassXC.BrowserServer -c "qrexec-client-vm vaultvm qubes.keepassXC"

in every client Qube, under user privileges. You may define a user systemd service, or a desktop entry.

Did not test with Chromium but should work in a similar fashion.


UPD: finishing testing with Chromium. Found no easy documented way to preinstall extensions (could be done with some effort, but looks ugly). Otherwise,

▲ ~ cat /home/user/.config/chromium/NativeMessagingHosts/org.keepassxc.keepassxc_browser.json                                                                                                         
    "allowed_origins": [
    "description": "KeePassXC integration with native messaging support",
    "name": "org.keepassxc.keepassxc_browser",
    "path": "/usr/bin/keepassxc-proxy",
    "type": "stdio"

does the trick. No idea what the first one is (pdffhm…), i think we can leave it out.

I can’t tell if this should go under ‘Guides’ or ‘General Discussion’, since the former is a subcategory of ‘User Support’ which this isn’t strictly part of.

Well, I could make some scripts to set up things in a more automated fashion (or even rpms), and a documentation page… But I do not think a lot of people do really share my view on Qubes password management :slight_smile:

That looks great! These split-keepasssxc instructions can probably be added to the Qubes Community pages, next to Split GPG.

I also think we should start to think about making those split-x configs more integrated, provide packages so they are less painful to install, especially for less technical users - but that’s a bit more work :slight_smile: .

1 Like

I also have split-smartcard via p11-kit working :slight_smile:

1 Like

Finally got around to replicating this :slight_smile:

I’m getting into some problems, though: although the qrexec connection gets established and I see the ncat running in the vault (and sticking around), I have no sign that KeepassXC saw a request, and the Firefox plugin says it “Cannot decrypt message”. When I kill the ncat process, that changes the Firefox plugin state to “Cannot connect to KeePassXC”.
Unfortunately KeePassXC has very little to no debugging support. When I get ncat to dump the traffic with -x, I see 2 blocks of json data, whose origin is not made unambiguous, but seems to be a change-public-keyrequest and the associated reply saying "success":"true". On client side, the reply gets dumped as well, causing to wonder. It could be, as I describe here that the browser plugin is too timing-dependant to let the user accept or deny the qrexec request (which would be bad), but maybe that’s not the only problem, as switching the policy from ask to allow does not always change things from user perspective (well, after a few tries I was able to achieve pairing, in fact).
Is this a problem you encountered ?

Let’s note that in QubesOS we have a visual cue that the keepass authorization popup comes from the vault, and we maybe we can accept to just allow connections at the qrexec level without asking, since the confirmation from KeePass shows more details about the request - not the origin of the query though, and it would not protect if someone finds a protocol exploit.

Some info that would be easier to follow the howto:

  • to autostart keepassxc in the vaultvm:
    user:~$ mkdir ~/.config/autostart
    user:~$ ln -s /usr/share/applications/org.keepassxc.KeePassXC.desktop .config/autostart/
  • socket in /run/ is not created until Enable browser integration is selected in the vaultvm keepass
  • allowing to restart the service requires to be careful with the unix “socket file”, force-removing it before attempting to launch ncat or socat is a good idea
  • a systemd user service would look like:
    $ cat .config/systemd/user/keepassxc-proxy.service 
    Description=KeepassXC proxy to vault
    ExecStart=sh -c 'rm -f /run/user/1000/org.keepassxc.KeePassXC.BrowserServer; exec /usr/bin/ncat -k -l -U /run/user/1000/org.keepassxc.KeePassXC.BrowserServer -c "qrexec-client-vm vaultvm qubes.keepassXC"'
    … and gets enabled with:
    $ systemctl --user enable keepassxc-proxy.service
    Created symlink /home/user/.config/systemd/user/ → /home/user/.config/systemd/user/keepassxc-proxy.service.
    $ systemctl --user start keepassxc-proxy.service
  • both client and server configurations requires ncat to be installed (for fedora-based qubes the package is named nmap-ncat). One can prefer to call socat instead, as it is included in qubes templates.
    On client side use:
    ExecStart=sh -c 'rm -f /run/user/1000/org.keepassxc.KeePassXC.BrowserServer; exec socat "UNIX-LISTEN:/run/user/1000/org.keepassxc.KeePassXC.BrowserServer,fork" "EXEC:qrexec-client-vm vault-keepass qubes.keepassXC"'
    and as qubes-rpc file:
    notify-send "[`qubesdb-read /name`] KeepassXC access from: $QREXEC_REMOTE_DOMAIN"
    socat - UNIX:/run/user/1000/org.keepassxc.KeePassXC.BrowserServer
1 Like

Thanks! Hope someday I will write salt scripts to automate everything properly.

I’m also interested in this topic but I think this topic is not very related to Qubes OS because you need to use some passwords besides Qubes OS like on your phone. Is there any better website to discuss this topic? I have tried , but there isn’t enough information.

I accepted the risks of syncing keepass database.

I guess that depends on what you want to achieve. To me, putting the keepassxc database in a vault qube is a clear gain over having them in the same domain as the browser.

If you need some passwords in another machine, setting up a replication clearly has an impact on the security of those passwords, which qubes+split-keepass protects, so it does not seem so out of theme, in fact.

As far as I’m concerned, I choose not to trust my phone: Android is a complicated stack, and until I replace the vendor-modified Android with something like /e/OS, or better a manageable Linux-based OS, I’m not going to entrust it to access any sensible accounts. But well, it’s a personal decision, everyone makes his own :slight_smile:

That decision of mine precludes replication of the keepass db, but I could still use a “partial export” of some sort - not a priority here, but willing to discuss ideas.

If someone has the guts to make selective tag-based sync / access / export for keepassXC and contribute it to upstream… :slight_smile: