blog/content/posts/automating-aliases.md
2021-04-30 20:25:09 +02:00

4.4 KiB

title date draft
Automating email aliases using Mailinabox and curl 2021-04-30 false

With every piece of furniture, website and bowl of instant ramen asking you to register a user account, it's getting hard to remember anything. Furthermore, the companies which so gladly hoard our contact information are having a hard time protecting it, and it seems like the age of password managers and email aliases is upon us.

One cool thing about email aliases is that they let you know which company is sending most spam your way. As a big fan of self-hosting, I have a Mailinabox and I recently found out about its REST API. In my pursuit for comfyness, I tried to automate the creation of aliases.

The credentials

First of all, all of Mailinabox's API needs admin authentication, either an api_key or a user:password tuple. Since the former needs the later, I'll just use user and password. Even though curl tries its best to hide its command line arguments from terminal history, it's just not good practice to pass -u admin@mydomain:mypassword directly. Reading a bit in its manual, I found out that option -K - lets you pass config parameters from stdin, like so:

$ gpg -qd credentials.gpg | curl -X GET "https://{host}/admin/mail/users?format=<string>"

Where credentials.gpg is an encrypted file with the text -u mail:password. This way, you can safely use this without fear of your credentials leaking into logs or ps output. If everything worked just right, you should be able to see a list of all of your mails.

Note that for GPG to be able to ask for secret key's password interactively, you may need to define GPG_TTY in your .bashrc or equivalent.

Creating the alias

The command for alias creation would be something like this:

$ gpg -qd credentials.gpg | curl -X POST "https://{host}/admin/mail/aliases/add" \
-d "address=<new-address>" \
-d "forward_to=<true-address>"

This is fine and usable, if a bit tedious. I like to set my aliases to random strings, so malicious actors cannot deduce the true email address. A simple shell script that creates a random email alias would look something like this:

#!/bin/sh

DOMAIN="@<your domain>"
HOST="<your host>"
NEW_ADDRESS=$(tr -dc a-z0-9 </dev/urandom | head -c 13 ; echo '')
TRUE_ADDRESS="<your mail@your domain>"

gpg -qd credentials.gpg | curl -X POST "https://${HOST}/admin/mail/aliases/add" \
                               -d "update_if_exists=0" \
                               -d "address=${NEW_ADDRESS}@${DOMAIN}" \
                               -d "forwards_to=${TRUE_ADDRESS}" \
                               -K - | grep "alias added" && echo "${NEW_ADDRESS}@${DOMAIN}"

We're using 13 alphanumeric characters (all lowercase) to maximize compatibility. We could pipe the new email address into something like xclip -sel clip to have it in our clipboard right away. Note that we need to grep curl's stdout to know if the account was actually created, since it will still return 0 on a failed creation.

Making it comfier

Making this script into a keyboard hotkey that does not need a terminal is a pain, since gpg's pinentry depends on gpg-agent. Rather than dealing with it, I'd recommend either using a new passwordless private key for the file or manually creating an input dialog box with something like zenity.

This is a script that works as a window-manager-launched keyboard shortcut:

#!/bin/sh

DOMAIN="@<your domain>"
HOST="<your host>"
NEW_ADDRESS=$(tr -dc a-z0-9 </dev/urandom | head -c 13 ; echo '')
TRUE_ADDRESS="<your mail@your domain>"

zenity --password | \
gpg --batch --passphrase-fd 0 --pinentry-mode loopback -q -d /full/path/to/credentials.gpg | \
curl -s -X POST "https://${HOST}/admin/mail/aliases/add" \
     -d "update_if_exists=0" \
     -d "address=${NEW_ADDRESS}@${DOMAIN}" \
     -d "forwards_to=${TRUE_ADDRESS}" \
     -K - | grep "alias added" && echo "${NEW_ADDRESS}@${DOMAIN}" | \
     xclip -sel clip && notify-send "Email created" || notify-send "Email creation failed"

Of course, you may dispense with the notify-send. I haven't delved into it since you don't always need a password along with the email and most browsers have very decent password generators, but automating KeePassXC's great CLI tools (or whatever alternative floats your boat) to generate and add passwords at the same time for these accounts shouldn't be terribly hard.