splitbrain.org

electronic brain surgery since 2001

Postfix Relay to SMTP2GO on NixOS

Postfix and NixOS Logos combined

I am in the process of setting up a new NAS/Homeserver. But I nerd sniped myself by wanting to use NixOS on it. So things are going slow. But here's a thing I learned today…

The goal is to set up a Postfix mail server that will allow me to send mails from the machine itself (through bin/sendmail and localhost:25) as well as from other machines in my network and on Docker. There won't be many mails but when there are, they might be important. So mails should be sent through some relay that is well managed and I don't have to admin myself.

I have a real domain name that I am using to address internal services. I simply have DNS names pointing 192.168.1.* addresses. The public domain allows me to get certificates from LetsEncrypt via ACME DNS-01 – but that's another story.

So the idea here is to have an external mail server that is the permitted sender for that domain and a local relay server that simply relays all mail through that external mail server.

smtp2go

The external service I picked is smtp2go. Their free tier should be good enough for my needs.

Setup on their side was simple. Here's the basic steps:

Create an account at smtp2go.com.

Follow the steps to create a verified sender domain under SenderVerified Senders. Simply create the three CNAME entries in your DNS config.

I changed the hostname for the return path from the suggested random string to “mail”. I think it's a bit nicer in the mail headers later.

Once the CNAMES are set up and verified, you need an SMTP user. Set one up under SendingSMTP Users.

The username has to be unique among all smtp2go customers, so I used my fully qualified host name nas.example.com. Be sure to make note of the password.

That's all that is needed on the smtp2go side. They automatically take care of DKIM, SPF and DMARC.

Nix Setup

There are a few things to set up in the configuration.nix file.

First of all we need to define the service:

/etc/nixos/configuration.nix
  services.postfix = {
    enable = true;
    relayHost = "mail.smtp2go.com";
    relayPort = 587;
    hostname = "mail.example.com";
    domain = "example.com";
    origin = "example.com";
    extraConfig = ''
      smtp_sasl_auth_enable = yes
      smtp_sasl_password_maps = texthash:/etc/nixos/secrets/postfix-sasl_passwd
      local_header_rewrite_clients = static:all
      append_dot_mydomain = yes
    '';
    networks = [
      "192.168.1.0/24"
      "172.17. 0.0/16"
    ];
  };

The first few lines should be pretty self-explanatory. They simply configure the relay via smtp2go and tell postfix to use my domain.

The extra config enables the authentication at the external mail host (more on that in a second) and it ensures that mails that don't have a proper sender address will have my domain added.

Finally the networks that may use this postfix as relay are added.

Now for authentication we need that postfix-sasl_passwd file.

It contains a single line:

/etc/nixos/secrets/postfix-sasl_passwd
[mail.smtp2go.com]:587 nas.example.com:mypassword

It tells postfix which username (nas.example.com) and which password (the one created earlier) to use when talking to smtp2go.

This config would be enough if you only want to access the postfix from the local machine. If you want to relay mail from your local network, you also need to open the firewall.

networking.firewall.allowedTCPPorts = [ 25 ];

After a nixos-rebuild switch your postfix relay should be working.

Testing

To test, install the mailutils package on your nix system (or start a shell with nix-shell -p mailutils) then send a mail to the outside world:

echo "hello world" | mail -s hello example@gmail.com

For testing via the network swaks is the best solution. On my Arch laptop:

yay -S swaks
swaks --to example@gmail.com --server 192.168.1.33

The ususal systemd tools for inspecting logs as well as the ReportsActivity page in smtp2go are helpful for debugging when something goes wrong.

Secrets Management? TBD.

For now I put the plain text password into secrets/postfix-sasl_passwd. Ideally I would use some kind of secrets management instead.

agenix seems to be the tool of choice here.

However piecing together the above config already took me the better half of the day, so that has to wait. As intriguing and cool the declarative configuration of Nix is, it does make things harder to set up than just editing a bunch of config files. Or to quote "sorbits" on Hackernews:

The problem I see with NixOS on a typical personal server is that you have to setup all these things using nix expressions, from which the actual configuration files are generated.

That means if you e.g. want to install postfix, instead of learning about main.cf you have to learn the syntax of the nix configuration wrapper for postfix, and postfix having hundreds if not thousands of options, many referring to external files/databases, you have to hope that whoever did this configuration wrapper, supported all the features of postfix that you want to use.
Tags:
nixos, postfix, mail, smtp, linux
Similar posts:

Comments