With the increase in online attacks and cybercrime, there is a serious need to securely generate, store, and manage passwords with utmost complexity for different online services and accounts. There are dozens of SaaS solutions that you can signup for and get started within seconds. For some users like myself, using self-hosted application is preferred and tools like Vaultwarden come into the picture.

Vaultwarden is a free to use and open source password management solution whose development was inspired by Bitwarden. Vaultwarden allows you to store, generate and manage your passwords in a secure manner. It has support for multi-factor authentication, end-to-end encryption of data, and multiple browser extensions as well as mobile apps for ease of use. Vaultwarden is committed to the open-source spirit of ensuring the software application is forever free to use. Vaultwarden is ideal for various use cases, and suitable for individuals, families, or smaller organizations.

How To Install Vaultwarden on Linux

The easiest way to using Vaultwarden is running it in a container. A container makes the application highly portable, meaning you can run Vaultwarden consistently across different environments. In this article we are using Docker Container Engine on a Linux machine. Windows and macOS users can use similar docker environment tools such as Portainer.

In this setup we’re using domain name passwords.techwizpro.com with A record 49.13.153.179.

Vaultwarden install 01

Start with the installation of Docker Engine.

I have Docker Engine version 25 on my Ubuntu system.

$ docker --version
Docker version 25.0.3, build 4debf41

Compose plugin is version 2.x

$ docker compose version
Docker Compose version v2.24.5

Create a directory where Vaultwarden data will be stored.

mkdir ~/vaultwarden && cd ~/vaultwarden 

Create new compose file.

vim docker-compose.yml

Modify DOMAIN value to your FQDN.

version: '3'
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      DOMAIN: "https://passwords.techwizpro.com" 
    volumes:
      - ./vw_data:/data

To start the container run the commands below.

$ docker compose up -d
[+] Running 7/7
 ✔ vaultwarden 6 layers [⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                          6.9s
   ✔ c57ee5000d61 Pull complete                                                                                                                                                                  0.7s
   ✔ a15201bfb52f Pull complete                                                                                                                                                                  0.6s
   ✔ b58597132f48 Pull complete                                                                                                                                                                  0.4s
   ✔ b3ef181c63dc Pull complete                                                                                                                                                                  0.8s
   ✔ d9668859131d Pull complete                                                                                                                                                                  1.2s
   ✔ a5e23e066860 Pull complete                                                                                                                                                                  1.3s
[+] Running 1/2
 ⠦ Network vaultwarden_default  Created                                                                                                                                                          0.6s
 ✔ Container vaultwarden        Started                                                                                                                                                          0.5s

The service will be available on host port 8080. We shall use Nginx to proxy request on domain to this port.

$ docker compose ps
NAME          IMAGE                       COMMAND       SERVICE       CREATED         STATUS                            PORTS
vaultwarden   vaultwarden/server:latest   "/start.sh"   vaultwarden   6 seconds ago   Up 5 seconds (health: starting)   3012/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp

You can now access Vaultwarden on your server IP and port 8080. But I recommend you use Nginx or any other web server to proxy.

Vaultwarden install 02

Configure Nginx Reverse Proxy

We can now configure Nginx as a reverse proxy server for Vaultwarden. Nginx can be run in a container, package installed on the OS, or using Nginx Proxy Manager solution. See guides below.

Examples on installation on Debian and RHEL based Linux systems.

### Debian / Ubuntu ###
sudo apt update && sudo apt install nginx
sudo systemctl enable --now nginx

### RHEL 8/9 or Fedora ###
sudo dnf -y install nginx
sudo systemctl enable --now nginx

Create Nginx Virtual Host file for Vaultwarden.

sudo vim /etc/nginx/conf.d/vaultwarden.conf

Edit the configuration file and adjust params to suit your use.

# The `upstream` directives ensure that you have a http/1.1 connection
# This enables the keepalive option and better performance
#
# Define the server IP and ports here.
upstream vaultwarden-default {
  zone vaultwarden-default 64k;
  server 127.0.0.1:8080;
  keepalive 2;
}

# Needed to support websocket connections
# See: https://nginx.org/en/docs/http/websocket.html
# Instead of "close" as stated in the above link we send an empty value.
# Else all keepalive connections will not work.
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      "";
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name passwords.techwizpro.com;

    client_max_body_size 525M;

    location / {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_pass http://vaultwarden-default;
    }

    # Optionally add extra authentication besides the ADMIN_TOKEN
    # Remove the comments below `#` and create the htpasswd_file to have it active
    #
    #location /admin {
    #  # See: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/
    #  auth_basic "Private";
    #  auth_basic_user_file /path/to/htpasswd_file;
    #
    #  proxy_http_version 1.1;
    #  proxy_set_header Upgrade $http_upgrade;
    #  proxy_set_header Connection $connection_upgrade;
    #
    #  proxy_set_header Host $host;
    #  proxy_set_header X-Real-IP $remote_addr;
    #  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #  proxy_set_header X-Forwarded-Proto $scheme;
    #
    #  proxy_pass http://vaultwarden-default;
    #}
}

