diff --git a/docs/rspamd-tuning.rst b/docs/rspamd-tuning.rst index 3ba8133..4feb99d 100644 --- a/docs/rspamd-tuning.rst +++ b/docs/rspamd-tuning.rst @@ -93,18 +93,14 @@ With an nginx reverse-proxy If you have a secured nginx reverse proxy set on the host, you can use it to expose the socket. **Keep in mind the UI is unsecured by default, you need to setup an authentication scheme**, for -exemple with `basic auth `_: +example with `basic auth `_: .. code:: nix - services.nginx.virtualHosts.rspamd = { - forceSSL = true; - enableACME = true; - basicAuthFile = "/basic/auth/hashes/file"; - serverName = "rspamd.example.com"; - locations = { - "/" = { - proxyPass = "http://unix:/run/rspamd/worker-controller.sock:/"; - }; - }; + mailserver.rspamdWebUI = { + enable = true; + domain = "rspamd.example.com"; + allowedIPs = [ "0.0.0.0" "::/0" ]; }; + + services.nginx.virtualHosts."${config.mailserver.rspamdWebUI.domain}".basicAuthFile = "/basic/auth/hashes/file"; diff --git a/mail-server/rspamd.nix b/mail-server/rspamd.nix index ec919c2..7097d31 100644 --- a/mail-server/rspamd.nix +++ b/mail-server/rspamd.nix @@ -24,6 +24,35 @@ let rspamdSocket = "rspamd.service"; in { + options.mailserver.rspamdWebUI = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = '' + Whether to enable the rspamd web ui on the configured domain. + ''; + }; + + allowedIPs = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + example = [ "0.0.0.0" "::/0" ]; + description = '' + List of IPs from which the web ui will be reachable *without* authentication. + + When using a reverse proxy like nginx and another authentication method like basic auth or oatuh2-proxy is implemented, + than this can be set to ``[ "0.0.0.0" "::/0" ]`` to solely rely on the other authentication method. + ''; + }; + + domain = lib.mkOption { + type = lib.types.str; + example = "rspamd.example.org"; + description = "The domain under which the rspamd web ui should be reachable."; + }; + }; + config = with cfg; lib.mkIf enable { environment.systemPackages = lib.mkBefore [ (pkgs.runCommand "rspamc-wrapped" { @@ -34,9 +63,23 @@ in '') ]; + services.nginx = lib.mkIf cfg.rspamdWebUI.enable { + enable = true; + virtualHosts = { + "${cfg.rspamdWebUI.domain}" = { + locations."/".proxyPass = "http://unix:/run/rspamd/worker-controller.sock:/"; + }; + }; + }; + services.rspamd = { enable = true; inherit debug; + + overrides = lib.mkIf cfg.rspamdWebUI.enable { + "worker-controller.inc".text = lib.concatMapStringsSep "\n" (ip: ''secure_ip = "${ip}";'') cfg.rspamdWebUI.allowedIPs; + }; + locals = { "milter_headers.conf" = { text = '' extended_spam_headers = true; diff --git a/tests/internal.nix b/tests/internal.nix index 5835ce6..b64173f 100644 --- a/tests/internal.nix +++ b/tests/internal.nix @@ -81,6 +81,11 @@ pkgs.nixosTest { vmailUID = 5000; enableImap = false; + + rspamdWebUI = { + enable = true; + domain = "localhost"; + }; }; }; }; @@ -185,6 +190,11 @@ pkgs.nixosTest { "set +o pipefail; ${pkgs.curl}/bin/curl --unix-socket /run/rspamd/worker-controller.sock http://localhost/ | grep -q ''" ) + with subtest("nginx serves web ui"): + machine.succeed( + "set +o pipefail; ${pkgs.curl}/bin/curl http://localhost/ | grep -q ''" + ) + with subtest("imap port 143 is closed and imaps is serving SSL"): machine.wait_for_closed_port(143) machine.wait_for_open_port(993)