Skip to content

Commit 3d5339b

Browse files
committed
rspamd: add sender whitelist/blacklist maps
1 parent 76361dc commit 3d5339b

File tree

5 files changed

+239
-13
lines changed

5 files changed

+239
-13
lines changed

install/lib/installer_base.lib.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,7 @@ public function configure_rspamd() {
18981898
'users.conf',
18991899
'groups.conf',
19001900
'multimap.conf',
1901+
'force_actions.conf',
19011902
);
19021903
foreach ($local_d as $f) {
19031904
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
@@ -1951,6 +1952,66 @@ public function configure_rspamd() {
19511952
}
19521953
}
19531954

1955+
$filename = '/etc/rspamd/local.d/maps.d/sender_whitelist.inc.ispc';
1956+
@unlink($filename);
1957+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
1958+
if (count($records) > 0) {
1959+
if ($fp = fopen($filename, 'w')) {
1960+
fwrite($fp, "# ISPConfig whitelisted sender addresses\n\n");
1961+
foreach($records as $record) {
1962+
fwrite($fp, $record['source'] . "\n");
1963+
}
1964+
fclose($fp);
1965+
} else {
1966+
$this->error("Error: cannot open $filename for writing");
1967+
}
1968+
}
1969+
1970+
$filename = '/etc/rspamd/local.d/maps.d/sender_blacklist.inc.ispc';
1971+
@unlink($filename);
1972+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
1973+
if (count($records) > 0) {
1974+
if ($fp = fopen($filename, 'w')) {
1975+
fwrite($fp, "# ISPConfig blacklisted sender addresses\n\n");
1976+
foreach($records as $record) {
1977+
fwrite($fp, $record['source'] . "\n");
1978+
}
1979+
fclose($fp);
1980+
} else {
1981+
$this->error("Error: cannot open $filename for writing");
1982+
}
1983+
}
1984+
1985+
$filename = '/etc/rspamd/local.d/maps.d/sender_domain_whitelist.inc.ispc';
1986+
@unlink($filename);
1987+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` NOT LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
1988+
if (count($records) > 0) {
1989+
if ($fp = fopen($filename, 'w')) {
1990+
fwrite($fp, "# ISPConfig whitelisted sender domains\n\n");
1991+
foreach($records as $record) {
1992+
fwrite($fp, ltrim($record['source'], '.') . "\n");
1993+
}
1994+
fclose($fp);
1995+
} else {
1996+
$this->error("Error: cannot open $filename for writing");
1997+
}
1998+
}
1999+
2000+
$filename = '/etc/rspamd/local.d/maps.d/sender_domain_blacklist.inc.ispc';
2001+
@unlink($filename);
2002+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` NOT LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
2003+
if (count($records) > 0) {
2004+
if ($fp = fopen($filename, 'w')) {
2005+
fwrite($fp, "# ISPConfig blacklisted sender domains\n\n");
2006+
foreach($records as $record) {
2007+
fwrite($fp, ltrim($record['source'], '.') . "\n");
2008+
}
2009+
fclose($fp);
2010+
} else {
2011+
$this->error("Error: cannot open $filename for writing");
2012+
}
2013+
}
2014+
19542015

19552016
# rename rspamd templates we no longer use
19562017
if(file_exists("/etc/rspamd/local.d/greylist.conf")) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
rules {
2+
3+
ISPC_WHITELIST_SENDER {
4+
expression = "(ISPC_WHITELIST_ENVFROM and (R_DKIM_ALLOW or R_SPF_ALLOW)) or (ISPC_WHITELIST_FROM and R_DKIM_ALLOW) and !CLAM_VIRUS and !JUST_EICAR";
5+
action = "no action";
6+
}
7+
8+
ISPC_BLACKLIST_SENDER {
9+
expression = "(ISPC_BLACKLIST_FROM or ISPC_BLACKLIST_FROM_DOMAIN) and R_DKIM_ALLOW and !ISPC_WHITELIST_SENDER and !ISPC_WHITELIST_SENDER_DOMAIN";
10+
action = "reject";
11+
}
12+
13+
ISPC_WHITELIST_SENDER_DOMAIN {
14+
expression = "(ISPC_WHITELIST_ENVFROM_DOMAIN and (ISPC_WHITELIST_DKIM or ISPC_WHITELIST_SPF)) or (ISPC_WHITELIST_FROM_DOMAIN and ISPC_WHITELIST_DKIM) and !CLAM_VIRUS and !JUST_EICAR";
15+
action = "no action";
16+
}
17+
18+
}

