+++ title = 'Postfix on a NixOS null client with external catch-all' date = 2020-09-11T18:49:00+02:00 [taxonomies] 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. ```txt,linenos,hl_lines=2-3 services.postfix = let localUser = "example-user"; forwardingAddress = "user@external.domain"; in { enable = true; destination = []; domain = config.networking.domain; virtual = '' @${config.networking.hostName}.${config.networking.domain} ${localUser} ${localUser} ${forwardingAddress} ''; config = { inet_interfaces = "loopback-only"; }; }; ``` 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][0]. The example config would be translated into NixOS like so: ```txt 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. [0]: http://www.postfix.org/STANDARD_CONFIGURATION_README.html#null_client