Merge branch 'rpsamd-web-ui' into 'master'

Add option to enable rspamd web ui

See merge request simple-nixos-mailserver/nixos-mailserver!341
This commit is contained in:
Sandro 2025-05-04 01:58:06 +02:00
commit 73304b495c
3 changed files with 60 additions and 11 deletions

View File

@ -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 <https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/>`_:
example with `basic auth <https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/>`_:
.. 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";

View File

@ -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;

View File

@ -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 '<body>'"
)
with subtest("nginx serves web ui"):
machine.succeed(
"set +o pipefail; ${pkgs.curl}/bin/curl http://localhost/ | grep -q '<body>'"
)
with subtest("imap port 143 is closed and imaps is serving SSL"):
machine.wait_for_closed_port(143)
machine.wait_for_open_port(993)