This space is dedicated to Vaultwarden, which is a lightweight open source password manager enabling powerful and secure workflows. It is an unofficial alternative implementation of the Bitwarden server, which runs well even on Raspberry Pi 4.
This guide walks you step by step until you get Vaultwarden published as a service on the Edge that can be accessed on the Internet.
Make sure that all of the mandatory prerequisites have been met before progressing further.
Name | Source | Description |
---|---|---|
<CONTAINER_NAME> | User input | The name of the Linux container where the app runs. |
<DB_PASSWORD> | User input | The password for logging in with the vaultwarden PostgreSQL user. |
<IP_ADDRESS__CONTAINER> | Generated | The IPv4 address of the contaier run by the server on the Edge. |
<IP_ADDRESS_INET_GW> | Linux VPS Admin Panel | |
<VAULTWARDEN_DOMAIN> | User input | The host for the A record created with your domain registrar, e.g. vault.myowndomain.net . |
GENERATED_ADMIN_TOKEN | Generated | The value for the ADMIN_TOKEN vaultwarden configuration property generated by running vaultwarden hash . |
If you need to collaborate with more users throught different organisations in Vaultwarden, you will need to set up email notifications and consequently a SMTP server. Manually creating Vaultwarden users and assigning them in organisations is not supported for security reasons. You can use your own SMTP server or use gmail.com as a very last resort.
Run the following commands on your server on the Edge.
incus launch images:debian/bookworm/cloud <CONTAINER_NAME>
incus exec <CONTAINER_NAME> bash
You may need to change the default MTU for HTTPS connections to function. Run
ip link set dev eth0 mtu 1000
if you findapt update
orapt upgrade
stuck for long time. This setting is non persistent and it is lost when the container reboots.
apt update && apt upgrade && apt install fish
chsh -s /usr/bin/fish
From here on the root user will use fish
as default shell.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
passwd
Set a password for the root user and make a (mental) note of it. It will be denoted with a variable <ROOT_PWD__CONTAINER>.
The ability to establish SSH connections from the server on the Edge to the container is key for the upcoming Ansible automation. There is an Ansible connection driver for Linux containers with limited capabilities. The default Ansible connection driver through SSH is much more robust and powerful.
You can perform this step now or in future, when you make up your mind to give the automated solutions for system and application maintanence a try.
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
apt update && apt install openssh-server
vi /etc/ssh/sshd_config
Add the following line to the file.
PermitRootLogin yes
systemctl enable ssh
systemctl start ssh
systemctl restart ssh
Run the following commands on your server on the Edge, i.e. outside of the container.
Run ssh-keygen
only if you haven't generated SSH private and public keys on the server on the Edge. Otherwise use the already existing pair.
ssh-keygen
incus ls | grep <CONTAINER_NAME>
Make a note of the IPV4 value <IP_ADDRESS__CONTAINER>.
ssh-copy-id root@<IP_ADDRESS__CONTAINER>
Pass the password for the root
user in the container as prompted.
From here on SSH connection as the
root
user will be possible from the server on the Edge to the container. Containers are not visible and accessible to any other network devices.
Run the following commands on your server on the Edge.
incus exec <CONTAINER_NAME> fish
Let's harden the setup of the ssh server running in the container by disabling the password for logging in with root
.
vi /etc/ssh/sshd_config
Delete the line PermitRootLogin yes
.
Append the line PermitRootLogin prohibit-password
.
systemctl restart ssh
You should have a fully functional Linux container named
<CONTAINER_NAME>
that has also a non-administrative useroffen
. In addition, the server on the Edge listens for SSH connections with theroot
user. You know all login credentials.
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
apt update && apt install wget
wget -qO- https://vaultwarden-deb.pages.dev/dists/bookworm/install.sh | sudo bash
apt update && apt install vaultwardwen
systemctl status vaultwarden
shall report back that the
vaultwarden
systemd service has been started and running.
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
apt update && apt install lsb-release curl gpg
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc|sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
apt update && apt install postgresql-16
In order to enable data checksums we need to delete the existing cluster and initialize it again.
systemctl stop postgresql@16-main.service
rm -rf /var/lib/postgresql/16/main
mkdir /var/lib/postgresql/16/main
chown -R postgres:postgres /var/lib/postgresql/16/main
chmod 700 /var/lib/postgresql/16/main
sudo -u postgres /usr/lib/postgresql/16/bin/initdb \
-D /var/lib/postgresql/16/main/ \
--locale=C.UTF-8 --encoding=UTF8 --data-checksums
systemctl start postgresql@16-main.service
Verify that the stage has been completed successfully by running the following command in the container. Its output should indicate that the service is running.
systemctl status postgresql@16-main.service
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
Take a not of the password for the database user. It will be denoted with a variable <DB_PASSWORD>.
sudo -u postgres createuser -P vaultwarden
Take a note of the password <DB_PASSWORD>.
sudo -u postgres createdb -O vaultwarden vaultwarden
Verify that the configuration works well.
sudo -u vaultwarden psql --host=/run/postgresql/ --dbname=vaultwarden --username=vaultwarden --password
mkdir -p /opt/vaultwarden/tls/
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /opt/vaultwarden/tls/vaultwarden.key \
-out /opt/vaultwarden/tls/vaultwarden.crt
openssl x509 \
-in /opt/vaultwarden/tls/vaultwarden.crt \
-out /opt/vaultwarden/tls/cert.pem
openssl rsa -in /opt/vaultwarden/tls/vaultwarden.key \
-text > /opt/vaultwarden/tls/key.pem
chown vaultwarden:vaultwarden -R /opt/vaultwarden
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
Generate a value for the ADMIN_TOKEN variable below. Pass and confirm any password string to vaultwarden hash
when prompted. Store the value, so it could be used later in /etc/vaultwarden.env
. From now on we will refer to the string generated by this tool as <GENERATED_ADMIN_TOKEN>.
vaultwarden hash
vi /etc/vaultwarden.env
Make sure the configuration file has been amended to reflect your needs and landscape.
Do not forget to substitute all occurrences of <VAULTWARDEN_DOMAIN> and <DB_PASSWORD> with the real values.
DATABASE_URL=postgresql://vaultwarden:<DB_PASSWORD>@localhost:5432/vaultwarden
DATABASE_MAX_CONNS=10
ADMIN_TOKEN=<GENERATED_ADMIN_TOKEN>
SIGNUPS_ALLOWED=true
INVITATIONS_ALLOWED=true
SENDS_ALLOWED=true
DOMAIN=https://<VAULTWARDEN_DOMAIN>
ROCKET_ADDRESS=0.0.0.0
ROCKET_PORT=8000
ROCKET_TLS={certs="/opt/vaultwarden/tls/cert.pem",key="/opt/vaultwarden/tls/key.pem"}
WEB_VAULT_ENABLED=true
EXTENDED_LOGGING=true
USE_SYSLOG=true
systemctl enable vaultwarden.service
systemctl restart vaultwarden.service
You should be able to run a successful HTTP request against the Vaultwarden server from within the container.
curl -k https://localhost:8000
In a terminal on on the server on the Edge run the following command to forward incoming HTTP connections on port 8000
of the server to port 8000
on the container.
Do not forget to substitute the value of the CONTAINER_NAME variable with its real value.
incus config device add <CONTAINER_NAME> https-vaultwarden-8000 proxy listen=tcp:0.0.0.0:8000 connect=tcp:127.0.0.1:8000
From here on the Vaultwarden server should be accessible from the Server on the Edge and any other device in the same network.
curl -k https://localhost:8000
Make sure that you have created an A domain record for <VAULTWARDEN_DOMAIN> with your domain registrar and you have waited for this record to become active.
If you use a domain name and that's not picked up by the domain name servers yet, Caddy will not be able to serve HTTPS requests because of Let's Encrypt (An SSL certificate authority) failing to verify the validity (ownership over) of the domain.
ssh mycelium@<IP_ADDRESS_INET_GW>
sudo su -
Add the following to /etc/caddy/Caddyfile
.
<VAULTWARDEN_DOMAIN> {
reverse_proxy <IP_ADDRESS_INET_GW>:8000 {
transport http {
tls_insecure_skip_verify
}
}
}
systemctl reload caddy
If everything is configured well, you should be able to access Vaultwarden through its domain name by using a web browser by typing
https://<VAULTWARDEN_DOMAIN>
in the address bar.
The workfows implemented by Vaultwarden rely a lot on proper email integration. In order to be able to benefit at most from self hosting Vaultwarden on The Edge one could
[Optionally] Spin up your own email service on The Edge. In this way you will be more independent owning your email. Thus, you could use your SMTP server/host for implementing secure workflows.
Provide valid values in /etc/vaultwarden.env
to use a SMTP server and restart the vaultwarden
service.
SMTP_HOST=<SMTP_HOST>
SMTP_FROM=vaultwarden@<EMAIL_DOMAIN>
SMTP_FROM_NAME=Vaultmaster
SMTP_USERNAME=<SMTP_USER_USERNAME>
SMTP_PASSWORD=<SMTP_USER_PASSWORD>
SMTP_TIMEOUT=15
SMTP_SECURITY=force_tls # Depends on the SMTP server
/etc/vaultwarden.env
and restart the vaultwarden
systemd service to prevent random user registration requests.