summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobin Gloster <mail@glob.in>2021-05-18 23:34:03 -0500
committerMaximilian Bosch <maximilian@mbosch.me>2021-08-24 23:46:06 +0200
commit0eafc74d503ffb6973676cb225d73c09c0fc1a39 (patch)
treec1d6fbe1659bd08ba8ec1c8d65086dd48f37046e
parentf03fc1e966fff4741356428ee132a33e613fb4ed (diff)
downloadnixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.tar
nixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.tar.gz
nixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.tar.bz2
nixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.tar.lz
nixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.tar.xz
nixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.tar.zst
nixpkgs-0eafc74d503ffb6973676cb225d73c09c0fc1a39.zip
postfixadmin: init at 3.3.9
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/mail/postfixadmin.nix164
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/postfixadmin.nix31
-rw-r--r--pkgs/servers/postfixadmin/default.nix27
-rw-r--r--pkgs/top-level/all-packages.nix2
6 files changed, 226 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 2fbab4a6873..f07de862eac 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -460,6 +460,7 @@
   ./services/mail/opensmtpd.nix
   ./services/mail/pfix-srsd.nix
   ./services/mail/postfix.nix
+  ./services/mail/postfixadmin.nix
   ./services/mail/postsrsd.nix
   ./services/mail/postgrey.nix
   ./services/mail/spamassassin.nix
diff --git a/nixos/modules/services/mail/postfixadmin.nix b/nixos/modules/services/mail/postfixadmin.nix
new file mode 100644
index 00000000000..9fd6630ee36
--- /dev/null
+++ b/nixos/modules/services/mail/postfixadmin.nix
@@ -0,0 +1,164 @@
+{ lib, config, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.postfixadmin;
+  fpm = config.services.phpfpm.pools.postfixadmin;
+  localDB = cfg.database.host == "localhost";
+  user = if localDB then cfg.database.username else "nginx";
+in
+{
+  options.services.postfixadmin = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to enable postfixadmin.
+
+        Also enables nginx virtual host management.
+        Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.&lt;name&gt;</literal>.
+        See <xref linkend="opt-services.nginx.virtualHosts"/> for further information.
+      '';
+    };
+
+    hostName = mkOption {
+      type = types.str;
+      example = "postfixadmin.example.com";
+      description = "Hostname to use for the nginx vhost";
+    };
+
+    adminEmail = mkOption {
+      type = types.str;
+      example = "postfixadmin.example.com";
+      description = ''
+        Define the Site Admin's email address below.
+        This will be used to send emails from to create mailboxes and
+        from Send Email / Broadcast message pages.
+      '';
+    };
+
+    setupPasswordFile = mkOption {
+      type = types.path;
+      description = ''
+        Password file for the admin.
+        Generate with <literal>php -r "echo password_hash('some password here', PASSWORD_DEFAULT);"</literal>
+      '';
+    };
+
+    database = {
+      username = mkOption {
+        type = types.str;
+        default = "postfixadmin";
+        description = ''
+          Username for the postgresql connection.
+          If <literal>database.host</literal> is set to <literal>localhost</literal>, a unix user and group of the same name will be created as well.
+        '';
+      };
+      host = mkOption {
+        type = types.str;
+        default = "localhost";
+        description = ''
+          Host of the postgresql server. If this is not set to
+          <literal>localhost</literal>, you have to create the
+          postgresql user and database yourself, with appropriate
+          permissions.
+        '';
+      };
+      passwordFile = mkOption {
+        type = types.path;
+        description = "Password file for the postgresql connection. Must be readable by user <literal>nginx</literal>.";
+      };
+      dbname = mkOption {
+        type = types.str;
+        default = "postfixadmin";
+        description = "Name of the postgresql database";
+      };
+    };
+
+    extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      description = "Extra configuration for the postfixadmin instance, see postfixadmin's config.inc.php for available options.";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.etc."postfixadmin/config.local.php".text = ''
+      <?php
+
+      $CONF['setup_password'] = file_get_contents('${cfg.setupPasswordFile}');
+
+      $CONF['database_type'] = 'pgsql';
+      $CONF['database_host'] = ${if localDB then "null" else "'${cfg.database.host}'"};
+      ${optionalString localDB "$CONF['database_user'] = '${cfg.database.username}';"}
+      $CONF['database_password'] = ${if localDB then "'dummy'" else "file_get_contents('${cfg.database.passwordFile}')"};
+      $CONF['database_name'] = '${cfg.database.dbname}';
+      $CONF['configured'] = true;
+
+      ${cfg.extraConfig}
+    '';
+
+    systemd.tmpfiles.rules = [ "d /var/cache/postfixadmin/templates_c 700 ${user} ${user}" ];
+
+    services.nginx = {
+      enable = true;
+      virtualHosts = {
+        ${cfg.hostName} = {
+          forceSSL = mkDefault true;
+          enableACME = mkDefault true;
+          locations."/" = {
+            root = "${pkgs.postfixadmin}/public";
+            index = "index.php";
+            extraConfig = ''
+              location ~* \.php$ {
+                fastcgi_split_path_info ^(.+\.php)(/.+)$;
+                fastcgi_pass unix:${fpm.socket};
+                include ${pkgs.nginx}/conf/fastcgi_params;
+                include ${pkgs.nginx}/conf/fastcgi.conf;
+              }
+            '';
+          };
+        };
+      };
+    };
+
+    services.postgresql = mkIf localDB {
+      enable = true;
+      ensureDatabases = [ cfg.database.dbname ];
+      ensureUsers = [ {
+        name = cfg.database.username;
+        ensurePermissions = {
+          "DATABASE ${cfg.database.username}" = "ALL PRIVILEGES";
+        };
+      } ];
+    };
+
+    users.users.${user} = mkIf localDB {
+      group = user;
+      isSystemUser = true;
+      createHome = false;
+    };
+    users.groups.${user} = mkIf localDB {};
+
+    services.phpfpm.pools.postfixadmin = {
+      user = user;
+      phpOptions = ''
+        error_log = 'stderr'
+        log_errors = on
+      '';
+      settings = mapAttrs (name: mkDefault) {
+        "listen.owner" = "nginx";
+        "listen.group" = "nginx";
+        "listen.mode" = "0660";
+        "pm" = "dynamic";
+        "pm.max_children" = 75;
+        "pm.start_servers" = 2;
+        "pm.min_spare_servers" = 1;
+        "pm.max_spare_servers" = 20;
+        "pm.max_requests" = 500;
+        "catch_workers_output" = true;
+      };
+    };
+  };
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 55b58d3bf22..6baa986b2bd 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -356,6 +356,7 @@ in
   pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {};
   postfix = handleTest ./postfix.nix {};
   postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
