summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/services/mail/rmilter.nix67
-rw-r--r--nixos/modules/services/mail/rspamd.nix59
-rw-r--r--pkgs/development/libraries/libmemcached/default.nix3
-rw-r--r--pkgs/servers/mail/rmilter/default.nix16
-rw-r--r--pkgs/servers/mail/rmilter/fd-passing-libmilter.patch80
-rw-r--r--pkgs/servers/mail/rspamd/default.nix8
6 files changed, 206 insertions, 27 deletions
diff --git a/nixos/modules/services/mail/rmilter.nix b/nixos/modules/services/mail/rmilter.nix
index a6e2a9fc7808..d1f7cd2e173e 100644
--- a/nixos/modules/services/mail/rmilter.nix
+++ b/nixos/modules/services/mail/rmilter.nix
@@ -7,9 +7,14 @@ let
   rspamdCfg = config.services.rspamd;
   cfg = config.services.rmilter;
 
+  inetSockets = map (sock: let s = stringSplit ":" sock; in "inet:${last s}:${head s}") cfg.bindInetSockets;
+  unixSockets = map (sock: "unix:${sock}") cfg.bindUnixSockets;
+
+  allSockets = unixSockets ++ inetSockets;
+
   rmilterConf = ''
 pidfile = /run/rmilter/rmilter.pid;
-bind_socket = ${cfg.bindSocket};
+bind_socket = ${if cfg.socketActivation then "fd:3" else concatStringsSep ", " allSockets};
 tempdir = /tmp;
 
   '' + (with cfg.rspamd; if enable then ''
@@ -68,14 +73,37 @@ in
         '';
        };
 
-      bindSocket =  mkOption {
-        type = types.string;
-        default = "unix:/run/rmilter/rmilter.sock";
-        description = "Socket to listed for MTA requests";
+      bindUnixSockets =  mkOption {
+        type = types.listOf types.str;
+        default = ["/run/rmilter.sock"];
+        description = ''
+          Unix domain sockets to listen for MTA requests.
+        '';
         example = ''
-            "unix:/run/rmilter/rmilter.sock" or
-            "inet:11990@127.0.0.1"
-          '';
+            [ "/run/rmilter.sock"]
+        '';
+      };
+
+      bindInetSockets = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Inet addresses to listen (in format accepted by systemd.socket)
+        '';
+        example = ''
+            ["127.0.0.1:11990"]
+        '';
+      };
+
+      socketActivation = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Enable systemd socket activation for rmilter.
+          (disabling socket activation not recommended
+          when unix socket used, and follow to wrong
+          permissions on unix domain socket.)
+        '';
       };
 
       rspamd = {
@@ -86,7 +114,7 @@ in
 
         servers = mkOption {
           type = types.listOf types.str;
-          default = ["r:0.0.0.0:11333"];
+          default = ["r:/run/rspamd.sock"];
           description = ''
             Spamd socket definitions.
             Is server name is prefixed with r: it is rspamd server.
@@ -129,7 +157,7 @@ in
           type = types.str;
           description = "Addon to postfix configuration";
           default = ''
-smtpd_milters = ${cfg.bindSocket}
+smtpd_milters = ${head allSockets}
 # or for TCP socket
 # # smtpd_milters = inet:localhost:9900
 milter_protocol = 6
@@ -169,21 +197,30 @@ milter_default_action = accept
 
       serviceConfig = {
         ExecStart = "${pkgs.rmilter}/bin/rmilter ${optionalString cfg.debug "-d"} -n -c ${rmilterConfigFile}";
+        ExecReload = "/bin/kill -USR1 $MAINPID";
         User = cfg.user;
         Group = cfg.group;
         PermissionsStartOnly = true;
         Restart = "always";
+        RuntimeDirectory = "rmilter";
+        RuntimeDirectoryPermissions="0755";
       };
 
-      preStart = ''
-        ${pkgs.coreutils}/bin/mkdir -p /run/rmilter
-        ${pkgs.coreutils}/bin/chown ${cfg.user}:${cfg.group} /run/rmilter
-      '';
+    };
 
+    systemd.sockets.rmilter = mkIf cfg.socketActivation {
+      description = "Rmilter service socket";
+      wantedBy = [ "sockets.target" ];
+      socketConfig = {
+          ListenStream = cfg.bindUnixSockets ++ cfg.bindInetSockets;
+          SocketUser = cfg.user;
+          SocketGroup = cfg.group;
+          SocketMode = "0660";
+      };
     };
 
     services.postfix.extraConfig = optionalString cfg.postfix.enable cfg.postfix.configFragment;
-
+    users.users.postfix.extraGroups = [ cfg.group ];
   };
 
 }
