Unlocker is a keychain and a CLI credentials manager. Useful when you use a terminal often than GUI applications for remote connections (e.g. databases, SSH, rsync). It can store passwords and private keys. It comes with additional helper shells to encrypt your secrets and quick connect to servers passwordless.
- cPython >= 2.7.12
- pip >= 9.0.2
$ pip install unlocker
Build from sources
$ python setup.py install
This software is in a beta phase, it is highly recommended to keep a copy of your credentials in a safe place! Also, please report any faulty runtime or unexpected behavior of Unlocker. Thank you!
Unlocker is a simple storage for passwords and private keys. The main purpose of unlocker is to be a manager for such data and give CRUD-like options to add, update, read and delete sets of credentials.
Stored credentials are kept inside a keychain-type database. In unlocker context, the keychain storage is called secrets and has a versioning system. Secrets stored in older versions of Unlocker may not be directly compatible, thus it's needed to migrate them before using. All stored sensible credentials are compressed and encoded.
As a side feature, Unlocker has additional helper shell scripts that make it easier to use in day-to-day life. These scripts can be installed directly from unlocker's addons option:
unlocker install. The result of this operation are two (2) new scripts in your
~/bin directory: an
unlock wrapper script to make passwordless connections to known servers; and a
lock script to encrypt your secrets.
Notice: if for any reasons you have scripts named
unlock in your
~/bin directory, unlocker will abort the installation of these scripts.
$ unlocker _ _ _ _ _ __ | | ___ ___| | _____ _ __ | | | | '_ \| |/ _ \ / __| |/ / _ \ '__| | |_| | | | | | (_) | (__| < __/ | \__,_|_| |_|_|\___/ \___|_|\_\___|_| Unlocker - CLI credentials manager Usage: init Create local keychain list List known hosts from keychain recall Retrieve secrets by name or signature (slower than lookup) forget Forget secrets by name or signature (slower than remove) append Add new set of credentials to keychain update Update password or private key to keychain remove Remove credentials from keychain lookup Find password for provided host, port and user install Install helper scripts migrate Migrate secrets to current unlocker version
||Create the keychain on the current machine inside your
||Displays table-like list of existing credentials from keychain|
||Update secrets or bounce server for an existing server|
||Remove set of credentials from keychain|
||Like remove, but handles names and signatures|
||Lookup secrets from keychain|
||Like lookup, but handles names and signatures|
||Installs two (2) new POSIX shell scripts as unlocker wrappers|
||Migrate secrets to current version of unlocker|
Features and conventions
Unlocker comes with a few tricks out of the box, it is written with some conventions in mind and tries to make it easier for developers to follow a defined "way of doing things" and work faster, although it's not mandatory and ignoring this section does not affect the usage of unlocker in any way.
Named servers with tags
Give your server a name otherwise it will receive a random string as name. You know better what's the purpose of each server. Follow this small convention when naming a server:
tag:the_name_you_want where tag is something unlocker recognizes as being part of the name. If you set the tag
prod to your server, unlocker will warn you before connecting to this server (e.g. in case you made a mistake when typing the name) and requires your direct confirmation to continue (this means you have to press a key to continue).
$ unlock ssh live:that_cool_server # unlocker recognizes "live" tag and gives a heads up Notice: Production server ahead! Notice: You are connecting to a LIVE production server... Notice: Proceed with caution Connecting to ssh://username@localhost:22 (live:that_cool_server) using password Press any key to continue or ^C to exit...
Unlocker does't make a difference between one user or another, it just keeps your credentials for later use. But for a developer or for a sysadmin there's a huge difference between a
root user and the next one. Whenever you attempt to connect to a server with a
root user, unlocker will notify you and it requires your direct input as a confirmation (just as the
live tag on named servers, it means a press of a key). The
root user will always be the last option for an ambiguous connection.
$ unlock ssh localhost # you haven't specified what user to use... # unlocker will query all possible options # from the known servers and choose the first # non-root user or fallback to root and alert ... $ unlock ssh root@localhst Notice: Root user ahead! Notice: You are connecting to a server with ROOT privileges... Notice: Proceed with caution Connecting to ssh://root@localhost:22 using password Press any key to continue or ^C to exit...
When connecting via a named server (e.g.
live:that_cool_server) unlocker has a special feature of detecting protocol mistakes. If you, for some whatever reason, type
mysql instead of
ssh for your named server and there is no
mysql known connection for that named server, then unlocker can detect other supported protocols and advise you to switch.
$ unlock redis live:that_cool_server You requested redis, but only ssh is available for this server Switch to ssh? [yN] y
Unlocker can save credentials to a server, but it can also save a jump server for that connection to work. Mostly useful when you have connections on localhost servers (such as databases binded to
localhost on a VPC) or are behind a firewall and accessible only though SSH tunnels. E.g. if you have a MySQL server binded to 127.0.0.1 on your my.server.tld, then you have to save the SSH server first, afterwards you'll be able to get the signature of the server and add the MySQL connection as well.
$ unlocker append -h my.server.tld -p 22 -u an_user -s ssh -a privatekey -n live:that_cool_server Path to private key: /tmp/secret.key Secrets successfully added! email@example.com:22 # this will be the IP address of my.server.tld $ unlocker list hash | bounce | protocol | ipv4 | port | hostname | user | friendly name ========== | ========== | ======== | =============== | ===== | ==================== | ============= | ==================== fa565262 | ~ | ssh | 0.0.0.0 | 22 | my.server.tld | an_user | live:that_cool_server
$ unlocker append -h localhost -p 3306 -u another_user -s mysql -a password -n db:my_mysql_server -j fa565262 Password: ***** Secrets successfully added! firstname.lastname@example.org:3306 $ unlocker list hash | bounce | protocol | ipv4 | port | hostname | user | friendly name ========== | ========== | ======== | =============== | ===== | ==================== | ============= | ==================== fa565262 | ~ | ssh | 0.0.0.0 | 22 | my.server.tld | an_user | live:that_cool_server 7c2ffc13 | fa565262 | mysql | 127.0.0.1 | 3306 | localhost | another_user | db:my_mysql_server
Add localhost MySQL server and quick connect
$ unlocker install OK $ unlocker append -h localhost -p 3306 -u user -s mysql -a password -n dev:mysql_server Password: <your password> ... Secrets successfully added! email@example.com:3306 ... $ unlock mysql dev:mysql_server OR $ unlock mysql user@localhost OR $ unlock mysql localhost
Save server with private key
$ unlocker append -h private.server.tld -p 22 -u root -s ssh -a privatekey -n prod:server Path to private key: /var/keys/rsa.pk ... Secrets successfully added! firstname.lastname@example.org:22 ...
Retrieve password for MySQL server
$ unlocker lookup -n dev:mysql_server OR $ unlocker recall dev:mysql_server ... Secret password for localhost email@example.com:3306 ############# <-- masked if shell supports, otherwise plain ...
Permanently remove server
$ unlocker remove -n dev:mysql_server OR $ unlocker forget dev:mysql_server ... Permanently removed secret password for localhost! This is the last chance to save this secret. firstname.lastname@example.org:3306 ############# <-- masked if shell supports, otherwise plain ...
Update a password or a private key for a server
$ unlocker update -n dev:mysql_server -a password Password: <your password> ... Secrets successfully updated! email@example.com:3306 ...
Recreate keychain (only if you know what you're doing!)
$ rm -r ~/.unlocker $ unlocker init OK
Migrate secrets over different versions
$ unlocker migrate OK
Export all secrets to unlocker file (.unl)
$ unlocker migrate --export > /tmp/secrets.unl OK
Export only certain secrets to unlocker file (.unl)
$ unlocker migrate --export name_1 name_2 name_3 > /tmp/secrets.unl OK
Notice: export tool does not check for jump servers. It's up to the user to select all needed servers to export
Import secrets from unlocker file (.unl)
$ unlocker migrate --import < /tmp/secrets.unl OK
Notice: current version of import does not map jump servers. It's up to the user to manually map imported servers
Encrypt your secrets
$ unlocker install OK $ lock ... Secrets are now encrypted. Don't forget the password!
- Additional helper script to unlock servers
- Encrypt secrets file
- Support secrets with connections through tunnels and jump servers
- Implement named records
- Better support for unicode
- Create helper scripts for MacOS and Windows
Copyright 2018 Alexandru Catrina
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.