There are lots of setups with programs that can collect email in testing environments. Some of them require you to install perl, nodejs, ruby, ... or require you do do a sophisticated setup with your mailserver.
But there is a little program called mailhog that is just a standalone statically linked binary that has no dependencies.
That makes it very easy to use.
Just download the latest release and put it into your /usr/local/bin:
wget -O /usr/local/bin/mailhog https://github.com/mailhog/MailHog/releases/download/v1.0.0/MailHog_linux_amd64
chmod +x /usr/local/bin/mailhog
You can just start the program by running /usr/local/bin/mailhog.
The SMTP will be available on port 1025 and the web UI on port 8025.
We want mailhog to start with system boot and restart when it would
crash. You can do that sort of stuff with systemd. Create a file named /lib/systemd/system/mailhog.service
with this in it:
[Unit]
Description=Mailhog SMTP
[Service]
User=mailhog
Group=mailhog
WorkingDirectory=/home/mailhog
Restart=always
ExecStart=/usr/local/bin/mailhog -api-bind-addr 127.0.0.1:8025 -ui-bind-addr 127.0.0.1:8025 -smtp-bind-addr 127.0.0.1:1025
[Install]
WantedBy=multi-user.target
Create the user mailhog with group mailhog and home directory /home/mailhog
first, or leave it out and mailhog will run as root. Running stuff
as root is a bad idea, especially if it is something that listens on the network.
It's also not a good idea to make mailhog accessible on your public IP. It does
that by default so that's why you would add -api-bind-addr 127.0.0.1:8025 -ui-bind-addr 127.0.0.1:8025 -smtp-bind-addr 127.0.0.1:1025
to make it only listen on localhost.
Now enable the mailhog service to start it at boot time and then start it manually:
systemctl enable mailhog
systemctl start mailhog
We hook it up to postfix and make it so that if you mail to an email
address ending in .external, it will be relayed to a real server.
And, if doesn't we relay it to mailhog.
Eg: mail to tom@somedomain.tdl will go to mailhog and tom@somedomain.tdl.external will be delivered to tom@somedomain.tdl.
Postfix configuration /etc/postfix/main.cf:
myhostname = myserver.mydomain.tld
relayhost = real-smtp-relay.mydomain.tld
smtp_generic_maps = pcre:/etc/postfix/smtp_generic_maps.pcre
transport_maps = hash:/etc/postfix/transport
The smtp maps make sure that the .external part is stripped off.
/(.*)\.external$/ $1
The transport maps decide that .external addresses will be relayed to the real
SMTP server and the rest will be relayed to mailhog.
.external :
* smtp:127.0.0.1:1025
Because the transport maps are hashed you need to run postmap /etc/postfix/transport.
I do want to make mailhog available on my public IP on /mailhog/. But I want to do it with
an Apache proxy that requires basic HTTP authentication.
Create the file /etc/apache2/conf-available/mailhog.conf with this in it:
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /mailhog/(.*) ws://0.0.0.0:8025/$1 [P,L]
ProxyPreserveHost Off
ProxyRequests Off
<Proxy *>
AuthType Basic
AuthName "Authentication required"
AuthUserFile "/etc/apache2/mailhog.password"
Require user mailhog
Order deny,allow
Allow from all
</Proxy>
ProxyPass /mailhog/ http://0.0.0.0:8025/
ProxyPassReverse /mailhog/ http://0.0.0.0:8025/
Generate the password file:
htpasswd -c /etc/apache2/mailhog.password mailhog
Enable the necessary Apache modules, and enable the config:
a2enmod proxy proxy_http rewrite
a2enconf mailhog
systemctl reload apache2