Just like we use password managers to safely store passwords for accounts on different websites, we also have passwords and confidenital information regarding our servers that we need to safely store and share with other system administrators.
Password managers aren’t developed for this use case in mind, so we need to use something else.
We can use public key cryptography to encrypt credentials with each system administrators key and store it in a private git repository.
Other then these credentials, we can also use this same repository to store public ssh and gpg keys of each administrator.
GPG is a program that can generate public/private key pairs with which it can encrypt, decrypt and also digitally sign files.
We will focus on encryption and decryption, but we can also sign files to guarantee that they where written by users identified by their public keys.
We can also sign other people’s public keys and share those signatures with everyone, so that they know that those keys really belong to those users. GPG supports different levels of trust to be specifed when signing other peoples keys, this can be used to create a Web Of Trust.
To generate your private and public key we use --gen-key
argument.
gpg --gen-key
During key generation it will ask you for your “Real name”. This can be any name, username, or really any text that will be listed with your public key as your identity.
It will also ask you for your email where you can also put your xmpp JID instead, if you wish.
It will take some time to generate those keys, which is mostly due to your computer gathering random data from input of your mouse or keyboard. Moving your mouse around or typing on your keyboard should speed up this process.
Unlike ssh, gpg saves your keys in a single file where it also stores other data, such as public keys of other users you add, key signatures and trust data.
To list all public keys (just their fingerprints and user information) in your gpg clients database, you can run:
gpg --list-keys
You can write usernames or email addresses associated with a certain gpg to only filter this list of keys to only public keys that contain it: Autocomplete should work with those filters.
gpg --list-keys user@example.org
You can export any or all of those keys in a file with export
and output
argument. Note that you might need to specify output
argument first, otherwise public keys might be printed in your command line instead.
gpg --output user.asc --export user@example.org
You can also export your private keys to a file with command:
gpg --output user.asc --export-secret-keys user@example.org
By default gpg outputs in a non-printable binary format, but you can use --armor
argument to output files in an ASCII format. Like with output argument, it might be needed to be specifed first, before both output and export arguments.
gpg --armor --output user.asc --export user@example.org
You can import keys from a file with command:
gpg --import user.asc
Exporting and importing by default also adds key signatures from keys of other users.
To encrypt data with a public key, we can use --encrypt
or -e
arguments.
It is also a lot easier to use -r
argument whenever we encrypt and list users whose keys we want to encrypt the file with, since autocomplate only works in the command line. Otherwise gpg will ask us in an interactive prompt to list users we are encrypting for, which is less user-friendly.
gpg -e -r user1 -r user2@dmz.rs --output file.asc unencryted.txt
For every user we need to specify -r
argument before the username or thier email address.
file.asc
is the name of the encrypted output file and user1
and user2@dmz.rs
are users we are encrypting for.
In the previous example, unencrypted.txt
is the filename of the file we are encrypting. If we don’t specify a file we are encrypting we will be prompted with a blank prompt where we can write our message and end it by pressing CTRL+D.
To decrypt we use --decrypt
or -d
argument and output argument this time specifies the decrypted file.
gpg -d file.asc
You can encrypt and decrypt any file, binary or text.
To sign users key you can use --sign-key
and export the public key later as specifed above. You can share that file with other users that can import the key in their gpg clients and if they trust your key, their gpg client will automatically mark it as trusted.
If you have multiple private keys imported in your gpg client, you will need to use --default-key
argument to explecetly specify to gpg with which key it should sign with.
gpg --default-key me@email.org --sign-key user
Git is a program that tracks changes to directories files and stores entire history. This directory we are tracking history of is called repository. It is a good choice for group password managers because credentails get changed from time to time, but you still don’t want to lose old credentials in case of emergency.
It also easily supports uploading and downloading the whole history of changes across multiple servers, making it easy for sharing between different system administrators.
For every change to the repository, username and email address of the user that made the change is stored with the change itself. Of course, you can configure your git to write any username or email, but you can also sign each of the changes with your gpg key.
To configure git you can use following commands:
git config --global user.name Boban
git config --global user.email bob@example.org
git config --global user.signingKey AEA413B8B2852C932629E2496389600769AEB12A
Where Boban is your username, bob@example.org your email and AEA413B8B2852C932629E2496389600769AEB12A fingerprint of your gpg key. To see fingerprint of your key, simply run gpg --list-secret-keys
to list fingerprints of all of keys that you own the private key for. If you have too many keys, you can type the username or email of the key you are searching for, just like with the --list-keys
command.
Based on this fingerprint, git will connect to your gpg clients database and find the needed key whenever it needs to sign a change to the repo.
If you want to download the already created git repository, you can run:
git clone https://gitea.example.org/user/examplerepo
Url for the location of the repository usually ends with .git
, but it not necessary to write.
Git also supports ssh urls, for example ssh://git@gitea.example.org/user/examplerepo
. In this ssh url example git
is the username you connect to the git server with, usually all users share the same username and don’t have actual ssh command line access.A
Usually git servers support both http and ssh links, but it is easier to specify from the start which one you are planning to use.
Using http for git allows everyone to clone (download) the repo (repository) without having an account registered on that git server. However, during uploading changes, you will need to type your credentials each time.
When using ssh, you can usally associate ssh key with your account on the git server in the settings page of that git server. Using the ssh key will save you time if you plan to make many changes to the repo as you can only type your password for the ssh key (or have no password set for the private key).
Usually you need to sign a certain challange message with your ssh key when adding it in your settings page and the needed command for siging is shown on the same settings page.
To update and refresh your local version of the repo from the git server to the newest state, you can enter the repo directory on your machine with cd
command and run:
git pull
If you want to download the new version from another url, you can specify that url on the end of that command:
git pull ssh://git@gitea.example.org:22/user/examplerepo
In the previous example :22
specifies the ssh port of the git server we are downloading the new changes from.
To make a change you can edit the needed files and run following commands:
git add .
git commit -S -m'comment about changes made'
First command in this example records the changes made to the files specified. In this example dot .
is specified, which means git will record changes of all the files in current working directory. You can also speciy only individual files instead, in case you made changes or added/removed some files in that directory which you don’t want to upload to a git server.
Second command in that example is the one that finalizes those changes and adds your username and gpg signature to the history of changes.
-S
argument specifes that we want to sign this change with our gpg key and -m
argument specifies the comment message to be recoreded with this change so that other users can make a quick look and know what this change is about.
To upload these changes to the git server, you can use:
git push
Same as with the git pull
command, you can also specify a specific url to upload the changes to, otherwise it will use the same url that repo was first downloaded from with git clone
command.
Git is really helpful with all of these commands if you make a typo or encounter some error. It usually displays the command that you likely would want to run next.
If you lost track of the git commands you typed or want to check the status of the changes in the repo, you can run:
git status
If you want to create a brand new repo, you can navigate to any directory on your computer with cd
and run:
git init
Usually to add a brand new repo to your account on the git server, you need to manually create the repo on it’s website first. Usually after doing this, the server displays the commands you need to type to create an upload it to that account.
You might also see git remote
commands mentioned from time to time. Those are commands that act like bookmarks in your browser, to save urls of that repo on different git servers.
One of the main git features, that we don’t really need when used as password manager, is tracking different versions of the repository. This is usually used by programers to track different versions of the program they are developing and they are called branches.