- Updated the Github Actions to build just one binary with all DB
Backends.
- Created a hadolint workflow to check and verify Dockerfiles.
- Fixed current hadolint errors.
- Fixed a bug in the Dockerfile.j2 which prevented the correct libraries
and tools to be installed on the Alpine images.
- Deleted travis.yml since that is not used anymore
When ticking the 'Also rotate my account's encryption key' box, the key
rotated ciphers are posted after the change of password.
During the password change the security stamp was reseted which made
the posted key's return an invalid auth. This reset is needed to prevent other clients from still being able to read/write.
This fixes this by adding a new database column which stores a stamp exception which includes the allowed route and the current security stamp before it gets reseted.
When the security stamp check fails it will check if there is a stamp exception and tries to match the route and security stamp.
Currently it only allows for one exception. But if needed we could expand it by using a Vec<UserStampException> and change the functions accordingly.
fixes#1240
* For clarity, add `UTC` suffix for datetimes in the `Diagnostics` admin tab.
* Format datetimes in the local timezone in the `Users` admin tab.
* Refactor some datetime code and add doc comments.
- Changed the user-agent, which caused at least one site to stall the
connection (Same happens on icons.bitwarden.com)
- Added default_header creation to the lazy static CLIENT
- Added referer passing, which is checked by some sites
- Some small other changes
- Added more checks to prevent panics (Removed unwrap)
- Try do download from base domain or add www when the provided domain
fails
- Added some more domain validation checks to prevent errors
- Added the ICON_BLACKLIST_REGEX to a Lazy Static HashMap which
speeds-up the checks!
- Validate the Regex before starting/config change.
- Some cleanups
- Disabled some noisy debugging from 2 crates.
Prevent clients from updating a cipher if the local copy is stale.
Validation is only performed when the client provides its last known
revision date; this date isn't provided when using older clients,
or when the operation doesn't involve updating an existing cipher.
Upstream PR: https://github.com/bitwarden/server/pull/994
- Updated crates
- Updated rust-toolchain
- Updated Dockerfile to use latest rust 1.48 version
- Updated AMD64 Alpine to use same version as rust-toolchain and support
PostgreSQL.
- Updated Rocket to the commit right before they updated hyper.
Until that update there were some crates updated and some small fixes.
After that build fails and we probably need to make some changes
(which is probably something already done in the async branch)
This has been requested a few times (#1136 & #246 & forum), and there already were two
(1:1 duplicate) PR's (#1222 & #1223) which needed some changes and no
followups or further comments unfortunally.
This PR adds two auth headers.
- ManagerHeaders
Checks if the user-type is Manager or higher and if the manager is
part of that collection or not.
- ManagerHeadersLoose
Check if the user-type is Manager or higher, but does not check if the
user is part of the collection, needed for a few features like
retreiving all the users of an org.
I think this is the safest way to implement this instead of having to
check this within every function which needs this manually.
Also some extra checks if a manager has access to all collections or
just a selection.
fixes#1136
- Added an option to enable smtp debugging via SMTP_DEBUG. This will
trigger a trace of the smtp commands sent/received to/from the mail
server. Useful when troubleshooting.
- Added two options to ignore invalid certificates which either do not
match at all, or only doesn't match the hostname.
- Updated lettre to the latest alpha.4 version.
plain/text emails should not contain html elements like <p> <a> etc..
This triggers some spamfilters and increases the spam score.
Also added the github link into the text only emails since this also
triggers spamfilters to increase the score since the url/link count is
different between the multipart messages.
- Added check if settings are changed but not saved when sending test
email.
- Added some styling to emphasize some risks settings.
- Fixed alignment of elements when the label has multiple lines.
Some issue people report are because of misconfiguration or bad .env
files. To mittigate this i added error handling for this.
- Panic/Quit on a LineParse error, which indicates bad .env file format.
- Emits a info message when there is no .env file found.
- Emits a warning message when there is a .env file, but not no
permissions.
- Emits a warning on every other message not specifically catched.
Updated the azure-pipelines.yml to build multidb now.
- Updated to Ubuntu 18.04 (Closer matches the docker builds)
- Added some really needed apt packages to be sure that they are
installed
- Now run cargo test using all database backeds in one go.
The runtime image was using a very old Alpine version.
This caused issues with the catatonit install
Now using the Balena armv7hf Alpine image for this.
With some apt/dpkg magic building multidb containers for arm versions
now also works. As long as the build stage and docker-image stage use
the same base (debian buster now) it should all work.
Resolves#530, resolves#1066
If for some reason the hashed password is cleared from memory within a
bitwarden client it will try to verify the password at the server side.
This endpoint was missing.
Resolves#1156
When using MariaDB v10.5+ Foreign-Key errors were popping up because of
some changes in that version. To mitigate this on MariaDB and other
MySQL forks those errors are now catched, and instead of a replace_into
an update will happen. I have tested this as thorough as possible with
MariaDB 10.5, 10.4, 10.3 and the default MySQL on Ubuntu Focal. And
tested it again using sqlite, all seems to be ok on all tables.
resolves#1081. resolves#1065, resolves#1050
Made some small changes to the description of the config options for
SMTP. Some were a bit cryptic and missing some extra descriptions.
Also made it more clear which type of secured smtp connection is going
to used.
Currently when for example using the admin interface to send out a test e-mail just
returns `SmtpError`. This is not very helpful. What i have done.
- Match some common Lettre errors to return the error message.
- Other errors will just be passed on as before.
Some small other changes:
- Fixed a clippy warning about using clone().
- Fixed a typo where Lettere was spelled with one t.
- Allow all SMTP Auth meganisms supported by Lettre.
- The config value order is leading and values can be separated by a
comma ','
- Case doesn't matter, and invalid values are ignored.
- Warning is printed when no valid value is found at all.
General:
- Updated several dependancies
Lettre:
- Updateded lettere and the workflow
- Changed encoding to base64
- Convert unix newlines to dos newlines for e-mails.
- Created custom e-mail boundary (auto generated could cause errors)
Tested the e-mails sent using several clients (Linux, Windows, MacOS, Web).
Run msglint (https://tools.ietf.org/tools/msglint/) on the generated e-mails until all errors were gone.
Lettre has changed quite some stuff compared between alpha.1 and alpha.2, i haven't noticed any issues sending e-mails during my tests.
If org owners/admins set their org access to only include selected
collections, then ciphers from non-selected collections shouldn't
appear in "My Vault". This matches the upstream behavior.
Diesel requires the following changes:
- Separate connection and pool types per connection, the generate_connections! macro generates an enum with a variant per db type
- Separate migrations and schemas, these were always imported as one type depending on db feature, now they are all imported under different module names
- Separate model objects per connection, the db_object! macro generates one object for each connection with the diesel macros, a generic object, and methods to convert between the connection-specific and the generic ones
- Separate connection queries, the db_run! macro allows writing only one that gets compiled for all databases or multiple ones
Currently, favorites are tracked at the cipher level. For org-owned ciphers,
this means that if one user sets it as a favorite, it automatically becomes a
favorite for all other users that the cipher has been shared with.
Note that Diesel implements its own parser for MySQL connection URIs, so it
probably doesn't accept the full range of syntax that would be accepted by
MySQL's client libraries, whereas for PostgreSQL, Diesel simply passes the
connection string/URI to PostgreSQL's libpq for processing.
The script works by reading the relevant files from the upstream Bitwarden
source repo and generating a matching JSON file. It could potentially be
integrated into the build/release process, but for now it can be run manually
as needed.
In this implementation, the `TZ` environment variable must be set
in order for the formatted output to use a more user-friendly
time zone abbreviation (e.g., `UTC`). Otherwise, the output uses
the time zone's UTC offset (e.g., `+00:00`).
This is useful for making local customizations upon container start. To use
this feature, mount a script into the container as `/etc/bitwarden_rs.sh`
and/or a directory of scripts as `/etc/bitwarden_rs.d`. In the latter case,
only files with an `.sh` extension are sourced, so files with other
extensions (e.g., data/config files) can reside in the same dir.
Note that the init scripts are run each time the container starts (not just
the first time), so these scripts should be idempotent.
In the event of a failed DNS Resolving checking for new versions will
cause a huge delay, and in the end a timeout when loading the page.
- Check if DNS resolving failed, if that is the case, do not check for
new versions
- Changed `fn get_github_api` to make use of structs
- Added a timeout of 10 seconds for the version check requests
- Moved the "Unknown" lables to the "Latest" lable
- Updated bootstrap js and css to the latest version
- Fixed issue with small-screens where the menu overlaps the token input
- The menu now collapses to a hamburger menu
- Menu's only accessable when logedin are hidden when you are not
- Changed Users Overview to use a table to prevent small-screen issues.
Main changes:
- Splitted up settings and users into two separate pages.
- Added verified shield when the e-mail address has been verified.
- Added the amount of personal items in the database to the users overview.
- Added Organizations and Diagnostics pages.
- Shows if DNS resolving works.
- Shows if there is a posible time drift.
- Shows current versions of server and web-vault.
- Optimized logo-gray.png using optipng
Items which can be added later:
- Amount of cipher items accessible for a user, not only his personal items.
- Amount of users per Org
- Version update check in the diagnostics overview.
- Copy/Pasteable runtime config which has sensitive data changed or removed for support questions either on the forum or github issues.
- Option to delete Orgs and all its passwords (when there are no members anymore).
- Etc....
PostgreSQL updates/inserts ignored None/null values.
This is nice for new entries, but not for updates.
Added derive option to allways add these none/null values for Option<>
variables.
This solves issue #965
* Make `SIGNUPS_DOMAINS_WHITELIST` override the `SIGNUPS_ALLOWED` setting.
Otherwise, a common pitfall is to set `SIGNUPS_DOMAINS_WHITELIST` without
realizing that `SIGNUPS_ALLOWED=false` must also be set.
* Whitespace is now accepted in `SIGNUPS_DOMAINS_WHITELIST`. That is,
`foo.com, bar.com` is now equivalent to `foo.com,bar.com`.
* Add validation on `SIGNUPS_DOMAINS_WHITELIST`. For example, `foo.com,`
is rejected as containing an empty token.
Ignore a missing `id` query param; it's unclear what this ID represents,
but it wasn't being used in the existing bitwarden_rs code, and no longer
seems to be sent in the latest versions of the official clients.
* Switch healthcheck interval/timeout from 30s/3s to 60s/10s.
30s interval is arguably overkill, and 3s timeout is definitely too short
for lower end machines.
* Use HEALTHCHECK CMD exec form to avoid superfluous `sh` invocations.
* Add `--silent --show-error` flags to curl call to avoid progress meter being
shown in healthcheck logs.
The organization uuid is most of the time within the uri path as a
parameter. But sometimes it only is there as a query value.
This fix checks both, and returns the uuid when possible.
During migrations some queries are out of order regarding to foreign
keys.
Because of this the migrations fail when the sql database has this
enforced by default.
Turning of this check during the migrations will fix this and this is
only per session.
If SSL is disabled, the SMTP ClientSecurity of the lettre crate
defaults to None, that is, an insecure connection. This is changed to
Opportunistic, which uses TLS if available. If TLS is not available,
the insecure connection is used (i.e., this change is backward
compatible).
- Moved smtp test option to within the "SMTP Email" Settings block.
- Added optional option to prevent full page reload.
- SMTP Test and Backup do not reload the admin interface any more.
- Added a test button for checking the e-mail settings.
- Fixed a bug with the _post JavaScript function:
A function was overwriten with a variable and errors were not handled
correctly like a 500 for example.
- Added a test button for checking the e-mail settings.
- Fixed a bug with the _post JavaScript function:
A function was overwriten with a variable and errors were not handled
correctly like a 500 for example.
panic!()'s only appear on stderr, this makes tracking down some strange
issues harder with the usage of docker since stderr does not get logged
into the bitwarden.log file. This change logs the message to stdout and
the logfile when activated.
I've checked the spots when `Invitation::new()` and `Invitation::take()`
are used and it seems like all spots are already correctly gated. So to
enable invitations via admin API even when invitations are otherwise
disabled, this check can be removed.
This was brought up today:
https://github.com/dani-garcia/bitwarden_rs/issues/752#issuecomment-586715073
I don't think it makes much sense in checking whether admin has the
right to send invitation as admin can change the setting anyway.
Removing the condition allows users to forbid regular users from
inviting new users to server while still preserving the option to do so
via the admin API.
Because of differences in how .on_conflict() works compared to .replace_into() the PostgreSQL backend wasn't correctly ensuring the unique constraint on user_uuid and atype wasn't getting violated.
This change simply issues a DELETE on the unique constraint prior to the insert to ensure uniqueness. PostgreSQL does not support multiple constraints in ON CONFLICT clauses.
The muslrust images seem to have a workdir of /volume as opposed to / in the
others so doing cargo new like this would create the folder in /volume/app.
No need to use two different base images. Debian buster is pulled later
anyway so we can just use it for the vault stage as well.
My reason for this change is partly to avoid redundancy and partly to
make it easier to build everything yourself. When all the build
environment is based on Debian than you just have to figure out how to
build a Debian Docker base image (ref:
https://github.com/ypid/docker-makefile).
Use LOG_LEVEL debug or trace to recover them.
Removed LOG_MOUNTS and bundled it with LOG_LEVEL debug and trace.
Removed duplicate error messages
Made websocket not proxied message more prominent, but only print it once.
Some sites are using base64 encoded inline images for favicons.
This will try to match those with some sane checks and return that.
These icons will have lower prio then the icons with a normal URL.
This feature can be enabled by setting SIGNUPS_ALLOWED=false and
providing a comma-separated list of whitelisted domains in
SIGNUPS_DOMAINS_WHITELIST.
Fixes#727
Now creates icon cache directory at startup.
And it also creates the directory if it went missing during runtime.
Also modified the icon_save/mark_negcache to be one.
When the icon_cache directory doesn't exists yet, and the first icon
catched is a miss this .miss file was not able to be created since the
directory was only created during a valid icon download.
During the 2fa activation there is no twofactor record yet.
Changed the layout a bit so that it will generate a new twofactor record
when it does not exists yet. Else it will just update the already
existing record.
- Added security check for previouse used codes
- Allow TOTP codes with 1 step back and forward when there is a time
drift. This means in total 3 codes could be valid. But only newer codes
then the previouse used codes are excepted after that.
This is done to enable backup functionality in the admin interface while
we're waiting for the libsqlite-sys 0.17 to bubble up in the upstream
dependencies. Then we can start using `VACUUM INTO`
This also extends the check for the sqlite binary to also try `sqlite3`
as this is the name of the binary in baseimage distributions we use.
This includes migrations as well as Dockerfile's for amd64.
The biggest change is that replace_into isn't supported by Diesel for the
PostgreSQL backend, instead requiring the use of on_conflict. This
unfortunately requires a branch for save() on all of the models currently
using replace_into.
This changes the healthcheck to use `sh` instead of bash, that is absent
from some image versions. (like alpine)
It also removes `*mariadb*` packages from runtime image of sqlite images
as these shouldn't be required.
TODO:
- At the moment each user needs to configure a DUO application and input the API keys, we need to check if multiple users can register with the same keys correctly and if so we could implement a global setting.
- Sometimes the Duo frame doesn't load correctly, but canceling, reloading the page and logging in again seems to fix it for me.
Some sites use XSRF Tokens, or other Tokens to verify a subseqense
response. The cookies which are sent during the page request are now
used when downloading the favicon.
A site which uses this is mijn.ing.nl.
- Using url from reqwest to fix href, this fixes:
+ "//domain.com/icon.png"
+ "relative/path/to/icon.png"
+ "/absolute/path/to/icon.png"
- Removed fix_href function
- Some variable changes
Improved error logging, now it won't show a generic error message in some situations.
Removed delete device, which is not needed as it will be overwritten later.
Logged more info when an error occurs saving a device.
Added orgmanager to JWT claims.
Removed: `include conf.d/proxy-confs/proxy.conf;` lines because they're specific to user (shauder) and will break nginx if copy-pasted/don't exist.
Changed: Moved listen value and server_name to top as is standard for nginx configs
Changed: Commented out SSL config as it's specific to user (shauder) and will break if copy-pasted/don't exist. But is still useful and a good idea for simplifying nginx config.
Changed: Rearranged location blocks because OCD. First /, then /notifications/hub, then /notifications/hub/negotiate because it looks nicer in a tree where each location grows.
## 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=bitwarden-rs@domain.tld
# SMTP_FROM_NAME=Bitwarden_RS
# 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_SSL=true # (Explicit) - This variable by default configures Explicit STARTTLS, it will upgrade an insecure connection to a secure one. Unless SMTP_EXPLICIT_TLS is set to true. Either port 587 or 25 are default.
# SMTP_EXPLICIT_TLS=true # (Implicit) - N.B. This variable configures Implicit TLS. It's currently mislabelled (see bug #851) - SMTP_SSL Needs to be set to true for this option to work. Usually port 465 is used here.
# 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
- `Rust nightly` (strongly recommended to use [rustup](https://rustup.rs/))
- `OpenSSL` (should be available in path, install through your system's package manager or use the [prebuilt binaries](https://wiki.openssl.org/index.php/Binaries))
- `NodeJS` (required to build the web-vault, (install through your system's package manager or use the [prebuilt binaries](https://nodejs.org/en/download/))
## Run/Compile
```sh
# Compile and run
cargo run
# or just compile (binary located in target/release/bitwarden_rs)
cargo build --release
```
When run, the server is accessible in [http://localhost:80](http://localhost:80).
### Install the web-vault
Clone the git repository at [bitwarden/web](https://github.com/bitwarden/web) and checkout the latest release tag (e.g. v2.1.1):
Finally copy the contents of the `build` folder into the `bitwarden_rs/web-vault` folder.
# Configuration
The available configuration options are documented in the default `.env` file, and they can be modified by uncommenting the desired options in that file or by setting their respective environment variables. Look at the README file for the main configuration options available.
Note: the environment variables override the values set in the `.env` file.
## How to recreate database schemas (for developers)
In this document, `<SERVER>` refers to the IP or domain where bitwarden_rs is accessible from. If both the proxy and bitwarden_rs are running in the same system, simply use `localhost`.
The ports proxied by default are `80` for the web server and `3012` for the WebSocket server. The proxies are configured to listen in port `443` with HTTPS enabled, which is recommended.
When using a proxy, it's preferrable to configure HTTPS at the proxy level and not at the application level, this way the WebSockets connection is also secured.
## Caddy
```nginx
localhost:443 {
# The negotiation endpoint is also proxied to Rocket
proxy /notifications/hub/negotiate <SERVER>:80 {
transparent
}
# Notifications redirected to the websockets server
Image is based on [Rust implementation of Bitwarden API](https://github.com/dani-garcia/bitwarden_rs).
_*Note, that this project is not associated with the [Bitwarden](https://bitwarden.com/) project nor 8bit Solutions LLC._
**This project is not associated with the [Bitwarden](https://bitwarden.com/) project nor 8bit Solutions LLC.**
#### ⚠️**IMPORTANT**⚠️: When using this server, please report any bugs or suggestions to us directly (look at the bottom of this page for ways to get in touch), regardless of whatever clients you are using (mobile, desktop, browser...). DO NOT use the official support channels.
---
**Table of contents**
- [Features](#features)
- [Missing features](#missing-features)
- [Docker image usage](#docker-image-usage)
- [Starting a container](#starting-a-container)
- [Updating the bitwarden image](#updating-the-bitwarden-image)
- [Changing persistent data location](#changing-persistent-data-location)
- [/data prefix:](#data-prefix)
- [database name and location](#database-name-and-location)
- [attachments location](#attachments-location)
- [icons cache](#icons-cache)
- [Changing the API request size limit](#changing-the-api-request-size-limit)
- [Changing the number of workers](#changing-the-number-of-workers)
- [SMTP configuration](#smtp-configuration)
- [Password hint display](#password-hint-display)
- [Disabling or overriding the Vault interface hosting](#disabling-or-overriding-the-vault-interface-hosting)
- [Other configuration](#other-configuration)
- [Building your own image](#building-your-own-image)
- [Building binary](#building-binary)
- [Available packages](#available-packages)
- [Arch Linux](#arch-linux)
- [Backing up your vault](#backing-up-your-vault)
- [1. the sqlite3 database](#1-the-sqlite3-database)
- [2. the attachments folder](#2-the-attachments-folder)
- [3. the key files](#3-the-key-files)
- [4. Icon Cache](#4-icon-cache)
- [Running the server with non-root user](#running-the-server-with-non-root-user)
- [Differences from upstream API implementation](#differences-from-upstream-api-implementation)
- [Changing user email](#changing-user-email)
- [Creating organization](#creating-organization)
- [Inviting users into organization](#inviting-users-into-organization)
- [Running on unencrypted connection](#running-on-unencrypted-connection)
- [Get in touch](#get-in-touch)
## Features
Basically full implementation of Bitwarden API is provided including:
* Basic single user functionality
* Organizations support
* Attachments
* Vault API support
* Vault API support
* Serving the static files for Vault interface
* Website icons API
* Authenticator and U2F support
## Missing features
* Email confirmation
* Other two-factor systems:
* YubiKey OTP (if your key supports U2F, you can use that)
* Duo
* Email codes
* YubiKey and Duo support
## Docker image usage
### Starting a container
The persistent data is stored under /data inside the container, so the only requirement for persistent deployment using Docker is to mount persistent volume at the path:
```
docker run -d --name bitwarden -v /bw-data/:/data/ -p 80:80 mprasil/bitwarden:latest
```
This will preserve any persistent data under `/bw-data/`, you can adapt the path to whatever suits you.
The service will be exposed on port 80.
### Updating the bitwarden image
Updating is straightforward, you just make sure to preserve the mounted volume. If you used the bind-mounted path as in the example above, you just need to `pull` the latest image, `stop` and `rm` the current container and then start a new one the same way as before:
## Installation
Pull the docker image and mount a volume from the host for persistent storage:
```sh
# Pull the latest version
docker pull mprasil/bitwarden:latest
# Stop and remove the old container
docker stop bitwarden
docker rm bitwarden
# Start new container with the data mounted
docker run -d --name bitwarden -v /bw-data/:/data/ -p 80:80 mprasil/bitwarden:latest
docker pull bitwardenrs/server:latest
docker run -d --name bitwarden -v /bw-data/:/data/ -p 80:80 bitwardenrs/server:latest
```
Then visit [http://localhost:80](http://localhost:80)
This will preserve any persistent data under /bw-data/, you can adapt the path to whatever suits you.
In case you didn't bind mount the volume for persistent data, you need an intermediate step where you preserve the data with an intermediate container:
**IMPORTANT**: Some web browsers, like Chrome, disallow the use of Web Crypto APIs in insecure contexts. In this case, you might get an error like `Cannot read property 'importKey'`. To solve this problem, you need to access the web vault from HTTPS.
```sh
# Pull the latest version
docker pull mprasil/bitwarden:latest
This can be configured in [bitwarden_rs directly](https://github.com/dani-garcia/bitwarden_rs/wiki/Enabling-HTTPS) or using a third-party reverse proxy ([some examples](https://github.com/dani-garcia/bitwarden_rs/wiki/Proxy-examples)).
# Create intermediate container to preserve data
docker run --volumes-from bitwarden --name bitwarden_data busybox true
If you have an available domain name, you can get HTTPS certificates with [Let's Encrypt](https://letsencrypt.org/), or you can generate self-signed certificates with utilities like [mkcert](https://github.com/FiloSottile/mkcert). Some proxies automatically do this step, like Caddy (see examples linked above).
# Stop and remove the old container
docker stop bitwarden
docker rm bitwarden
# Start new container with the data mounted
docker run -d --volumes-from bitwarden_data --name bitwarden -p 80:80 mprasil/bitwarden:latest
# Optionally remove the intermediate container
docker rm bitwarden_data
# Alternatively you can keep data container around for future updates in which case you can skip last step.
```
## Configuring bitwarden service
### Disable registration of new users
By default new users can register, if you want to disable that, set the `SIGNUPS_ALLOWED` env variable to `false`:
```sh
docker run -d --name bitwarden \
-e SIGNUPS_ALLOWED=false \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Note: While users can't register on their own, they can still be invited by already registered users. Read bellow if you also want to disable that.
### Disable invitations
Even when registration is disabled, organization administrators or owners can invite users to join organization. This won't send email invitation to the users, but after they are invited, they can register with the invited email even if `SIGNUPS_ALLOWED` is actually set to `false`. You can disable this functionality completely by setting `INVITATIONS_ALLOWED` env variable to `false`:
```sh
docker run -d --name bitwarden \
-e SIGNUPS_ALLOWED=false \
-e INVITATIONS_ALLOWED=false \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
### Enabling HTTPS
To enable HTTPS, you need to configure the `ROCKET_TLS`.
Note that you need to mount ssl files and you need to forward appropriate port.
Softwares used for getting certs are often using symlinks. If that is the case, both locations need to be accessible to the docker container.
Example: [certbot](https://certbot.eff.org/) will create a folder that contains the needed `cert.pem` and `privacy.pem` files in `/etc/letsencrypt/live/mydomain/`
These files are symlinked to `../../archive/mydomain/mykey.pem`
*Important: This does not apply to the mobile clients, which use push notifications.*
To enable WebSockets notifications, an external reverse proxy is necessary, and it must be configured to do the following:
- Route the `/notifications/hub` endpoint to the WebSocket server, by default at port `3012`, making sure to pass the `Connection` and `Upgrade` headers.
- Route everything else, including `/notifications/hub/negotiate`, to the standard Rocket server, by default at port `80`.
- If using Docker, you may need to map both ports with the `-p` flag
Example configurations are included in the [PROXY.md](https://github.com/dani-garcia/bitwarden_rs/blob/master/PROXY.md) file.
Note: The reason for this workaround is the lack of support for WebSockets from Rocket (though [it's a planned feature](https://github.com/SergioBenitez/Rocket/issues/90)), which forces us to launch a secondary server on a separate port.
### Enabling U2F authentication
To enable U2F authentication, you must be serving bitwarden_rs from an HTTPS domain with a valid certificate (Either using the included
HTTPS options or with a reverse proxy). We recommend using a free certificate from Let's Encrypt.
After that, you need to set the `DOMAIN` environment variable to the same address from where bitwarden_rs is being served:
```sh
docker run -d --name bitwarden \
-e DOMAIN=https://bw.domain.tld \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Note that the value has to include the `https://` and it may include a port at the end (in the format of `https://bw.domain.tld:port`) when not using `443`.
### Changing persistent data location
#### /data prefix:
By default all persistent data is saved under `/data`, you can override this path by setting the `DATA_FOLDER` env variable:
```sh
docker run -d --name bitwarden \
-e DATA_FOLDER=/persistent \
-v /bw-data/:/persistent/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Notice, that you need to adapt your volume mount accordingly.
#### database name and location
Default is `$DATA_FOLDER/db.sqlite3`, you can change the path specifically for database using `DATABASE_URL` variable:
```sh
docker run -d --name bitwarden \
-e DATABASE_URL=/database/bitwarden.sqlite3 \
-v /bw-data/:/data/ \
-v /bw-database/:/database/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Note, that you need to remember to mount the volume for both database and other persistent data if they are different.
#### attachments location
Default is `$DATA_FOLDER/attachments`, you can change the path using `ATTACHMENTS_FOLDER` variable:
```sh
docker run -d --name bitwarden \
-e ATTACHMENTS_FOLDER=/attachments \
-v /bw-data/:/data/ \
-v /bw-attachments/:/attachments/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Note, that you need to remember to mount the volume for both attachments and other persistent data if they are different.
#### icons cache
Default is `$DATA_FOLDER/icon_cache`, you can change the path using `ICON_CACHE_FOLDER` variable:
```sh
docker run -d --name bitwarden \
-e ICON_CACHE_FOLDER=/icon_cache \
-v /bw-data/:/data/ \
-v /icon_cache/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Note, that in the above example we don't mount the volume locally, which means it won't be persisted during the upgrade unless you use intermediate data container using `--volumes-from`. This will impact performance as bitwarden will have to re-download the icons on restart, but might save you from having stale icons in cache as they are not automatically cleaned.
### Changing the API request size limit
By default the API calls are limited to 10MB. This should be sufficient for most cases, however if you want to support large imports, this might be limiting you. On the other hand you might want to limit the request size to something smaller than that to prevent API abuse and possible DOS attack, especially if running with limited resources.
To set the limit, you can use the `ROCKET_LIMITS` variable. Example here shows 10MB limit for posted json in the body (this is the default):
```sh
docker run -d --name bitwarden \
-e ROCKET_LIMITS={json=10485760} \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
### Changing the number of workers
When you run bitwarden_rs, it spawns `2 * <number of cpu cores>` workers to handle requests. On some systems this might lead to low number of workers and hence slow performance, so the default in the docker image is changed to spawn 10 threads. You can override this setting to increase or decrease the number of workers by setting the `ROCKET_WORKERS` variable.
In the example bellow, we're starting with 20 workers:
```sh
docker run -d --name bitwarden \
-e ROCKET_WORKERS=20 \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
### SMTP configuration
You can configure bitwarden_rs to send emails via a SMTP agent:
```sh
docker run -d --name bitwarden \
-e SMTP_HOST=<smtp.domain.tld> \
-e SMTP_FROM=<bitwarden@domain.tld> \
-e SMTP_PORT=587 \
-e SMTP_SSL=true \
-e SMTP_USERNAME=<username> \
-e SMTP_PASSWORD=<password> \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
When `SMTP_SSL` is set to `true`(this is the default), only TLSv1.1 and TLSv1.2 protocols will be accepted and `SMTP_PORT` will default to `587`. If set to `false`, `SMTP_PORT` will default to `25` and the connection won't be encrypted. This can be very insecure, use this setting only if you know what you're doing.
### Password hint display
Usually, password hints are sent by email. But as bitwarden_rs is made with small or personal deployment in mind, hints are also available from the password hint page, so you don't have to configure an email service. If you want to disable this feature, you can use the `SHOW_PASSWORD_HINT` variable:
```sh
docker run -d --name bitwarden \
-e SHOW_PASSWORD_HINT=false \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
### Disabling or overriding the Vault interface hosting
As a convenience bitwarden_rs image will also host static files for Vault web interface. You can disable this static file hosting completely by setting the WEB_VAULT_ENABLED variable.
```sh
docker run -d --name bitwarden \
-e WEB_VAULT_ENABLED=false \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Alternatively you can override the Vault files and provide your own static files to host. You can do that by mounting a path with your files over the `/web-vault` directory in the container. Just make sure the directory contains at least `index.html` file.
```sh
docker run -d --name bitwarden \
-v /path/to/static/files_directory:/web-vault \
-v /bw-data/:/data/ \
-p 80:80 \
mprasil/bitwarden:latest
```
Note that you can also change the path where bitwarden_rs looks for static files by providing the `WEB_VAULT_FOLDER` environment variable with the path.
### Other configuration
Though this is unlikely to be required in small deployment, you can fine-tune some other settings like number of workers using environment variables that are processed by [Rocket](https://rocket.rs), please see details in [documentation](https://rocket.rs/guide/configuration/#environment-variables).
## Building your own image
Clone the repository, then from the root of the repository run:
```sh
# Build the docker image:
docker build -t bitwarden_rs .
```
## Building binary
For building binary outside the Docker environment and running it locally without docker, please see [build instructions](https://github.com/dani-garcia/bitwarden_rs/blob/master/BUILD.md).
## Available packages
### Arch Linux
Bitwarden_rs is already packaged for Archlinux thanks to @mqus. There is an [AUR package](https://aur.archlinux.org/packages/bitwarden_rs) (optionally with the [vault web interface](https://aur.archlinux.org/packages/bitwarden_rs-vault/) ) available.
## Backing up your vault
### 1. the sqlite3 database
The sqlite3 database should be backed up using the proper sqlite3 backup command. This will ensure the database does not become corrupted if the backup happens during a database write.
This command can be run via a CRON job everyday, however note that it will overwrite the same backup.sq3 file each time. This backup file should therefore be saved via incremental backup either using a CRON job command that appends a timestamp or from another backup app such as Duplicati.
### 2. the attachments folder
By default, this is located in `$DATA_FOLDER/attachments`
### 3. the key files
This is optional, these are only used to store tokens of users currently logged in, deleting them would simply log each user out forcing them to log in again. By default, these are located in the `$DATA_FOLDER` (by default /data in the docker). There are 3 files: rsa_key.der, rsa_key.pem, rsa_key.pub.der.
### 4. Icon Cache
This is optional, the icon cache can re-download itself however if you have a large cache, it may take a long time. By default it is located in `$DATA_FOLDER/icon_cache`
## Running the server with non-root user
The root user inside the container is already pretty limited in what it can do, so the default setup should be secure enough. However if you wish to go the extra mile to avoid using root even in container, here's how you can do that:
1. Create a data folder that's owned by non-root user, so you can use that user to write persistent data. Get the user `id`. In linux you can run `stat <folder_name>` to get/verify the owner ID.
2. When you run the container, you need to provide the user ID as one of the parameters. Note that this needs to be in the numeric form and not the user name, because docker would try to find such user defined inside the image, which would likely not be there or it would have different ID than your local user and hence wouldn't be able to write the persistent data. This can be done with the `--user` parameter.
3. bitwarden_rs listens on port `80` inside the container by default, this [won't work with non-root user](https://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html), because regular users aren't allowed to open port bellow `1024`. To overcome this, you need to configure server to listen on a different port, you can use `ROCKET_PORT` to do that.
Here's sample docker run, that uses user with id `1000` and with the port redirection configured, so that inside container the service is listening on port `8080` and docker translates that to external (host) port `80`:
```sh
docker run -d --name bitwarden \
--user 1000 \
-e ROCKET_PORT=8080 \
-v /bw-data/:/data/ \
-p 80:8080 \
mprasil/bitwarden:latest
```
## Differences from upstream API implementation
### Changing user email
Because we don't have any SMTP functionality at the moment, there's no way to deliver the verification token when you try to change the email. User just needs to enter any random token to continue and the change will be applied.
### Creating organization
We use upstream Vault interface directly without any (significant) changes, this is why user is presented with paid options when creating organization. To create an organization, just use the free option, none of the limits apply when using bitwarden_rs as back-end API and after the organization is created it should behave like Enterprise organization.
### Inviting users into organization
The invited users won't get the invitation email, instead all already registered users will appear in the interface as if they already accepted the invitation. Organization admin then just needs to confirm them to be proper Organization members and to give them access to the shared secrets.
Invited users, that aren't registered yet will show up in the Organization admin interface as "Invited". At the same time an invitation record is created that allows the users to register even if [user registration is disabled](#disable-registration-of-new-users). (unless you [disable this functionality](#disable-invitations)) They will automatically become "Accepted" once they register. From there Organization admin can confirm them to give them access to Organization.
### Running on unencrypted connection
It is strongly recommended to run bitwarden_rs service over HTTPS. However the server itself while [supporting it](#enabling-https) does not strictly require such setup. This makes it a bit easier to spin up the service in cases where you can generally trust the connection (internal and secure network, access over VPN,..) or when you want to put the service behind HTTP proxy, that will do the encryption on the proxy end.
Running over HTTP is still reasonably secure provided you use really strong master password and that you avoid using web Vault over connection that is vulnerable to MITM attacks where attacker could inject javascript into your interface. However some forms of 2FA might not work in this setup and [Vault doesn't work in this configuration in Chrome](https://github.com/bitwarden/web/issues/254).
## Usage
See the [bitwarden_rs wiki](https://github.com/dani-garcia/bitwarden_rs/wiki) for more information on how to configure and run the bitwarden_rs server.
## Get in touch
To ask a question, offer suggestions or new features or to get help configuring or installing the software, please [use the forum](https://bitwardenrs.discourse.group/).
To ask an question, [raising an issue](https://github.com/dani-garcia/bitwarden_rs/issues/new) is fine, also please report any bugs spotted here.
If you spot any bugs or crashes with bitwarden_rs itself, please [create an issue](https://github.com/dani-garcia/bitwarden_rs/issues/). Make sure there aren't any similar issues open, though!
If you prefer to chat, we're usually hanging around at [#bitwarden_rs:matrix.org](https://matrix.to/#/#bitwarden_rs:matrix.org) room on Matrix. Feel free to join us!
The hooks in this directory are used to create multi-arch images using Docker Hub automated builds.
Docker Hub hooks provide these predefined [environment variables](https://docs.docker.com/docker-hub/builds/advanced/#environment-variables-for-building-and-testing):
* `SOURCE_BRANCH`: the name of the branch or the tag that is currently being tested.
* `SOURCE_COMMIT`: the SHA1 hash of the commit being tested.
* `COMMIT_MSG`: the message from the commit being tested and built.
* `DOCKER_REPO`: the name of the Docker repository being built.
* `DOCKERFILE_PATH`: the dockerfile currently being built.
* `DOCKER_TAG`: the Docker repository tag being built.
* `IMAGE_NAME`: the name and tag of the Docker repository being built. (This variable is a combination of `DOCKER_REPO:DOCKER_TAG`.)
The current multi-arch image build relies on the original bitwarden_rs Dockerfiles, which use cross-compilation for architectures other than `amd64`, and don't yet support all arch/database/OS combinations. However, cross-compilation is much faster than QEMU-based builds (e.g., using `docker buildx`). This situation may need to be revisited at some point.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.