Skip to content

Commit e27a978

Browse files
committed
rspamd: add recipient whitelist/blacklist maps
1 parent 3d5339b commit e27a978

File tree

4 files changed

+212
-28
lines changed

4 files changed

+212
-28
lines changed

install/lib/installer_base.lib.php

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,7 +1939,7 @@ public function configure_rspamd() {
19391939
# generated local.d/maps.d files
19401940
$filename = '/etc/rspamd/local.d/maps.d/ip_whitelist.inc.ispc';
19411941
@unlink($filename);
1942-
$records = $this->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']);
1942+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'client' AND `access` = 'OK' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
19431943
if (count($records) > 0) {
19441944
if ($fp = fopen($filename, 'w')) {
19451945
fwrite($fp, "# ISPConfig whitelisted ip addresses\n\n");
@@ -1954,7 +1954,7 @@ public function configure_rspamd() {
19541954

19551955
$filename = '/etc/rspamd/local.d/maps.d/sender_whitelist.inc.ispc';
19561956
@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']);
1957+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
19581958
if (count($records) > 0) {
19591959
if ($fp = fopen($filename, 'w')) {
19601960
fwrite($fp, "# ISPConfig whitelisted sender addresses\n\n");
@@ -1969,7 +1969,7 @@ public function configure_rspamd() {
19691969

19701970
$filename = '/etc/rspamd/local.d/maps.d/sender_blacklist.inc.ispc';
19711971
@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']);
1972+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
19731973
if (count($records) > 0) {
19741974
if ($fp = fopen($filename, 'w')) {
19751975
fwrite($fp, "# ISPConfig blacklisted sender addresses\n\n");
@@ -1984,7 +1984,7 @@ public function configure_rspamd() {
19841984

19851985
$filename = '/etc/rspamd/local.d/maps.d/sender_domain_whitelist.inc.ispc';
19861986
@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']);
1987+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` NOT LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
19881988
if (count($records) > 0) {
19891989
if ($fp = fopen($filename, 'w')) {
19901990
fwrite($fp, "# ISPConfig whitelisted sender domains\n\n");
@@ -1999,7 +1999,7 @@ public function configure_rspamd() {
19991999

20002000
$filename = '/etc/rspamd/local.d/maps.d/sender_domain_blacklist.inc.ispc';
20012001
@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']);
2002+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'sender' AND `source` NOT LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
20032003
if (count($records) > 0) {
20042004
if ($fp = fopen($filename, 'w')) {
20052005
fwrite($fp, "# ISPConfig blacklisted sender domains\n\n");
@@ -2012,6 +2012,66 @@ public function configure_rspamd() {
20122012
}
20132013
}
20142014

2015+
$filename = '/etc/rspamd/local.d/maps.d/recipient_whitelist.inc.ispc';
2016+
@unlink($filename);
2017+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'recipient' AND `source` LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
2018+
if (count($records) > 0) {
2019+
if ($fp = fopen($filename, 'w')) {
2020+
fwrite($fp, "# ISPConfig whitelisted recipient addresses\n\n");
2021+
foreach($records as $record) {
2022+
fwrite($fp, $record['source'] . "\n");
2023+
}
2024+
fclose($fp);
2025+
} else {
2026+
$this->error("Error: cannot open $filename for writing");
2027+
}
2028+
}
2029+
2030+
$filename = '/etc/rspamd/local.d/maps.d/recipient_blacklist.inc.ispc';
2031+
@unlink($filename);
2032+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'recipient' AND `source` LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
2033+
if (count($records) > 0) {
2034+
if ($fp = fopen($filename, 'w')) {
2035+
fwrite($fp, "# ISPConfig blacklisted recipient addresses\n\n");
2036+
foreach($records as $record) {
2037+
fwrite($fp, $record['source'] . "\n");
2038+
}
2039+
fclose($fp);
2040+
} else {
2041+
$this->error("Error: cannot open $filename for writing");
2042+
}
2043+
}
2044+
2045+
$filename = '/etc/rspamd/local.d/maps.d/recipient_domain_whitelist.inc.ispc';
2046+
@unlink($filename);
2047+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'recipient' AND `source` NOT LIKE '%@%' AND `access` = 'OK' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
2048+
if (count($records) > 0) {
2049+
if ($fp = fopen($filename, 'w')) {
2050+
fwrite($fp, "# ISPConfig whitelisted recipient domains\n\n");
2051+
foreach($records as $record) {
2052+
fwrite($fp, ltrim($record['source'], '.') . "\n");
2053+
}
2054+
fclose($fp);
2055+
} else {
2056+
$this->error("Error: cannot open $filename for writing");
2057+
}
2058+
}
2059+
2060+
$filename = '/etc/rspamd/local.d/maps.d/recipient_domain_blacklist.inc.ispc';
2061+
@unlink($filename);
2062+
$records = $this->db->queryAllRecords("SELECT `source` FROM ?? WHERE `type` = 'recipient' AND `source` NOT LIKE '%@%' AND `access` LIKE 'REJECT%' AND `active` = 'y' AND `sys_userid` IN (SELECT `userid` FROM `sys_user` WHERE `sys_groupid` = 0) AND `server_id` = ? ORDER BY `source` ASC", $conf['mysql']['database'] . '.mail_access', $conf['server_id']);
2063+
if (count($records) > 0) {
2064+
if ($fp = fopen($filename, 'w')) {
2065+
fwrite($fp, "# ISPConfig blacklisted recipient domains\n\n");
2066+
foreach($records as $record) {
2067+
fwrite($fp, ltrim($record['source'], '.') . "\n");
2068+
}
2069+
fclose($fp);
2070+
} else {
2071+
$this->error("Error: cannot open $filename for writing");
2072+
}
2073+
}
2074+
20152075

20162076
# rename rspamd templates we no longer use
20172077
if(file_exists("/etc/rspamd/local.d/greylist.conf")) {

install/tpl/rspamd_force_actions.conf.master

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ rules {
66
}
77

88
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";
9+
expression = "(ISPC_BLACKLIST_FROM or ISPC_BLACKLIST_FROM_DOMAIN) and R_DKIM_ALLOW and !ISPC_WHITELIST_SENDER and !ISPC_WHITELIST_SENDER_DOMAIN and !ISPC_WHITELIST_RECIPIENT";
1010
action = "reject";
1111
}
1212

@@ -15,4 +15,19 @@ rules {
1515
action = "no action";
1616
}
1717

18+
ISPC_WHITELIST_RECIPIENT {
19+
expression = "ISPC_WHITELIST_ENVRCPT and !CLAM_VIRUS and !JUST_EICAR";
20+
action = "no action";
21+
}
22+
23+
ISPC_BLACKLIST_RECIPIENT {
24+
expression = "(ISPC_BLACKLIST_TO or ISPC_BLACKLIST_TO_DOMAIN) and !ISPC_WHITELIST_SENDER and !ISPC_WHITELIST_SENDER_DOMAIN and !ISPC_WHITELIST_RECIPIENT";
25+
action = "reject";
26+
}
27+
28+
ISPC_WHITELIST_RECIPIENT_DOMAIN {
29+
expression = "ISPC_WHITELIST_ENVRCPT_DOMAIN and !CLAM_VIRUS and !JUST_EICAR";
30+
action = "no action";
31+
}
32+
1833
}

install/tpl/rspamd_multimap.conf.master

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
ISPC_WHITELIST_IP {
2-
description = "Whitelisted ip address";
32
group = "ISPConfig";
3+
description = "Whitelisted ip address.";
44
type = "ip";
55
map = [ "$LOCAL_CONFDIR/local.d/maps.d/ip_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/ip_whitelist.inc.local" ];
66
prefilter = "true";
@@ -10,63 +10,110 @@ ISPC_WHITELIST_IP {
1010
# ISPC_BLACKLIST_IP: Postfix blocks blacklisted IP's, no need to configure those here.
1111

1212
ISPC_WHITELIST_ENVFROM {
13-
type = "from";
14-
filter = "email";
13+
group = "ISPConfig";
14+
description = "Whitelisted sender address.";
15+
type = "selector";
16+
filter = "from('smtp')";
1517
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.local" ];
1618
score = -7.0;
17-
description = "Whitelisted sender address";
18-
group = "ispconfig";
1919
}
2020

2121
# ISPC_BLACKLIST_ENVFROM: Postfix blocks blacklisted senders, no need to configure those here.
2222

2323
ISPC_WHITELIST_ENVFROM_DOMAIN {
24-
type = "from";
25-
filter = "email:domain";
24+
group = "ISPConfig";
25+
description = "Whitelisted sender domain.";
26+
type = "selector";
27+
filter = "from('smtp'):domain";
2628
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.local" ];
2729
score = -7.0;
28-
description = "Whitelisted sender domain";
29-
group = "ispconfig";
3030
}
3131

3232
# ISPC_BLACKLIST_ENVFROM_DOMAIN: Postfix blocks blacklisted sender domains, no need to configure those here.
3333

3434
ISPC_WHITELIST_FROM {
35+
group = "ISPConfig";
36+
description = "From: header address in sender whitelist.";
3537
type = "selector";
3638
selector = "from('mime')";
3739
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_whitelist.inc.local" ];
3840
# trivial to spoof so primarily used via composite expression in force_actions.conf
3941
score = -1.0;
40-
description = "From: header address in sender whitelist.";
41-
group = "ispconfig";
4242
}
4343

4444
ISPC_BLACKLIST_FROM {
45+
group = "ISPConfig";
46+
description = "From: header address in sender blacklist.";
4547
type = "selector";
4648
selector = "from('mime')";
4749
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_blacklist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_blacklist.inc.local" ];
4850
score = 12.0;
49-
description = "From: header address in sender blacklist.";
50-
group = "ispconfig";
5151
}
5252

5353
ISPC_WHITELIST_FROM_DOMAIN {
54+
group = "ISPConfig";
55+
description = "From: header domain in sender whitelist.";
5456
type = "selector";
5557
selector = "from('mime'):domain";
5658
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_whitelist.inc.local" ];
5759
# trivial to spoof so primarily used via composite expression in force_actions.conf
5860
score = -1.0;
59-
description = "From: header domain in sender whitelist.";
60-
group = "ispconfig";
6161
}
6262

6363
ISPC_BLACKLIST_FROM_DOMAIN {
64+
group = "ISPConfig";
65+
description = "From: header domain in sender blacklist.";
6466
type = "selector";
6567
selector = "from('mime'):domain";
6668
map = [ "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_blacklist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/sender_domain_blacklist.inc.local" ];
6769
score = 12.0;
68-
description = "From: header domain in sender blacklist.";
69-
group = "ispconfig";
70+
}
71+
72+
# Reminder: test if whitelisted sender bypasses dkim signing for sender
73+
# Reminder: test if whitelisted recipient address bypasses dkim signing for sender
74+
75+
ISPC_WHITELIST_ENVRCPT {
76+
group = "ISPConfig";
77+
description = "Whitelisted recipient address.";
78+
type = "selector";
79+
filter = "rcpts('smtp')";
80+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/recipient_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/recipient_whitelist.inc.local" ];
81+
score = -7.0;
82+
}
83+
84+
# ISPC_BLACKLIST_ENVRCPT: Postfix blocks blacklisted recipients, no need to configure those here.
85+
86+
ISPC_WHITELIST_ENVRCPT_DOMAIN {
87+
group = "ISPConfig";
88+
description = "Whitelisted recipient domain.";
89+
type = "selector";
90+
filter = "rcpts('smtp'):domain";
91+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/recipient_domain_whitelist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/recipient_domain_whitelist.inc.local" ];
92+
score = -7.0;
93+
}
94+
95+
# ISPC_BLACKLIST_ENVRCPT_DOMAIN: Postfix blocks blacklisted recipient domains, no need to configure those here.
96+
97+
# ISPC_WHITELIST_TO: headers are trivial to forge, no whitelisting based on them
98+
99+
ISPC_BLACKLIST_TO {
100+
group = "ISPConfig";
101+
description = "To:/Cc: header address in recipient blacklist.";
102+
type = "selector";
103+
selector = "rcpts('mime')";
104+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/recipient_blacklist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/recipient_blacklist.inc.local" ];
105+
score = 12.0;
106+
}
107+
108+
# ISPC_WHITELIST_TO_DOMAIN: headers are trivial to forge, no whitelisting based on them
109+
110+
ISPC_BLACKLIST_TO_DOMAIN {
111+
group = "ISPConfig";
112+
description = "To:/Cc: header domain in recipient blacklist.";
113+
type = "selector";
114+
selector = "rcpts('mime'):domain";
115+
map = [ "$LOCAL_CONFDIR/local.d/maps.d/recipient_domain_blacklist.inc.ispc", "$LOCAL_CONFDIR/local.d/maps.d/recipient_domain_blacklist.inc.local" ];
116+
score = 12.0;
70117
}
71118

72119

0 commit comments

Comments
 (0)