From 0eafc74d503ffb6973676cb225d73c09c0fc1a39 Mon Sep 17 00:00:00 2001 From: Robin Gloster <mail@glob.in> Date: Tue, 18 May 2021 23:34:03 -0500 Subject: [PATCH] postfixadmin: init at 3.3.9 --- nixos/modules/module-list.nix | 1 + nixos/modules/services/mail/postfixadmin.nix | 164 +++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/postfixadmin.nix | 31 ++++ pkgs/servers/postfixadmin/default.nix | 27 +++ pkgs/top-level/all-packages.nix | 2 + 6 files changed, 226 insertions(+) create mode 100644 nixos/modules/services/mail/postfixadmin.nix create mode 100644 nixos/tests/postfixadmin.nix create mode 100644 pkgs/servers/postfixadmin/default.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2fbab4a68739..f07de862eacd 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 000000000000..9fd6630ee368 --- /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.<name></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 55b58d3bf22d..6baa986b2bda 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 000000000000..aba5e3eed102 --- /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 000000000000..e2da40bbc291 --- /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 7d4076043088..a2f6ba134a0d 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 { };