RokkuCode / go-policyd

Postfix policy sender rate limiter server for authenticated postfix users designed to limit spam volume after successfull phishing attacks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

lock go-policyd : a simple Postfix Policyd Rate limiter

Build Status Go Report Card

go-policyd project purpose is to limit postfix spam volume emission sent via authenticated abused user when phishing succeeds.

This daemon has been written from a existing policyd daemon : polka

go-policyd use postfix policy protocol (check Postfix SMTP Access Policy Delegation), and based on recipients numbers cumulated by day respond DUNNO (neutral)/ HOLD (store in quarantine)/ REJECT ( refuse mail.).

Using a centralized database, it may be used for multiple authenticated postfix relays.

Using this projects we successfully reduced our spam volume during phishing campaigns from 60.000 users spammed to 1500 per day.

Main features

accept.png Single binary serving as network daemon, allowing multiple remote postfix smtps centralisation.

accept.png Mysql(Mariadb) storage of policyd events.

accept.png Quota of total recipients by day for an authenticated sender (max 1500 recipients).

accept.png Hold queue when over quota for mail analysis and requeue if whitelisting or errors.

accept.png Rejection when recipients sum is over 2x quota max (3000)

accept.png Whitelisting is available during offices hours ( not Week Ends ). Blacklisted entries are permanent.

Build

"go build" should download dependencies and build binary

Using Makefile

NAME= $(notdir $(shell pwd))
TAG=$(shell git tag)

{NAME}:
  go build -ldflags '-w -s -X main.Version=${NAME}-${TAG}' -o ${NAME}

How to use go-policyd step by step

  • Configure postfix for policyd restrictions
  • Create mariadb database
  • copy binary in /local/bin/policyd,
  • Adapt config file contrib/policyd.cfg to /etc/postfix/policyd.cfg
  • Enable and start (CentOS systemd) service /local/etc/policyd.service

Postfix Configuration

Edit /etc/postfix/main.cf to add :

# Policyd restrictions ( at end_of_data stage for nbrcpt )
smtpd_end_of_data_restrictions = check_policy_service inet:127.0.0.1:9093

Then verify configuration with postfix check command

Mariadb SQL database creation

Mariadb should be enabled and running in order to create database.

> CREATE USER 'policyd_daemon'@'localhost' IDENTIFIED BY 'yourChoiceOfPassword';
Query OK, 0 rows affected (0.01 sec)

> CREATE DATABASE policyd;
Query OK, 1 row affected (0.00 sec)

> CREATE TABLE IF NOT EXISTS `events` (
  `ts` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `sasl_username` char(8) NOT NULL DEFAULT '',
  `sender` char(80) NOT NULL DEFAULT '',
  `client_address`char(80) NOT NULL DEFAULT '',
  `recipient_count` int(6) DEFAULT NULL,
  PRIMARY KEY (`ts`,`sasl_username`,`sender`,`client_address`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

> GRANT ALL PRIVILEGES ON policyd.* TO 'policyd_daemon'@'localhost';
Query OK, 0 rows affected (0.00 sec)

Nota :

  • DATETIME(3) avoid key collision when multiples connections occurs.
  • The cleaning of records older than 7 days is done daily every 24 hours.
  • A policyd top 20 usage display utility is available in contrib/policyd-top20.sh

CentOS Systemd daemon setup

# mkdir -p /local/bin/
# cp policyd /local/bin
# cp contrib/unit.service /local/etc/policyd.service
# cp contrib/policyd.cfg /etc/postfix/policyd.cfg
# edit /etc/postfix/policyd.cfg

# systemctl daemon-reload
# systemctl enable /local/etc/policyd.service
# systemctl start policyd.service
# systemctl status  policyd.service

Binary and config file localisation may be modified

Monit check (optional)

The daemon once started by systemd is restarted in the event of an unexpected shutdown.

However the daemon is also monitored by monit via the lines

check program policyd with path "/usr/bin/systemctl --quiet is-active policyd"
   if status != 0 then restart
   start program = "/usr/bin/systemctl start policyd.service"
   stop  program = "/usr/bin/systemctl stop  policyd.service"

## When user is over quota, mail is stored to postfix HOLD Queue, send alert
check file daemon.info with path /var/log/daemon.info
    ignore content = "monit"
    if match "DEFERRING overquota" then alert

Logs examples

go-policyd use syslog "daemon.ERR|INFO" facility

# tail /var/log/daemon.err
Sep 23 11:08:56 smtps policyd[8168]: ERROR while UPDATING db :dial tcp 127.0.0.1:3306: connect: connection refused
Sep 23 11:09:03 smtps policyd[8168]: ERROR while UPDATING db :dial tcp 127.0.0.1:3306: connect: connection refused
Sep 25 11:19:55 smtps systemd: Failed to start Policyd go daemon for Postfix.
Sep 25 11:20:20 smtps systemd: Failed to start Policyd go daemon for Postfix.

# tail /var/log/daemon.info
Sep 26 16:23:34 smtps policyd[18771]: Updating db: nathxxx/nathalie.xxxxxxxx@mydomain.fr/192.168.39.7/1/6
Sep 26 16:24:22 smtps policyd[18771]: Updating db: anaxxx/anabelle.xxxxxxx@mydomain.fr/192.168.39.96/1/46
Sep 26 16:28:15 smtps policyd[18771]: Updating db: marxxx/maria.xxxxxxx@sub.mydomain.fr/192.168.24.154/1/14

The log format is identifier / email / ip / recipients / recipientssumforthelast24h.

Sep 26 16:27:53 smtps policyd[18771]: Updating db: anaxxx/anabelle.xxxxxxx@mydomain.fr/192.168.39.96/2/50

indicates the sending of an email to 2 recipients, bringing the total of recipients over 24 hours to 50.

About

Postfix policy sender rate limiter server for authenticated postfix users designed to limit spam volume after successfull phishing attacks

License:GNU Affero General Public License v3.0


Languages

Language:Go 88.2%Language:Shell 6.4%Language:Makefile 5.3%