Roman Bezlepkin’s Website

Running a headless ProtonMail Bridge with a SMTP Relay for homelab use

When running a homelab, often times there are various services which send you email notifications. Be it NAS reports, firewall, backup alerts and notifications.
Up until recently I was using Gmail to send me such reports, but ever since moving to ProtonMail I have been slowly removing all dependencies I had on Google Services.

Due to ProtonMail’s architecture, they do not offer direct SMTP/IMAP connections to their servers. Instead, they offer people run the ProtonMail Bridge which provides SMTP/IMAP listeners running on localhost ports and using ephemeral credentials (those that are generated by the bridge, but not those you actually use to sign-in to read your mail). Email clients like Mozilla Thunderbird then connect like any other SMTP/IMAP server.

Bridge Setup

Now, I am not the first to explore the Bridge setup, as PY Chuang has already done a lot of excellent work on the matter.
I will add, that GPG key generation will take a considerable amount of time. At first I thought that gpg --batch --passphrase '' --quick-gen-key 'ProtonMail Bridge' default default never wasn't working as I did not see any output. Turns out it was just taking a while. GPG requires additional entropy to generate keys, and actually suggests some random keyboard input or disk I/O to help with that. So in parallel, running dd if=/dev/sda of=/dev/null seemed to speed up this process.

Once the bridge was setup with a dedicated email account, it was time to make it a service/daemon, of course, to make it start and stop with the system.

/etc/systemd/system/protonmailbridge.service
[Unit]
Description=Protonmail client bridge service

[Service]
Type=simple
StandardOutput=journal
ExecStart=/usr/bin/protonmail-bridge --noninteractive
User=<name of linux user under which bridge was setup>

[Install]
WantedBy=default.target

SMTP Relay

Now that the bridge is setup and is running, it is time to make a local SMTP relay which can listen on plaintext port 25. Why? ProtonMail bridge utilizes STARTSSL for mail clients connecting to it, uses a self-signed certificate, and only binds to localhost. This presents complexities with usability like not all “clients” provide methods to trust self-signed certificates (like backup software, firewall and NAS appliances as I have mentioned); additionally, you would also have to use port forwarding to bypass localhost bind. However, all clients allow plain connections over port 25.

Though not the most secure, nor recommended way, running a plaintext SMTP relay on this local and restricted homelab network simplifies the complexity and would generally be used only by a handful of services. Furthermore, the mail relay will be sitting on a dedicated and restricted network to minimize access to it from potential rogue clients.

For this purpose, I decided to use Postfix which can both listen on port 25 and forward emails to the ProtonMail bridge.
After installing Postfix, additional configuration is required to make it work. First, ProtonMail expects the From address to match that of the email account, otherwise it will not accept mail.
Postfix sender_canonical_maps can be used to rewrite the From header.

/etc/postfix/main.cf (excerpt)
[…]
# ProtonMail Bridge listening on port 1025
relayhost = [127.0.0.1]:1025
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CApath = /etc/ssl/certs
smtp_use_tls = yes
[…]
sender_canonical_maps = regexp:/etc/postfix/canonical
[…]
/etc/postfix/canonical
/.*/ mailer-daemon@example.org

Again, this rule will rewrite any From email address with the actual ProtonMail account address (mailer-daemon@example.org provided here as an example, use your own).
Postfix will also require login credentials to ProtonMail Bridge, provided in a file specified below.

/etc/postfix/sasl_passwd
[127.0.0.1]:1025 mailer-daemon@example.org:P@ssw0rdPr0videdByBridge

Be sure to chmod 0600 /etc/postfix/sasl_passwd && chown root:root /etc/postfix/sasl_passwd after you are done.

Since postfix will be connecting to the bridge with STARTSSL, it will need to validate the bridge certificate. Symlinking the self-signed certificate will be necessary:

$ sudo ln -s /home/user under which bridge was setup/.config/protonmail/bridge/cert.pem /etc/ssl/certs/protonmail-bridge.pem

Finally, configure email clients to send mail to the relay host on port 25.