Skip to content

Instantly share code, notes, and snippets.

@Discoded
Last active March 5, 2024 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Discoded/b2388b5aebd08774036ad4b4d63830cc to your computer and use it in GitHub Desktop.
Save Discoded/b2388b5aebd08774036ad4b4d63830cc to your computer and use it in GitHub Desktop.
Vaultwarden and Swag in Unraid Installation Guide

Table of Contents

  1. Overview
  2. Guide
    1. DuckDNS
    2. Unraid
    3. SWAG
    4. Vaultwarden
    5. fail2ban
  3. Sources

Overview

The purpose of this guide is to show you how to install Vaultwarden and allow you to access it safely over the internet through Swag in Unraid.

Vaultwarden is a self-hosted password manager based on Bitwarden.

SWAG - formerly known as letsencrypt is an Nginx webserver and reverse proxy that offers a safe way to host Vaultwarden through the internet. It offers this safety through:

  • fail2ban - an instrusion prevention software that prevents brute-force attacks
  • SSL certs - Encrypted data transmission.
  • Reverse Proxy (From Spaceinvader One video):
    • Allows online access
    • Redirects requests made to it to other places behind a firewall
    • Additional layer of abstraction and therefore additional security.

DuckDNS - Free dynamic DNS. Support the project through their Patreon

This guide is mostly taken from Spaceinvader One's videos but with updated information.

How to Setup and Configure a Reverse Proxy on unRAID with LetsEncrypt & NGINX

Easily Setup a Bitwarden/vaultwarden Server on Unraid or a VPS for Password Management

Guide

DuckDNS

DuckDNS allows us to track our WAN IP. This IP changes often depending on your ISP so this is whyDuckDNS is needed. With DuckDNS, you can easily access your server at myUnraidServer.duckdns.org

  1. Go to https://www.duckdns.org/
  2. Create an account and add 2 domains.
    1. The first domain points directly to your Unraid server. Example: myUnraidServer.duckdns.org
    2. The second domain points to your Vaultwarden container. Example: myUnraidServerVaultwarden.duckdns.org
  3. Make sure you write this down somewhere, or can remember it
  4. Go to APPS/Unraid Community Applications and install Linuxserver.io's duckdns container
Container Variables Value Details
Repository linuxserver/duckdns
Network Type Host
Privileged On
SUBDOMAINS myUnraidServer.duckdns.org, myUnraidServerVaultwarden.duckdns.org These are the custom domain names you made in DuckDNS
TOKEN yourDuckDNS_Token Your token from https://www.duckdns.org/

Unraid

Port Forward

  1. On your Router port forward your server ports:
External Port Internal IP Internal Port
80 myUnraidServerLanIpAddress 180
443 myUnraidServerLanIpAddress 1443

The Internal Port numbers do not matter, just make sure they're not used by other services on your server and take note of them.

Create a UserDefinedBridge

In Unraid, create a UserDefined Bridge. There are many reasons to do this but here are some from docs.docker

  • User-defined bridges provide automatic DNS resolution between containers
  • User-defined bridges provide better isolation
  • Containers can be attached and detached from user-defined networks on the fly
  • Each user-defined network creates a configurable bridge
  • Linked containers on the default bridge network share environment variables
  1. Disable Docker by going to Unraid Settings>Docker>Enable Docker set to No then apply
  2. Under Docker settings and with Advanced View enabled, set Preserve user defined networks to Yes
  3. Reenable Docker Unraid Settings>Docker>Enable Docker set to Yes then apply
  4. Open an Unraid Terminal then run: docker network create myNetName

SWAG

We are now ready to install the SWAG container.

  1. Go to APPS also known as Unraid's Community Applications and install linuxserver's swag:

Overview:

SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx webserver and reverse proxy with php support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.

Container Variables Value Details
Repository lscr.io/linuxserver/swag
Network Type myNetName This is the custom network or UserDefinedBridge
WebUI 1443 This is the custom internal port that was forwarded
Port 80 180 This is the custom internal port that was forwarded
URL duckdns.org
VALIDATION http
SUBDOMAINS myUnraidServer, myUnraidServerVaultwarden These are the custom domain names you made in DuckDNS
DNSPLUGIN duckdns
EMAIL yourEmail@whatever.com
STAGING false
DUCKDNSTOKEN yourDuckDNS_Token Your token from https://www.duckdns.org/
Log Storage Path /mnt/user/appdata/logs/ See Log Storage Path
Appdata /mnt/user/appdata/swag

Log Storage Path

This is used for fail2ban.

Under SWAG's docker settings, Add another Path, Port, Variable, Label or Device

Setting Value
Config Type Path
Name Log Storage Path
Container Path /logs
Host Path /mnt/user/appdata/logs/
Default Value
Access Mode Read Only

Create a folder wherever you would like. In my case I used /mnt/user/appdata/logs

vaultwarden.subdomain.conf

Under /appdata/swag/nginx/proxy-confs/ or where Appdata variable is set for swag: swag/nginx/proxy-confs/

Create a new file named vaultwarden.subdomain.conf. There should be samples for different services under swag/nginx/proxy-confs/

Refer to the vaultwarden.subdomain.conffile attached to this guide.

Vaultwarden

Install the vaultwarden container.

  1. Go to APPS/Unraid's Community Applications and install vaultwarden:
