Roger Wilco wrote:MOD: Das ist eher ein MySQL- als ein Exim-Problem. ;)
Danke, das ist ein guter Denkanstoß. Hab die ganze Zeit in der falschen Richtung gesucht (CIDR-Matching in Exim :roll: ) Muss wohl doch mal meine SQL-Kenntnisse aufpolieren :D
Edith sagt, ich sollte wohl mal die genaue Lösung posten:
Zuerst mal eine geeignete Tabelle in der Datenbank anlegen:
Code: Select all
create table `blacklist` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`ip` VARCHAR(16) NOT NULL,
`mask` TINYINT UNSIGNED NOT NULL,
`entry_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(`id`),
UNIQUE KEY `cidr` (`ip`, `mask`)
);
Mit folgenden Statements lässt sich überprüfen, dass tatsächlich Subnetz-Matches erkannt werden:
Code: Select all
-- erst mal ein Subnetz eintragen
INSERT INTO `blacklist` (`ip`, `mask`) VALUES ('192.168.0.0', 16);
-- Positiv-Beispiel
SELECT 1 FROM `blacklist` WHERE
SUBSTRING(LPAD(BIN(INET_ATON('192.168.1.2')), 32, 0), 1, `blacklist`.`mask`)
= SUBSTRING(LPAD(BIN(INET_ATON(`blacklist`.`ip`)), 32, 0), 1, `blacklist`.`mask`);
-- Negativ-Beispiel
SELECT 1 FROM `blacklist` WHERE
SUBSTRING(LPAD(BIN(INET_ATON('10.0.0.1')), 32, 0), 1, `blacklist`.`mask`)
= SUBSTRING(LPAD(BIN(INET_ATON(`blacklist`.`ip`)), 32, 0), 1, `blacklist`.`mask`);
Die ACL für Exim sieht dementsprechend so aus:
Code: Select all
acl_check_connect:
deny message = We do not accept mails from spammers.
log_message = Rejected connection from ${sender_host_address}: This host is blacklisted.
condition = ${lookup mysql{ SELECT 1 FROM `blacklist` WHERE SUBSTRING(LPAD(BIN(INET_ATON('${quote_mysql:$sender_host_address}')), 32, 0), 1, `blacklist`.`mask`) = SUBSTRING(LPAD(BIN(INET_ATON(`blacklist`.`ip`)), 32, 0), 1, `blacklist`.`mask`); }{true}{false}}
accept
Die condition gehört natürlich in eine Zeile. Übrigens: wenn man {true} und {false} vertauscht, bekommt man eine Whitelist. Die sollte man vielleicht aber nicht in acl_check_connect einsetzen - zumindest nicht für einen öffentlich erreichbaren Mailserver
