PGP encrypt email using procmail

PUBLISHED ON JUL 13, 2017 — INFRASTRUCTURE

How to setup a PGP/MIME encrypted email address with procmail

There are good reasons to have some emails encrypted at rest. Good examples of emails to protect include password reset emails and secret shared keys.

It is not very hard to setup encryption with PGP/MIME (RFC2015 and RFC3156). However it’s a pain to have all email encrypted and adding to the pain, many PGP encryption email plugins do not support alternative displays of content. It means that emails will be text-only and sometimes both plaintext and html will be shown. In a few words, your encrypted emails will not look as pretty as they used to, and it will be a hassle. Still, for me it’s useful to help make sure my password resets stay private. You should make sure that your email server can speak SSL/TLS too, but that is another matter.

Thanks to Björn for a rough guide to PGP/MIME in: How to automatically PGP/MIME encrypt incoming mail via procmail.

What is expected to happen

Procmail processing summary:

  • Procmail will grab the incoming email (thanks to the .forward file)
  • Procmail will then process the unencrypted MIME message
    1. Append (PGP) to the subject, to clarify that the message was PGP encrypted
    2. Extract regular MIME boundaries and content metadata from the headers
    3. Add loop prevention
    4. Add the MIME boundaries and content metadata, and then encrypt the original MIME message
    5. Wrap the encrypted message in the templated pgp-mime preamble and postamble
  • Forward the encrypted message to the destination.

How to setup procmail

You need to know a bit about procmail and have the possibility to use procmail in your email pipeline. To route to procmail, setup a .forward file and point to |/usr/bin/procmail. Then setup your .procmailrc file and two mime templates, the preamble and postamble, and you should be good to go. In the files below, you need to update the following:

  • Your email address to forward the encrypted emails to
    • unless you want to deliver them locally, if so remove the last :0 section
  • Your PGP key identifier
  • The MIME delimiter (KFqxfZHeeSFksfvsMMtbQvUW)

The files

.procmailrc (where the main work happens)

SHELL=/bin/sh
# --- OPTIONAL, USED FOR DEBUGGING (comment out)
VERBOSE=yes
LOGABSTRACT=all
LOGFILE="procmail.log"
# --- OPTIONAL, USED FOR DEBUGGING (comment out)
UMASK=077

:0
# Used to prevent endless looping of emails
* ! ^X-Loop: pgp-procmail
* ^Subject:[	 ]*\/.*
{
   # Add " (PGP)" to the email subject, change according to taste!
   SUBJECT="$MATCH (PGP)"
   KEEPMIMEHEADERS=`formail -c -XContent-Type: -XContent-disposition: -XContent-transfer-encoding:`

   :0 fh
   # change headers as needed for PGP/MIME
   | formail -I "Subject: $SUBJECT" -I 'Content-Type: multipart/encrypted; protocol="application/pgp-encrypted";boundary="KFqxfZHeeSFksfvsMMtbQvUW"' -A"X-Loop: pgp-procmail" -I Content-transfer-encoding: -I Content-disposition:

   :0 fb
   # replace with your PGP key (to encrypt to):
   | { cat ~/.pgp-mime-start ; { echo "$KEEPMIMEHEADERS"; echo ; cat - ; } | gpg --batch --quiet --always-trust -a -e -r 0123456789ABCDEF; cat ~/.pgp-mime-end; }

   :0
   # change to where emails should be sent
   ! my.email@destination.tld
}

.pgp-mime-start (note the last line, which must be included in the mime preamble)

--KFqxfZHeeSFksfvsMMtbQvUW
Content-Type: application/pgp-encrypted
Content-Disposition: attachment

Version: 1

--KFqxfZHeeSFksfvsMMtbQvUW
Content-Type: application/octet-stream
Content-Disposition: inline; filename="message.asc"

.pgp-mime-end (note the initial blank line which must be there in the postamble)


--KFqxfZHeeSFksfvsMMtbQvUW

How to setup your local PGP and user environment if needed

You will need to have a proper setup for the email account, some or many of the following commands may be needed to get you setup.

# Install GPG on the server
apt-get install gnupg2

# Add the email account, why not encrypt@yourdomain.tld?
useradd -m encrypt

# Add the .forward file
echo "|/usr/bin/procmail" > ~encrypt/.forward
touch ~encrypt/.procmailrc

# Make the files owned by the account, or not if that feels better
chown encrypt ~encrypt/.procmailrc ~encrypt/.forward

# Receive the key twice to be sure to download it, the config is created on the first gpg run
sudo -H -u encrypt gpg --recv-keys 0123456789ABCDEF
sudo -H -u encrypt gpg --recv-keys 0123456789ABCDEF