Desktop

Install Passbolt Password Manager on Ubuntu 26.04 / 24.04

Shared admin passwords usually live in a spreadsheet, a pinned chat message or the memory of one engineer. The weak ones get reused on every system a team touches. This may lead to data breaches as the credentials can be easily stolen and cause threats to businesses, which is why many organizations deploy an enterprise password manager to store and share credentials securely. Passbolt password manager is the self-hosted, open source answer: its browser extension encrypts every secret with OpenPGP before it leaves your machine, so the server only stores ciphertext.

Original content from computingforgeeks.com - post 128325

This guide installs Passbolt CE from the official apt repository on Ubuntu and serves it over HTTPS with nginx. It then covers the web installer and browser extension, shares a credential with a second user and backs up the server keys. A fresh install of Passbolt 5.17 (tested October 2026 on Ubuntu 26.04, package steps repeated on 24.04) pulled 76 packages and passed the healthcheck with zero failures. For containers, the Passbolt Docker setup covers that path.

What the Passbolt package installs on each Ubuntu LTS

The same passbolt-ce-server package installs on both LTS releases, but it pulls a different database and PHP stack on each, because it only recommends default-mysql-server and lets Ubuntu decide what that means. These numbers come from the apt summary and the service cgroups on the two lab hosts:

Measured on the test boxUbuntu 26.04 LTSUbuntu 24.04 LTS
Passbolt CE package5.17.0-15.17.0-1
Database pulled inMySQL 8.4.11MySQL 8.0.46
PHP-FPM8.5.48.3.6
nginx1.28.31.24.0
Packages installed7687
Download / disk added54.2 MB / 322 MB65.3 MB / 417 MB
Repository suite usedfocalfocal
Memory after setup (MySQL, PHP-FPM, nginx)541 MB, 78 MB, 5 MBnot measured

Two rows matter more than the rest. The Passbolt documentation says the package installs MariaDB. On Ubuntu the recommended database resolves to Oracle MySQL instead, so you get MySQL 8.4 on the newer release and 8.0 on the older one. MySQL 8.4 passed every database check in the healthcheck on 26.04, and on 24.04 the package created its MySQL 8.0 database cleanly. The MySQL on Ubuntu guide covers tuning that server if your vault grows. The memory figures are cgroup totals read with systemctl show -p MemoryCurrent after two users and one shared password existed, and MySQL dominates them: about 620 MB for the whole stack, which fits comfortably inside the 2 GB that Passbolt recommends. The 24.04 host was a minimal LXC container, so some of its 11 extra packages are libraries a VM image already ships. The MeCab dictionary packages pulled in by MySQL 8.0 and a separate PHP opcache package account for the rest.

Prerequisites

Passbolt’s install scripts rewrite the nginx and database configuration, so start from a server that runs nothing else. You need:

  • Server: a fresh Ubuntu 26.04 or 24.04 server with sudo access. Passbolt recommends 2 CPU cores and 2 GB of RAM; our lab VM ran 2 vCPU and 4 GB, which is a floor for following along, not a sizing target for a large team.
  • Domain: a hostname such as passbolt.example.com with an A record pointing at the server. Any DNS provider works.
  • Ports: TCP 80 and 443 reachable from the internet if you want the automatic certificate, plus 22 for SSH.
  • Time sync: a working NTP client. The Passbolt login handshake signs messages with timestamps, and the healthcheck fails when the clock drifts. Ubuntu 26.04 runs chrony out of the box and 24.04 runs systemd-timesyncd, so a stock install already has one.
  • SMTP (optional): a mail relay for user invitations. The core install works without one, and Step 8 adds it later.

Sizing beyond that is driven by the number of users and stored secrets, which land in MySQL. A team of a few hundred people is still a small database, so add RAM for the MySQL buffer pool before you add CPU.

Step 1: Set the domain and open the firewall

Export the domain once at the top of your SSH session, because the HTTPS check in Step 4 uses it. Replace the value with the real hostname:

export PASSBOLT_DOMAIN="passbolt.example.com"
echo "Passbolt domain: ${PASSBOLT_DOMAIN}"

