Simple and secure Password Management in the Shell
Today, secure password management tools are a necessity especially in a professional environment. Unfortunately, many users still either choose bad passwords or they store them insecurely (on a piece of paper or in a text file). The perception of password management tools as being inconvenient probably is one of the main causes for this behaviour. In this article we present an easy way to set up a convenient and secure password management system that can be used from the shell.
Motivation
The goal of this article is to show a workflow for a secure and fast password management in a linux environment that can be accessed both from a command line and from a graphical user interface. The main audience for this article are users that already know their way around the shell or are willing to get to know it. For desktop users who prefer purely graphical solutions, there are good alternatives out there, e. g. Keepass for linux and windows.
Accessing the passwords through the shell is especially useful when we want to combine password management with other commands or when we are using an ssh terminal to access a machine without a gui.
The workflow we present allows a very fast access of all stored passwords. The passwords are encrypted with a gpg key, so you only have to remember one pass phrase to access all your passwords, which are stored in a simple directory structure inside the user's home directory. All passwords have to be entered into the password storage once. Old passwords can be restored through the usage of a git repository.
Benefits
- Allows the use of long, complex, and secure passwords, since they don't have to be remembered or typed
- Passwords are encrypted
- Fast access
- Long lists of passwords are stored in a simple structure
- No password lists in unencrypted files or on sheets of paper
- Passwords can be encrypted with the user's public gpg key and transferred securely (e.g. via mail)
- A centrally stored and secured password store that can be accessed from multiple work environments.
Drawbacks
- If a person gains access to the user's private gpg key, they can see all the user's passwords
- The tools have to be installed once on all working environments. As a solution you could set up an ssh server and access your passwords through an ssh terminal.
- There's a small security risk, if your gpg agent buffers your private gpg-key.
Requirements
The Operating System should be any linux distribution. The required tools are also available on BSD, MacOS X or other UNIX-derivatives, but we assume a working distribution of linux.
There are useful installation guides and references for all of the tools in the arch linux wiki.
The following tools are part of the workflow:
pass
The command line tool pass
provides the central logic for the password store and the access of it.
GnuPG
GnuPG offers command line tools for encrypting the password store through OpenPGP.
dmenu (optional)
dmenu
uses X Window System to allow fast selection from an arbitrary list through a search field.
The installation of pass
provides the command line tool passmenu
, which uses dmenu
to list the passwords.
git (optional)
The command line tool git
is a popular distributed version control system for software projects. The passwords are stored as a git project, which allows accessing from different locations and restoring old versions.
Setup
All tools should be available in the respective distro’s package manager. The following setup instructions assume that all tools are installed and ready to use.
Initializing the password store
pass init "somebody@example.com"
Generates a new password store and uses the gpg key pair with the ID somebody@example.com
to encrypt and decrypt the passwords.
If no gpg key pair has been generated, this can be done using the following command:
gpg --gen-key
In case a password was selected for the new private gpg key, the user will be prompted to enter it when accessing the passwords. Caution: Don't forget to store the gpg keypair securely. If the key gets lost, the password store is unusable.
Initialize a git repository
pass git init
pass git remote add origin "https://github.com/somebody/password-store.git"
pass git push
Initializes a local git project for the password store and sets the path to the remote storage on which the repository will be stored.
Now a git commit will be generated every time the password storage is changed via a pass
command.
Caution: The names of the password entries should not be too telling, since the files will be named after them. It's recommended to store the git repository on a local network, a private server or a private github.com repo.
GPG agent
GPG agent is a GnuPG program running in the background and buffering private gpg keys, so they don't have to be entered on every single password retrieval.
The file ~/.gnupg/gpg-agent.conf
contains all options for the agent.
Here are some useful configurations:
# Sets the lifetime of the last password request to five hours. After that, the /private gpg key/
# must be entered again.
default-cache-ttl 18000
# Sets the maximum lifetime of the buffered /private gpg key/ to 24 hours.
max-cache-ttl 86400
Workflow
Entering passwords
pass insert email/somebody@example.com/smtp
Adds an entry smtp
in the directory email/somebody@example.com
.
Here email
is a directory that holds all the email-accounts.
smtp
is the name of the account.
This generates a file smtp.pgp
in the directory email
.
The user is prompted to enter the password. If necessary, the private gpg key must be entered.
pass insert email/somebody@example.com/smtp < password.txt
Reads the content of password.txt
and stores it as the new password.
Retrieving passwords
pass email/somebody@example.com/smtp
Writes the retrieved password to stdout.
pass -c email/somebody@example.com/smtp
Writes the retrieved password to the clipboard for 45 seconds.
passmenu -l 20
Displays a list of (up to) 20 entries and a search box. A global shortcut can be assigned to this command.
Moving passwords
pass mv email/somebody@example.com/smtp email/somebody@example.com
The password store is located at .password-store
in the home directory of the current user.
Generating passwords
pass generate email/somebody@example.com/smtp 12
Generates a new password of length 12. The password manager offers multiple options. One useful option might be --no-symbols
, allowing only allows alphanumeric characters.
Forwarding passwords
First of all, we need the recipient's public key (recipient.key
). It can be imported with this command:
gpg --import recipient.key
This key is now stored in the keychain and you don't have to import it again. Now we encrypt the password we want to forward. Here we chose the password stored in somebody@example.com
. The email address somedoby@example.com
identifies the private gpg key of the sender, which we used to initialize the password store, while recipient@example.com
identifies the recipient's public gpg key (which we just imported).
pass email/somebody@example.com/smtp | gpg -e -a -u "somebody@example.com" -r "recipient@exapmle.com" > password.txt
The file password.txt
now contains the encrypted password. Now we can send this file i.g. per e-mail. The recipient can decrypt this message using his private gpg key:
gpg -d password.txt
The correct private gpg key is selected automatically, and the encrypted password is written to stdout.
Saving the password store
pass git pull
pass git push
Pulls the current state of the remote store to the local store. Subsequently stores the local changes in the remote store.
pass git log
Displays all changes to the local password store in the form of commit messages.