From 1a64deeb894dc95e2645a75771732c6cc53a79ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Wed, 4 Oct 2023 01:35:06 +0200 Subject: Squash changes containing private information There were a lot of changes since the previous commit, but a lot of them contained personnal information about users. All thos changes got stashed into a single commit (history is kept in a different place) and private information was moved in a separate private repository --- flakes/private/milters/flake.lock | 186 ++++++++++++++++++++++++++++++++++ flakes/private/milters/flake.nix | 106 +++++++++++++++++++ flakes/private/milters/verify_from.py | 60 +++++++++++ 3 files changed, 352 insertions(+) create mode 100644 flakes/private/milters/flake.lock create mode 100644 flakes/private/milters/flake.nix create mode 100755 flakes/private/milters/verify_from.py (limited to 'flakes/private/milters') diff --git a/flakes/private/milters/flake.lock b/flakes/private/milters/flake.lock new file mode 100644 index 0000000..1a0c138 --- /dev/null +++ b/flakes/private/milters/flake.lock @@ -0,0 +1,186 @@ +{ + "nodes": { + "environment": { + "locked": { + "lastModified": 1, + "narHash": "sha256-rMKbM7fHqWQbI7y59BsPG8KwoDj2jyrvN2niPWB24uE=", + "path": "../environment", + "type": "path" + }, + "original": { + "path": "../environment", + "type": "path" + } + }, + "files-watcher": { + "locked": { + "lastModified": 1, + "narHash": "sha256-ZsdumUVoSPkV/DB6gO6dNDttjzalye0ToVBF9bl5W0k=", + "path": "../../files-watcher", + "type": "path" + }, + "original": { + "path": "../../files-watcher", + "type": "path" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1609246779, + "narHash": "sha256-eq6ZXE/VWo3EMC65jmIT6H/rrUc9UWOWVujkzav025k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "08c7ad4a0844adc4a7f9f5bb3beae482e789afa4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1609246779, + "narHash": "sha256-eq6ZXE/VWo3EMC65jmIT6H/rrUc9UWOWVujkzav025k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "08c7ad4a0844adc4a7f9f5bb3beae482e789afa4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "myuids": { + "locked": { + "lastModified": 1, + "narHash": "sha256-HkW9YCLQCNBX3Em7J7MjraVEZO3I3PizkVV2QrUdULQ=", + "path": "../myuids", + "type": "path" + }, + "original": { + "path": "../myuids", + "type": "path" + } + }, + "myuids_2": { + "locked": { + "lastModified": 1, + "narHash": "sha256-HkW9YCLQCNBX3Em7J7MjraVEZO3I3PizkVV2QrUdULQ=", + "path": "../myuids", + "type": "path" + }, + "original": { + "path": "../myuids", + "type": "path" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1597943282, + "narHash": "sha256-G/VQBlqO7YeFOSvn29RqdvABZxmQBtiRYVA6kjqWZ6o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c59ea8b8a0e7f927e7291c14ea6cd1bd3a16ff38", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1597943282, + "narHash": "sha256-G/VQBlqO7YeFOSvn29RqdvABZxmQBtiRYVA6kjqWZ6o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c59ea8b8a0e7f927e7291c14ea6cd1bd3a16ff38", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "openarc": { + "inputs": { + "flake-utils": "flake-utils", + "myuids": "myuids", + "nixpkgs": "nixpkgs", + "openarc": "openarc_2" + }, + "locked": { + "lastModified": 1, + "narHash": "sha256-+X3x0t7DSYBvgFAUGNnMV4F/vQOUWE+9Q4Az6V8/iTw=", + "path": "../../openarc", + "type": "path" + }, + "original": { + "path": "../../openarc", + "type": "path" + } + }, + "openarc_2": { + "flake": false, + "locked": { + "lastModified": 1537545083, + "narHash": "sha256-xUSRARC7875vFjtZ66t8KBlKmkEdIZblWHc4zqGZAQQ=", + "owner": "trusteddomainproject", + "repo": "OpenARC", + "rev": "355ee2a1ca85acccce494478991983b54f794f4e", + "type": "github" + }, + "original": { + "owner": "trusteddomainproject", + "repo": "OpenARC", + "type": "github" + } + }, + "opendmarc": { + "inputs": { + "flake-utils": "flake-utils_2", + "myuids": "myuids_2", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1, + "narHash": "sha256-dDS9a1XujZU6KVCgz2RKbx2T3yT1k7z0EknUh1OyMdQ=", + "path": "../../opendmarc", + "type": "path" + }, + "original": { + "path": "../../opendmarc", + "type": "path" + } + }, + "root": { + "inputs": { + "environment": "environment", + "files-watcher": "files-watcher", + "openarc": "openarc", + "opendmarc": "opendmarc", + "secrets": "secrets" + } + }, + "secrets": { + "locked": { + "lastModified": 1, + "narHash": "sha256-5AakznhrJFmwCD7lr4JEh55MtdAJL6WA/YuBks6ISSE=", + "path": "../../secrets", + "type": "path" + }, + "original": { + "path": "../../secrets", + "type": "path" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flakes/private/milters/flake.nix b/flakes/private/milters/flake.nix new file mode 100644 index 0000000..c4de5b6 --- /dev/null +++ b/flakes/private/milters/flake.nix @@ -0,0 +1,106 @@ +{ + inputs.secrets.url = "path:../../secrets"; + inputs.environment.url = "path:../environment"; + inputs.files-watcher.url = "path:../../files-watcher"; + inputs.opendmarc.url = "path:../../opendmarc"; + inputs.openarc.url = "path:../../openarc"; + outputs = { self, secrets, environment, opendmarc, openarc, files-watcher }: { + nixosModule = self.nixosModules.milters; + nixosModules.milters = { lib, pkgs, config, nodes, ... }: + { + imports = [ + secrets.nixosModule + environment.nixosModule + files-watcher.nixosModule + opendmarc.nixosModule + openarc.nixosModule + ]; + options.myServices.mail.milters.enable = lib.mkEnableOption "enable Mail milters"; + options.myServices.mail.milters.sockets = lib.mkOption { + type = lib.types.attrsOf lib.types.path; + default = { + opendkim = "/run/opendkim/opendkim.sock"; + opendmarc = config.services.opendmarc.socket; + openarc = config.services.openarc.socket; + }; + readOnly = true; + description = '' + milters sockets + ''; + }; + config = lib.mkIf config.myServices.mail.milters.enable { + secrets.keys = { + "opendkim" = { + isDir = true; + user = config.services.opendkim.user; + group = config.services.opendkim.group; + permissions = "0550"; + }; + "opendkim/eldiron.private" = { + user = config.services.opendkim.user; + group = config.services.opendkim.group; + permissions = "0400"; + text = config.myEnv.mail.dkim.eldiron.private; + }; + }; + users.users."${config.services.opendkim.user}".extraGroups = [ "keys" ]; + services.opendkim = { + enable = true; + socket = "local:${config.myServices.mail.milters.sockets.opendkim}"; + domains = + let + getDomains = p: lib.mapAttrsToList (n: v: v.fqdn) p.emailPolicies; + bydomain = builtins.mapAttrs (n: getDomains) nodes.eldiron.config.myServices.dns.zones; + domains' = lib.flatten (builtins.attrValues bydomain); + in + builtins.concatStringsSep "," domains'; + keyPath = config.secrets.fullPaths."opendkim"; + selector = "eldiron"; + configFile = pkgs.writeText "opendkim.conf" '' + SubDomains yes + UMask 002 + AlwaysAddARHeader yes + ''; + group = config.services.postfix.group; + }; + systemd.services.opendkim.serviceConfig.Slice = "mail.slice"; + systemd.services.opendkim.preStart = lib.mkBefore '' + # Skip the prestart script as keys are handled in secrets + exit 0 + ''; + services.filesWatcher.opendkim = { + restart = true; + paths = [ + config.secrets.fullPaths."opendkim/eldiron.private" + ]; + }; + + systemd.services.milter_verify_from = { + description = "Verify from milter"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Slice = "mail.slice"; + User = "postfix"; + Group = "postfix"; + ExecStart = let + pymilter = with pkgs.python38Packages; buildPythonPackage rec { + pname = "pymilter"; + version = "1.0.4"; + src = fetchPypi { + inherit pname version; + sha256 = "1bpcvq7d72q0zi7c8h5knhasywwz9gxc23n9fxmw874n5k8hsn7k"; + }; + doCheck = false; + buildInputs = [ pkgs.libmilter ]; + }; + python = pkgs.python38.withPackages (p: [ pymilter ]); + in "${python}/bin/python ${./verify_from.py} -s /run/milter_verify_from/verify_from.sock"; + RuntimeDirectory = "milter_verify_from"; + }; + }; + }; + }; + }; +} diff --git a/flakes/private/milters/verify_from.py b/flakes/private/milters/verify_from.py new file mode 100755 index 0000000..b75001e --- /dev/null +++ b/flakes/private/milters/verify_from.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +import Milter +import argparse +from email.header import decode_header +from email.utils import parseaddr + +class CheckMilter(Milter.Base): + def __init__(self): + self.envelope_from = None + self.header_from = None + + @Milter.noreply + def connect(self, IPname, family, hostaddr): + return Milter.CONTINUE + + def hello(self, heloname): + return Milter.CONTINUE + + def envfrom(self, mailfrom, *args): + self.envelope_from = parseaddr(mailfrom)[1] + return Milter.CONTINUE + + @Milter.noreply + def envrcpt(self, to, *str): + return Milter.CONTINUE + + @Milter.noreply + def header(self, name, hval): + if name.lower() == "from": + self.header_from = parseaddr(decode_header(hval)[-1][0])[1] + return Milter.CONTINUE + + def eoh(self): + if self.header_from is not None and self.header_from != "" and self.header_from != self.envelope_from: + self.setreply("553", xcode="5.7.1", msg="<%s>: From header rejected: not matching envelope From %s" + % (self.header_from, self.envelope_from)) + return Milter.REJECT + + return Milter.CONTINUE + + @Milter.noreply + def body(self, chunk): + return Milter.CONTINUE + + def eom(self): + return Milter.ACCEPT + + def close(self): + return Milter.CONTINUE + + def abort(self): + return Milter.CONTINUE + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--socket", "-s", type=str, help="socket to listen to") + config = parser.parse_args() + + Milter.factory = CheckMilter + Milter.runmilter("check_from", config.socket, timeout=300) -- cgit v1.2.3