summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hostnix/elmo/configuration.nix6
-rw-r--r--hostnix/elmo/email.nix97
2 files changed, 103 insertions, 0 deletions
diff --git a/hostnix/elmo/configuration.nix b/hostnix/elmo/configuration.nix
index 6a4d1e2..6945fa5 100644
--- a/hostnix/elmo/configuration.nix
+++ b/hostnix/elmo/configuration.nix
@@ -5,6 +5,7 @@
./acme.nix
./dns.nix
./dyndns.nix
+ ./email.nix
./hardware-configuration.nix
./home-assistant.nix
./oidc.nix
@@ -55,6 +56,11 @@
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
+ virtualHosts."elmo.mou.fo" = {
+ default = true;
+ enableACME = true;
+ forceSSL = true;
+ };
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
diff --git a/hostnix/elmo/email.nix b/hostnix/elmo/email.nix
new file mode 100644
index 0000000..462a3d7
--- /dev/null
+++ b/hostnix/elmo/email.nix
@@ -0,0 +1,97 @@
+{ config, pkgs, ... }:
+
+{
+ imports = [ ./dyndns.nix ];
+
+ systemd.tmpfiles.rules = [
+ "d /var/lib/postfix/tls 0770 root root"
+ ];
+
+ security.acme.certs."${config.networking.fqdn}".postRun = ''
+ rm -rf /var/lib/postfix/tls/new
+ mkdir /var/lib/postfix/tls/new
+ cp -a fullchain.pem key.pem /var/lib/postfix/tls/new/
+ systemctl start postfix-tls-rotate
+ '';
+
+ systemd.services.postfix-tls-rotate = {
+ requires = [ "network-online.target" ];
+ after = [ "network-online.target" ];
+ serviceConfig = {
+ Type = "oneshot";
+ # Not really necessary indirection but interesting to try out. Note we
+ # must run as root (not DynamicUser) to run systemctl.
+ LoadCredential = [ "dyndns:/var/secrets/dyndns/" ];
+ };
+ environment = {
+ "DYNDNS" = "%d/dyndns";
+ };
+ script = ''
+ cd /var/lib/postfix/tls
+
+ publish() {
+ fqdn=${config.networking.fqdn}
+ tlsfps_fqdn=_tlsfps.''${fqdn%%.*}.dynamic.''${fqdn#*.}
+
+ ${pkgs.dnsutils}/bin/nsupdate -v -k ''${DYNDNS}_$(< ''${DYNDNS}_basename).private <<.
+ update delete $tlsfps_fqdn. TXT
+ $(
+ for cert in */fullchain.pem; do
+ echo -n "update add $tlsfps_fqdn. 300 TXT "
+ ${pkgs.openssl}/bin/openssl x509 -noout -fingerprint -sha256 -in "$cert" | cut -d= -f2
+ done
+ )
+ send
+ .
+ }
+
+ # If a certificate is next, we must have been invoked by our timer;
+ # rotate it to live.
+ if [[ -d next ]]; then
+ rm -rf prev
+ mv live prev
+ mv next live
+ systemctl reload postfix
+ # If a certificate is new then publish it.
+ elif [[ -d new ]]; then
+ publish
+ # We'll run again in at least an hour, after the postfix master picks up
+ # the new TLS fingerprints. But if this is the first run (there are no
+ # live certificates), rotate immediately.
+ if [[ -d live ]]; then
+ mv new next
+ else
+ mv new live
+ systemctl reload postfix
+ fi
+ fi
+ '';
+ };
+
+ systemd.timers.postfix-tls-rotate = {
+ wantedBy = [ "multi-user.target" ];
+ timerConfig = {
+ OnBootSec = "2h";
+ OnUnitInactiveSec = "2h";
+ };
+ };
+
+ services.postfix = {
+ enable = true;
+ hostname = config.networking.fqdn;
+ relayHost = "smtp.mou.town";
+ relayPort = 587;
+ sslCert = "/var/lib/postfix/tls/live/fullchain.pem";
+ sslKey = "/var/lib/postfix/tls/live/key.pem";
+ extraAliases = ''
+ root: joe
+ joe: joe@mou.fo
+ '';
+ config = {
+ smtp_tls_security_level = "encrypt";
+ smtp_tls_session_cache_database = "btree:\${data_directory}/smtp_scache";
+ message_size_limit = "51200000";
+ default_destination_rate_delay = "1s";
+ };
+ };
+}