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