diff --git a/nixos/modules/services/mail/rspamd.nix b/nixos/modules/services/mail/rspamd.nix
index a083f8293243..412b99ccc570 100644
--- a/nixos/modules/services/mail/rspamd.nix
+++ b/nixos/modules/services/mail/rspamd.nix
@@ -6,6 +6,35 @@ let
 
   cfg = config.services.rspamd;
 
+  mkBindSockets = socks: concatStringsSep "\n" (map (each: "  bind_socket = \"${each}\"") socks);
+
+  rspamdConf =
+    ''
+      .include "$CONFDIR/common.conf"
+
+      options {
+        pidfile = "$RUNDIR/rspamd.pid";
+        .include "$CONFDIR/options.inc"
+      }
+
+      logging {
+        type = "file";
+        filename = "$LOGDIR/rspamd.log";
+        .include "$CONFDIR/logging.inc"
+      }
+
+      worker {
+      ${mkBindSockets cfg.bindSocket}
+        .include "$CONFDIR/worker-normal.inc"
+      }
+
+      worker {
+      ${mkBindSockets cfg.bindUISocket}
+        .include "$CONFDIR/worker-controller.inc"
+      }
+   '';
+   rspamdConfFile = pkgs.writeText "rspamd.conf" rspamdConf;
+
 in
 
 {
@@ -26,6 +55,32 @@ in
         description = "Whether to run the rspamd daemon in debug mode.";
       };
 
