How Not to Configure Your Mail Server

As I reported earlier, I run my own email server; I still do. The server is fine, and I keep using it for my personal mail. I also have a “server” at home, and that server has been serving mail for even longer. I chiefly use it for outgoing mail — the automatic notifications my various computers generate — but it also serves as a backup MX for my main email server, so the SMTP port is open to the Internet at large.

I use Postfix, and it is set up so that relaying is only done for the authorized domains (my own), and for a very short list of selected IP addresses on my home network. Of course, to have incoming mail working I rented a “real” IP address from my ISP and set up port forwarding on my router. I never had issues with the whole setup — well, until not so long ago.

Unfortunately, I’m planning on changing ISPs in the near future, and the new ISP comes with layers of NAT and a router that I can’t comfortably set up port forwarding on. Moving the multiple things I host at home (including my Nextcloud instance and my Navidrome-powered music collection) to a cloud would defeat the purpose1, so I needed a solution.

The solution came in the form of a relatively low-spec VPS rented from a cloud provider (with “real” IP) and a clever tool called FRP (Fast Reverse Proxy). The idea is you set up the FRP server on the VPS and have it listen on a specific port; you then set up the FRP client on a machine at home, and have the client connect to the server. The client then tells the server to open a port (say, port 80 for HTTP traffic) and forward all the connections from that port right to the client that routes them to a port on your local machine. The users connect to the VPS in the cloud, but all the traffic lands on your machine at home; in a way2, the VPS running the FRP server acts as a router, and the FRP server does the “port forwarding” to the client (or clients).

For Nextcloud and other web servers I host it worked like a charm, even HTTP/3 connections worked just fine. SMTP is much less complicated protocol-wise, so I configured an FRP client on the Raspberry Pi, and told it to have the server open port 25 and channel the traffic to the local port 25.

What a blunder!

You probably already see the problem with this setup. FRP is not a router. The traffic that reaches port 25 at home is not coming from a remote server3; instead, it’s coming from the FRP client running on the same machine. The localhost.

You may remember that a very short list of selected IP addresses on my home network was cleared for relaying mail through this server. In Postfix, such a list automatically includes the localhost. Which was now where all the external connections were coming from.

Yep, I made my Raspberry Pi an open mail relay. Just like that.

Fortunately, it took less than a day for the poor machine to overheat under load and reboot itself. And, fortunately, I misconfigured the FRP client so that it failed to start after reboot. But by the time the system failed, the mail queue was so big it took Postfix several hours to list and remove the messages not addressed to my authorized domains.

Of course, I only brought the poor thing back online after I told FRP client to use the PROXY protocol, and opened a separate port in Postfix that only allowes relaying mail to authorized domains (and uses the PROXY‌ protocol to figure the sender’s actual IP‌ address anyway) — the way you should set up things if you ever feel like doing SMTP over FRP.


  1. And the budget, too. ↩︎

  2. In fact, this very metaphor was what caused trouble. “In a way” is not “actually” — obvious in hindsight… ↩︎

  3. Well, it is, sort of, but not directly. ↩︎

Comments can be sent as webmentions or by email.