policyd

最後更新: 2022-08-12

目錄

  • MySQL Backend
  • Greylist
  • Greylist training
  • sender throttle
  • spamtrap
  • whitelist / blacklist
  • RCPT_ACL
  • Greylist Opt-in / Opt-out
  • Log
  • Troubleshot

 

介紹

Lang: C

Version:

policyd-1.8 (Version 1)

cluebringer (policyd-2)

 


Postfix 設定

 

main.cf

smtpd_recipient_restrictions =
 ...............
 reject_unauth_destination,
 check_policy_service inet:127.0.0.1:10031

事前要建立 mysql 的 DB 及 DB User

 


Install

 

  • postfix-policyd - anti-spam plugin for Postfix
  • postfwd - Postfix policyd to combine complex restrictions in a ruleset
  • postfix-policyd-spf-python - Postfix policy server for SPF checking

 


MySQL Backend

 

Centos:

/etc/policyd.conf

MYSQLHOST="127.0.0.1"
MYSQLDBASE="policyd"
MYSQLUSER="policyd"
MYSQLPASS="?????????????"
MYSQLOPT=""

FAILSAFE=1    <-- 連不到 DB 時會直接收 Mail

DATABASE_KEEPALIVE=0

DEBUG=0
DAEMON=1

BINDHOST="127.0.0.1"      <-- 入 E-Mail 的接口
BINDPORT="10031"

CONN_ACL="127.0.0.1 192.168.0.0/24" <-- 什麼人可以 connect 它

 

Debian 設定檔:

/etc/dbconfig-common/postfix-policyd.conf   <-- any changes you make will be preserved (dpkg-reconfigure postfix-policyd)

# configure database with dbconfig-common ?
dbc_install='false'

/etc/postfix-policyd.conf

 

DOC:

  • /usr/share/doc/postfix-policyd

 


Greylist

 

此功能大約可以擋掉 50-90% 的垃圾郵件

/etc/policyd.conf

停用:

#   1=on  0=off
GREYLISTING=0

設定:

Postfix Setting

smtpd_recipient_restrictions = ..... check_policy_service inet:127.0.0.1:10031 .......

/etc/policyd.conf

GREYLIST_REJECTION="Please try later." <-- 第一次來信彈回的對話

GREYLIST_X_HEADER=1    <-- 通過 Greylist 的 mail 會加 header (比人知做了野)

GREYLIST_HOSTADDR=3   <-- 來源的 IP 限制 1.2.3.4 (對 roaming MTAs 很有用)

TRAINING_MODE=1           <-- 所有 mail 都可以通過, 藉此建立 triplets list  <-- 在 log 會見到 greylist=update_train

TRAINING_POLICY_TIMEOUT=7d  <-- training 幾耐(對新加的 Domain 尤其有用)

TRIPLET_TIME=1m           <-- 過多久後的來信才算是"第2次"來信

TRIPLET_AUTH_TIMEOUT=14d   <-- 成功建立的 TRIPLET  保存幾耐 (發信成功)

TRIPLET_UNAUTH_TIMEOUT=1d   <-- 沒有成功的 TRIPLET 幾時 Delete (no retry attempt)

OPTINOUT=0                  <-- 當 1 時, 只會對 "某些" 人啟用 greylist

policy_time_limit = 3600    <-- 單位是 sec, 它是指會一個 policy 的 process 可以活幾耐(spawn)

 

作用

SMTP Error Code: 450 (Please Try Again Later)

... mail policyd: rcpt=70, greylist=new, host=R.R.R.R (unknown), [email protected], to=tester@?????, size=0
... mail postfix/smtpd[4702]: NOQUEUE: reject: RCPT from unknown[209.85.160.45]: 450 4.7.1 <tester@???>:
    Recipient address rejected: Policy Rejection- Please try later.; 
    from=<[email protected]> to=<tester@???> proto=ESMTP helo=<mail-pb0-f45.google.com>

 


Greylist training

 

啟用:

TRAINING_MODE=1

TRAINING_POLICY_TIMEOUT=7d

DB:

Table: policy_training

  _rcpt   = email address or domain
  _expire = seconds since epoch

使用:

INSERT INTO policy_training (_rcpt,_expire) VALUES  ('@mweb.co.za', UNIX_TIMESTAMP() );

意思:

domain: mweb.co.za 會接受由現在開始的 7 天 training

 


 

DB 結構:

 

table: triplet

_from
_rcpt
_host         <--- 來源的 IP (當不同 IP 來時, 那就當是另一 triplet 記錄)
_datanew
_data_last
_count

 

Result:

新入來的 E-Mail 會收到以下回覆:

Recipient address rejected: Policy Rejection- Please try later.

 


 

Sender throttle

 

