Password managers have been a hot topic lately and there are no shortages of how-to guides for using Bitwarden as a preferred password manager. In this guide, we’re going take the System Administrator/Security Practitioners perspective on how to deploy a Bitwarden instance at Digital Ocean – I will guide you through the strategies and design intent for leveraging Digital Ocean for your Bitwarden instance.
Solution Design and Considerations
Reliability and Availability
For security reasons and concerns we look to password managers for safeguarding our credentials, although the idea does have its benefits and pitfalls. We usually tend to prefer a public cloud based SaaS solution for its availability and reliability, yet it can have shortcoming similar to those experienced with LastPass. Availability tends to be a subject of requirement for our credential storage, yet one could find themselves credential-less if the credential vault is in a private cloud during an outage – possibly when you may just need the credentials most. But what if you could deploy your own solution based on open source technology in a reliable, available, more secure manner? Enter, a self-hosted Bitwarden at Digital Ocean.
Leveraging Bitwarden on their SaaS platform lacks a few key requirements for our secrets – the system cannot be restricted to particular IP addresses or networks and the data resides under their possession. I am sure many Last Pass customers would likely prefer to have had their data not residing under Last Pass’ proprietary system throughout 2022+. Below, I am going to guide you through the process how to deploy a Bitwarden instance at Digital Ocean, all within your control.
Manageability
Too often, we deploy various solutions only to find that one day they are found offline or even containing software vulnerabilities due to the lack of management attention. I desired a solution that offered self maintenance and less administrator attention. Digital Ocean (https://www.digitalocean.com) can offer such an instance. Now, I’m not a Digital Ocean fanboy but in this scenario I thought the service was very fitting. Digital Ocean’s Bitwarden Droplet offers an almost 1-click deployment and once it’s standing, it’s configured for automatic Bitwarden updates so you’ll not need to be concerned about keeping the service up to date or patched yourself – Digital Ocean’s droplet can take care of that for you here.
Workload Segmentation
Desiring to keep the Bitwarden segmented from any current workloads was a requirement, so given that most of the workloads are in a hybrid enviroment between a private cloud and public (such as Azure or AWS); the desired configuration was to offer workload segmentation.
Through the rest of this post, we are going to walk the process of deploying a Bitwarden instance at Digital Ocean. Let’s go.
Deploying the Droplet
Create Digital Ocean Droplet
- If you do not have a Digital Ocean account, sign up for one here https://cloud.digitalocean.com/registrations/new
- Deploy the Bitwarden Droplet from the Marketplace here https://marketplace.digitalocean.com/apps/bitwarden
- Select a datacenter near your preferred location
- Depending on the needs, select the desired specifications. Keep in mind that Bitwarden recommends at least 2GB of memory for the instance
- Depending on your needs, enable the backup service option. Personally, it’s a no-brainer, spend the couple of bucks for the backup service – these are your credential jewels.
- Modify the hostname as you wish
- Create the droplet
Configure a Digital Ocean Firewall
Now, since we want to tie this service down to specific networks for security purpose, we want to configure a firewall for this Droplet. This step will restrict the availability to a given IP address, so if you’re looking for vault availability from mobile devices or dynamic IP addresses, you’ll probably want to skip this step.
- Select Network
- Select Firewall
- Default Firewall Settings
- Provide Name
- Remove All IPv4 and All IPv4 for each protocol
- Add HTTP and HTTPS to the Inbound Rules and add the desired target IP address
- Ok, a slight annoyance here. Ideally we would like to restrict all outbound traffic from the Droplet to Bitwarden (for licensing and push requirements) and our specific address. Unfortunately, Digital Ocean does not allow us to enter FQDN’s suck as api.bitwarden.com, so this is a bit frustrating (if anyone knows differently, please comment below). Here, we’ll leave the Outbound Rules to all IPv4 and IPv6 addresses (sad face). Not all hope is lost though! I do believe we can leverage UFW from the droplet OS to control the outbound traffic and since that’s really the right way to manage the traffic. We’re not going to do that on this post but I do intend to follow up with this process
- Near the bottom, type the name of the droplet you wish to apply this firewall policy to
- Select “Create Firewall”
- Back at the droplet menu, select “Network” then edit the firewall button at the bottom to assign your new firewall to this droplet
Configure your public DNS for your new server by adding an A record for the server in your public DNS zone. Hang onto this, you’ll need this through the configuration phase.
Create a DNS Record Pointing to Your Digital Ocean Droplet
Your new Bitwarden will be needing a FQDN to call it’s home, so you will want to add a record to your Domain which points to your Bitwarden droplet’s public IP address. This is required for the Let’s Encrypt certificate if you chose to go that route (more on that later). Record your droplet’s IP address and browse to your domain configuration to add the record to your DNS. Doing this now should allow enough time for you Droplet to query the FQDN during the installation process. Not that the use of the record is masqueraded I like to use bw.domainname, rather than bitwarden.domainname, but that’s just me.
Create the Bitwarden SaaS Instance
Even though we’re looking to deploy a self-hosted instance, an account need to be built on their site as where licensing and the installation keys can be leveraged.
As mentioned previously, one can self host even a free license for up to 2 users and non-business use. However, you will beed an Enterprise license for business use, and at the time of this writing, the price per user for an Enterprise license is $5 per month. We’re going to focus on the Business/Enterprise model through this guide.
- Go to Bitwarden’s site to build the SaaS instance here https://bitwarden.com to create the Bitwarden account and then elevate it to a Premium account
- Select “+New Organization” from the left menu on Organizations from the main menu
- Enter the required fields and submit payment information and complete transaction
See https://bitwarden.com/pricing for up-to-date pricing and information. Additional information about the self-hosting process can be found here https://bitwarden.com/help/families-for-enterprise-self-hosted
Retrieve the Installation ID and Installation Key
We need to capture an installation ID and Key for each self-hosted instance. These keys can be retrieved by simply browsing to https://bitwarden.com/host/ and entering your Bitwarden cloud administrator email address
Hang onto these numbers as you will need them throughout the rest of this process. Record them for good keeping, and not in your new Bitwarden instance 😉
Retrieve the License File
Download the license file
- select Organization
- Select Billing from the top menu
- Select Subscription from the left menu
- Scroll down to the “Self-hosting” then the “Download License” button
- Enter the Installation ID you recorded the step prior
- Save this file, we’ll need it shortly.
- Next to the “Download License” button is “Setup Billing Sync”
- Select “Setup Billing Sync and enter your master password to proceed”
- Record this Key as you did with the Installation ID and Key earlier
Ok, on to the good stuff, let’s get the instance deployed and configured.
Bitwarden Instance Deployment
In order to complete the configuration stage of the self-hosted instance, we need to SSH into the the instance using the IP assigned to the droplet and follow the steps below
- First, let’s take a snapshot of the current state of the droplet
- Enter the domain name for your Bitwarden instance
- I use Let’s Encrypt to generate the SSL certificate. If you want to do the same, enter Y for yes
- If you are using Let’s Encrypt, enter the email address where you’d like to receive your reminder
- Enter your email address if you chose Let’s Encrypt for your certificate reminder, if you wish
- The process will go through certificate generation for the FQDN you entered
- You will be prompted for the database name for the instance. I like the default ‘vault’
- Next, you will need to enter the Installation ID and key we retrieved from the Bitwarden sight earlier.
- Sit back and let the installation process churn – it should not take more than a few minutes
- The screen output will look something like this
Customize Settings for the Bitwarden Instance
Configure SMTP Settings
We need to modify the environment file at ./bwdata/env/global.override.env
for the SMTP configuration. I use vi so if you’re unfamiliar with vi, use your favorite editor.
- SSH into the instance
- enter
vi ./bwdata/env/global.override.env
- Modify the lines below accordingly to match your SMTP server configuration
globalSettings__mail__smtp__host=REPLACE
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__ssl=false
globalSettings__mail__smtp__username=REPLACE
globalSettings__mail__smtp__password=REPLACE
- Save the file
- Enter
./bitwarden.sh restart
For additional information of these settings, see the documentation at https://bitwarden.com/help/install-on-premise-linux/#post-install-configuration
Configure the Bitwarden Interface
- Browse to your new instance at the FQDN you configured, i.e., bw.domain.name
- You’ll need to create your initial account. Do that.
- Log in with your new account
- You’ll see a brown box to verify the email address. Do that also.
General Bitwarden Instance House Cleaning
Let’s do a few good hygiene tasks
- Grab the fingerprint phase. Not needed, but why not.
- Click your Profile dot in the upper right hand corner of the screen, Account Settings, My Account. Capture that phrase.
- More information on the fingerprint phrase here https://bitwarden.com/help/fingerprint-phrase
- Lets enforce 2 factor authentication
- From the same Account Settings menu, select Security, and the Two-Step login. Choose wisely (smile)
Create the Organization and Upload the license file
In order to upload the Organization license file we downloaded earlier, we need to create a new Organization
- Select Vault, then Organization
- Lets upload the license file. Select ‘Browse’, select the file, and Submit
Organization Menu Options
You will now see a new Menu option titled ‘Organizations’. Let’s run through them quickly!
- Vault, is just that. The organizations Vault, which is sharable with other Organization members.
- Manage. Here, you can manage members, invites, Collections, and groups. I strongly encourage the use of Collections – think of them almost as Tags for the Vault items.
- Reporting. Well, Reporting.
- Billing. This one displays the Billing information and where you will upload a new license file after the plan expiration.
-
Settings. A glob of goodies are found here. A few particular options should be given special attention here.
– Policies
– Require two-step login for the organization
– Master Password Requirements forces password requirements
– Remove Individual Vault if you want to force all items to be saved to the Organization
– Export Vault
– This offers the ability to export the Organization’s vault. Obviously go with an encrypted json file if the file is not air-gapped or secured physically.
Organization Policies – updated 1/2024
Policies are a great option to establish standards across a Bitwarden Organization. There are a few policies you may wish to consider enabling.
- Account Recovery Administration. Account Recovery Administration offers end users the self-service ability to recover a lost password from the instance, otherwise, the user will need to be deleted by an administrator and recreated.
- Require Two-Step Login. This policy enables multi-factor authentication for all users of the organization.
- Password Generator. This is a friendly tool to allow users of the organization to generate passwords or passphrases.
- Single Organization. This policy may vary in usefulness to each instance, but it forces users to one organization to avoid a multi-organization enrollment.
- Master Password Requirements. A strong master password or passphrase is essential to securing access to the instance. This policy enforces a master password to your complexity requirements.
Updating the Bitwarden Instance and other Common CLI Commands
There are some CLI commands one should have in the arsenal in order to administer the Bitwarden Droplet. Although the Bitwarden container is scripted to update itself, it can be executed manually by entering the following commands:
./bitwarden.sh updateself
then ./bitwarden.sh update
To renew the Let’s Encrypt certificate
./bitwarden.sh renewcert
Some obvious results would be to execute
./bitwarden.sh restart
./bitwarden.sh start
./bitwarden.sh stop
After editing global.override.env, run the following command to apply your changes:
./bitwarden.sh restart
If further configuration changes are desired with config.yml
, you will need to apply the changes by running:
./bitwarden.sh rebuild
or ./bitwarden.sh update
If you want to learn more information about updating on Bitwarden’s website, https://bitwarden.com/help/updating-on-premise/
Planing Ahead for Your Bitwarden Instance
Licensing
Something to keep in mind is the expiration date of the self-hosted license. Note that if or when the license expires, you will not be able to gain access to the Organization (at all). I find it comforting to take regular backups of the vault, especially if it finds many modifications.
The SaaS Bitwarden account is needed when the user count is modified, particularly when the count is increased. Once the license is modified, the license file must be exported and imported into the self-hosted instance as we did earlier in this article.
You may note that there is a Billing Sync Token available where the license is to be downloaded. I was hoping that this token allowed the self-hosted instance license to be synced with Bitwarden but was unable to find that configuration process.
SSL Certificates
Like the license, you’ll want to monitor the expiration date of the certificate, especially if you choose to go the Let’s Encrypt route as the certificate is only good for about 3 months. Recall earlier, run ./bitwarden.sh renewcert
to renew the certificate.
Encrypted JSON Export
Early on, I exported the vault to an encrypted JSON file using a lengthy passphrase. I tested the recovery using the SaaS Bitwarden account because restoring the over any existing data will result with duplicate vault items, including Collections. The process of exporting the data was fine yet restoring failed. For some reason, the passphrase I used was not compatible, or something, I’m not real clear. I ended up trying a different style of password and that restored successfully. The takeaway here is to be sure to test the restoration of the export and not just assume all is well with the restoration process.
Bitwarden has a FAQ site for various other frequently asked questions which might be helpful https://bitwarden.com/help/hosting-faqs/
Conclusion
In this article, we reviewed how to deploy a Bitwarden instance at Digital Ocean. We deployed it in a manner where you have manageability of the data and the ability to secure the interface to specific networks. We also reviewed some of the common CLI commands used to manage the instance and discussed some planning strategies for the instance.
I intend to do another article on restoring this droplet from backup along with restoring the database from backup. Additionally, I’d like to run though tying the droplet firewall down beyond the limitations of the Digital Ocean firewall.
If you found this article helpful, consider buying a complete stranger a cup of coffee the next time you grab yourself one. Strike up a conversation, they’re probably a really wonderful human being.