passwordless-server
passwordless-server copied to clipboard
Self-hosting with reverse proxy
How to setup self-hosting passwordless server with a reverse proxy.
My entry in docker-compose.yml and getting "Bad Gateway" errors:
passwordless:
container_name: passwordless
image: ghcr.io/passwordless/passwordless-self-host:latest
volumes:
- /my/persistent/storage:/etc/bitwarden_passwordless
restart: unless-stopped
environment:
# BWP_ENABLE_SSL: 'true'
BWP_PORT: 443
BWP_DOMAIN: passwordless.srv.${DOMAIN}
labels:
- "traefik.enable=true"
- "traefik.http.routers.passwordless.rule=Host(`passwordless.srv.${DOMAIN}`)"
- "traefik.http.routers.passwordless.entrypoints=websecure"
- "traefik.http.services.passwordless.loadbalancer.server.port=5701"
- "traefik.http.routers.passwordless.service=passwordless"
- "traefik.http.routers.passwordless.tls=true"
- "traefik.http.routers.passwordless.tls.certresolver=leresolver"
Log from container:
Adding group `bitwarden' (GID 1000) ...
Done.
Adding user `bitwarden' ...
Adding new user `bitwarden' (1000) with group `bitwarden (1000)' ...
Not creating home directory `/home/bitwarden'.
Adding new user `bitwarden' to supplemental / extra groups `users' ...
Adding user `bitwarden' to group `users' ...
[Configuration] SMTP E-mail configuration not set. Writing to a local file instead in '/etc/bitwarden_passwordless/mail.md' or your mounted volume. See 'https://docs.passwordless.dev/guide/self-hosting/configuration.html'.
[Configuration] SSL: Disabled
[Configuration] API public: http://passwordless.srv.mydomain.net:443/api
[Configuration] API private: http://localhost:5000
2023-12-21 20:07:59,154 INFO Included extra file "/etc/supervisor.d/admin.ini" during parsing
2023-12-21 20:07:59,154 INFO Included extra file "/etc/supervisor.d/api.ini" during parsing
2023-12-21 20:07:59,154 INFO Included extra file "/etc/supervisor.d/nginx.ini" during parsing
2023-12-21 20:07:59,156 INFO RPC interface 'supervisor' initialized
2023-12-21 20:07:59,156 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2023-12-21 20:07:59,157 INFO supervisord started with pid 1
2023-12-21 20:08:00,160 INFO spawned: 'admin' with pid 59
2023-12-21 20:08:00,161 INFO spawned: 'api' with pid 60
2023-12-21 20:08:00,163 INFO spawned: 'nginx' with pid 61
2023-12-21 20:08:15,869 INFO success: admin entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2023-12-21 20:08:15,869 INFO success: api entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2023-12-21 20:08:15,869 INFO success: nginx entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
The scheme for public urls must be https but there should no certificates generated. I am using Traefik as reverse proxy which handles everything about Certificates
When I am extracting the SSL Certificates from Traefik and assign in the docker container, still the same "Bad Gateway" errors. It seems that the startup/entrypoint still wants to override existing certificates.
passwordless:
container_name: passwordless
image: ghcr.io/passwordless/passwordless-self-host:latest
volumes:
- /my/persistent/storage:/etc/bitwarden_passwordless
- /my/persistent/storage/passwordless.srv.crt:/etc/bitwarden_passwordless/passwordless_ssl.crt:ro
- /my/persistent/storage/passwordless.srv.key:/etc/bitwarden_passwordless/passwordless_ssl.key:ro
restart: unless-stopped
environment:
BWP_ENABLE_SSL: 'true'
BWP_ENABLE_SSL_CA: 'false'
BWP_PORT: 443
BWP_DOMAIN: passwordless.srv.${DOMAIN}
BWP_SSL_CERT: passwordless_ssl.crt
BWP_SSL_KEY: passwordless_ssl.key
labels:
- "traefik.enable=true"
- "traefik.http.routers.passwordless.rule=Host(`passwordless.srv.${DOMAIN}`)"
- "traefik.http.routers.passwordless.entrypoints=websecure"
- "traefik.http.services.passwordless.loadbalancer.server.port=5701"
- "traefik.http.routers.passwordless.service=passwordless"
- "traefik.http.routers.passwordless.tls=true"
- "traefik.http.routers.passwordless.tls.certresolver=leresolver"
Log from container:
[Configuration] SMTP E-mail configuration not set. Writing to a local file instead in '/etc/bitwarden_passwordless/mail.md' or your mounted volume. See 'https://docs.passwordless.dev/guide/self-hosting/configuration.html'.
[Configuration] SSL: Enabled
[Configuration] API public: https://passwordless.srv.mydomain.net:443/api
[Configuration] API private: http://localhost:5000
chown: changing ownership of '/etc/bitwarden_passwordless/passwordless_ssl.crt': Read-only file system
chown: changing ownership of '/etc/bitwarden_passwordless/passwordless_ssl.key': Read-only file system
2023-12-21 20:42:08,655 INFO Included extra file "/etc/supervisor.d/admin.ini" during parsing
2023-12-21 20:42:08,655 INFO Included extra file "/etc/supervisor.d/api.ini" during parsing
2023-12-21 20:42:08,655 INFO Included extra file "/etc/supervisor.d/nginx.ini" during parsing
2023-12-21 20:42:08,658 INFO RPC interface 'supervisor' initialized
2023-12-21 20:42:08,658 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2023-12-21 20:42:08,658 INFO supervisord started with pid 1
2023-12-21 20:42:09,662 INFO spawned: 'admin' with pid 34
2023-12-21 20:42:09,664 INFO spawned: 'api' with pid 35
2023-12-21 20:42:09,667 INFO spawned: 'nginx' with pid 36
2023-12-21 20:42:25,579 INFO success: admin entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2023-12-21 20:42:25,579 INFO success: api entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2023-12-21 20:42:25,579 INFO success: nginx entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
Hi Christoph, thank you for your interest in self-hosting Passwordless.dev. I will look into it. Feel free to send me an e-mail to schedule a call as you see fit to walk things through.
At first glance, it does not look like your certificates are being overwritten by the entrypoint.sh
script.
Hi @pocki, I've published a bug fix. We're currently working on publishing the image.
I tried the new image v1.0.56:
I think there is a misunderstanding: I use the reverse proxy traefik for all the SSL/TLS stuff. So none of my container itself needs SSL Certificates or has any. No webserver is running on SSL ports.
Variant 1:
passwordless:
container_name: passwordless
#image: ghcr.io/passwordless/passwordless-self-host:latest
image: docker.io/bitwarden/passwordless-self-host:latest
volumes:
- /my/persistent/storage/passwordless:/etc/bitwarden_passwordless
restart: unless-stopped
environment:
BWP_ENABLE_ADMIN: 'true'
BWP_ENABLE_API: 'true'
#BWP_ENABLE_SSL: 'true'
BWP_PORT: 80
BWP_DOMAIN: passwordless.srv.${DOMAIN}
labels:
- "traefik.enable=true"
- "traefik.http.routers.passwordless.rule=Host(`passwordless.srv.${DOMAIN}`)"
- "traefik.http.routers.passwordless.entrypoints=websecure"
- "traefik.http.services.passwordless.loadbalancer.server.port=80"
- "traefik.http.routers.passwordless.service=passwordless"
- "traefik.http.routers.passwordless.tls=true"
- "traefik.http.routers.passwordless.tls.certresolver=leresolver"
Log:
Adding group `bitwarden' (GID 1000) ...
Done.
Adding user `bitwarden' ...
Adding new user `bitwarden' (1000) with group `bitwarden (1000)' ...
Not creating home directory `/home/bitwarden'.
Adding new user `bitwarden' to supplemental / extra groups `users' ...
Adding user `bitwarden' to group `users' ...
[Configuration] SMTP E-mail configuration not set. Writing to a local file instead in '/etc/bitwarden_passwordless/mail.md' or your mounted volume. See 'https://docs.passwordless.dev/guide/self-hosting/configuration.html'.
[Configuration] WARNING: Set environment variable 'BWP_ENABLE_SSL' to 'true' when 'BWP_DOMAIN' is not 'localhost'.
[Configuration] WARNING: WebAuthn requires SSL when not running on 'localhost'. This could result in unexpected behavior.
[Configuration] SSL: Disabled
[Configuration] API public: http://passwordless.srv.mydomain.net:80/api
[Configuration] API private: http://localhost:5000
2024-01-11 14:44:35,999 INFO Included extra file "/etc/supervisor.d/admin.ini" during parsing
2024-01-11 14:44:35,999 INFO Included extra file "/etc/supervisor.d/api.ini" during parsing
2024-01-11 14:44:35,999 INFO Included extra file "/etc/supervisor.d/nginx.ini" during parsing
2024-01-11 14:44:36,002 INFO RPC interface 'supervisor' initialized
2024-01-11 14:44:36,002 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2024-01-11 14:44:36,003 INFO supervisord started with pid 1
2024-01-11 14:44:37,008 INFO spawned: 'admin' with pid 60
2024-01-11 14:44:37,012 INFO spawned: 'api' with pid 61
2024-01-11 14:44:37,016 INFO spawned: 'nginx' with pid 62
2024-01-11 14:44:52,886 INFO success: admin entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2024-01-11 14:44:52,886 INFO success: api entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2024-01-11 14:44:52,886 INFO success: nginx entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
results in Bad Gateway which is clear, as NGINX don't allow https requests.
Variant 2:
passwordless:
container_name: passwordless
#image: ghcr.io/passwordless/passwordless-self-host:latest
image: docker.io/bitwarden/passwordless-self-host:latest
volumes:
- /my/persistant/storage/passwordless:/etc/bitwarden_passwordless
restart: unless-stopped
environment:
BWP_ENABLE_ADMIN: 'true'
BWP_ENABLE_API: 'true'
BWP_ENABLE_SSL: 'true'
BWP_PORT: 443
BWP_DOMAIN: passwordless.srv.${DOMAIN}
RP_PORT: 5701
labels:
- "traefik.enable=true"
- "traefik.http.routers.passwordless.rule=Host(`passwordless.srv.${DOMAIN}`)"
- "traefik.http.routers.passwordless.entrypoints=websecure"
- "traefik.http.services.passwordless.loadbalancer.server.port=5701"
- "traefik.http.routers.passwordless.service=passwordless"
- "traefik.http.routers.passwordless.tls=true"
- "traefik.http.routers.passwordless.tls.certresolver=leresolver"
Log:
Adding group `bitwarden' (GID 1000) ...
Done.
Adding user `bitwarden' ...
Adding new user `bitwarden' (1000) with group `bitwarden (1000)' ...
Not creating home directory `/home/bitwarden'.
Adding new user `bitwarden' to supplemental / extra groups `users' ...
Adding user `bitwarden' to group `users' ...
[Configuration] SMTP E-mail configuration not set. Writing to a local file instead in '/etc/bitwarden_passwordless/mail.md' or your mounted volume. See 'https://docs.passwordless.dev/guide/self-hosting/configuration.html'.
[Configuration] WARNING: Set environment variable 'BWP_ENABLE_SSL' to 'true' when 'BWP_DOMAIN' is not 'localhost'.
[Configuration] WARNING: WebAuthn requires SSL when not running on 'localhost'. This could result in unexpected behavior.
[Configuration] SSL: Enabled
[Configuration] API public: https://passwordless.srv.mydomain.net:443/api
[Configuration] API private: http://localhost:5000
2024-01-11 14:54:09,639 INFO Included extra file "/etc/supervisor.d/admin.ini" during parsing
2024-01-11 14:54:09,639 INFO Included extra file "/etc/supervisor.d/api.ini" during parsing
2024-01-11 14:54:09,639 INFO Included extra file "/etc/supervisor.d/nginx.ini" during parsing
2024-01-11 14:54:09,642 INFO RPC interface 'supervisor' initialized
2024-01-11 14:54:09,642 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2024-01-11 14:54:09,642 INFO supervisord started with pid 1
2024-01-11 14:54:10,646 INFO spawned: 'admin' with pid 59
2024-01-11 14:54:10,650 INFO spawned: 'api' with pid 60
2024-01-11 14:54:10,656 INFO spawned: 'nginx' with pid 61
2024-01-11 14:54:26,410 INFO success: admin entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2024-01-11 14:54:26,410 INFO success: api entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2024-01-11 14:54:26,410 INFO success: nginx entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
result in Bad Request: The plain HTTP request was sent to HTTPS port.
Here is an example how it normally looks like with traefik when the system needs the calling Url (ex. Nextcloud): Webserver is running on port 80, but works with https://nextcloud.xyz:443
nextcloud:
container_name: nextcloud
image: nextcloud
hostname: "nextcloud.${DOMAIN}"
restart: always
environment:
NEXTCLOUD_TRUSTED_DOMAINS: "nextcloud.${DOMAIN}"
NEXTCLOUD_DOMAIN_NAME: "nextcloud.${DOMAIN}"
OVERWRITEPROTOCOL: "https"
# other settings also skipped
volumes:
# skipped
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`nextcloud.${DOMAIN}`)"
- "traefik.http.routers.nextcloud.entrypoints=websecure"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
- "traefik.http.routers.nextcloud.service=nextcloud"
- "traefik.http.routers.nextcloud.tls=true"
- "traefik.http.routers.nextcloud.tls.certresolver=leresolver"
PS: I have to switch to docker hub as it seems that the ghcr don't have the latest image pushed.
I got it working, but logging looks strange:
passwordless:
container_name: passwordless
#image: ghcr.io/passwordless/passwordless-self-host:latest
image: docker.io/bitwarden/passwordless-self-host:latest
volumes:
- /my/persistent/storage/passwordless:/etc/bitwarden_passwordless
restart: unless-stopped
environment:
BWP_ENABLE_ADMIN: 'true'
BWP_ENABLE_API: 'true'
# BWP_ENABLE_SSL: 'true'
BWP_PORT: 443
BWP_DOMAIN: https://passwordless.srv.${DOMAIN}
RP_PORT: 5701
labels:
- "traefik.enable=true"
- "traefik.http.routers.passwordless.rule=Host(`passwordless.srv.${DOMAIN}`)"
- "traefik.http.routers.passwordless.entrypoints=websecure"
- "traefik.http.services.passwordless.loadbalancer.server.port=5701"
- "traefik.http.routers.passwordless.service=passwordless"
- "traefik.http.routers.passwordless.tls=true"
- "traefik.http.routers.passwordless.tls.certresolver=leresolver"
Log:
Adding group `bitwarden' (GID 1000) ...
Done.
Adding user `bitwarden' ...
Adding new user `bitwarden' (1000) with group `bitwarden (1000)' ...
Not creating home directory `/home/bitwarden'.
Adding new user `bitwarden' to supplemental / extra groups `users' ...
Adding user `bitwarden' to group `users' ...
[Configuration] SMTP E-mail configuration not set. Writing to a local file instead in '/etc/bitwarden_passwordless/mail.md' or your mounted volume. See 'https://docs.passwordless.dev/guide/self-hosting/configuration.html'.
[Configuration] WARNING: Set environment variable 'BWP_ENABLE_SSL' to 'true' when 'BWP_DOMAIN' is not 'localhost'.
[Configuration] WARNING: WebAuthn requires SSL when not running on 'localhost'. This could result in unexpected behavior.
[Configuration] SSL: Disabled
[Configuration] API public: http://https://passwordless.srv.mydomain.net:443/api
[Configuration] API private: http://localhost:5000
2024-01-11 15:25:11,768 INFO Included extra file "/etc/supervisor.d/admin.ini" during parsing
2024-01-11 15:25:11,768 INFO Included extra file "/etc/supervisor.d/api.ini" during parsing
2024-01-11 15:25:11,768 INFO Included extra file "/etc/supervisor.d/nginx.ini" during parsing
2024-01-11 15:25:11,770 INFO RPC interface 'supervisor' initialized
2024-01-11 15:25:11,771 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2024-01-11 15:25:11,771 INFO supervisord started with pid 1
2024-01-11 15:25:12,774 INFO spawned: 'admin' with pid 60
2024-01-11 15:25:12,778 INFO spawned: 'api' with pid 61
2024-01-11 15:25:12,780 INFO spawned: 'nginx' with pid 62
2024-01-11 15:25:28,703 INFO success: admin entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2024-01-11 15:25:28,703 INFO success: api entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
2024-01-11 15:25:28,703 INFO success: nginx entered RUNNING state, process has stayed up for > than 15 seconds (startsecs)
Please have a look at the API public url.
@pocki Have you tried setting:
-
BWP_ENABLE_SSL = true
-
BWP_SSL_KEY = point to /etc/bitwarden_passwordless/ssl.key
-
BWP_DOMAIN = passwordless.srv.mydomain.net
-
BWP_PORT = 443
-
RP_PORT (delete)
-
BWP_ENABLE_ADMIN (delete)
-
BWP_ENABLE_API (delete)
Then paste the private key in the root of the mounted volume.
# Generate SSL certificates
if [ "$BWP_ENABLE_SSL" = "true" ] && [ ! -f /etc/bitwarden_passwordless/${BWP_SSL_KEY:-ssl.key} ]; then
openssl req \
-x509 \
-newkey rsa:4096 \
-sha256 \
-nodes \
-days 36500 \
-keyout /etc/bitwarden_passwordless/${BWP_SSL_KEY:-ssl.key} \
-out /etc/bitwarden_passwordless/${BWP_SSL_CERT:-ssl.crt} \
-reqexts SAN \
-extensions SAN \
-config <(cat /usr/lib/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:${BWP_DOMAIN:-localhost}\nbasicConstraints=CA:true")) \
-subj "/C=US/ST=California/L=Santa Barbara/O=Bitwarden Inc./OU=Bitwarden Passwordless/CN=${BWP_DOMAIN:-localhost}"
fi
I don't want to share the SSL Key in the container - it is not needed. The reverse proxy is doing all the SSL termination and is renewing the zertificates before expiring. So the key files are changing every few weeks when using Let's Encrypt.
docker run \
--name passwordless \
-p 5701:5701 \
-e BWP_DOMAIN=example.com \
-v /local/path/passwordless-self-hosting:/etc/bitwarden_passwordless \
bitwarden/passwordless