Vaultwarden and HTTPS tutorial

Hi there,

I was wondering: Is there a simple to follow tutorial how make vaultwarden run with HTTPS with the goal to reach it from the internet (I e. without VPN) as well as lan (via von)?

I have set ddns up as well as vaultwarden.

Only issue is: only HTTP works, not HTTPS

I have successfully created the certificates with letsencrypt.

This is where I am stuck. How to go from here?
I understand there are 2 routes: setting up a reverse proxy or make sure vaultwarden can read the created certificates.
Both I an not skilled enough to do that myself and destroy my existing nextcloud, pihole, wireguard setup.

Hoping for some tips. Thank you

T

Just have a look to our forum. There are a couple of post describing reverse proxy solution. One example could be following. Of course this is just one example and you could use other web server to setup to configure reverse proxy. Confused Reverse proxy and vaultwarden - #21 by Joulinar

Thanks for the quick reply.

I am aware of this post and have read it at least 3 times.

This is for 2 RPI with having HTTPS disabled.

Also, this example is for lighttpd about which you say in another post is not the best option for a reverse proxy.

this is where I stopped reading into the details of this post.

What if I have only one rpi with lighttpd running?

Still worth installing nginx for the reverse proxy way or is there an easier way to make HTTPS work for vaultwarden?

Thanks again.

I followed the settings

But eventually end up with when accessing /vault/

404: Not Found
The requested resource could not be found.

Rocket

Nextcloud can be accessed with HTTPS though

I have mod proxy of lighttpd enabled and restated the Webserver.

Of course you can also apply the HTTPS certificate and key to vaultwarden directly and skip the reverse proxy.

But if you have a webserver already, it is simpler to use it as reverse proxy. You do not need two RPis, but vaultwarden and the proxy can run on a single machine. Lighttpd is not the simplest webserver to setup as reverse proxy and often needs more directives depending on the backend software, but obviously for vaultwarden we found a working solution.

Yes, you could easily have everything running on a single SBC. No need to install 2. And if you are already running lighttpd, you could use it as revers proxy.

Could you share the configuration files you created pls?

I thought about skipping the reverse proxy but I could make the keys and cert to work by editing the vaultwarden config and specifying the link to the keys/certs created with letsencrypt earlier.
But just adding the paths to the letsencrypt/live folder using the rocket TLS variable might just not be enough and this is where my skills and Google left me.

I was also reluctant to copy keys around in case they need to get renewed.

So, reverse proxy… vaultwarden and lighttpd configs as follows (as per Joulinars post in another thread)

vaultwarden.env

root@DietPi:~# cat /mnt/dietpi_userdata/vaultwarden/vaultwarden.env
## Vaultwarden Configuration File
## Uncomment any of the following lines to change the defaults
##
## Be aware that most of these settings will be overridden if they were changed
## in the admin interface. Those overrides are stored within DATA_FOLDER/config.json .
##
## By default, vaultwarden expects for this file to be named ".env" and located
## in the current working directory. If this is not the case, the environment
## variable ENV_FILE can be set to the location of this file prior to starting
## vaultwarden.

## Main data folder
DATA_FOLDER=/mnt/dietpi_userdata/vaultwarden

## Database URL
## When using SQLite, this is the path to the DB file, default to %DATA_FOLDER%/db.sqlite3
# DATABASE_URL=data/db.sqlite3
## When using MySQL, specify an appropriate connection URI.
## Details: https://docs.diesel.rs/diesel/mysql/struct.MysqlConnection.html
# DATABASE_URL=mysql://user:password@host[:port]/database_name
## When using PostgreSQL, specify an appropriate connection URI (recommended)
## or keyword/value connection string.
## Details:
## - https://docs.diesel.rs/diesel/pg/struct.PgConnection.html
## - https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
# DATABASE_URL=postgresql://user:password@host[:port]/database_name

## Database max connections
## Define the size of the connection pool used for connecting to the database.
# DATABASE_MAX_CONNS=10

## Database connection initialization
## Allows SQL statements to be run whenever a new database connection is created.
## This is mainly useful for connection-scoped pragmas.
## If empty, a database-specific default is used:
## - SQLite: "PRAGMA busy_timeout = 5000; PRAGMA synchronous = NORMAL;"
## - MySQL: ""
## - PostgreSQL: ""
# DATABASE_CONN_INIT=""

## Individual folders, these override %DATA_FOLDER%
# RSA_KEY_FILENAME=data/rsa_key
# ICON_CACHE_FOLDER=data/icon_cache
# ATTACHMENTS_FOLDER=data/attachments
# SENDS_FOLDER=data/sends
# TMP_FOLDER=data/tmp

## Templates data folder, by default uses embedded templates## Check source code to see the format
# TEMPLATES_FOLDER=/path/to/templates
## Automatically reload the templates for every request, slow, use only for development
# RELOAD_TEMPLATES=false

## Client IP Header, used to identify the IP of the client, defaults to "X-Real-IP"
## Set to the string "none" (without quotes), to disable any headers and just use the remote IP
IP_HEADER=X-Forwarded-For

## Cache time-to-live for successfully obtained icons, in seconds (0 is "forever")
# ICON_CACHE_TTL=2592000
## Cache time-to-live for icons which weren't available, in seconds (0 is "forever")
# ICON_CACHE_NEGTTL=259200

## Web vault settings
# WEB_VAULT_FOLDER=web-vault/
WEB_VAULT_ENABLED=true

## Enables websocket notifications
WEBSOCKET_ENABLED=true

## Controls the WebSocket server address and port
WEBSOCKET_ADDRESS=0.0.0.0
WEBSOCKET_PORT=3012

## Controls whether users are allowed to create Bitwarden Sends.
## This setting applies globally to all users.
## To control this on a per-org basis instead, use the "Disable Send" org policy.
# SENDS_ALLOWED=true

## Controls whether users can enable emergency access to their accounts.
## This setting applies globally to all users.
# EMERGENCY_ACCESS_ALLOWED=true

## Job scheduler settings
##
## Job schedules use a cron-like syntax (as parsed by https://crates.io/crates/cron),
## and are always in terms of UTC time (regardless of your local time zone settings).
##
## How often (in ms) the job scheduler thread checks for jobs that need running.
## Set to 0 to globally disable scheduled jobs.
# JOB_POLL_INTERVAL_MS=30000
##
## Cron schedule of the job that checks for Sends past their deletion date.
## Defaults to hourly (5 minutes after the hour). Set blank to disable this job.
# SEND_PURGE_SCHEDULE="0 5 * * * *"
##
## Cron schedule of the job that checks for trashed items to delete permanently.
## Defaults to daily (5 minutes after midnight). Set blank to disable this job.
# TRASH_PURGE_SCHEDULE="0 5 0 * * *"
##
## Cron schedule of the job that checks for incomplete 2FA logins.
## Defaults to once every minute. Set blank to disable this job.
# INCOMPLETE_2FA_SCHEDULE="30 * * * * *"
##
## Cron schedule of the job that sends expiration reminders to emergency access grantors.
## Defaults to hourly (5 minutes after the hour). Set blank to disable this job.
# EMERGENCY_NOTIFICATION_REMINDER_SCHEDULE="0 5 * * * *"
##
## Cron schedule of the job that grants emergency access requests that have met the required wait time.
## Defaults to hourly (5 minutes after the hour). Set blank to disable this job.
# EMERGENCY_REQUEST_TIMEOUT_SCHEDULE="0 5 * * * *"

## Enable extended logging, which shows timestamps and targets in the logs
# EXTENDED_LOGGING=true

## Timestamp format used in extended logging.
## Format specifiers: https://docs.rs/chrono/latest/chrono/format/strftime
# LOG_TIMESTAMP_FORMAT="%Y-%m-%d %H:%M:%S.%3f"

## Logging to file
# LOG_FILE=/path/to/log

## Logging to Syslog
## This requires extended logging
# USE_SYSLOG=false

## Log level
## Change the verbosity of the log output
## Valid values are "trace", "debug", "info", "warn", "error" and "off"
## Setting it to "trace" or "debug" would also show logs for mounted
## routes and static file, websocket and alive requests
# LOG_LEVEL=Info

## Enable WAL for the DB
## Set to false to avoid enabling WAL during startup.
## Note that if the DB already has WAL enabled, you will also need to disable WAL in the DB,
## this setting only prevents vaultwarden from automatically enabling it on start.
## Please read project wiki page about this setting first before changing the value as it can
## cause performance degradation or might render the service unable to start.
# ENABLE_DB_WAL=true

## Database connection retries
## Number of times to retry the database connection during startup, with 1 second delay between each retry, set to 0 to retry indefinitely
# DB_CONNECTION_RETRIES=15

## Icon service
## The predefined icon services are: internal, bitwarden, duckduckgo, google.
## To specify a custom icon service, set a URL template with exactly one instance of `{}`,
## which is replaced with the domain. For example: `https://icon.example.com/domain/{}`.
##
## `internal` refers to Vaultwarden's built-in icon fetching implementation.
## If an external service is set, an icon request to Vaultwarden will return an HTTP
## redirect to the corresponding icon at the external service. An external service may
## be useful if your Vaultwarden instance has no external network connectivity, or if
## you are concerned that someone may probe your instance to try to detect whether icons
## for certain sites have been cached.
# ICON_SERVICE=internal

## Icon redirect code
## The HTTP status code to use for redirects to an external icon service.
## The supported codes are 301 (legacy permanent), 302 (legacy temporary), 307 (temporary), and 308 (permanent).
## Temporary redirects are useful while testing different icon services, but once a service
## has been decided on, consider using permanent redirects for cacheability. The legacy codes
## are currently better supported by the Bitwarden clients.
# ICON_REDIRECT_CODE=302

## Disable icon downloading
## Set to true to disable icon downloading in the internal icon service.
## This still serves existing icons from $ICON_CACHE_FOLDER, without generating any external
## network requests. $ICON_CACHE_TTL must also be set to 0; otherwise, the existing icons
## will be deleted eventually, but won't be downloaded again.
# DISABLE_ICON_DOWNLOAD=false

## Icon download timeout
## Configure the timeout value when downloading the favicons.
## The default is 10 seconds, but this could be to low on slower network connections
# ICON_DOWNLOAD_TIMEOUT=10

## Icon blacklist Regex
## Any domains or IPs that match this regex won't be fetched by the icon service.
## Useful to hide other servers in the local network. Check the WIKI for more details
## NOTE: Always enclose this regex withing single quotes!
# ICON_BLACKLIST_REGEX='^(192\.168\.0\.[0-9]+|192\.168\.1\.[0-9]+)$'

## Any IP which is not defined as a global IP will be blacklisted.
## Useful to secure your internal environment: See https://en.wikipedia.org/wiki/Reserved_IP_addresses for a list of IPs which it will block
# ICON_BLACKLIST_NON_GLOBAL_IPS=true

## Disable 2FA remember
## Enabling this would force the users to use a second factor to login every time.
## Note that the checkbox would still be present, but ignored.
# DISABLE_2FA_REMEMBER=false

## Maximum attempts before an email token is reset and a new email will need to be sent.
# EMAIL_ATTEMPTS_LIMIT=3

## Token expiration time
## Maximum time in seconds a token is valid. The time the user has to open email client and copy token.
# EMAIL_EXPIRATION_TIME=600

## Email token size
## Number of digits in an email 2FA token (min: 6, max: 255).
## Note that the Bitwarden clients are hardcoded to mention 6 digit codes regardless of this setting!
# EMAIL_TOKEN_SIZE=6

## Controls if new users can register
# SIGNUPS_ALLOWED=true

## Controls if new users need to verify their email address upon registration
## Note that setting this option to true prevents logins until the email address has been verified!
## The welcome email will include a verification link, and login attempts will periodically
## trigger another verification email to be sent.
# SIGNUPS_VERIFY=false

## If SIGNUPS_VERIFY is set to true, this limits how many seconds after the last time
## an email verification link has been sent another verification email will be sent
# SIGNUPS_VERIFY_RESEND_TIME=3600

## If SIGNUPS_VERIFY is set to true, this limits how many times an email verification
## email will be re-sent upon an attempted login.
# SIGNUPS_VERIFY_RESEND_LIMIT=6

## Controls if new users from a list of comma-separated domains can register
## even if SIGNUPS_ALLOWED is set to false
# SIGNUPS_DOMAINS_WHITELIST=example.com,example.net,example.org

## Controls which users can create new orgs.
## Blank or 'all' means all users can create orgs (this is the default):
# ORG_CREATION_USERS=
## 'none' means no users can create orgs:
# ORG_CREATION_USERS=none
## A comma-separated list means only those users can create orgs:
# ORG_CREATION_USERS=admin1@example.com,admin2@example.com

## Token for the admin interface, preferably use a long random string
## One option is to use 'openssl rand -base64 48'
## If not set, the admin panel is disabled
# ADMIN_TOKEN=Vy2VyYTTsKPv8W5aEOWUbB/Bt3DEKePbHmI4m9VcemUMS2rEviDowNAFqYi1xjmp

## Enable this to bypass the admin panel security. This option is only
## meant to be used with the use of a separate auth layer in front
# DISABLE_ADMIN_TOKEN=false

## Invitations org admins to invite users, even when signups are disabled
# INVITATIONS_ALLOWED=true
## Name shown in the invitation emails that don't come from a specific organization
# INVITATION_ORG_NAME=Vaultwarden

## Per-organization attachment storage limit (KB)
## Max kilobytes of attachment storage allowed per organization.
## When this limit is reached, organization members will not be allowed to upload further attachments for ciphers owned by that organization.
# ORG_ATTACHMENT_LIMIT=
## Per-user attachment storage limit (KB)
## Max kilobytes of attachment storage allowed per user.
## When this limit is reached, the user will not be allowed to upload further attachments.
# USER_ATTACHMENT_LIMIT=

## Number of days to wait before auto-deleting a trashed item.
## If unset (the default), trashed items are not auto-deleted.
## This setting applies globally, so make sure to inform all users of any changes to this setting.
# TRASH_AUTO_DELETE_DAYS=

## Number of minutes to wait before a 2FA-enabled login is considered incomplete,
## resulting in an email notification. An incomplete 2FA login is one where the correct
## master password was provided but the required 2FA step was not completed, which
## potentially indicates a master password compromise. Set to 0 to disable this check.
## This setting applies globally to all users.
# INCOMPLETE_2FA_TIME_LIMIT=3

## Controls the PBBKDF password iterations to apply on the server
## The change only applies when the password is changed
# PASSWORD_ITERATIONS=100000

## Controls whether users can set password hints. This setting applies globally to all users.
# PASSWORD_HINTS_ALLOWED=true

## Controls whether a password hint should be shown directly in the web page if
## SMTP service is not configured. Not recommended for publicly-accessible instances
## as this provides unauthenticated access to potentially sensitive data.
# SHOW_PASSWORD_HINT=false

## Domain settings
## The domain must match the address from where you access the server
## It's recommended to configure this value, otherwise certain functionality might not work,
## like attachment downloads, email links and U2F.
## For U2F to work, the server must use HTTPS, you can use Let's Encrypt for free certs
DOMAIN=https://DOMAIN.duckdns.org

## Allowed iframe ancestors (Know the risks!)
## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
## Allows other domains to embed the web vault into an iframe, useful for embedding into secure intranets
## This adds the configured value to the 'Content-Security-Policy' headers 'frame-ancestors' value.
## Multiple values must be separated with a whitespace.
# ALLOWED_IFRAME_ANCESTORS=

## Number of seconds, on average, between login requests from the same IP address before rate limiting kicks in.
# LOGIN_RATELIMIT_SECONDS=60
## Allow a burst of requests of up to this size, while maintaining the average indicated by `LOGIN_RATELIMIT_SECONDS`.
## Note that this applies to both the login and the 2FA, so it's recommended to allow a burst size of at least 2.
# LOGIN_RATELIMIT_MAX_BURST=10

## Number of seconds, on average, between admin requests from the same IP address before rate limiting kicks in.
# ADMIN_RATELIMIT_SECONDS=300
## Allow a burst of requests of up to this size, while maintaining the average indicated by `ADMIN_RATELIMIT_SECONDS`.
# ADMIN_RATELIMIT_MAX_BURST=3

## Yubico (Yubikey) Settings
## Set your Client ID and Secret Key for Yubikey OTP
## You can generate it here: https://upgrade.yubico.com/getapikey/
## You can optionally specify a custom OTP server
# YUBICO_CLIENT_ID=11111
# YUBICO_SECRET_KEY=AAAAAAAAAAAAAAAAAAAAAAAA
# YUBICO_SERVER=http://yourdomain.com/wsapi/2.0/verify

## Duo Settings
## You need to configure all options to enable global Duo support, otherwise users would need to configure it themselves## Create an account and protect an application as mentioned in this link (only the first step, not the rest):
## https://help.bitwarden.com/article/setup-two-step-login-duo/#create-a-duo-security-account
## Then set the following options, based on the values obtained from the last step:
# DUO_IKEY=<Integration Key>
# DUO_SKEY=<Secret Key>
# DUO_HOST=<API Hostname>
## After that, you should be able to follow the rest of the guide linked above,
## ignoring the fields that ask for the values that you already configured beforehand.

## Authenticator Settings
## Disable authenticator time drifted codes to be valid.
## TOTP codes of the previous and next 30 seconds will be invalid
##
## According to the RFC6238 (https://tools.ietf.org/html/rfc6238),
## we allow by default the TOTP code which was valid one step back and one in the future.
## This can however allow attackers to be a bit more lucky with there attempts because there are 3 valid codes.
## You can disable this, so that only the current TOTP Code is allowed.
## Keep in mind that when a sever drifts out of time, valid codes could be marked as invalid.
## In any case, if a code has been used it can not be used again, also codes which predates it will be invalid.
# AUTHENTICATOR_DISABLE_TIME_DRIFT=false

## Rocket specific settings
## See https://rocket.rs/v0.4/guide/configuration/ for more details.
ROCKET_ADDRESS=0.0.0.0
ROCKET_PORT=8001
# ROCKET_WORKERS=10
# ROCKET_TLS={certs="./cert.pem",key="./privkey.pem"}

## Mail specific settings, set SMTP_HOST and SMTP_FROM to enable the mail service.
## To make sure the email links are pointing to the correct host, set the DOMAIN variable.
## Note: if SMTP_USERNAME is specified, SMTP_PASSWORD is mandatory
# SMTP_HOST=smtp.domain.tld
# SMTP_FROM=vaultwarden@domain.tld
# SMTP_FROM_NAME=Vaultwarden
# SMTP_SECURITY=starttls # ("starttls", "force_tls", "off") Enable a secure connection. Default is "starttls" (Explicit - ports 587 or 25), "force_tls" (Implicit - port 465) or "off", no encryption (port 25)
# SMTP_PORT=587          # Ports 587 (submission) and 25 (smtp) are standard without encryption and with encryption via STARTTLS (Explicit TLS). Port 465 is outdated and used with Implicit TLS.
# SMTP_USERNAME=username
# SMTP_PASSWORD=password
# SMTP_TIMEOUT=15

## Defaults for SSL is "Plain" and "Login" and nothing for Non-SSL connections.
## Possible values: ["Plain", "Login", "Xoauth2"].
## Multiple options need to be separated by a comma ','.
# SMTP_AUTH_MECHANISM="Plain"

## Server name sent during the SMTP HELO
## By default this value should be is on the machine's hostname,
## but might need to be changed in case it trips some anti-spam filters
# HELO_NAME=

## SMTP debugging
## When set to true this will output very detailed SMTP messages.
## WARNING: This could contain sensitive information like passwords and usernames! Only enable this during troubleshooting!
# SMTP_DEBUG=false

## Accept Invalid Hostnames
## DANGEROUS: This option introduces significant vulnerabilities to man-in-the-middle attacks!
## Only use this as a last resort if you are not able to use a valid certificate.
# SMTP_ACCEPT_INVALID_HOSTNAMES=false

## Accept Invalid Certificates
## DANGEROUS: This option introduces significant vulnerabilities to man-in-the-middle attacks!
## Only use this as a last resort if you are not able to use a valid certificate.
## If the Certificate is valid but the hostname doesn't match, please use SMTP_ACCEPT_INVALID_HOSTNAMES instead.
# SMTP_ACCEPT_INVALID_CERTS=false

## Require new device emails. When a user logs in an email is required to be sent.
## If sending the email fails the login attempt will fail!!
# REQUIRE_DEVICE_EMAIL=false

## HIBP Api Key
## HaveIBeenPwned API Key, request it here: https://haveibeenpwned.com/API/Key
# HIBP_API_KEY=

# vim: syntax=ini


10-proxy.conf

root@DietPi:~# cat /etc/lighttpd/conf-enabled/10-proxy.conf 
# /usr/share/doc/lighttpd/proxy.txt

server.modules   += ( "mod_proxy" )

## Balance algorithm, possible values are: "hash", "round-robin" or "fair" (default)
# proxy.balance     = "hash"


## Redirect all queries to files ending with ".php" to 192.168.0.101:80
#proxy.server     = ( ".php" =>
#                     (
#                       ( "host" => "192.168.0.101",
#                         "port" => 80
#                       )
#                     )
#                    )

## Redirect all connections on www.example.com to 10.0.0.1{0,1,2,3}
#$HTTP["host"] == "www.example.com" {
#  proxy.balance = "hash"
#  proxy.server  = ( "" => ( ( "host" => "10.0.0.10" ),
#                            ( "host" => "10.0.0.11" ),
#                            ( "host" => "10.0.0.12" ),
#                            ( "host" => "10.0.0.13" ) )

$HTTP["host"] == "DOMAIN.duckdns.org" {
    $HTTP["url"] =~ "^/notifications/hub($|/)" {
       # WebSocket proxy
      proxy.server = ( "" => ("vaultwarden" => ( "host" => "192.168.x.2", "port" => 3012 )))
      proxy.forwarded = ("for" => 1 )
      proxy.header = (
           "https-remap" => "enable",
           "upgrade" => "enable",
           "connect" => "enable"
      )
    } else {
   $HTTP["url"] =~ "^/vault($|/)" {
       proxy.server = ( "" => ("vaultwarden" => ( "host" => "192.168.x.2", "port" => 8001 )))
       proxy.forwarded = ("for" => 1 )
       proxy.header = ( "https-remap" => "enable" )
       }
    }
}

Stupid question, but did you adjust the host IP to point to your own device? 192.168.x.2 was just the example and needs to be changed according to your config. You could use localhost 127.0.0.1 if everythig is running on a single device.

Yes, I changed the IP to the one of my Pi and only made the change for this post.

As mentioned earlier, I can access nextcloud via HTTPS (so the IP I set is correct I would assume), but vaultwarden does throw a 404 error.

Also tested 127.0.0.1 with the same result (I.e. 404) error)

Can you check which interface Vaultwarden is using

ss -tulpn | grep LISTEN

root@DietPi:~# ss -tulpn | grep LISTEN
tcp     LISTEN   0        5              127.0.0.1:4711           0.0.0.0:*      users:(("pihole-FTL",pid=490,fd=14))
tcp     LISTEN   0        80             127.0.0.1:3306           0.0.0.0:*      users:(("mysqld",pid=17316,fd=20))
tcp     LISTEN   0        511            127.0.0.1:6379           0.0.0.0:*      users:(("redis-server",pid=17245,fd=7))
tcp     LISTEN   0        1024             0.0.0.0:80             0.0.0.0:*      users:(("lighttpd",pid=17409,fd=4))
tcp     LISTEN   0        32               0.0.0.0:53             0.0.0.0:*      users:(("pihole-FTL",pid=490,fd=5))
tcp     LISTEN   0        128              0.0.0.0:22             0.0.0.0:*      users:(("sshd",pid=466,fd=3))
tcp     LISTEN   0        256            127.0.0.1:5335           0.0.0.0:*      users:(("unbound",pid=543,fd=4))
tcp     LISTEN   0        1024             0.0.0.0:443            0.0.0.0:*      users:(("lighttpd",pid=17409,fd=6))
tcp     LISTEN   0        1024             0.0.0.0:8001           0.0.0.0:*      users:(("vaultwarden",pid=17414,fd=37))
tcp     LISTEN   0        1024             0.0.0.0:3012           0.0.0.0:*      users:(("vaultwarden",pid=17414,fd=34))
tcp     LISTEN   0        128              0.0.0.0:5252           0.0.0.0:*      users:(("dietpi-dashboar",pid=433,fd=6))
tcp     LISTEN   0        5                  [::1]:4711              [::]:*      users:(("pihole-FTL",pid=490,fd=13))
tcp     LISTEN   0        1024                [::]:80                [::]:*      users:(("lighttpd",pid=17409,fd=5))
tcp     LISTEN   0        128                    *:21                   *:*      users:(("proftpd",pid=17242,fd=0))
tcp     LISTEN   0        32                  [::]:53                [::]:*      users:(("pihole-FTL",pid=490,fd=7))
tcp     LISTEN   0        128                 [::]:22                [::]:*      users:(("sshd",pid=466,fd=4))

that seems to be fine. How do you access Vaultwarden on your local network? Using HTTP or HTTPS?

Via Http

HTTPS gives a ERR_SSL_PROTOCOL_ERROR

Also, I noticed nextcloud in LAN via HTTPS doesn’t work but it works via internet for some odd reason.

Any (other) idea why HTTPS (with lighttpd) is not working as expected in all cases, @Joulinar ?

Do you need more info to further investigate?

Sorry I was on business trip without possibility to test this further. It’s still on my aganda to do.

1 Like

I guess I found it.

Did you already activate the sub path /vault within Vaultwarden configuration?

If not, ensure you set correct value inside /mnt/dietpi_userdata/vaultwarden/vaultwarden.env

DOMAIN=http://dietpi.example.com/vault

And this is the fitting configuration on lighttpd. I’m now able to open http://dietpi.example.com/vault/ (including the trailing slash)

If you are guessing, you are guessing pretty good :wink:

The subpath was the missing link.

I had the domain set but the subpath was missing.

I can now access vaultwarden via https from the internet.

What do you mean by

I’m not able to open http://dietpi.example.com/vault/ (including the trailing slash)
?

Do I need to change my lighttpd config if I can access vaultwarden?

there was a typo not > now. Fixed above.

All good if you are able to access Vaultwarden now.

1 Like

Excellent.

Thanks for your professional support. Much appreciated.

1 Like

Just as it came up further above: The vaultwarden user has no permissions to read the private key, so when skipping the reverse proxy, a common solution is to copy and chown key and cert via e.g. certbot deploy hook script into vaultwarden’s home directory.

1 Like