Bitwarden is available for Cloud, Windows, Mac, Linux, iPhone, iPad and Android. Bitwarden and LastPass are two of the best password managers around, offering excellent free plans, solid security and a long list of features. When it comes to free password management, it doesn’t.
Aug 07, 2018•#productivity,#securityI have been looking to replace my password management setup for a few monthsnow. Up until now I was using KeePassXC, but I never got around to putting inthe work to make it work properly on mobile.
I understand that the standard solution is to just get the file synced on yourphone using Dropbox and then install a mobile app which can read the file off ofDropbox. But the idea that all my passwords are in one single file somewhere onthe internet (cloud, if you will) is a bit disturbing.
Incidentally, this is also the reason I never got around to using 1password,Lastpass, or other cloud-hosted password managers.
This is not to discount the work that the security folks at these companies areputting in on a daily basis to make their services secure. And I know that mypasswords file is encrypted. I've just seen enough mistakes happen and I'd liketo avoid being a part of one.
Requirements
My requirements were fairly simple. I wanted something that
- is open-source
- allows self-hosting
- works on mobile
.. in that order.
Turns out that just these 3 requirements narrowed down the search toBitwarden.
Bitwarden
Bitwarden is open source. There's a core
server written in C# and then thereare multiple client apps (iOS, Android, desktop).
Bitwarden Host Dropbox
The backend appears quite heavy weight. Being written in C# and talking to a SQLserver installation, it's not exactly what I would call 'deployment friendly'.Luckily, they provide a Docker image which you can use to self-host the wholething.
While this works on a modern machine, I wanted to run Bitwarden on a spareRaspberry Pi connected to my home network where the system requirements are abit less than what the Docker image requires.
It turns out that I'm not the first person to run into this problem. @jcsalready wrote a Ruby server which is API-compatible with the 'official'Bitwarden backend. This implementation is very lightweight, and completelydoable for the Pi. So all I had to do was create a new bitwarden
user on thePi, install rvm
, git clone
the repository, and then start the serverprocess.
The only problem left now was setting up a static IP for the Pi so that thedesktop client on my laptop and the iOS app on my phone know the(static & private) IP address they should be connecting to. Luckily my modemsupported allocating the same IP to devices based on their MAC addresses so thiswas also easy.
Migrating from KeePassXC
rubywarden includes a script to import existing KeePassXC database files, andit worked without any problems. The script somehow didn't handle my KeePassXCfolders very well. So an entry called 'Google' in the 'Internet' folder wasimported as 'Internet/Google'. Those slashes look pretty annoying, so I tooksome time out to delete some unused passwords and organize the rest intofolders.
Migration was a non-issue, I would say.
Caveats
The only caveat with this system that I can think of right now is that whenyou're not at home, you won't be able to save/edit/delete passwords. You'll beable to read just fine, but editing won't work.
The reason is that your client apps are configured to talk to a private IPaddress (of the Pi in this case). But so far I haven't had the need tosave/edit/delete passwords when I'm outside. And reading them works just fine.
If this is important for you, then this is probably the price you pay forkeeping the passwords on a machine you can physically look at.
But overall, I find this setup quite nice to work with.
I’ve been using anOpenBSDlaptopas my workstation a lot more lately, probably because most of my hardware justworks now and I don’t have to think too much about it.The touchpadworkswhen I touch it, I can be confident that when I close the lid, the laptopwill fully suspend and then fully resume again when I open it,WiFi works all throughout my house (although it’s not terribly fast), and myweb browseris fast and stable.What amazing times we live in.
In the past, one thing that frequently kept me going back to myMac,aside fromiOS and Androiddevelopment, was1Password.I have a ton of logins for websites and servers, and because mybrowsersare all configured toclear cookiesfor most websites after I close their tabs,I need frequent access to passwords synced across my laptops and phones, and1Password has great apps for all of those except OpenBSD.
All of 1Password’s syncing currently works through my Dropbox account.My Mac has 1Password configured to store its encrypted database in my localDropbox directory, Dropbox does its automatic syncing of that directory to theirservers, and 1Password on my phone uses Dropbox’s API to pick up any changedfiles.It’s been reliable for years, I have local versioned backups of my database, itworks when my devices are offline, and I know I can access that data years in thefuture.
Using 1Password on OpenBSD
To bring OpenBSD into the mix, there are 3rd-party command-line apps which canread local 1Password files such as1passwritten in Go.Getting the 1Password files onto OpenBSD was left as an exercise to the reader, sending me down the rabbit hole of trying to add OpenBSD support tovariousFUSE-basedpackages that could provide a local filesystem view of my Dropbox directory.I managed tohackone of them into semi-working shape, but eventually I gave up and usedrcloneto do one-way fetching of my Dropbox directory on demand.
While this allowed me to at least view and copy passwords, the process was lessthan ideal.Browsing in Firefox, I’d have to open a terminal, type1pass copy <some website>
,choose the right one,and then go back to Firefox and paste it in the proper field.Tedious, error-prone, vulnerable to phishing, and now my password is hanging outin clear-text on the clipboard.
A Firefox add-on calledPasscardsfrom the developer of 1pass seemed encouraging, as it did Dropbox syncing on itsown and supported auto-filling passwords in the browser, but I could never get it to work.The hard-coded Dropbox API token in the add-on doesn’t work and the mess ofNode dependencies to build a local version failed miserably on OpenBSD.
Bitwarden Dropbox
1Password Lock-In
Meanwhile, AgileBits, the80-personcompany developing 1Password, has been pushing their new hosted,subscription-based model for 1Password going forward.Instead of users being in control of their data files, 1Password will store themon AgileBits’ servers and users pay a monthly subscription fee for the privilege,forever.
After effect cs6 for mac. I’m anapp developer,I get it.A big company can’t sustain development of a product that users only pay for once.However, I’ve paid for 1Password and all of its major version upgrades, and the$10 or whatever it was to unlock the “pro” features of the iOS app.I’m not opposed to paying money for apps, or for upgrades, or even for asubscription, but I don’t want to pay to host my passwords on AgileBits’ servers.Security concernsaside, there is an issue of lock-in and now having to make my OpenBSD hacks workwith AgileBits’ new API (is there even one?) instead of just accessing and backing up files from Dropbox.
Since I wasn’t sure how long 1Password would keep working with itsnon-subscription-based syncing and I was still missing first-class OpenBSDsupport, I started looked into migrating to something else.
Finding Bitwarden
The main competitor to 1Password isLastPass,which looks nice and works well as a standaloneFirefox add-onon OpenBSD, but it has the same lock-in problem and server-sidesecurity concernsas 1Password.
KeePassis a popular open-source alternative but its use case seems focused on a singlemachine.I don’t need a stand-alone GUI and I do need browser extensions and mobile appsthat can all sync reliably.And honestly, looking at theirpluginspage left me with a bit of decision fatigue: which ones are good, which ones aresecure, which ones are still maintained?Does the browser extension have to read files from my home directory or talk toa daemon that my unprivileged Firefox won’t be able to do?
There are various command-line concoctions such aspasswhich stores PGP-encrypted files in a Git repo, but that doesn’t improve mysituation over 1Password.I would still have to manually look up passwords and copy them to the clipboard.These command-line packages also lack mobile apps and syncing.
Eventually I stumbled uponBitwardenwhich is similar to LastPass but is entirelyopen-sourceand its primary developer is funded by users paying for subscriptions to storetheir data on Bitwarden’s servers.However, all of their browser extensions and phone apps supportsetting a custom API URLbefore logging in, to allow for private installations.The iOS app and Firefox extension that I tried out looked fairly well polished,but I was more concerned with it being an open platform so I could fix bugs,add features, and host my own data.
Unfortunately, the open-sourcebackendfor these apps is written in .NET and expects to talk to a Microsoft SQL Server,requiring a big Docker image to deploy a private installation on Linux.
Since I was expecting to run my own API server on OpenBSD without all of thatoverhead, I decided to write my own compatible server.Sadly, there is no documentation on Bitwarden’s API (outside of its .NET code) soI was not even able to figure out what my server would need to provide.
Rubywarden
Rather than wade through lots of .NET code, I decided to go for a black-boxapproach.I wrote asimple proxyin Sinatra that I could point the Bitwarden Firefox add-on to as its private APIURL.The proxy would intercept each request, print it out to the console, then send itto Bitwarden’s actual API, print out the response, and send it back to the Firefoxadd-on.
With that tool I was able todocument all of the API calls that the Firefox extension and iOS app made and the responseeach was expecting.The encryption key derivation scheme used to actually encrypt and decrypt allof the data took a bit longer to figure out, but because everything is opensource, I was able to read theJavascript codeof the Firefox add-on to understand what it was doing to encrypt a string with agiven password.
With my documentation in-hand, I wrote anew Sinatra serverthat implements all of the API calls needed by the Firefox extension and iOS app.I deployed it to a server with Unicorn behind nginx, and used Let’s Encrypt to geta TLS certificate for it.
My API server is now small and easy to understand, it has a much smaller attacksurface than the .NET version, and all of my data is stored in a SQLite databasethat I can backup and version with cp
.No lock-in, a first-class experience on OpenBSD and Firefox, and I feel betterunderstanding the details of how my data is encrypted.
Migrating from 1Password
The Bitwarden web client (not the Firefox add-on) supports directly importing1Password data files for users subcribed to Bitwarden’s hosted service.Since I’m not using Bitwarden’s web client, I wrote a command-line1Password conversion toolthat can read a 1Password Interchange Format file, encrypt the passwords usingBitwarden’s format, and insert them into the database that bitwarden-ruby uses.
After importing more than 700 logins from my 1Password file, I noticed that theBitwarden Firefox add-on was quite sluggish on OpenBSD.Unlocking it with my master password would take four or five seconds to parseeverything before showing the large list of logins.
Bitwarden Vs Dropbox
Since this data was years of migrated 1Password installations and otherpassword stores, I decided to spend a few hours cleaning it up.After deleting some 300 logins and moving others into various folders, the add-on seems a bit snappier though still leaves something to be desired.I’d also like to change its keyboard shortcut to Alt+ like Cmd+ is for1Password, but Firefox’s new WebExtension system doesn’t support changing thesehard-coded keyboard shortcuts yet like Chrome does.
At this point I’ve been using Bitwarden’s iOS app and Firefox extensionexclusively.
My server now hasTOTP support,and everythingseems to be working well.
Fetch the Rubywarden code from GitHubif you want to check it out.