Offline & Encrypted Personal E-Mail
Feb 16, 2021
I find most e-mail clients to be both complicated and restrictive. I like being able to read, write and manage my e-mail offline. I also like storing my e-mail in an encrypted mailbox, in case someone else gets access to my device.
In this guide, I will explain how I have configured my e-mail system, and how it can be implemented for other users. I will be using an exemplary Yandex e-mail account (firstname.lastname@example.org).
The programs needed to replicate this setup are:
gnupg2(encryption and signing tool)
These programs are easily available in most Linux and BSD systems, even though their package names might be different. For this guide, Void Linux is used. Instructions for other Linux or BSD systems should be very similar.
Before we begin, we need to install the required packages.
[user@void: ~]$ doas xbps-install mutt isync msmtp gnupg2 pass
We start by configuring
mutt, which is a very flexible and customizable e-mail client with many options.
The lines below are the ones that are relevant to this guide.
If you are already a
mutt user, then these lines should be enough.
If not, then you might need to tweak the configuration to make it more usable for you.
We open the configuration file in a text editor.
[user@void: ~]$ vim ~/.config/mutt/muttrc
We add the following lines, which tell
mutt how to send e-mail, and where to look for received e-mail.
Next, we configure
isync to get e-mail from a remote IMAP server.
The binary for
isync is called
mbsync, and the default configuration file is
In this guide, we will put the configuration file in
~/.config/mbsync/mbsyncrc, and read the file when running
This makes our home directory tidier.
[user@void: ~]$ mkdir -p ~/.config/mbsync [user@void: ~]$ vim ~/.config/mbsync/mbsyncrc
A basic configuration looks something like this.
Then, we open up the
msmtp configuration file, which is read from
~/.config/msmtp/config by default.
[user@void: ~]$ vim ~/.config/msmtp/config
Here is a simple configuration that works.
Next, we generate two RSA keypairs with
gnupg2 (one for the mailbox encryption, and one for the encrypted password storage).
The binary is called
gpg2 on Void Linux.
[user@void: ~]$ gpg2 --full-generate-key
The program will ask us questions about the keys we are generating. We need to:
- Choose "RSA and RSA" keys (this is default)
- Choose 4096 bits as the keysize for better security (type 4096 when prompted for the keysize)
- Specify a duration of validity for the keys (this is optional, but is a good security measure, and the key can always be extended when necessary)
- Confirm the choices
- Enter a real name (Example User)
- Enter an e-mail address (email@example.com)
- Enter a comment (this is optional)
- Press "O" for "Okay"
- Enter the passphrase to protect the new keys
- Perform random actions on the mouse and on the keyboard in order to gain entropy while generating the keys (this is optional, and fun).
Then, we enter the following command to see the secret key ID.
[user@void: ~]$ gpg2 --list-keys --keyid-format LONG /home/example/.gnupg/pubring.kbx -------------------------------- pub rsa4096/0000000000000000 2021-01-01 [SC] # The 16-digit number here is the secret key ID. 0000000000000000000000000000000000000000 uid [ultimate] Example User <firstname.lastname@example.org> sub rsa4096/0000000000000000 2021-01-01 [E]
The line beginning with
pub should contain the secret key ID (
rsa4096/<key_id>). We note this number.
We then generate a new RSA keypair with the same process. This time, we might provide a comment when prompted, in order to make the new keypair more recognizable. When the generation is complete, we note the ID of the new key as well.
Next up, we initialize the password storage with
pass, using one of the key IDs we have generated.
[user@void: ~]$ pass init "0000000000000000"
pass saves passwords in a
gpg2 encrypted file in the
We are going to store our e-mail account password with
pass, because it is more secure than storing it in plain text.
We can insert a new password with the following command (we enter the password when prompted).
[user@void: ~]$ pass insert yandex
We can see the newly added password like this:
[user@void: ~]$ pass ls
We also need to make the mailbox directory, compress it into a
tar archive, and encrypt it using the other RSA keypair.
We will be decrypting the mailbox whenever we synchronize with
mbsync or run the
mutt e-mail client, and encrypting it again when we are done.
I am using a different fake key ID this time, to differentiate it from the previous one.
We run the following commands first to make the encrypted
tar archive containing the empty mailbox, and remove the unencrypted files.
[user@void: ~]$ mkdir ~/.mailbox [user@void: ~]$ tar -cf ~/.mailbox.tar -C ~/ .mailbox [user@void: ~]$ rmdir ~/.mailbox [user@void: ~]$ gpg2 -r 1111111111111111 -e ~/.mailbox [user@void: ~]$ rm ~/.mailbox.tar
Finally, we write a simple shell script that will run everything as required. Let's call the script
[user@void: ~]$ vim mymail
Our script will:
- Decrypt the encrypted
tararchive, and make a backup of the encrypted one, in case something goes wrong.
- Extract the mailbox from the archive, and remove the archive.
mbsyncto get the latest e-mail from the remote server.
muttis closed, compress the mailbox into a
tararchive, and remove the uncompressed mailbox.
- Encrypt the archived mailbox, and remove the unencrypted one.
Here is the script:
#!/bin/sh MBOX="~/.mailbox" && \ && [ && && && \
We save the script and make it executable.
[user@void: ~]$ chmod +x mymail
Then, we copy the script to a directory in our
$PATH, or we just run it.
[user@void: ~]$ ./mymail