Postfix Setting

/etc/postfix/main.cf

# sender throttle
smtpd_end_of_data_restrictions = check_policy_service inet:127.0.0.1:10032

 

設定 [email protected] 有以下限制

  • 在 1 天內
  • 發 50 信
  • Total 250Mbyte (每信最大 10Mbyte)
     

From Limit:

INSERT INTO throttle \
 (_from,_count_max,_quota_max,_time_limit,_mail_size,_date,_priority)
 VALUES ('[email protected]',  # from address                             
          50,                # maximum messages per time unit
          250000000,         # size in bytes (250 megs) (maximum is 2gig)
          86400,             # time unit in seconds (1 day)
          10240000,          # maximum message size (10 meg)
          UNIX_TIMESTAMP(),  # current time
          10);               # priority of record

 

From Domain Limit:

INSERT INTO throttle \
 (_from,_count_max,_quota_max,_time_limit,_mail_size,_date,_priority)
 VALUES ('@domain.com',      # domain                                   
          50,                # maximum messages per time unit
          250000000,         # size in bytes (250 megs) (maximum is 2gig)
          86400,             # time unit in seconds (1 day)
          10240000,          # maximum message size (10 meg)
          UNIX_TIMESTAMP(),  # current time
          5);                # priority of record

 

SASL user name:

INSERT INTO throttle
(_from,_count_max,_quota_max,_time_limit,_mail_size,_date)
 VALUES ('SASL_username',    # from address, SASL username or ip address
          50,                # maximum messages per time unit
          250000000,         # size in bytes (250 megs)
          86400,             # time unit in seconds (1 day)
          10240000,          # maximum message size (10 meg)
          UNIX_TIMESTAMP()); # current time

 

IP:

INSERT INTO throttle \
 (_from,_count_max,_quota_max,_time_limit,_mail_size,_date,_priority)
 VALUES ('192.168.0.%',      # domain                                   
          50,                # maximum messages per time unit
          250000000,         # size in bytes (250 megs) (maximum is 2gig)
          86400,             # time unit in seconds (1 day)
          10240000,          # maximum message size (10 meg)
          UNIX_TIMESTAMP(),  # current time
          5);                # priority of record

 

在 iredmail 上, 它會用另外一個 policyd 去控制 Sender throttle

/etc/init.d

cp  -a  /etc/init.d/postfix-policyd  /etc/init.d/postfix-policyd_throttle

vi /etc/init.d/postfix-policyd_throttle

# Include policyd defaults if available
#if [ -f /etc/default/postfix-policyd ] ; then
#       . /etc/default/postfix-policyd
#fi

CONFIG=/etc/postfix-policyd_throttle.conf

Postfix setting:

smtpd_end_of_data_restrictions = check_policy_service inet:127.0.0.1:10032

Policyd Setting:

/etc/postfix-policyd_throttle.conf          <--- port 10032

..........................
BINDPORT=10032
PIDFILE=/var/run/policyd_throttle.pid

# Disable other function first
RECIPIENTTHROTTLE=0           # <-- Disable recipient throttling in this instance.

WHITELISTING=0                # <-- If set to 1, throttling won't work!
BLACKLISTING=0
BLACKLIST_HELO=0
BLACKLISTSENDER=0
HELO_CHECK=0
SPAMTRAPPING=0
GREYLISTING=0

# you may only enable SENDER_THROTTLE_SASL or SENDER_THROTTLE_HOST
# but *NOT* both.
SENDERTHROTTLE=1
SENDER_THROTTLE_SASL=1
SENDER_THROTTLE_HOST=0

# 一個人可 send 多少 mail 出去, default: 360
SENDERMSGLIMIT=100

# 收件人數量限制, default: 5000
SENDERRCPTLIMIT=300

# default: 250 meg
SENDERQUOTALIMIT=500000000

# counters reset
# m: minute
SENDERTIMELIMIT=1h

# defualt: 10 Mbyte
SENDERMSGSIZE=20480000

# trigger a warning to syslog
SENDERMSGSIZE_WARN=50

# 保持 DB 清潔
SENDER_INACTIVE_EXPIRE=7d

就算沒有開啟 RECIPIENTTHROTTLE, DB 仍會有 RECIPIENTTHROTTLE 所需的資料.

RECIPIENTTHROTTLE=1

RECIPIENTMSGLIMIT=64

RECIPIENTTIMELIMIT=1h

RECIPIENT_QUOTA_REJECTION="Quota Exceeded."

 

DB 內 _count_max 決定了上限, _count_cur 是現在的寄出數量,

_date 是第一次有 record 的時間, _time_limit 是幾耐 refresh 一次 quota. (有 mail 時才 refresh)