Container Variables Value Details
Repository vaultwarden/server
Network Type myNetName This is the custom network or UserDefinedBridge
WebUI HTTP Port 4743
SIGNUPS_ALLOWED false
INVITATIONS_ALLOWED false
WEBSOCKET_ENABLED true
ADMIN_TOKEN yourTemporaryPassword See ADMIN_TOKEN
LOG_FILE /logs/vaultwarden.log
Log Storage /mnt/user/appdata/logs/
Storage /mnt/user/appdata/vaultwarden

ADMIN_TOKEN

Before initial setup

On your Unraid terminal, run: openssl rand -base64 48

Use the output as your ADMIN_TOKEN

After initial setup

Secure the ADMIN_TOKEN

Important: The ADMIN_TOKEN should be hashed after the initial setup.

While the vaultwarden container is running, on your Unraid terminal: docker exec -it vaultwarden /vaultwarden hash

Vaultwarden setup

  1. Click on the Vaultwarden container and press the WebUI button. This should take you to the admin page myUnraidServerLanIpAddress:4743/admin.
  2. Change the Domain URL to https://myUnraidServerVaultwarden.duckdns.org. This should be the DuckDNS domain you set up in [[#DuckDNS]].
  3. Secure the [[#ADMIN_TOKEN]].
  4. Optional: Follow Spaceinvader One's video to enable SMTP Email
  5. Under General settings, temporarily enable Allow new signups
  6. Save/Apply the settings by pressing the Save button on the bottom left of the UI.
  7. Restart the Vaultwarden container.
  8. Go to https://myUnraidServerVaultwarden.duckdns.org and create an account.
  9. Go back to the Vaultwarden admin panel, General settings > disable Allow new signups
  10. IMPORTANT Edit vaultwarden.subdomain.conf at /appdata/swag/nginx/proxy-confs/ to disable the admin panel from WAN access but allow local/LAN access or just disable the admin panel altogether.

fail2ban

Swag also includes fail2ban.

We can setup fail2ban to read Vaultwarden's logs and ban an IP address if attempted logins exceed a certain amount.

  1. On /appdata/swag/fail2ban/jail.local

Add a new jail:

[vaultwarden]
enabled = true
port = http,https
filter = vaultwarden
action = iptables-allports[name=vaultwarden]
logpath = /logs/vaultwarden.log
maxretry = 5
bantime = 14400
findtime = 14400
  1. On /appdata/swag/fail2ban/filter.d/ Create a new file: vaultwarden.conf
# https://github.com/dani-garcia/bitwarden_rs/wiki/Fail2Ban-Setup
#   - Set up logging to file > https://github.com/dani-garcia/bitwarden_rs/wiki/Logging
#   - Set logging level to warn or error
# Logged in bwdata/logs/identity/Identity/log.txt

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =
  1. Verify fail2ban works by using a VPN and fail login past the maxretry value(default is 5)
    • Logs are located at /appdata/swag/log/ and /appdata/logs
    • You can unban an IP using the following command on your Unraid terminal:
    • sudo docker exec -t fail2ban fail2ban-client set vaultwarden unbanip XX.XX.XX.XX

Sources

## Version 2022/08/20 - Changelog: https://github.com/linuxserver/docker-swag/commits/master/root/defaults/fail2ban/jail.local
# This is the custom version of the jail.conf for fail2ban
# Feel free to modify this and add additional filters
# Then you can drop the new filter conf files into the fail2ban-filters
# folder and restart the container
[DEFAULT]
# Prevents banning LAN subnets
ignoreip = 10.0.0.0/8
192.168.0.0/16
172.16.0.0/12
# Changes the default ban action from "iptables-multiport", which causes issues on some platforms, to "iptables-allports".
banaction = iptables-allports
# "bantime" is the number of seconds that a host is banned.
bantime = 600
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 600
# "maxretry" is the number of failures before a host get banned.
maxretry = 5
[ssh]
enabled = false
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /config/log/nginx/error.log
[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /config/log/nginx/access.log
maxretry = 2
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /config/log/nginx/access.log
[nginx-deny]
enabled = true
port = http,https
filter = nginx-deny
logpath = /config/log/nginx/error.log
[nginx-unauthorized]
enabled = true
port = http,https
filter = nginx-unauthorized
logpath = /config/log/nginx/access.log
[vaultwarden]
enabled = true
port = http,https
filter = vaultwarden
action = iptables-allports[name=vaultwarden]
logpath = /logs/vaultwarden.log
maxretry = 5
bantime = 14400
findtime = 14400
# https://github.com/dani-garcia/bitwarden_rs/wiki/Fail2Ban-Setup
#   - Set up logging to file > https://github.com/dani-garcia/bitwarden_rs/wiki/Logging
#   - Set logging level to warn or error
# Logged in bwdata/logs/identity/Identity/log.txt
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =
## Version 2023/05/31
# make sure that your vaultwarden container is named vaultwarden
# make sure that your dns has a cname set for vaultwarden
# set the environment variable WEBSOCKET_ENABLED=true on your vaultwarden container
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name myUnraidServerVaultwarden.*;
    include /config/nginx/ssl.conf;
    client_max_body_size 128M;
    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;
    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;
    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;
    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;
        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;
        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;
        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
    location ~ ^(/vaultwarden)?/admin {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;
        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;
        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;
        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
# enable to disable the admin panel once you have done the initial setup
        #allow 192.168.X.X/24;
        #deny all;
    }
    location ~ (/vaultwarden)?/api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
    location ~ (/vaultwarden)?/notifications/hub {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 3012;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
    location ~ (/vaultwarden)?/notifications/hub/negotiate {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vaultwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment