Unverified Commit 97cd8f2b authored by Sandro Jäckel's avatar Sandro Jäckel Committed by GitHub
Browse files

postsrsd: 1.12 -> 2.0.10 + corresponding service changes (#397316)

parents 6ee34a4b d1e920fc
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -58,6 +58,10 @@
  OpenSMTPD 7.6.0 or later. The package has been removed in favor of a set of new
  `opensmtpd-table-*` packages.

- `postsrsd` upgraded to `>= 2.0.0`, with some different behaviors and
  configuration settings. Notably, it now defaults to listening on a socket
  rather than a port. See [Migrating from version 1.x](https://github.com/roehling/postsrsd/blob/2.0.10/README.rst#migrating-from-version-1x) and [Postfix Setup](https://github.com/roehling/postsrsd?tab=readme-ov-file#postfix-setup) for details.

- The hand written `perlPackages.SearchXapian` bindings have been dropped in favor of the (mostly compatible)
  `perlPackages.Xapian`.

+71 −58
Original line number Diff line number Diff line
@@ -7,16 +7,52 @@
let

  cfg = config.services.postsrsd;
  runtimeDirectoryName = "postsrsd";
  runtimeDirectory = "/run/${runtimeDirectoryName}";
  # TODO: follow RFC 42, but we need a libconfuse format first:
  #       https://github.com/NixOS/nixpkgs/issues/401565
  # Arrays in `libconfuse` look like this: {"Life", "Universe", "Everything"}
  # See https://www.nongnu.org/confuse/tutorial-html/ar01s03.html.
  #
  # Note: We're using `builtins.toJSON` to escape strings, but JSON strings
  # don't have exactly the same semantics as libconfuse strings. For example,
  # "${F}" gets treated as an env var reference, see above issue for details.
  libconfuseDomains = "{ " + lib.concatMapStringsSep ", " builtins.toJSON cfg.domains + " }";
  configFile = pkgs.writeText "postsrsd.conf" ''
    secrets-file = "''${CREDENTIALS_DIRECTORY}/secrets-file"
    domains = ${libconfuseDomains}
    separator = "${cfg.separator}"
    socketmap = "unix:${runtimeDirectory}/socket"

    # Disable postsrsd's jailing in favor of confinement with systemd.
    unprivileged-user = ""
    chroot-dir = ""
  '';

in
{

  ###### interface
  imports =
    map
      (
        name:
        lib.mkRemovedOptionModule [ "services" "postsrsd" name ] ''
          `postsrsd` was upgraded to `>= 2.0.0`, with some different behaviors and configuration settings:
            - NixOS Release Notes: https://nixos.org/manual/nixos/unstable/release-notes#sec-nixpkgs-release-25.05-incompatibilities
            - NixOS Options Reference: https://nixos.org/manual/nixos/unstable/options#opt-services.postsrsd.enable
            - Migration instructions: https://github.com/roehling/postsrsd/blob/2.0.10/README.rst#migrating-from-version-1x
            - Postfix Setup: https://github.com/roehling/postsrsd/blob/2.0.10/README.rst#postfix-setup
        ''
      )
      [
        "domain"
        "forwardPort"
        "reversePort"
        "timeout"
        "excludeDomains"
      ];

  options = {

    services.postsrsd = {

      enable = lib.mkOption {
        type = lib.types.bool;
        default = false;
@@ -29,9 +65,11 @@ in
        description = "Secret keys used for signing and verification";
      };

      domain = lib.mkOption {
        type = lib.types.str;
        description = "Domain name for rewrite";
      domains = lib.mkOption {
        type = lib.types.listOf lib.types.str;
        description = "Domain names for rewrite";
        default = [ config.networking.hostName ];
        defaultText = lib.literalExpression "[ config.networking.hostName ]";
      };

      separator = lib.mkOption {
@@ -44,36 +82,6 @@ in
        description = "First separator character in generated addresses";
      };

      # bindAddress = lib.mkOption { # uncomment once 1.5 is released
      #   type = lib.types.str;
      #   default = "127.0.0.1";
      #   description = "Socket listen address";
      # };

      forwardPort = lib.mkOption {
        type = lib.types.int;
        default = 10001;
        description = "Port for the forward SRS lookup";
      };

      reversePort = lib.mkOption {
        type = lib.types.int;
        default = 10002;
        description = "Port for the reverse SRS lookup";
      };

      timeout = lib.mkOption {
        type = lib.types.int;
        default = 1800;
        description = "Timeout for idle client connections in seconds";
      };

      excludeDomains = lib.mkOption {
        type = lib.types.listOf lib.types.str;
        default = [ ];
        description = "Origin domains to exclude from rewriting in addition to primary domain";
      };

      user = lib.mkOption {
        type = lib.types.str;
        default = "postsrsd";
@@ -85,17 +93,10 @@ in
        default = "postsrsd";
        description = "Group for the daemon";
      };

    };

  };

  ###### implementation

  config = lib.mkIf cfg.enable {

    services.postsrsd.domain = lib.mkDefault config.networking.hostName;

    users.users = lib.optionalAttrs (cfg.user == "postsrsd") {
      postsrsd = {
        group = cfg.group;
@@ -107,30 +108,42 @@ in
      postsrsd.gid = config.ids.gids.postsrsd;
    };

    systemd.services.postsrsd-generate-secrets = {
      path = [ pkgs.coreutils ];
      script = ''
        if [ -e "${cfg.secretsFile}" ]; then
          echo "Secrets file exists. Nothing to do!"
        else
          echo "WARNING: secrets file not found, autogenerating!"
          DIR="$(dirname "${cfg.secretsFile}")"
          install -m 750 -o ${cfg.user} -g ${cfg.group} -d "$DIR"
          install -m 600 -o ${cfg.user} -g ${cfg.group} <(dd if=/dev/random bs=18 count=1 | base64) "${cfg.secretsFile}"
        fi
      '';
      serviceConfig = {
        Type = "oneshot";
      };
    };

    systemd.services.postsrsd = {
      description = "PostSRSd SRS rewriting server";
      after = [ "network.target" ];
      after = [
        "network.target"
        "postsrsd-generate-secrets.service"
      ];
      before = [ "postfix.service" ];
      wantedBy = [ "multi-user.target" ];

      path = [ pkgs.coreutils ];
      requires = [ "postsrsd-generate-secrets.service" ];
      confinement.enable = true;

      serviceConfig = {
        ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -a${cfg.separator} -f${toString cfg.forwardPort} -r${toString cfg.reversePort} -t${toString cfg.timeout} "-X${lib.concatStringsSep "," cfg.excludeDomains}"'';
        ExecStart = "${lib.getExe pkgs.postsrsd} -C ${configFile}";
        User = cfg.user;
        Group = cfg.group;
        PermissionsStartOnly = true;
        RuntimeDirectory = runtimeDirectoryName;
        LoadCredential = "secrets-file:${cfg.secretsFile}";
      };

      preStart = ''
        if [ ! -e "${cfg.secretsFile}" ]; then
          echo "WARNING: secrets file not found, autogenerating!"
          DIR="$(dirname "${cfg.secretsFile}")"
          install -m 750 -o ${cfg.user} -g ${cfg.group} -d "$DIR"
          install -m 600 -o ${cfg.user} -g ${cfg.group} <(dd if=/dev/random bs=18 count=1 | base64) "${cfg.secretsFile}"
        fi
      '';
    };

  };
}
+9 −2
Original line number Diff line number Diff line
{
  lib,
  libconfuse,
  stdenv,
  fetchFromGitHub,
  cmake,
@@ -8,18 +9,20 @@

stdenv.mkDerivation rec {
  pname = "postsrsd";
  version = "1.12";
  version = "2.0.10";

  src = fetchFromGitHub {
    owner = "roehling";
    repo = "postsrsd";
    rev = version;
    sha256 = "sha256-aSI9TR1wSyMA0SKkbavk+IugRfW4ZEgpzrNiXn0F5ak=";
    sha256 = "sha256-8uy7a3wUGuLE4+6ZPqbFMdPzm6IZqQSvpZzLYAkBxNg=";
  };

  cmakeFlags = [
    "-DGENERATE_SRS_SECRET=OFF"
    "-DINIT_FLAVOR=systemd"
    "-DFETCHCONTENT_TRY_FIND_PACKAGE_MODE=ALWAYS"
    "-DINSTALL_SYSTEMD_SERVICE=OFF"
  ];

  preConfigure = ''
@@ -31,6 +34,10 @@ stdenv.mkDerivation rec {
    help2man
  ];

  buildInputs = [
    libconfuse
  ];

  meta = with lib; {
    homepage = "https://github.com/roehling/postsrsd";
    description = "Postfix Sender Rewriting Scheme daemon";