+      bindSocket = mkOption {
+        type = types.listOf types.str;
+        default = [
+          "/run/rspamd.sock mode=0666 owner=${cfg.user}"
+        ];
+        description = ''
+          List of sockets to listen, in format acceptable by rspamd
+        '';
+        example = ''
+          bindSocket = [
+            "/run/rspamd.sock mode=0666 owner=rspamd"
+            "*:11333"
+          ];
+        '';
+      };
+
+      bindUISocket = mkOption {
+        type = types.listOf types.str;
+        default = [
+          "localhost:11334"
+        ];
+        description = ''
+          List of sockets for web interface, in format acceptable by rspamd
+        '';
+      };
+
       user = mkOption {
         type = types.string;
         default = "rspamd";
@@ -62,7 +117,7 @@ in
 
     users.extraGroups = singleton {
       name = cfg.group;
-      gid = config.ids.gids.spamd;
+      gid = config.ids.gids.rspamd;
     };
 
     systemd.services.rspamd = {
@@ -72,7 +127,7 @@ in
       after = [ "network.target" ];
 
       serviceConfig = {
-        ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -f";
+        ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -c ${rspamdConfFile} -f";
         RuntimeDirectory = "/var/lib/rspamd";
         PermissionsStartOnly = true;
         Restart = "always";
diff --git a/pkgs/development/libraries/libmemcached/default.nix b/pkgs/development/libraries/libmemcached/default.nix
index 619aa0144976..2570c645f26e 100644
--- a/pkgs/development/libraries/libmemcached/default.nix
+++ b/pkgs/development/libraries/libmemcached/default.nix
@@ -19,7 +19,8 @@ stdenv.mkDerivation rec {
       sha256 = "1nvxwdkxj2a2g39z0g8byxjwnw4pa5xlvsmdk081q63vmfywh7zb";
     });
 
-  buildInputs = [ cyrus_sasl libevent ];
+  buildInputs = [ libevent ];
+  propagatedBuildInputs = [ cyrus_sasl ];
 
   meta = with stdenv.lib; {
     homepage = http://libmemcached.org;
diff --git a/pkgs/servers/mail/rmilter/default.nix b/pkgs/servers/mail/rmilter/default.nix
index c12ca525294c..d5ba98bfbb3c 100644
--- a/pkgs/servers/mail/rmilter/default.nix
+++ b/pkgs/servers/mail/rmilter/default.nix
@@ -1,22 +1,28 @@
-{ stdenv, fetchFromGitHub, cmake, bison, flex, openssl, pcre, libmilter, opendkim }:
+{ stdenv, fetchFromGitHub, cmake, bison, flex, openssl, pcre, libmilter, opendkim,
+ libmemcached }:
+
+let patchedLibmilter = stdenv.lib.overrideDerivation  libmilter (_ : {
+    patches = libmilter.patches ++ [ ./fd-passing-libmilter.patch ];
+});
+in
 
 stdenv.mkDerivation rec {
   name = "rmilter-${version}";
-  version = "1.7.3";
+  version = "1.8.1";
 
   src = fetchFromGitHub {
     owner = "vstakhov";
     repo = "rmilter";
     rev = version;
-    sha256 = "04xalaxq5xgg5ls0f4ayp8yhzdfq5gqjb8qwfyha3mrx4dqrgh7s";
+    sha256 = "0cplkc1acgysxn8id9wakd1fx0f76cazscpfqhrxyjbk5fb11ll4";
   };
 
   nativeBuildInputs = [ bison cmake flex ];
-  buildInputs = [ libmilter openssl pcre opendkim ];
+  buildInputs = [ libmemcached patchedLibmilter openssl pcre opendkim];
 
   meta = with stdenv.lib; {
     homepage = "https://github.com/vstakhov/rmilter";
-    license = licenses.bsd2;
+    license = licenses.asl20;
     description = ''
       Daemon to integrate rspamd and milter compatible MTA, for example
       postfix or sendmail
diff --git a/pkgs/servers/mail/rmilter/fd-passing-libmilter.patch b/pkgs/servers/mail/rmilter/fd-passing-libmilter.patch
new file mode 100644
index 000000000000..3ab61a6fab00
--- /dev/null
+++ b/pkgs/servers/mail/rmilter/fd-passing-libmilter.patch
@@ -0,0 +1,80 @@
+Description: systemd-like socket activation support for libmilter
+Author: Mikhail Gusarov <dottedmag@debian.org
+diff --git a/libmilter/docs/smfi_setconn.html b/libmilter/docs/smfi_setconn.html
+index 70a510e..013f04e 100644
+--- a/libmilter/docs/smfi_setconn.html
++++ b/libmilter/docs/smfi_setconn.html
+@@ -43,6 +43,7 @@ Set the socket through which this filter should communicate with sendmail.
+ 	<LI><CODE>{unix|local}:/path/to/file</CODE> -- A named pipe.
+ 	<LI><CODE>inet:port@{hostname|ip-address}</CODE> -- An IPV4 socket.
+ 	<LI><CODE>inet6:port@{hostname|ip-address}</CODE> -- An IPV6 socket.
++	<LI><CODE>fd:number</CODE> -- Pre-opened file descriptor.
+ 	</UL>
+ 	</TD></TR>
+     </TABLE>
+diff --git a/libmilter/listener.c b/libmilter/listener.c
+index 48c552f..2249a1f 100644
+--- a/libmilter/listener.c
++++ b/libmilter/listener.c
+@@ -197,6 +197,11 @@ mi_milteropen(conn, backlog, rmsocket, name)
+ 			L_socksize = sizeof addr.sin6;
+ 		}
+ #endif /* NETINET6 */
++		else if (strcasecmp(p, "fd") == 0)
++		{
++			addr.sa.sa_family = AF_UNSPEC;
++			L_socksize = sizeof (_SOCK_ADDR);
++		}
+ 		else
+ 		{
+ 			smi_log(SMI_LOG_ERR, "%s: unknown socket type %s",
+@@ -443,7 +448,21 @@ mi_milteropen(conn, backlog, rmsocket, name)
+ 	}
+ #endif /* NETINET || NETINET6 */
+ 
+-	sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
++	if (addr.sa.sa_family == AF_UNSPEC)
++	{
++		char *end;
++		sock = strtol(colon, &end, 10);
++		if (*end != '\0' || sock < 0)
++		{
++			smi_log(SMI_LOG_ERR, "%s: expected positive integer as fd, got %s", name, colon);
++			return INVALID_SOCKET;
++		}
++	}
++	else
++	{
++		sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
++	}
++
+ 	if (!ValidSocket(sock))
+ 	{
+ 		smi_log(SMI_LOG_ERR,
+@@ -466,6 +485,7 @@ mi_milteropen(conn, backlog, rmsocket, name)
+ #if NETUNIX
+ 	    addr.sa.sa_family != AF_UNIX &&
+ #endif /* NETUNIX */
++	    addr.sa.sa_family != AF_UNSPEC &&
+ 	    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt,
+ 		       sizeof(sockopt)) == -1)
+ 	{
+@@ -511,7 +531,8 @@ mi_milteropen(conn, backlog, rmsocket, name)
+ 	}
+ #endif /* NETUNIX */
+ 
+-	if (bind(sock, &addr.sa, L_socksize) < 0)
++	if (addr.sa.sa_family != AF_UNSPEC &&
++	    bind(sock, &addr.sa, L_socksize) < 0)
+ 	{
+ 		smi_log(SMI_LOG_ERR,
+ 			"%s: Unable to bind to port %s: %s",
+@@ -817,7 +838,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
+ # ifdef BSD4_4_SOCKADDR
+ 		     cliaddr.sa.sa_len == 0 ||
+ # endif /* BSD4_4_SOCKADDR */
+-		     cliaddr.sa.sa_family != L_family))
++		     (L_family != AF_UNSPEC && cliaddr.sa.sa_family != L_family)))
+ 		{
+ 			(void) closesocket(connfd);
+ 			connfd = INVALID_SOCKET;
diff --git a/pkgs/servers/mail/rspamd/default.nix b/pkgs/servers/mail/rspamd/default.nix
index f3156afd97ac..a9da7953978f 100644
--- a/pkgs/servers/mail/rspamd/default.nix
+++ b/pkgs/servers/mail/rspamd/default.nix
@@ -1,18 +1,18 @@
 { stdenv, fetchFromGitHub, cmake, perl
 , file, glib, gmime, libevent, luajit, openssl, pcre, pkgconfig, sqlite }:
 
-let libmagic = file;  # libmagic provided buy file package ATM
+let libmagic = file;  # libmagic provided by file package ATM
 in
 
 stdenv.mkDerivation rec {
   name = "rspamd-${version}";
-  version = "1.2.0";
+  version = "1.2.5";
 
   src = fetchFromGitHub {
     owner = "vstakhov";
     repo = "rspamd";
     rev = version;
-    sha256 = "00d9c9b8w6j0ls1w08bfghn4635as779b45vhhlv1f5wfzhxz6a1";
+    sha256 = "0slpixcfd74qkm7445lmcry4s1yamayphzzyr7cxjlr9xfxlblqn";
   };
 
   nativeBuildInputs = [ cmake pkgconfig perl ];
@@ -32,7 +32,7 @@ stdenv.mkDerivation rec {
 
   meta = with stdenv.lib; {
     homepage = "https://github.com/vstakhov/rspamd";
-    license = licenses.bsd2;
+    license = licenses.asl20;
     description = "advanced spam filtering system";
     maintainers = with maintainers; [ avnik fpletz ];
   };