Run the export again if you reconnect, since the variable only lives in the current shell. Next, open the firewall before installing anything. Port 80 has to be reachable during the package install itself, because the automatic TLS option requests the certificate from inside the installer. The nginx UFW profile does not exist yet at this point, so allow the ports by number:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable

Allow SSH before you enable UFW, or the enable step cuts off your own session. Cloud servers usually have a second firewall (a security group or the provider’s firewall panel), and ports 80 and 443 need to be open there too. The UFW firewall guide covers rate limiting and logging if you want more than these three rules.

Step 2: Add the Passbolt repository

Passbolt ships a script that installs the repository key, the apt source, nginx and certbot, and publishes a SHA512 checksum for it on GitHub. Download both:

curl -LO https://download.passbolt.com/ce/installer/passbolt-repo-setup.ce.sh
curl -LO https://github.com/passbolt/passbolt-dep-scripts/releases/latest/download/passbolt-ce-SHA512SUM.txt

Verify the checksum and run the script only if it matches. This is the exact one-liner from the Passbolt documentation:

sha512sum -c passbolt-ce-SHA512SUM.txt && sudo bash ./passbolt-repo-setup.ce.sh || echo "Bad checksum. Aborting" && rm -f passbolt-repo-setup.ce.sh

A good run prints passbolt-repo-setup.ce.sh: OK first and ends with the Passbolt ASCII banner and “passbolt repository setup is finished”. Run it from an interactive SSH session: from a script or a non-interactive ssh host 'command' call, the final clear in the setup script fails and the one-liner prints “Bad checksum. Aborting” even though the checksum passed (see the errors section at the end). Confirm the source it wrote:

cat /etc/apt/sources.list.d/passbolt.sources

Expect a deb822 source with a signed-by keyring:

Types: deb
URIs: https://download.passbolt.com/ce/ubuntu
Suites: focal
Components: stable
Signed-By: /usr/share/keyrings/passbolt-repository.gpg

A focal suite looks wrong on a newer Ubuntu, but the script writes it on every release we tested. The Passbolt package is architecture-independent PHP, and its PHP, MySQL and nginx dependencies still come from your own Ubuntu archive.

Step 3: Choose how nginx gets its TLS certificate

Decide this before the install, because the package asks during installation and the manual option needs the certificate files to exist already. The installer offers three answers:

  • auto: the package runs certbot with the nginx plugin and gets a Let’s Encrypt certificate over HTTP-01. Pick this for any server with a public IP, a DNS record that already resolves and port 80 open.
  • manual: you point the installer at an existing fullchain PEM and private key. Pick this on a private network, behind NAT, or when you already issue certificates from an internal CA or with a DNS-01 client.
  • none: plain HTTP only. Skip it: switching an instance from HTTP to HTTPS later unlinks every user’s browser extension.

Our lab server sits on a private LAN with no inbound port 80, so we used the manual option with a certificate from a lab CA. The auto option was not run in our lab. It is the same certbot HTTP-01 flow described in the Let’s Encrypt certificate guide, triggered from the package. For the manual option, copy your files into place first. We used these paths:

sudo mkdir -p /etc/ssl/passbolt
sudo cp fullchain.pem /etc/ssl/passbolt/fullchain.pem
sudo install -m 600 privkey.pem /etc/ssl/passbolt/privkey.pem

One behaviour to plan for with manual certificates: the installer copies both files into /etc/ssl/certs/<timestamp>-fullchain.pem and /etc/ssl/private/<timestamp>-privkey.pem and points nginx at the copies. A renewed certificate at your original path is never picked up. Either re-run sudo dpkg-reconfigure passbolt-ce-server after each renewal (No to the database question, Yes to nginx, manual again with the renewed certificate and key paths, then sudo systemctl reload nginx), or edit the two ssl_certificate lines in /etc/passbolt/nginx-ssl.conf to point at the live files and reload nginx from your renewal hook.

An internal CA needs one more step. The server has to trust that CA itself and resolve its own hostname, because Passbolt and the curl check below connect back to https://passbolt.example.com. Without that, curl and the SSL checks in the healthcheck fail even though every browser that trusts the CA works fine. Our lab trusted its CA like this and mapped the name in /etc/hosts:

