commit
02760890f3
|
@ -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
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
services.postfix.extraConfig = optionalString cfg.postfix.enable cfg.postfix.configFragment;
|
||||
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 ];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
80
pkgs/servers/mail/rmilter/fd-passing-libmilter.patch
Normal file
80
pkgs/servers/mail/rmilter/fd-passing-libmilter.patch
Normal file
|
@ -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;
|
|
@ -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 ];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue