Seems going to bitwarden-nginx on 8443 as https did the job and it's now forwarding correctly! Kspearrin closed this May 24, 2020 Sign up for free to join this conversation on GitHub. Bitwarden Server is an open source project that contains all of the core infrastructure backend of all Bitwarden client applications. This includes APIs, database, Docker and other infrastructure items. Bitwarden is an open source password management solution that stores sensitive information in.
This article will cover setting up your own self-hosted Bitwarden instance with Docker and configuring ngnix to allow for public exposure for cross-device access to your vault.
Bitwarden is a free and open-source password management service that stores sensitive information such as website credentials in an encrypted vault. The Bitwarden platform offers a variety of client applications including a web interface, desktop applications, browser extensions, mobile apps, and a CLI.
I use Bitwarden as my main password vault. It stores my card details for automating the filling out of payment forms. Saves me from having to find or remember my card details. I also use Bitwarden for storing all of my passwords.
Having Bitwarden as a public endpoint means that I can connect to my password vault using the Bitwarden app on Android, specifying my self hosted instance.
This section of the tutorial is to set up the main Bitwarden 'hub'. This will be a publicly exposed Bitwarden API that will live on your server.
You'll need to either have an existing server instance or create one. I use a Proxmox instance running on a server in my loft. You could also use something like Digital Ocean to host your Bitwarden Server. Using the following link will give you $100 worth of credits for 60 days to play around with, just sign up using this link.
Once you have the server set up, or have logged in. You'll need to do some updates and run some prerequisite installs.
Next, you'll need to create a new folder, this will house your Bitwarden Server, you can call it anything memorable. I'll just call mine bitwarden
Next, you'll need to create a docker-compose.yml file. This is an orchistration file which docker-compose will use to provision your Docker instance.
Next, you'll need to edit your `docker-compose.yml` file and paste in the following content.
I'm using bitwarden_rs as it's written in Rust, faster and more reliable. Also entirely opensource with a heavy user-base. https://bestqfiles327.weebly.com/path-finder-7-3-2.html.
Save your docker-compose.yml file and exit back to your bitwarden directory.
Now, you have everything provisioned for running your Bitwarden Server.
The next thing to do is run it.
This will start up your Bitwarden Server inside Docker, it may take some time to pull down the images.
You can eventually see your instance running by executing the following
This will list your running instance.
If all is well, you can locally view your Bitwarden Server by navigating to http://localhost:PORT. Or from another machine by using your ip address instead of localhost
You should see something that looks like the following.
Finally, you'll just need to register for an account on your new hosted instance.
Click the Create Account button
Then fill out your details. If you have an existing Bitwarden account, you'll still have to create a new account on this instance. You can then Export and Import between accounts.
The last thing to do is hit Submit
This part may sound scary, but it is required to allow your Bitwarden Clients (Android, iOS, Chrome extension etc) to connect to your server.
We're going to be using nginx.
Nginx is a reverse proxy that allows you to point incoming web traffic to your new Bitwardeb server.
Firstly, install nginx if you haven't already
If you have UFW installed, you will have to Allow Nginx through your local firewall.
I have a tutorial for setting up UFW here
As you can see, there are three profiles available for Nginx:
It is recommended that you enable the most restrictive profile that will still allow the traffic you’ve configured. Since we will be configuring SSL for our server we will need to allow traffic on port 443. Cocktail 12 4 1.
You can enable this by typing:
Next thing to do is just double check your nginx server is up and running
You should see something that looks like the following Avid pro tools hd 10 3 10 download free.
The next part allows us to take incoming traffic and point it to your container instance. Allowing you to expose your Bitwarden server to the internet.
Navigate to /etc/nginx/
Use your favorite text editor and open the following file with sudo
I use the following code for my syncing server
You will need to port forward your instance to allow public access to your instance. This will involve googling how to port forward from your router.
You'll need to point port 443 to your instance where nginx is set up.
You will also need to set up a public domain name. This can then be used to call your new public instance with port 443 exposed.
For example, I would set up a subdomain on bowlerdesign.tech to be vault.bowlerdesign.tech. Notice this is also the domain I specified in my nginx config above.
Here's something to search for with regards to setting up a domain name
Certbot allows us to generate SSL certificates for free with Let's Encrypt. It's simple to install and use. Even hooks in with nginx, meaning that there's no more manual configuration required.
To install Certbot, simply run the following command
Then, to set up your SSL certificate, run
Follow the instructions, select your domain name from the nginx list.
Also, select redirect as this will upgrade any http requests to https.
I'm going to use the Firefox Bitwarden Plugin for this part of the tutorial. But the process is identical for all Bitwarden clients.
First, if you haven't already, install your chosen Bitwarden client and open it.
In the top left corner, click the cog icon
You'll then get some configuration. Simply add your full url into the Server URL field
Like so, then just hit Save and log in as normal
Pretty easy right?
Please don't hesitate to get in touch in the comments if you get stuck. I'd be more than happy to help out with any issues you may face.
Also, if this helped, please consider buying me a beer! It helps with server costs and providing these blog posts.
Thanks for reading!
One of the key requirements of pursuing Good Digital Hygiene is using strong passwords, and a different strong password for every application. This is relatively easy to do in theory, with the aid of clever software, but it's something desperately few people do well in practice. I'm going to explain how I've addressed this issue of digital hygiene for myself, and how you can do it for yourself, and your entire family, social circle, or community.
Password Keepers (or managers or safes) have emerged as that 'clever software'. A good password keeper has to do a bunch of things to be really useful:
That's a lot of requirements. There're quite a few efforts that have had a crack at solving this. The KeePassX community has been addressing this for ages and has created a comprehensive (if variable) ecosystem of apps which work across all of the required platforms, but only with a lot of work.
In the proprietary world, there're many options, with a few front runners like 1Password and LastPass. The former doesn't work on Linux, so it only gets a passing reference and no link :) (update 2019-05-31 - 1Password has added Linux support). The latter, which I used (grudgingly, mostly because I couldn't get KeePassX to work for me) for a few years, works across all the platforms relevant to me, but it was becoming progressively more invasive and annoying to use. Also, because it has a lot of users, and stores everything (albeit, encrypted) in a centralised cloud repository, it's a big target. Also, with its largely proprietary code, I wasn't happy trusting it.
Then I heard about BitWarden. They offered a commercial service (with a free tier) that I could quickly try. they supported all the OSs, mobile and desktop, and browsers that I use. and they release their entire codebase (server and clients) under open source licenses. I tried it, it worked for me, I was sold!
Then I decided I wanted to run my own BitWarden server, rather than use their commercial centralised cloud platform (because, as with LastPass, it's a tempting target). That's when I found out the server of BitWarden was written using Microsoft technologies, C# (yeah, it's mostly open source, but it's dirty to me due to its Microsoft legacy), and MS SQL Server, which is a nasty proprietary dependency (especially given how basic the database requirements for this sort of application are).
So I was devastated that I couldn't set up my own server without compromising my iron-clad anti-Microsoft position (I've managed to maintain it for the past 25 years). until another Free and Open Source Software aficionado pointed me at Daniel Garcia's work! Daniel has implemented a full (unofficial) BitWarden work-alike using a fully FOSS stack: the Rust language, storing data in SQLite, and (quite thoughtfully) re-using other open source licensed components of the BitWarden system that don't have proprietary dependencies, including the website code and layout (which is part of the server).
Daniel's server implementation also unlocks all the 'premium' services that BitWarden offers through their hosted service, too. so that's a nice bonus.
Another open source developer, mpasil, has created a 'fork' of Daniel's project from which he maintains an up-to-date Docker container on hub.docker.com. Thanks to both Daniel Garcia and mpasil's efforts, it turns out to be quite straightforward to set up your own Docker-based BitWarden-compatible service! Here's how.
The first step is to get yourself an entry-level virtual server or compute instance somewhere. I generally use DigitalOcean (I have no affiliation with the company), but there are many other commodity hosting services (check out Vultr or Linode, for example) around the world which offer comparably (or better) spec'd servers for USD5.00/month, or USD60.00/year - I encourage you to do a bit of research. For that you get a Gigabyte (GB) of RAM, a processor, and 40GB of SSD (Static Storage Device = faster) storage. That's oodles of grunt for what this application requires.
I suggest you create an account for yourself (and I encourage you to use Two Factor Authentication, aka 2FA) and create an Ubuntu 18.04 (or the most recent LTS version - the next will be 20.04, in April 2020 :) ) in the zone nearest to you. You'll need to note the server's IP address (it'll be a series of 4 numbers, 0-254, separated by full stops, e.g. 103.99.72.244). With that, you can log into it via SSH.
You will want to have a domain to point at your server, so you don't have to remember the IP number. There're are thousands of domain 'registrars' in the world who'll help you do that. You just need to 'register' a name, and you pay yearly fee (usually between USD10-30 depending on the country and the 'TLD' (Top Level Domain. There're national ones like .nz, .au, .uk, .tv, .sa, .za, etc., or international domains (mostly associated with the US) like .com, .org, .net, and a myriad of others. Countries decide on how much their domains wholesale for and registrars add a margin for the registration service).
Here in NZ, I use the services of Metaname (they're local to me in Christchurch, and I know them personally and trust their technical capabilities). If you're not sure who to use, ask your friends. Someone's bound to have recommendations (either positive or negative, in which case you'll know who to avoid).
If you want to use your domain for other things besides your BitWarden instance, I'd encourage you to use a subdomain, like (my usual choice) is 'safe.domainname', namely the subdomain 'safe' of 'domainname'.
Once you have selected and registered your domain, you can set up (usually through a web interface provided by the registrar) an 'A Record' which associates your website's name to the IP address of your server. So you should just be able to enter your server's IP address, the domain name (or sub-domain) you want to use for your BitWarden service, and that's it. For a password safe, I tend to use the subdomain 'safe', so, for example, safe.mydomain.nz or similar.
You might be asked to set a 'Time-to-live' (which has to do with the length of time Domain Name Servers are asked to 'cache' the association that the A Record specifies) in which case you can put in 3600 seconds or an hour depending on the time units your interface requests. but in most cases that'll be set to a default of an hour automatically.
You should be able to test that your A Record has been set correctly by SSHing to your domain name rather than the IP address. It should (after you accept the SSH warning that the server's name has changed) work the same way your original SSH login did.
Once I've first logged into it as the 'root' (full admin) user, here's what I usually do:
# Configuration file for Let's Encrypt ACME Challenge location
# This file is already included in listen_xxx.conf files.
# Do NOT include it separately!
#############################################################################
#
# This config enables to access /.well-known/acme-challenge/xxxxxxxxxxx
# on all our sites (HTTP), including all subdomains.
# This is required by ACME Challenge (webroot authentication).
# You can check that this location is working by placing ping.txt here:
# /var/www/letsencrypt/.well-known/acme-challenge/ping.txt
# And pointing your browser to:
# http://xxx.domain.tld/.well-known/acme-challenge/ping.txt
#
# Sources:
# https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491
#
# Rule for legitimate ACME Challenge requests
location ^~ /.well-known/acme-challenge/ {
default_type 'text/plain';
# this can be any directory, but this name keeps it clear
root /var/www/letsencrypt;
}
# Hide /acme-challenge subdirectory and return 404 on all requests.
# It is somewhat more secure than letting Nginx return 403.
# Ending slash is important!
location = /.well-known/acme-challenge/ {
return 404;
}
Now you need to create the directory described in the letsencrypt.conf file:
mkdir /var/www/letsencrypt
Create 'forward secrecy & Diffie Hellman ephemeral parameters' to make your server more secure. The result will be a secure signing key stored in /etc/ssl/certs/dhparam.pem (note, getting enough 'entropy' to generate sufficient randomness to calculate this will take a few minutes!):
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
and then you need to create the reverse proxy configuration file as follows:
cd ./sites-available
and fill it with this content, replacing all [tokens] with your relevant values:
# HTTP does *soft* redirect to HTTPS
#
server {
# add [IP-Address:]80 in the next line if you want to limit this to a single interface
listen 0.0.0.0:80;
root /home/data/[your domain];
index index.php;
# change the file name of these logs to include your server name
# if hosting many services.
access_log /var/log/nginx/[your domain]_access.log;
error_log /var/log/nginx/[your domain]_error.log;
include includes/letsencrypt.conf;
# redirect all HTTP traffic to HTTPS.
location / {
return 302 https://[your domain]$request_uri;
}
}
and make the configuration available to NGINX by linking the file from sites-available into sites-enabled (you can disable the site by removing the link and reloading NGINX)
ln -sf sites-available/bitwarden sites-enabled/bitwarden
Check to make sure NGINX is happy with the configuration
nginx -t
If you don't get any errors, you can restart NGINX
service nginx restart
and it should be configured properly to respond to requests at http://[your domain]/.well-known/acme-challenge/ which is required for creating a Let's Encrypt certificate.
$EDIT sites-available/bitwarden
So now we can create the certificate. You'll need to install the letscencrypt scripts:
apt-get install letsencrypt
You will be asked to enter some information about yourself, including an email address - this is necessary so that the letsencrypt service can email you if any of your certificates are not successfully updated (they need to be renewed every few weeks - normally this happens automatically!) so that you site and users aren't affected by an expired SSL certificate (a bad look!). Trust me, these folks are the good guys.
You create a certificate for [your domain] with the following command (with relevant substitutions):
letsencrypt certonly --webroot -w /var/www/letsencrypt -d $DOMAIN
If the process works, you should see a 'Congratulations!' message.
Edit the nginx configuration file for the BitWarden service again
$EDIT sites-available/bitwarden
and add the following to the bottom of file (starting the line below the final '}')
# HTTPS
#
# This assumes you're using Let's Encrypt for your SSL certs (and why wouldn't
# you!?). https://letsencrypt.org
server {
# add [IP-Address:]443 ssl in the next line if you want to limit this to a single interface
listen 0.0.0.0:443 ssl;
ssl on;
ssl_certificate /etc/letsencrypt/live/[your domain]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[your domain]/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# to create this, see https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_dhparam /etc/ssl/certs/dhparam.pem;
keepalive_timeout 20s;
server_name [your domain];
root /home/data/[your domain];
index index.php;
# change the file name of these logs to include your server name
# if hosting many services.
access_log /var/log/nginx/[your domain]_access.log;
error_log /var/log/nginx/[your domain]_error.log;
location /notifications/hub/negotiate {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $http_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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
proxy_connect_timeout 2400;
proxy_read_timeout 2400;
proxy_send_timeout 2400;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $http_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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
proxy_connect_timeout 2400;
proxy_read_timeout 2400;
proxy_send_timeout 2400;
}
location /notifications/hub {
proxy_pass http://127.0.0.1:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
#
# These 'harden' your security
add_header 'Access-Control-Allow-Origin' '*';
}
Now everything is read to set up your BitWarden Docker containers!
Before we start this part, you'll need a few bits of information. First, you'll need a 64 character random string to be your 'admin token'. you can create that like this:
pwgen -y 64 1
copy the result (highlight the text and hit CTRL+SHIFT+C) and paste it somewhere so you can copy-and-paste it into the file below later.
Also, if you want your BitWarden server to be able to send out emails, like for password recovery, you'll need to have an 'authenticating SMTP email account'. I would recommend setting one up specifically for this purpose. You can use a random gmail account or any other email account that lets you send mail by logging into an SMTP (Simple Mail Transfer Protocol) server, i.e. most mail servers. You'll need to know the SMTP [host name], the [port] (usually 465 or 587), the [login security] (usually 'true' or 'TLS'), and your authenticating [username] (possibly this is also the email address) and [password]. You'll also need a '[from email] like bitwarden@[your domain] or similar, which will be the sender of email from your server.
You're going to be setting up your configuration in the directory we created earlier, so run
cd /home/docker/$DOMAIN
and there
$EDIT docker-compose.yml
copy-and-pasting in the following, replacing the [tokens] appropriately:
services:
app:
image: bitwardenrs/server
environment:
- DOMAIN=https://[your domain]
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=false
- LOG_FILE='/data/bitwarden.log'
- INVITATIONS_ALLOWED=true
- ADMIN_TOKEN=[admin token]
- SMTP_HOST=[host name]
- SMTP_FROM=[from email]
- SMTP_PORT=[port]
- SMTP_SSL=[login security]
- SMTP_USERNAME=[username]
- SMTP_PASSWORD=[password]
volumes:
- /home/data/[your domain]/data/:/data/
ports:
- '127.0.0.1:8080:80'
- '127.0.0.1:3012:3012'
restart:
unless-stopped
Note that the indentation has to be exact in this file - Docker Compose will complain otherwise.
With the docker-compose file completed, you're ready to 'pull' your package!
docker-compose pull
This will download the BitWarden Docker container from hub.docker.com. Then all you need to do is start it:
docker-compose up -d && docker-compose logs -f
the 'up -d' option actually starts the container called 'app' which is actually your BitWarden rust server in 'daemon' mode, which means it'll keep running unless you tell it to stop. If that's successful, it automatically then shows you the logs of that container. You can exit at any time with CTRL-C which will put you back on the command prompt. If you do want the container to stop, just run
docker-compose stop
If your start up was successful, you should see a message like this (albeit your version number could be higher - 1.9.0 is the current version of the Rust implementation at the time of writing):
| Starting Bitwarden_RS |
| Version 1.9.0 |
|--------------------------------------------------------------------|
| This is an *unofficial* Bitwarden implementation, DO NOT use the |
| official channels to report bugs/features, regardless of client. |
| Report URL: https://github.com/dani-garcia/bitwarden_rs/issues/new |
--------------------------------------------------------------------/
You should now be able to point your browser at http://[your domain] which, in turn, should automatically redirect you to https://[your domain] and you should see the BitWarden web front end similar to that shown in the attached screen shot!
To do your initial login by going to https://[your domain]/admin/ and you'll be asked to provide your 'admin token' (a random string you created earlier for your docker-compose.yml file, where you should be able to find it) to create a first user with administration privileges. That will allow you to create your initial personal user and other useful stuff.
For additional info on setting up these services - and new options as Daniel and his co-developers add them in - consult the repository pages and issues and for Docker-specific questions, look at mpasil's pages.
It'll be worth testing if your email services work, like by requesting a password hint! You should be able to see what the server's doing via the
docker-compose logs -f
I recommend not including your login credentials to your BitWarden instance in your BitWarden database ;) that's the one thing you need to remember. If you need to write it down somewhere, then do so (but make sure you don't include all the info needed to log in on the same piece of paper, that's just asking for trouble).
Also, you can easily configure all the BitWarden clients - browser plugins, mobile apps, or the desktop app - to use your server rather than BitWarden's default hosted service. Just click the 'gear' settings icon on each app's interface, and set the 'Self-Hosted Environment' Server URL to be your server, i.e. https://[your domain]
I've created a SQLite backup script (which maintains automatic versioned hourly, daily, weekly, monthly, and yearly database dumps, the content in which is encrypted) described in more detail in another post.
This configuration should allow you to simply turn on Two Factor Authentication for any given BitWarden user.
One of the best things about this Docker configuration is that it's very straightforward to upgrade your installation to Daniel's (via mpasil's Docker work) latest server version. Just log into the server as your unprivileged user,
https://zillaxeno.weebly.com/gemini-the-duplicate-finder-2-6-1.html. cd /home/docker/[your domain]
docker-compose pull
docker-compose up -d && docker-compose logs -f
The whole process shouldn't take much more than a minute, with a few seconds downtime only as your new Docker BitWarden container is being created.
Hope this helps a few folks! If you find any of the above doesn't work, please let me know in the comments. I'll do my best to make sure this how-to is accurate and up-to-date, and I'll do my best to assist people if they're having trouble.
Have (secure and private) fun!t
Really appreciate the document.
Would love to see these too:
To do your initial login, I believe (I'll test this and update this howto!) you'll be asked to provide your 'admin token' to create a first user with administration privileges.
&
I'll add information on my SQLite backup scripts (which maintain automatic versioned hourly, daily, weekly, monthly, and yearly database dumps, the content in which is encrypted).
Thanks!