_abuse_cur 是 在 _time_limit 內有無違後  polciy

 

log:

DEBUG=0 時的 log

Dec 16 18:45:26 mail policyd: connection from: 127.0.0.1 port: 33843 slots: 0 of 2044 used
# SENDER THROTTLE
Dec 16 18:45:26 mail policyd: rcpt=8, throttle=update(a), host=127.0.0.1, [email protected], [email protected], size=112/15728640, quota=224/250000000, count=2/5(7), rcpt=2/300(7), threshold=0%|20%|0%, [email protected]
# RECIPIENTMSGLIMIT
Dec 16 18:45:26 mail policyd: rcpt=8, throttle_rcpt=update(a), host=127.0.0.1, [email protected], [email protected], count=7/64(2), threshold=9%

失敗時:

Dec 16 19:01:54 mail policyd: rcpt=25, throttle=abuse(f), host=127.0.0.1, [email protected], [email protected], size=112/15728640, quota=560/250000000, count=5/5(18), rcpt=5/300(18), threshold=0%|100%|1%, [email protected]

 

原本的:

/etc/postfix-policyd.conf

SENDERTHROTTLE=0
SENDER_THROTTLE_SASL=0
SENDER_THROTTLE_HOST=0

RECIPIENTTHROTTLE=1         # <-- Enable recipient throttling in this instance.

 

自動執行:

/etc/init.d/policyd_throttle

# Provides:          postfix-policyd_throttle
CONFIG=/etc/postfix-policyd_throttle.conf

start-stop-daemon --start --quiet --background --pidfile /var/run/policyd_throttle.pid --exec /usr/sbin/postfix-policyd -- -c $DAEMON_CONFIG

 

設定:

# 啟用
SENDERTHROTTLE=1

# 用 login 決定 sender
SENDER_THROTTLE_SASL=1   <--- 與 SENDER_THROTTLE_HOST=1 只能2選1

QUOTA_EXCEEDED_TEMP_REJECT=1    <---- 4xx

SENDERMSGLIMIT=512
SENDERRCPTLIMIT=3600
SENDERQUOTALIMIT=250000000      <--- meg ( maximum supported size is 2gig)

SENDERTIMELIMIT=1h

SENDERMSGSIZE=10240000   <--- default: 10 meg

 

Result:

Log:

Jun 25 14:42:37 demo_iredmail postfix-policyd: DEBUG: fd: 9 checking throttle
Jun 25 14:42:37 demo_iredmail postfix-policyd: DEBUG: fd: 9 checking throttle-from
Jun 25 14:42:37 demo_iredmail postfix-policyd: rcpt=4, throttle=update(a), host=127.0.0.1, from=test@domain, to=test@????, size=1737/15728640, quota=10126/250000000, count=8/512(8), rcpt=8/3600(8), threshold=0%|1%|0%

 


spamtrap

 

設定:

SPAMTRAPPING=1
SPAMTRAP_REJECTION="Abuse. Go away."
SPAMTRAP_AUTO_EXPIRE=7d

使用:

INSERT INTO spamtrap (_rcpt,_active) VALUES ('[email protected]', 1);

當有人 Send E-Mail 比 [email protected], 它會被 Ban 7

Log:

在這 setting 下.

smtpd_recipient_restrictions = reject_unknown_sender_domain,
 reject_unknown_recipient_domain,
 reject_non_fqdn_sender,
 reject_non_fqdn_recipient,
 reject_unlisted_recipient,
 check_recipient_access regexp:/etc/postfix/check_recipient_access,
 check_sender_access regexp:/etc/postfix/check_sender_access,
 check_recipient_access proxy:mysql:/etc/postfix/mysql/check_recipient_access.cf
 permit_mynetworks, permit_sasl_authenticated,
 reject_unauth_destination
 check_policy_service inet:127.0.0.1:10031

當沒有 info 這 mailbox 時

5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual mailbox table

建立 mailbox 後

5.7.1 <[email protected]>: Recipient address rejected: Policy Rejection- Abuse. Go away.

P.S.

spamtrap 要用到 blacklisting 這 module !!

當有人中左 trap, 在 Table: blacklist 內有以下 record

_blacklist  _description                                 _expire
x.x.x.x     # spamtrap delivery: ([email protected])   1393407054

此外 whitelist > blacklist . 所以我們應該把 relay server 加到入 whitelist.


 

whitelist / blacklist

 

在 policyd.conf 加入

WHITELISTING=1

WHITELISTNULL=0    <-- Null Sender 不在 whitelist

WHITELISTSENDER=1

WHITELISTDNSNAME=0

