Recently I decided to start using a password manager as I’ve found myself caring more and more about security lately. Like many others I had the bad habit of using the same few passwords across many sites and with the multitude of security breaches and password dumps we’ve seen this year (I’m pretty sure that you could find my old DropBox password in there if you looked hard enough.) has motivated me to correct that. So, I’ve taken it upon myself to “up my game” and practice what my good friend Jason Crosby preaches (turns out he isn’t just a crazy old sysadmin).
A quick side note about this guide
I assume in this guide that you’re running in a Linux, Mac, BSD, or some other Unix-like system running bash or a comparable shell. On Windows I have no idea how to set all this up, there is a Windows client for password-store that I can attest to working quite well but I already had my password store set up with a git repo etc. before I tried using it.
So what is a password manager?
Some of you may be wondering what a password manager is and I don’t blame you. A password manager is a piece of software that will store your passwords in an encrypted form and tie those to specific websites so you don’t have to remember them. The benefit of this is you can then store very complex passwords which are unique to each site making any one security breach mean nothing because they cannot use that info to get access to your other accounts, while the complexity of the passwords will thwart most if not all attempts to even get the password for the breached site. You also get the convenience of only needing to remember one password as you will use a “master password” to unlock all of the other randomized passwords.
There are a lot of password managers out there to try, some which cost money and some that don’t, and unfortunately none of the hosted options are immune security breaches themselves. This led me to look for a self hosted solution that was simple to understand and flexible so at least if it got breached it was my own fault and hadn’t cost me any money. This is when I stumbled upon pass
What is pass?
Stealing from the password-store website:
passmakes managing individual password files extremely easy. All passwords live in
passprovides some nice commands for adding, editing, generating, and retrieving passwords. It is a very short and simple shell script. It’s capable of temporarily putting passwords on your clipboard and tracking password changes using git.
The important thing to note is that it’s based on the Unix philosophy and is a command line tool which means that it’s simple to grok and easy to extend.
Pass itself is little more than a set of scripts wrapping gpg and git but to me that is its strength because those are tools which I’m already familiar with. Enough rambling however, lets get to the guide.
Step 1. Setting up gpg
GPG can seem extremely complicated at first and that’s because it is, but once it’s set up you rarely have to mess with it again. Yay!
GPG works in much the same way an SSH key or an SSL cert works, you have a public key which encrypts things and a matching private key which decrypts those things. This means it’s safe to give out your public key but not your private key. Here is a simplified explanation:
public-key.gpg + "some text" = <encrypted garbage>private-key.gpg + <encrypted garbage> = "some text"however you cannot do this:public-key.gpg + <encrypted garbage> != "some text"
So first things first we need to generate a gpg key:
Fill out the prompts with your own information, for the first question (kind of key) the default is best but for key length go ahead and pick 4096, this will future proof you a bit and is plenty practical given the speed of modern computers. Make sure you use your full name and email when prompted. We will use the email to reference this key in later steps.
When prompted for a password pick something that you will for sure remember, as this is your “master password” and will be used to unlock your other passwords once you set them up. If you forget the master password after you’ve set all this up you’re going to have a bad time.
Step 2. Set up pass
Now that we have a public and private key to encrypt and decrypt with we can set up our password store. First run:
pass init firstname.lastname@example.org
email@example.com with your email that you used when setting up your gpg key. Next let’s set up git:
pass git init
This has turned our password store into a git repository, if you’re unsure about what that means fear not because pass takes care of the hard parts of git for us and we’ll leave the bits we need to know until later. If you really want to know about using git I recently gave a talk at Ohio Linuxfest which would be a good starting point. Toot toot goes my horn.
Now we can add our first password, let’s create a test password:
pass generate test 10
The way generate works is that pass takes first the name of the password (often the domain name such as google.com) and then the length of password you want it to generate. There are multiple flags you can give generate to make it conform to whatever password rules you would like, you can view possible options with
pass generate --help
You’ll now be able to do a listing of your password store by just running
pass with no arguments:
home/chasinglogic λ pass
If you don’t see output like the above try running through the steps above again to make sure you didn’t miss anything. If that still doesn’t work drop a comment below and I’ll try to help.
Retrieving a password
If you want to see the password simply tell pass which one you want and enter your master password when prompted:
If you would like it copied to your clipboard automatically you can use the
pass -c test
All pass is doing here is storing the generated file in an encrypted plain text file in a folder located at
$HOME/.password-store and in case you were wondering, yes since it’s just an encrypted plain text file you can store whatever you want in there! Such as notes etc. I often use mine to keep encrypted IP addresses of servers and what ports they are using.
Since we no longer need our test password lets get rid of it:
pass rm test
There you go! That’s all you need to know to effectively use
pass for basic use cases. I recommend checking out the main site since they link to the android, desktop, ios apps, and browser plugins.
If you want to sync to another device you just need to copy the
$HOME/.gnupg to the target machine, however there is a much better method that allows you to sync continuously without using dropbox or a flash drive but requires a little more setup work up front which I will go over below.
Step 3. Git
First things first, you’ll need a server that has a publically accessible IP address and that you have ssh access to. I recommend using DigitalOcean as it’s probably the easiest way to get up and running.
Once you have that server you need to set up git. I’m going to assume that you’re running Ubuntu 16.04 but if you’re on another Linux just replace apt with your package manager and most of this should just work.
First things first lets ssh into the server and install git:
ssh <your server ip>
sudo apt install -y git
Now create a git user who will hold everything (you could even use pass to set this users password!):
sudo adduser git
Now on your local machine generate an ssh key pair, just accept all the defaults, then install that for the new git user:
ssh-keygen -t rsa
ssh-copy-id git@<your server ip>
Once that’s done try ssh’ing into the server directly as that use to test the key, if you’re prompted for a password you’ve done something wrong and will need to consult your ssh config. Here is an excellent DigitalOcean guide on setting up ssh with keys. It’s for FreeBSD but will work on Linux the same.
Creating the git repo
Now that ssh is all set up you need to create the git repo, I keep everything in the git users home folder so if you’ve just ssh’d in as the git user you can run:
git init --bare pass-repo
This will create a folder called pass-repo which will have a lot of auto generated git files in it, we can ignore all of that we’re done working on the server side for now.
Back to our local machine
On your local machine you just need to set up the remote for your password store’s git repo using the following command
pass git remote add origin ssh://git@<your server's ip>:/home/git/pass-repo
You can then start pushing to and pulling from the remote using
pass git push origin master and
pass git pull origin master respectively. Pass will take care of the rest of the git commands for you, but again if you ever get stuck you can either watch my talk or try Github’s excellent interactive tutorial to learn more about git.
If you’re thinking “Ok Mat I have this repo and stuff but how do I get the store on another machine?” then this section is for you. I’ll lay out what you need to do to get another machine up and running with your new repo.
First things first you’ll need your gpg private key on the new box so go ahead and export it from the first machine you set up:
gpg2 --export-secret-keys > secret.gpg
This will create a file called secret.gpg which will be your gpg secret key. DO NOT PUT THIS ANYWHERE PUBLICALLY VISIBLE (I.E. NOT ON YOUR GIT REPO). If you lose this it makes it possible for someone to compromise your password store, even if the secret key is password protected.
Next you need to move that file to the target machine, I’ll assume you’ve installed git, pass, and gpg on the target machine since you’ve followed this guide so far. If you need a refresher you can always reference the beginning of this guide.
Once that file is on the target machine you can import it using this:
gpg2 --import /path/to/secret.gpg
Once you have the secret key imported you can then get your password store by
git clone ing it like so:
git clone ssh://git@<your server's ip>:/home/git/pass-repo ~/.password-store
Once that’s done all of your pass commands will work just like you expect!
Or just the beginning? If you come up with any cool / creative ways to use pass please let me know, I’ve literally fallen in love with this tool. As a final note for all the hackers in the room there is an Emacs package for pass