sudo cp lab-ca.crt /usr/local/share/ca-certificates/lab-ca.crt
sudo update-ca-certificates

With auto, a few things decide whether it works on the first try. We did not run this path in the lab, so this list comes from the package scripts and the Passbolt TLS guide rather than a capture:

  • Contact email: the certificate email prompt is pre-filled with [email protected]. Replace it with an address you read.
  • Failed certificate request: if certbot fails (DNS not propagated, port 80 blocked), the package is left half-configured. Fix the cause, then run sudo dpkg --configure -a. It asks every question again: answer No to the database question, since the database already exists (or reuse the exact same password), then pick auto again.
  • Renewal: keep port 80 open after the install, because renewals repeat the HTTP-01 check. sudo certbot renew --dry-run proves renewal works before the first real one is due.

Step 4: Install passbolt-ce-server and answer the prompts

Install the package. On Ubuntu 26.04 this pulled 76 more packages, including MySQL and PHP-FPM (nginx and certbot already came with the repository script in Step 2):

sudo apt install passbolt-ce-server

Before unpacking anything, debconf asks a series of questions. Two of them are Yes/No dialogs (create the database, configure nginx), and on both releases the cursor starts on <No>. Press the left arrow (or Tab) to select <Yes> before Enter. Pressing Enter straight away skips the database and nginx setup completely, which is what happened on our first run. The full sequence, in order:

  1. Create a passbolt database on the local mysql? Select Yes.
  2. MySQL administrator username: keep root.
  3. MySQL administrator password: leave it empty. Root on a fresh Ubuntu MySQL authenticates with auth_socket, and the installer runs as root, so no password is needed.
  4. Passbolt database user: keep passboltadmin, then enter and repeat a strong password for it. Write it down; the web installer asks for it again. Avoid quote characters in it, because the package pastes the password straight into a SQL statement.
  5. Passbolt database name: keep passboltdb.
  6. Do you want to configure the nginx server? Select Yes.
  7. Passbolt nginx setup: choose auto or manual from Step 3. This list starts on none, so move the highlight with the arrow keys before Enter, or you end up with an HTTP-only site.
  8. Passbolt domain name: your hostname, for example passbolt.example.com. With auto, the next prompt asks for the Let’s Encrypt contact email; with manual, the next two ask for the certificate and key paths.

Read the TLS question carefully, since it decides how users reach the server:

Passbolt package nginx TLS setup dialog with none, manual and auto options on Ubuntu 26.04

When the package finishes it prints “Well done! Visit https://passbolt.example.com to finish installation”. Check that nginx now answers on HTTPS and sends you to the installer:

curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" "https://${PASSBOLT_DOMAIN}/"

A 302 to /install means TLS and PHP-FPM are in place and Passbolt is waiting for its installer:

302 https://passbolt.example.com/install

If curl cannot connect at all and you reached this point through dpkg-reconfigure rather than a fresh install, nginx is not listening on 443 yet, and the troubleshooting section shows the one-line fix. The stock Ubuntu nginx default site is also still enabled, so anyone browsing to the server’s IP address gets the “Welcome to nginx!” page instead of Passbolt. Remove it:

sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx

Now that nginx is installed, you can swap the two port rules from Step 1 for the named Nginx Full UFW profile, which opens the same two ports:

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 80/tcp
sudo ufw delete allow 443/tcp

Afterwards sudo ufw status should list only OpenSSH and Nginx Full, each with its v6 twin.

Step 5: Run the Passbolt web installer

Open https://passbolt.example.com in the browser that will run the extension, click Get Started, and the installer starts with a system check. All three lines must be green before you continue. A red line here usually means the clock is not synced or the site is being reached over plain HTTP.

Passbolt web installer system check passing over HTTPS on Ubuntu 26.04

Click Start configuration. The database step wants the credentials you typed into the package dialogs: host localhost, port 3306, user passboltadmin, the password you chose and database passboltdb. Leave the connection type on mysql:// even though the server is MySQL rather than MariaDB.

Passbolt web installer database step with MySQL connection details