AUTO_WHITE_LISTING=1                 <-- remote networks
AUTO_WHITELIST_NUMBER=10             <-- 當它的 IP Send 多過 10 mail 而又過到 whitlist 時
AUTO_WHITELIST_NETBLOCK=0            <-- 它的主機 ( 1 = Class C )
AUTO_WHITELIST_EXPIRE=7d             <-- 將會被加到白名單 7 天 ( 0 = 永遠 )

 

BLACKLISTING=1

BLACKLISTDNSNAME=0        <--- 不用 DNS Name 去記錄

BLACKLIST_TEMP_REJECT=0

BLACKLIST_NETBLOCK=0

BLACKLIST_REJECTION="Abuse. Go away."

AUTO_BLACK_LISTING=1
AUTO_BLACKLIST_NUMBER=500
AUTO_BLACKLIST_EXPIRE=7d

 

BLACKLIST_HELO=0

BLACKLIST_HELO_AUTO_EXPIRE=0      <--- permanent blacklist

 

BLACKLISTSENDER=1

 

 

優先次序:

whitelist_sender >  blacklist_sender

格式:

在 mysql 內的 table

whitelist (ip):

192.168.10.%

whitelist_dnsname(reverse DNS):

bigfish.com
%.bigfish.com
 

whitelist_sender(@domain):

[email protected]
@mweb.co.za

 

中了 blacklist 的人:

By Sender:

554 5.7.1 <[email protected]>: Recipient address rejected: Policy Rejection- Abuse. Go away. <-- 人手設定的

By IP:

554 5.7.1 <[email protected]>: Recipient address rejected: Policy Rejection- Abuse. Go away.

 

 


 

RCPT_ACL

功能:

Per User / Domain Whitelist / blacklists.

table: rcpt_acl

  • _sender
  • _rcpt
  • _wblist
  • _priority

設定:

RCPT_ACL=1

 


 

Greylist Opt-in / Opt-out

 

功能:

某些 account 不受 Greylist 影響

spamtraps 一定要在此, 否則捉唔到 spamer

Table: policy

  • _rcpt
  • _optin(1 = Opt-in, 0 = Opt-out)
  • _priority (高=勝)

設定:

OPTINOUT=1             // 啟用 opt in / out 功能

OPTINOUTALL=1       // default 所有人opted in (選擇在)

 

Example:

除了[email protected] 外, 所有在 @mweb.co.za 會受 graylist 影響

  INSERT INTO policy (_rcpt,_optin,_priority) VALUES ('[email protected]', 0, 50);

只有 cami 影 graylist 影響

  INSERT INTO policy (_rcpt,_optin,_priority) VALUES ('@mweb.co.za', 1, 10);
  INSERT INTO policy (_rcpt,_optin,_priority) VALUES ('[email protected]', 0, 50);

 


 

Log

Jun 25 14:42:37 demo_iredmail postfix-policyd: rcpt=4, throttle=update(a),

host=127.0.0.1, from=test@domain, to=test@????,

size=1737/15728640, quota=10126/250000000, count=8/512(8), rcpt=8/3600(8),

threshold=0%|1%|0%

 

rcpt=4         // 用了 policyd 多少次

 

# throttling

throttle=new          <- first mail from a sender
throttle=update       <- update mail quota
throttle=abuse        <- user limit has been reached
throttle=clear        <- user time has expired

 

# greylisting

greylist=new_train          <- 1st attempt to delivery mail to a user (training mode)
greylist=update_train      <- 2nd or more mail delivery attempts (training mode)
greylist=abl                    <- autoblacklist enabled & triggered
greylist=pass                 <- mysql has failed, but failover mode is enabled
greylist=abuse                <- 2 or more mail delivery attempts within defined "TRIPLET_TIME"

 

# spamtrap / other

type=spamtrap         <- delivery attempt to a spamtrap address
type=blacklist            <- blacklisted host/netblock
type=blacklist_helo   <- host caught using forged HELO

 


 

Troubleshot

 

configure file 的 value 沒有單位時:

Jun 25 11:51:51 mymailserver postfix-policyd: fatal: invalid time unit: 1

當 servcie 起不到時:

Jan 10 18:51:52 mymailserver postfix/smtpd[21035]: warning: connect to 127.0.0.1:10032: Connection refused
Jan 10 18:51:52 mymailserver postfix/smtpd[21035]: warning: problem talking to server 127.0.0.1:10032: Connection refused

查看 Debug MSG:

修改 /etc/postfix-policyd.conf

DEBUG=1 
DAEMON=0

postfix-policyd -c /etc/postfix-policyd.conf

 


詳見

HomePage

http://policyd.sourceforge.net/readme.html

http://www.policyd.org/

Version2

http://datahunter.org/cluebringer

 

 

附加檔案大小
database.zip777 位元

Creative Commons license icon Creative Commons license icon