install/tpl/rspamd_multimap.conf.master

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,68 @@ ISPC_WHITELIST_IP {
99

1010
# ISPC_BLACKLIST_IP: Postfix blocks blacklisted IP's, no need to configure those here.
1111

12+
ISPC_WHITELIST_ENVFROM {
13+
type = "from";
14+
filter = "email";
15+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.local" ];
16+
score = -7.0;
17+
description = "Whitelisted sender address";
18+
group = "ispconfig";
19+
}
20+
21+
# ISPC_BLACKLIST_ENVFROM: Postfix blocks blacklisted senders, no need to configure those here.
22+
23+
ISPC_WHITELIST_ENVFROM_DOMAIN {
24+
type = "from";
25+
filter = "email:domain";
26+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.local" ];
27+
score = -7.0;
28+
description = "Whitelisted sender domain";
29+
group = "ispconfig";
30+
}
31+
32+
# ISPC_BLACKLIST_ENVFROM_DOMAIN: Postfix blocks blacklisted sender domains, no need to configure those here.
33+
34+
ISPC_WHITELIST_FROM {
35+
type = "selector";
36+
selector = "from('mime')";
37+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.local" ];
38+
# trivial to spoof so primarily used via composite expression in force_actions.conf
39+
score = -1.0;
40+
description = "From: header address in sender whitelist.";
41+
group = "ispconfig";
42+
}
43+
44+
ISPC_BLACKLIST_FROM {
45+
type = "selector";
46+
selector = "from('mime')";
47+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_blacklist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_blacklist.inc.local" ];
48+
score = 12.0;
49+
description = "From: header address in sender blacklist.";
50+
group = "ispconfig";
51+
}
52+
53+
ISPC_WHITELIST_FROM_DOMAIN {
54+
type = "selector";
55+
selector = "from('mime'):domain";
56+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.local" ];
57+
# trivial to spoof so primarily used via composite expression in force_actions.conf
58+
score = -1.0;
59+
description = "From: header domain in sender whitelist.";
60+
group = "ispconfig";
61+
}
62+
63+
ISPC_BLACKLIST_FROM_DOMAIN {
64+
type = "selector";
65+
selector = "from('mime'):domain";
66+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_blacklist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_blacklist.inc.local" ];
67+
score = 12.0;
68+
description = "From: header domain in sender blacklist.";
69+
group = "ispconfig";
70+
}
71+
72+
73+
# Invaluement.com Service Provider DNSBLs
1274
# from https://rspamd.com/doc/configuration/selectors.html
1375
INVALUEMENT_SENDGRID_ID {
1476
type = "selector";

install/tpl/rspamd_whitelist.conf.master

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ rules {
22
"ISPC_WHITELIST_SPF" = {
33
valid_spf = true;
44
domains = [
5-
"$LOCAL_CONFDIR/local.d/maps.d/spf_whitelist.inc.ispc"
5+
"$LOCAL_CONFDIR/local.d/maps.d/spf_whitelist.inc.ispc",
6+
"$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.ispc",
7+
"$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.local"
68
];
79
score = -2.0
810
inverse_symbol = "ISPC_BLACKLIST_SPF";
@@ -11,7 +13,9 @@ rules {
1113
"ISPC_WHITELIST_DKIM" = {
1214
valid_dkim = true;
1315
domains = [
14-
"$LOCAL_CONFDIR/local.d/maps.d/dkim_whitelist.inc.ispc"
16+
"$LOCAL_CONFDIR/local.d/maps.d/dkim_whitelist.inc.ispc",
17+
"$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.ispc",
18+
"$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.local"
1519
];
1620
score = -2.0;
1721
inverse_symbol = "ISPC_BLACKLIST_DKIM";

server/plugins-available/rspamd_plugin.inc.php

Lines changed: 92 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -510,19 +510,100 @@ function mail_access_update($event_name, $data) {
510510

511511
$mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail');
512512

513+
514+
/*
515+
[new] => Array
516+
(
517+
[access_id] => 5
518+
[sys_userid] => 1
519+
[sys_groupid] => 1
520+
[sys_perm_user] => riud
521+
[sys_perm_group] => riud
522+
[sys_perm_other] =>
523+
[server_id] => 1
524+
[source] => 1.2.3.5
525+
[access] => OK
526+
[type] => client
527+
[active] => y
528+
)
529+
*/
513530
# generated local.d/maps.d files
514-
$filename = '/etc/rspamd/local.d/maps.d/ip_whitelist.inc.ispc';
515-
@unlink($filename);
516-
$records = $app->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'client' AND `access` = 'OK' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
517-
if (count($records) > 0) {
518-
if ($fp = fopen($filename, 'w')) {
519-
fwrite($fp, "# ISPConfig whitelisted ip addresses\n\n");
520-
foreach($records as $record) {
521-
fwrite($fp, $record['source'] . "\n");
531+
if ($data['old']['type'] == 'client' || $data['new']['type'] == 'client') {
532+
$filename = '/etc/rspamd/local.d/maps.d/ip_whitelist.inc.ispc';
533+
@unlink($filename);
534+
$records = $app->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'client' AND `access` = 'OK' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
535+
if (count($records) > 0) {
536+
if ($fp = fopen($filename, 'w')) {
537+
fwrite($fp, "# ISPConfig whitelisted ip addresses\n\n");
538+
foreach($records as $record) {
539+
fwrite($fp, $record['source'] . "\n");
540+
}
541+
fclose($fp);
542+
} else {
543+
$app->log("Error: cannot open $filename for writing", LOGLEVEL_WARN);
544+
}
545+
}
546+
}
547+
548+
if ($data['old']['type'] == 'sender' || $data['new']['type'] == 'sender') {
549+
$filename = '/etc/rspamd/local.d/maps.d/sender_whitelist.inc.ispc';
550+
@unlink($filename);
551+
$records = $app->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
552+
if (count($records) > 0) {
553+
if ($fp = fopen($filename, 'w')) {
554+
fwrite($fp, "# ISPConfig whitelisted sender addresses\n\n");
555+
foreach($records as $record) {
556+
fwrite($fp, $record['source'] . "\n");
557+
}
558+
fclose($fp);
559+
} else {
560+
$app->log("Error: cannot open $filename for writing", LOGLEVEL_WARN);
561+
}
562+
}
563+
564+
$filename = '/etc/rspamd/local.d/maps.d/sender_blacklist.inc.ispc';
565+
@unlink($filename);
566+
$records = $app->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
567+
if (count($records) > 0) {
568+
if ($fp = fopen($filename, 'w')) {
569+
fwrite($fp, "# ISPConfig blacklisted sender addresses\n\n");
570+
foreach($records as $record) {
571+
fwrite($fp, $record['source'] . "\n");
572+
}
573+
fclose($fp);
574+
} else {
575+
$app->log("Error: cannot open $filename for writing", LOGLEVEL_WARN);
576+
}
577+
}
578+
579+
$filename = '/etc/rspamd/local.d/maps.d/sender_domain_whitelist.inc.ispc';
580+
@unlink($filename);
581+
$records = $app->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` NOT LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
582+
if (count($records) > 0) {
583+
if ($fp = fopen($filename, 'w')) {
584+
fwrite($fp, "# ISPConfig whitelisted sender domains\n\n");
585+
foreach($records as $record) {
586+
fwrite($fp, ltrim($record['source'], '.') . "\n");
587+
}
588+
fclose($fp);
589+
} else {
590+
$app->log("Error: cannot open $filename for writing", LOGLEVEL_WARN);
591+
}
592+
}
593+
594+
$filename = '/etc/rspamd/local.d/maps.d/sender_domain_blacklist.inc.ispc';
595+
@unlink($filename);
596+
$records = $app->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` NOT LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
597+
if (count($records) > 0) {
598+
if ($fp = fopen($filename, 'w')) {
599+
fwrite($fp, "# ISPConfig blacklisted sender domains\n\n");
600+
foreach($records as $record) {
601+
fwrite($fp, ltrim($record['source'], '.') . "\n");
602+
}
603+
fclose($fp);
604+
} else {
605+
$app->log("Error: cannot open $filename for writing", LOGLEVEL_WARN);
522606
}
523-
fclose($fp);
524-
} else {
525-
$app->log("Error: cannot open $filename for writing", LOGLEVEL_WARN);
526607
}
527608
}
528609
}

0 commit comments

Comments
 (0)