Next comes the server OpenPGP key, which Passbolt uses to sign its side of every login. Enter a server name and an email address, keep the default RSA 3072-bit key and click Next. The key was generated and saved in 3.5 seconds on our VM.

Passbolt web installer creating the server OpenPGP key

On the options page, your https:// URL should already be the full base URL with Force SSL set to Yes. Keep both. With Force SSL on, Passbolt itself redirects plain HTTP requests to HTTPS with a 302, so you do not need a separate nginx redirect block.

Passbolt web installer options with HTTPS full base URL and Force SSL

Next, the emails page asks for SMTP details. If you have a relay, enter it and use Send test email. If you do not, enter a sender name and address plus localhost, port 25, no TLS and no authentication, then click Next. The installer accepts the form even when the test fails, and only invitations and notifications need working mail. Step 8 fixes it from the admin panel. The next page creates the first administrator. Use a real address you control, because that is your login name.

Passbolt web installer creating the first administrator account

Click Skip on the subscription key page (that is for Passbolt Pro). The installation step took 27 seconds on our server, after which the browser lands on a setup URL for the admin account.

Step 6: Set up the admin account in the browser extension

Passbolt does all encryption in its browser extension, so the setup page stops until the extension is present. The Download extension button links to the store for your browser (Passbolt publishes the extension for Chrome, Firefox, Edge and Safari). Install it, then click Refresh to detect extension:

Passbolt setup page asking to install the browser extension

After the refresh, the extension takes over the page and asks for a passphrase. This passphrase unlocks the private key that decrypts every secret you will ever store, and the server cannot reset it, so use a long phrase you can type from memory. The quality bar should read “Very strong” before you continue.

Passbolt browser extension asking for a new passphrase

After that, the extension generates your key and starts downloading the recovery kit, a file holding your private key. Treat this step as the lockout warning it is: if you lose both the browser profile and the recovery kit, your encrypted passwords are gone, and no administrator command can bring them back. Store the kit in a second location (an offline USB key or a sealed backup) before ticking the box.

Passbolt recovery kit download step during account setup

The last step picks a color and a three-character security token. Passbolt shows that token every time it asks for your passphrase, so a fake prompt drawn by a phishing page will not have it.

Passbolt security token color and three character code setup

Click Next and you land in an empty password workspace, logged in as the administrator, with the extension holding your decrypted key for the session.

Step 7: Store and share a password in Passbolt

Folders keep shared credentials organised by team or system, and sharing a folder applies its permissions to everything inside it. We created an Infrastructure folder from Create > Folder, opened it, and used Create > Password to add a Grafana admin login with a generated password. Saving a new secret asks for your passphrase, and the prompt carries the security token from Step 6:

Passbolt passphrase prompt showing the security token

Once saved, the password shows up in the folder with the secret masked. Copying it, revealing it or using autofill each asks the extension to decrypt it locally.

Passbolt password resource saved in an Infrastructure folder

Sharing needs a second user who has finished their own extension setup, because Passbolt re-encrypts the secret with each recipient’s public key. With working mail (Step 8), add people from Users & Groups > Create > User and they get the setup link by email, which is how we added Amina ([email protected]). Without SMTP, register the user from the shell instead, which prints the same link for you to hand over:

sudo -u www-data /usr/share/php/passbolt/bin/cake passbolt register_user -u [email protected] -f Joseph -l Mwangi -r user

Hand over the one-time setup URL on the last line:

User saved successfully.
To start registration follow the link provided in your mailbox or here:
https://passbolt.example.com/setup/start/f23d8819-9eae-4945-9926-8bb3f313780c/f2e5571b-f97a-408a-a399-b052206011a2

The new user opens it in their own browser and goes through the same passphrase, recovery kit and security token screens as Step 6. Once they finish, select the password, click the share icon, type their name and pick a permission. The three levels are can read, can update and is owner, and read is the safe default for credentials people only need to use.

Passbolt share dialog granting a second user read access

After Save and one more passphrase prompt, the Grafana password appeared in Amina’s vault on the next page load, with no manual sync.

Shared Passbolt password visible in the second user vault

If a user moves to a new laptop and still has their recovery kit, an administrator can issue a recovery link from the server instead of deleting and re-inviting the account:

sudo -u www-data /usr/share/php/passbolt/bin/cake passbolt recover_user -u [email protected] -c

The command prints a one-time URL, and the extension on the new machine asks for the recovery kit and passphrase:

The recovery token has been created.
The user [email protected] can recover its account here:
https://passbolt.example.com/setup/recover/start/28187d81-6f53-49f3-9ff9-690de0c5cf64/874e1763-c43e-48df-82dc-37c797760682

That link restores access to an existing key. It cannot replace a lost one, which is why the recovery kit warning in Step 6 matters.

Step 8: Configure email for invitations (optional)

Skip this step if you are happy handing out setup links from register_user. Everything up to Step 7 works without mail, but invitations from the UI and share notifications need a working relay. Open the gear icon and go to Organisation Settings > Emails > Email Server. Pick your provider (AWS SES, Google Workspace, Office 365, Mailgun, SendGrid and others) or Other, then fill in the host, port, TLS setting and credentials:

Passbolt administration Email Server SMTP settings page

Click Save, then Send test email. In the lab we pointed Passbolt at a local Mailpit catcher on port 1025 instead of a real relay, and the test message arrived immediately. Invitations do not go out instantly, though: Passbolt queues them and a cron job installed by the package (/etc/cron.d/passbolt-ce-server) sends the queue once a minute. Our invitation left the queue 52 seconds after the user was created.

Once mail works, close the hole the healthcheck flags as “The SMTP Settings plugin endpoints are enabled”. Those endpoints let an administrator session read and change the SMTP credentials through the API, which you no longer need once mail is configured. Keep a copy of the Passbolt config file, then open it:

sudo cp -p /etc/passbolt/passbolt.php /etc/passbolt/passbolt.php.bak
sudo vim /etc/passbolt/passbolt.php

Add the security block after the existing ssl block inside the passbolt array. The installer writes the closing ] of the ssl block without a trailing comma, so add one there, and the section reads:

        'ssl' => [
            'force' => true,
        ],
        'security' => [
            'smtpSettings' => [
                'endpointsDisabled' => true,
            ],
        ],
    ],
];

The file is read-only (mode 0440, owned by www-data), so save with :wq! as root. PHP-FPM reads it on every request, which means a typo takes the site down the moment you save. Check the syntax straight away, and copy the .bak file back if it fails:

sudo php -l /etc/passbolt/passbolt.php

PHP should answer No syntax errors detected in /etc/passbolt/passbolt.php. From now on the Email Server page shows “SMTP settings endpoints disabled.” instead of the form, so remove the block again if you ever need to change the relay from the UI.

Step 9: Verify the server with the Passbolt healthcheck

About 70 checks run across PHP, GPG, TLS, the database and the application config, so the healthcheck catches most misconfigurations before a user does. Run it as the web server user:

sudo -u www-data /usr/share/php/passbolt/bin/cake passbolt healthcheck

Our server finished with 65 PASS, 3 WARN and no FAIL before the SMTP change, and with the SMTP warning gone afterwards. The summary we kept an eye on:

Passbolt CE healthcheck and version output on Ubuntu 26.04

The two warnings left are judgment calls rather than faults. “Host availability checking is disabled” means Passbolt does not verify the MX record of new users’ email domains. Turning on passbolt.email.validate.mx (an 'email' => ['validate' => ['mx' => true]] entry in the passbolt array) makes Passbolt look up the domain on every email validation and reject domains that have neither an MX nor an A record, so only enable it on a server with dependable outbound DNS. “Some email notifications are disabled by the administrator” reflects the default notification settings, which you can review under Emails > Email Notifications. Any FAIL line, on the other hand, needs fixing before you invite users.

Step 10: Back up the server keys and the database

A Passbolt restore needs three things: the database, the server OpenPGP key pair in /etc/passbolt/gpg, and /etc/passbolt/passbolt.php, which holds the key fingerprint and database credentials. A database dump without the server key cannot be restored into a working instance. Export the database with the built-in Passbolt command, which leaves out session and token data:

sudo -u www-data /usr/share/php/passbolt/bin/cake passbolt sql_export

Passbolt reports where the dump went. On our server it was a 170 KB file:

Saving backup file: /var/lib/passbolt/tmp/cache/database/backup_1792580538.sql
Excluding data of table(s): sessions, authentication_tokens.
Success: the database was saved on file!

Bundle the dump with the keys and config into one archive under /root:

sudo mkdir -p /root/passbolt-backup
sudo tar czf /root/passbolt-backup/passbolt-$(date +%F).tgz /etc/passbolt/gpg /etc/passbolt/passbolt.php /var/lib/passbolt/tmp/cache/database/backup_*.sql

Our archive came to 44 KB with two users. The SQL dump is written world-readable (mode 0644), so delete it once the archive exists and copy the archive off the server, ideally encrypted, because it contains the server’s private key:

sudo rm /var/lib/passbolt/tmp/cache/database/backup_*.sql

Users’ own private keys are never on the server, which is the point of the design: their recovery kits are their backup. Passbolt documents the full restore order in its official Ubuntu install and hosting docs, and the release notes are worth reading before each upgrade. The current release added passkeys as an MFA option. If you are still choosing between self-hosted managers, Vaultwarden on Ubuntu is the lighter Bitwarden-compatible alternative.

Errors we hit and how to fix them

Every message below came from the lab runs for this guide, on one of the two Ubuntu releases.

“Bad checksum. Aborting” right after “passbolt-repo-setup.ce.sh: OK”

The checksum was fine. We ran the one-liner through a non-interactive SSH command, the setup script finished, and then its final clear failed with 'unknown': I need something more specific. because there was no terminal. That non-zero exit triggers the || echo "Bad checksum. Aborting" branch. The repository is installed anyway. Confirm with apt-cache policy passbolt-ce-server, which showed a 5.17.0-1 candidate for us. Run the script from an interactive session to avoid the false alarm.

Pressing Enter skipped the database and nginx setup

Both Yes/No dialogs default to <No>, so Enter records passbolt/mysql-configuration: false and passbolt/nginx-configuration: false in debconf. The package then installs with no database and an HTTP-only site. Nothing is lost: run sudo dpkg-reconfigure passbolt-ce-server and answer the same questions again, selecting <Yes> with the arrow key.

HTTPS does not answer after dpkg-reconfigure

After the reconfigure, the new TLS include was on disk and nginx -t passed, but nothing listened on port 443 until nginx was reloaded. A fresh install did not need this. Reload it, as the Passbolt docs also suggest:

sudo systemctl reload nginx

Then repeat the curl check from Step 4. It should return the 302 to /install.

Email could not be sent: stream_socket_client(): Unable to connect to tcp://localhost:25 (Connection refused)

You get this from the web installer’s test email when no mail server listens on the host and port you entered. It does not block the installer, and the form keeps your values:

Passbolt SMTP test email error connection refused on localhost port 25

Point the settings at a real relay (port 587 with TLS for most providers) in Step 8. If the error names your relay rather than localhost, check that the server can reach it at all, since many cloud providers block outbound port 25.

“Please install the browser extension” with the extension installed

The setup page checks for the extension when it loads, so a page opened before the extension was installed keeps showing the download prompt. Click Refresh to detect extension or reload the tab. If it still does not appear, make sure the extension is enabled for the site and that you are on the https:// URL from the installer, not the server IP.

“SMTP settings endpoints disabled.” on the Email Server page

This appears after the endpointsDisabled change from Step 8 and means the hardening worked. To edit the relay again, remove the security block from /etc/passbolt/passbolt.php, make the change in the UI, and put the block back.

Keep reading

UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 Security UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Php PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Php PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Best Pentesting Hardware for Kali Linux in 2026 Security Best Pentesting Hardware for Kali Linux in 2026 APT CVE-2026-109518: Check and Patch Debian and Ubuntu Debian APT CVE-2026-109518: Check and Patch Debian and Ubuntu Change SSH Port on Rocky Linux 10 with SELinux AlmaLinux Change SSH Port on Rocky Linux 10 with SELinux

Leave a Comment

Press ESC to close