Unique email per service

Use a unique email per service, like you do for passwords.

Anonymous

You already use a password manager to keep track of all the unique passwords for each of your online accounts. If one of these services gets breached or a malicious developer steals your password you can be sure they don’t hack all your other online accounts. You do, however, use the same email address. Not as important as your passwords but a breach will still expose the email address. It also means all these websites can keep sending you spam now that they have your email. What if we would use a unique email per online service as we do with passwords?

Beginner

The email standard supports the use of a plus sign in an address: john+twitter@example.com will be delivered to john@example.com. Gmail and Outlook support this out of the box, other mail services might do too. No setup required, the part after the plus sign can be anything you want. Use this little trick when signing up for an online account and you have instant unique email addresses! Receive spam on your john+twitter@example.com address? Add a rule in your email client to drop emails to that address. Got a random spam mail on john+twitter@example.com? Twitter might have sold your email address or worse, they got breached.

This simple solution has some disadvantages. First, it’s super simple to guess the main address: remove the “+something” part. Bots can see this too, they will be quick to spam the main address. Secondly, not all web applications are created equally and some will refuse the address because they see the plus sign as an invalid character, meaning you would have to use your main address anyway, bummer.

Intermediate

What if we create a real unique address per service, not an alias? Say abc@example.com is the address I used for Twitter and efg@example.com for Facebook and I forward both addresses to john@example.com? Now, no one can guess my real address based on the ones I created: there is no link between abc@example.com and john@example.com. Problem? It’s extra work each time you sign up for a new service.

Some services do exactly that, take AnonAddy for example, which allows you to create random something@user.anonaddy.com addresses on the fly. Just make sure you use a custom domain as you don’t want to go update all your accounts if AnonAddy would go bust.

Advanced

Why not run our own email forwarding service? We can create as many aliases as we want, no snooping on our emails and no 3rd party middleman. It does require we run a web server though. Let’s configure a Postfix email forwarder.

Postfix

Start a Linux VPS and buy a domain name you like. Say we bought example.com (well, rented, you don’t buy a domain name, you rent and renew it each year). First, update the server and install Postfix.

  $ sudo apt-get update && sudo apt-get upgrade
  $ sudo apt install postfix -y
  $ postconf | grep config_directory
  

Which gives you the path to the Postfix config file, probably /etc/postfix/main.cf. Add the following two lines to the config file and replace example.com with your domain (the part that goes after the @ sign of the email address we are going to create).

  virtual_alias_domains = example.com
  virtual_alias_maps = hash:/etc/postfix/virtual
  

The second line tells Postfix where it can find the aliases. Create the /etc/postfix/virtual file if it doesn’t exist yet and add the first alias. Each line is an alias, it starts with the receiving address and is followed with the address you want to forward to. For example:

  twitter@example.com john@something.com
  facebook@example.com john@something.com
  

Each time we add or remove an alias we have to tell Postfix about it and reload the service.

  $ sudo postmap /etc/postfix/virtual
  $ sudo systemctl reload postfix
  

Set the FQDN as well:

$ sudo hostname mail.example.com

Firewall

You should run a firewall on your server. I am using ufw:

  $ sudo ufw allow postfix
  $ sudo ufw allow ssh
  $ sudo ufw enable
  

Note, there is more you should do to harden your server but that’s out-of-scope for this tutorial!

DNS

The internet doesn’t know that our new server is ready to receive emails to twitter@example.com and facebook@example.com yet. You can probably configure the DNS in the same place where you bought your domain name. Add an A-record for the mail subdomain pointing to the IP of the server (replace 127.0.01 with the IP-address of your server.

mail  A  1800 127.0.0.1

Also, add an MX-record pointing to the mail subdomain.

@ MX  1800 10  mail.example.com.

Point the PTR record to mail.example.com. This will depend on the company hosting your VPS, with Digital Ocean this is the name of the “droplet”.

Give it a bit of time to propagate and test it. Mails send to twitter@example.com should now be forwarded to john@something.com.

STARTTLS

At the moment we are receiving and forwarding emails in the clear. If the goal is to improve our privacy we should at least try to encrypt the connection. Luckily we can do this for free thanks to Let’s Encrypt’s TLS certificates. Install certbot and request a new certificate.

  $ sudo apt install certbot -y
  $ sudo certbot-auto certonly --standalone -d mail.example.com
  

Note that this certificate is only valid for a few months, see the certbot documentation on how to set up automatic renewals. Add the following to your Postfix config file: /etc/postfix/main.cf.

  smtp_tls_note_starttls_offer = yes
  smtp_tls_security_level = may
  smtpd_helo_required = yes
  smtpd_helo_restrictions = reject_non_fqdn_helo_hostname,reject_invalid_helo_hostname,reject_unknown_helo_hostname
  smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
  smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
  smtpd_tls_received_header = yes
  smtpd_tls_security_level = may
  disable_vrfy_command = yes
  

The last line is optional. Postfix supports the VRFY command which allows anyone to determine if an email account exists, which can help brute force attackers, better disable it. Reload Postfix to enable encrypted email connections.

$ sudo systemctl reload postfix

Scripting

Adding a new alias still means logging in to the server, adding a line to a file and reloading Postfix. Not exactly quick. A little scripting can go a long way.

  FORWARD_TO=john@something.com
  DOMAIN=example.com
  UUID=$(cat /proc/sys/kernel/random/uuid)
  echo "$UUID@$DOMAIN $FORWARD_TO" >> /etc/postfix/virtual
  postmap /etc/postfix/virtual
  systemctl reload postfix
  echo $UUID@$DOMAIN
  

Save this as newmail in the home dir on the server. You can now easily add aliases from your laptop via SSH.

  $ ssh user@example.com 'sudo ./newmail'
  345ab0bf-6144-4f36-97d2-be934df2278a@example.com
  

Resources

This post is open source. Did you spot a mistake? Ideas for improvements? Contribute to this post via Github. Thank you!