+  postfixadmin = handleTest ./postfixadmin.nix {};
   postgis = handleTest ./postgis.nix {};
   postgresql = handleTest ./postgresql.nix {};
   postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
diff --git a/nixos/tests/postfixadmin.nix b/nixos/tests/postfixadmin.nix
new file mode 100644
index 00000000000..aba5e3eed10
--- /dev/null
+++ b/nixos/tests/postfixadmin.nix
@@ -0,0 +1,31 @@
+import ./make-test-python.nix ({ pkgs, ...} : {
+  name = "postfixadmin";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ globin ];
+  };
+
+  nodes = {
+    postfixadmin = { config, pkgs, ... }: {
+      services.postfixadmin = {
+        enable = true;
+        hostName = "postfixadmin";
+        setupPasswordFile = pkgs.writeText "insecure-test-setup-pw-file" "$2y$10$r0p63YCjd9rb9nHrV9UtVuFgGTmPDLKu.0UIJoQTkWCZZze2iuB1m";
+      };
+      services.nginx.virtualHosts.postfixadmin = {
+        forceSSL = false;
+        enableACME = false;
+      };
+    };
+  };
+
+  testScript = ''
+    postfixadmin.start
+    postfixadmin.wait_for_unit("postgresql.service")
+    postfixadmin.wait_for_unit("phpfpm-postfixadmin.service")
+    postfixadmin.wait_for_unit("nginx.service")
+    postfixadmin.succeed(
+        "curl -sSfL http://postfixadmin/setup.php -X POST -F 'setup_password=not production'"
+    )
+    postfixadmin.succeed("curl -sSfL http://postfixadmin/ | grep 'Mail admins login here'")
+  '';
+})
diff --git a/pkgs/servers/postfixadmin/default.nix b/pkgs/servers/postfixadmin/default.nix
new file mode 100644
index 00000000000..e2da40bbc29
--- /dev/null
+++ b/pkgs/servers/postfixadmin/default.nix
@@ -0,0 +1,27 @@
+{ fetchFromGitHub, stdenv }:
+
+stdenv.mkDerivation rec {
+  pname = "postfixadmin";
+  version = "3.3.9";
+
+  src = fetchFromGitHub {
+    owner = pname;
+    repo = pname;
+    rev = "${pname}-${version}";
+    sha256 = "178ibnz8cd8nalg98zifsrpvqhi1i3k9rq5fbdpwlikqvppk0h08";
+  };
+
+  installPhase = ''
+    mkdir $out
+    cp -r * $out/
+    ln -sf /etc/postfixadmin/config.local.php $out/
+    ln -sf /var/cache/postfixadmin/templates_c $out/
+  '';
+
+  meta = {
+    description = "Web based virtual user administration interface for Postfix mail servers";
+    maintainers = with stdenv.lib.maintainers; [ globin ];
+    license = stdenv.lib.licenses.gpl2Plus;
+    platforms = stdenv.lib.platforms.all;
+  };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 7d407604308..a2f6ba134a0 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -20098,6 +20098,8 @@ with pkgs;
 
   postfix = callPackage ../servers/mail/postfix { };
 
+  postfixadmin = callPackage ../servers/postfixadmin { };
+
   postsrsd = callPackage ../servers/mail/postsrsd { };
 
   rspamd = callPackage ../servers/mail/rspamd { };