Postfix on a NixOS null client with external catch-all
Tags: nixos infrastructure
I wanted to set up a server so that any local email (e.g. generated by cron jobs/systemd timers) would be forwarded to an external address, regardless of the user. I also wanted the from address to keep the system hostname whilst not allowing any external use of the mailserver.
It took me a while to figure out how to this, so I thought I'd share my method.
Here's the config that can be used to do this on any NixOS host, after redefining the first two variables.
1 services.postfix = let
2 localUser = "example-user";
3 forwardingAddress = "user@external.domain";
4 in
5 {
6 enable = true;
7 destination = [];
8 domain = config.networking.domain;
9 virtual = ''
10 @${config.networking.hostName}.${config.networking.domain} ${localUser}
11 ${localUser} ${forwardingAddress}
12 '';
13 config = {
14 inet_interfaces = "loopback-only";
15 };
16 };
Emails to any user without a domain part are all sent to the forwarding address with a clear from address (e.g. System administrator <root@host.example.com>
).
Background
First, the basic setup for a null client can be found in the postfix documentation. The example config would be translated into NixOS like so:
services.postfix = {
enable = true;
destination = [];
domain = config.networking.domain;
origin = config.networking.domain;
relayHost = config.networking.domain;
lookupMX = true;
config = {
inet_interfaces = "loopback-only";
};
};
However, this rewrites user@hostname.example.com to user@example.com (due to origin
on line 5). I wanted to be able to see which host a mail concerns.