Posts Tagged ‘gpg-mailgate


GPG-Encrypting your incoming mail using Postfix and Google Apps

I’ve recently chosen to take more control over my data when it’s stored in the cloud. Some big parts of that data are my email accounts. Like most geeks, I have a few “vanity” domains that I receive email at. Also like most geeks, I host them on Google Apps. So, I’ve decided to encrypt all incoming emails before they get stored on Google’s servers.

I searched around for methods of implementing this, but many used Exim or Procmail. I’m partial to Postfix myself, I like they’re privilege separation model. I was running up blanks, until I stumbled upon This project is a very straightforward filter to GPG encrypt mail if a recipient’s key is locally stored. Getting this operational on Ubuntu was easy.

Creating a mail forwarder

First, I installed Postfix with a blank configuration. Then, to create a basic forwarder configuration I made /etc/postfix/

myhostname = forwarder.DOMAIN.COM
mydomain = localhost
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, $mydomain
mynetworks_style = host
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
append_dot_mydomain = no
readme_directory = no
relay_domains = DOMAIN.COM
transport_maps = hash:/etc/postfix/transport

Next I needed to make /etc/postfix/transport:


And due a slight bug in Ubuntu’s blank configuration, I needed to make an aliases db:

echo 'postmaster: root' >> /etc/aliases

Restart Postfix:

service postfix restart

At this point I changed my DNS to point the MX record to this server. I sent a test email to ensure fowarding worked.

Installing the GPG encryption filter

You’ll want to install gpg, then install GPG-Mailgate:

cd /root
hg clone
cd gpg-mailgate

From here I mostly followed the steps from INSTALL, but they’re a bit dated and didn’t quite work for me. Here’s the short version, my apologies for the lazy instructions, make sure you replace the python version below with the version that’s live on your system:

cp -R GnuPG /usr/lib/python2.6/
vi /usr/lib/python2.6/GnuPG/

Above, we need to add “–trust-model always” to the command in line 43. Otherwise GPG throws an error about not trusting the key and fails to encrypt messages.

cp gpg-mailgate.conf.sample /etc/gpg-mailgate.conf
vi /etc/gpg-mailgate.conf

In /etc/gpg-mailgate.conf, modify the domains variable to include all domains you want to encrypt messages for. Then, if you have mail aliases, you’ll probably want to add entries under [keymap] in the format email = longKeyID. Leave keyhome as default.

After this is done, we need to get the public keys we want to use for encryption. We can take advantage of Postfix’s privilege separation here:

adduser -s /bin/false -d /var/gpg -M gpgmap
mkdir -p /var/gpg/.gnupg
chown -R gpgmap /var/gpg
chmod 700 /var/gpg/.gnupg

The next command needs to be repeated for each email address you want to encrypt mails for. If you want an email alias encrypted with a key, use the keymap section of the config file above.

sudo -u gpgmap /usr/bin/gpg --homedir /var/gpg/.gnupg --keyserver hkp:// --search myemail@DOMAIN.COM

Then, we’ll need to tell Postfix to have a filter that calls the external script, and a channel to accept mail from the script after it’s encrypted. The following goes in /etc/postfix/, keep in mind that I’m using a different username than the INSTALL directions do (this part gets a bit wide, you may need to expand your viewing window):

gpg-mailgate    unix    -       n       n       -       -       pipe
        flags= user=gpgmap argv=/usr/local/bin/ inet    n       -       n       -       10      smtpd
        -o content_filter=
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=
        -o smtpd_authorized_xforward_hosts=

And then we tell Postfix to use the filter by running this quick command to add a line to /etc/postfix/

echo 'content_filter = gpg-mailgate' >> /etc/postfix/

Restart Postfix:

service postfix restart

With all that, you should find that a test email sent to the email address you specified ends up in your Google inbox encrypted with your gpg key. This works perfectly with a PGP-capable IMAP client, such as Thunderbird or K-9 Mail on Android.


As an added bonus, I threw together an apparmor profile. If your system uses AppArmor, you can place the following in /etc/apparmor.d/ — keep in mind that you’ll need to match the version of python below with the version used on your system.

#include <tunables/global>

/usr/local/bin/ {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/python>

  /usr/bin/python2.6 ix,
  /usr/include/python2.6/pyconfig.h r,
  /usr/lib/python2.6/GnuPG/__init__.pyc r,
  /usr/local/bin/ r,
  /usr/bin/gpg Cx -> gpg,

  /etc/gpg-mailgate.conf r,
  /etc/default/apport r,
  /tmp/gpg-mailgate.log rw,

  profile gpg {
    #include <abstractions/base>
    #include <abstractions/nameservice>
    /usr/bin/gpg r,

    /var/gpg/.gnupg/* r,
    /var/gpg/.gnupg/.* w,
    /var/gpg/.gnupg/trustdb.gpg w,
    /var/gpg/.gnupg/random_seed wk,

Then just run the following to activate the profile:

aa-enforce /etc/apparmor.d/

I found that I still get one apparmor warning, about it wanting to unlink the GnuPG library, which I thought was odd so I didn’t write a rule for it. If this bothers you, add a ‘d’ beside the ‘r’ for that line. Obviously debugging AppArmor is out of scope for this blog post, but there are plenty of useful resources that are just a Google search away.

Edit: I am not at all confident that this AppArmor profile improves the security of using the gpg-mailgate script. Use at your own risk, etc.

Anyways, there you have it. Now all your mail is encrypted before it hits Google’s server for data mining. There’s probably a double-encryption bug that needs to be worked out, and outgoing mail won’t be stored encrypted, but we can at least regain a little bit of control over the data we store in the cloud.


March 2023