Confirm you have no nginx syntax errors:

$ sudo nginx  -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

1 – Using Let’s Encrypt SSL

Install certbot tool used to generate Let’s Encrypt SSL certificates.

# Ubuntu / Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx

# Fedora
sudo dnf install certbot python3-certbot-nginx

# CentOS  / RHEL / Alma / Rocky 8
sudo dnf -y install epel-release
sudo yum -y install certbot python3-certbot-nginx

# CentOS 7
sudo yum -y install epel-release
sudo yum -y install certbot python2-certbot-nginx

Generate Let’s Encrypt for the domain.

DOMAIN="passwords.techwizpro.com"
export ALERTS_EMAIL="[email protected]"
sudo certbot --nginx --redirect -d $DOMAIN --preferred-challenges http --agree-tos -n -m $ALERTS_EMAIL --keep-until-expiring

Let’s Encrypt SSL generation process.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Account registered.
Requesting a certificate for passwords.techwizpro.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/passwords.techwizpro.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/passwords.techwizpro.com/privkey.pem
This certificate expires on 2024-05-15.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for passwords.techwizpro.com to /etc/nginx/conf.d/vaultwarden.conf
Congratulations! You have successfully enabled HTTPS on https://passwords.techwizpro.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Since we specified --nginx option certbot will modify vaultwarden.conf file and inject SSL settings.

cat /etc/nginx/conf.d/vaultwarden.conf

2 – Using custom or Self-signed certificates

See our article on how to Generate OpenSSL Self-Signed Certificates with Ansible

If using Custom SSL or Self-signed certificates, you can update the file manually as shown below.

# The `upstream` directives ensure that you have a http/1.1 connection
# This enables the keepalive option and better performance
#
# Define the server IP and ports here.
upstream vaultwarden-default {
  zone vaultwarden-default 64k;
  server 127.0.0.1:8080;
  keepalive 2;
}

# Needed to support websocket connections
# See: https://nginx.org/en/docs/http/websocket.html
# Instead of "close" as stated in the above link we send an empty value.
# Else all keepalive connections will not work.
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      "";
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name passwords.techwizpro.com;

    if ($host = passwords.techwizpro.com) {
        return 301 https://$host$request_uri;
    }
    return 404;
}

server {
    # For older versions of nginx appened http2 to the listen line after ssl and remove `http2 on`
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name passwords.techwizpro.com;

    # Specify SSL Config when needed - adjust for custom paths
    ssl_certificate /path/to/certificate/letsencrypt/live/passwords.techwizpro.com/fullchain.pem;
    ssl_certificate_key /path/to/certificate/letsencrypt/live/passwords.techwizpro.com/privkey.pem;
    ssl_trusted_certificate /path/to/certificate/letsencrypt/live/passwords.techwizpro.com/fullchain.pem;

    client_max_body_size 525M;

    location / {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_pass http://vaultwarden-default;
    }

    # Optionally add extra authentication besides the ADMIN_TOKEN
    # Remove the comments below `#` and create the htpasswd_file to have it active
    #
    #location /admin {
    #  # See: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/
    #  auth_basic "Private";
    #  auth_basic_user_file /path/to/htpasswd_file;
    #
    #  proxy_http_version 1.1;
    #  proxy_set_header Upgrade $http_upgrade;
    #  proxy_set_header Connection $connection_upgrade;
    #
    #  proxy_set_header Host $host;
    #  proxy_set_header X-Real-IP $remote_addr;
    #  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #  proxy_set_header X-Forwarded-Proto $scheme;
    #
    #  proxy_pass http://vaultwarden-default;
    #}
}

Restart Nginx web server for the changes to be loaded into memory.

sudo systemctl restart nginx

Access Vaultwarden over https

The final step is accessing Vaultwarden using https and configured domain name.

Install Vaultwarden 03

Create first account by inputing all the required information.

Install Vaultwarden 04

Once the account is created provide email address to login to Vaultwarden backend.

Install Vaultwarden 05

Provide the master password as configured earlier.

Install Vaultwarden 06

Here is the screenshot of Vaultwarden dashboard. Here you can create an organization and store login information to your website and other online services.

Install Vaultwarden 07

This is an example on how to create login item.

Install Vaultwarden 08
Install Vaultwarden 09

Configure Bitwarden clients

 Vaultwarden is compatible with the official Bitwarden clients. Download and configure then appropriately.

References:

LEAVE A REPLY

Please enter your comment!
Please enter your name here