Testing software that requires unique email addresses is a pain. Automated testing tools can lessen the burden by using counters or random strings to create unique email addresses, but that stops at localized testing – those email addresses can’t actually receive mail. A common method often used to resolve this is a “catch-all” email alias that accepts any email sent to it and forwards it to a specfic address. While this method can work well for the solo developer, it’s inadequate in a team environment where each member needs to see the message.
Fortunately, Python has an excellent customizeable SMTP server built-in that we can leverage to help us create a simple system that accepts emails and forwards them onto the appropriate recipient.
For this to work we have a few prerequisites:
- A pubicly accessible machine (i.e. EC2 micro instance, etc.) that can send outbound email and run a Python script
- A domain name with DNS under our control
- sendmail or another Mail Transfer Agent
Let’s begin:
Launch a publicly accessible server that can send outbound email
Log into the machine and start an MTA (like sendmail) running on localhost, only accepting connections from 127.0.0.1. Many Linux distributions come with sendmail pre-installed.
Create a subdomain for your development email addresses
Access the DNS zone for your domain and create an A record pointing to the public IP address of the server mentioned above. Then, create an MX record pointing to that subdomain as well.
Example:
devmail.example.org A 1.2.3.4
devmail.example.org MX 0 devmail.example.org
Write the Python SMTP server code and run it on the server
The following gist runs a simple SMTP server that accepts all mail sent to it and processes it as follows:
- If recipient is a list of email addresses, only process the first email address found
- If recipient is a single email address, process it as usual
- Using the format
account--anything@devmail.YOURDOMAIN.COM, extract the token before the double hyphen – if nothing is found, discard the message - If a string is found before the double-hypen, use it to build a real email address
Example:
joe--testing123@devmail.YOURDOMAIN.COM will be processed and re-sent to joe@YOURDOMAIN.COM
The script expects a local MTA to be running on localhost:587. Please be sure to not run that MTA on your public IP address and create an open SPAM relay.
Setup the SMTP server script to run in a daemon process
You can run the SMTP server script with any service monitor like upstart, supervisor, daemontools, etc.
To install supervisor:
> pip install supervisor
Add the following to the end of /etc/supervisor.conf:
[program:smtp-proxy]
command=/path/to/smtp_proxy.py
user=root
redirect_stderr=true
exitcodes=1
To run on port 25 (or any port < 1024) the script will need to be run as root. If you can run on a port > 1024, please do so and replace user=root with another user on the system (also replacing ('0.0.0.0', 25) with the appropriate port in the SMTP server script).
Start the SMTP server with:
> supervisorctl -c /etc/supervisor.conf start smtp-proxy
Tail supervisor’s logs for any issues:
> tail -f /tmp/supervisord.log
Tim