標籤

4GL (1) 人才發展 (10) 人物 (3) 太陽能 (4) 心理 (3) 心靈 (10) 文學 (31) 生活常識 (14) 光學 (1) 名句 (10) 即時通訊軟體 (2) 奇狐 (2) 音樂 (2) 產業 (5) 郭語錄 (3) 無聊 (3) 統計 (4) 新聞 (1) 經濟學 (1) 經營管理 (42) 解析度 (1) 遊戲 (5) 電學 (1) 網管 (10) 廣告 (1) 數學 (1) 機率 (1) 雜趣 (1) 證券 (4) 證券期貨 (1) ABAP (15) AD (1) agentflow (4) AJAX (1) Android (1) AnyChart (1) Apache (14) BASIS (4) BDL (1) C# (1) Church (1) CIE (1) CO (38) Converter (1) cron (1) CSS (23) DMS (1) DVD (1) Eclipse (1) English (1) excel (5) Exchange (4) Failover (1) FI (57) File Transfer (1) Firefox (2) FM (2) fourjs (1) gladiatus (1) google (1) Google Maps API (2) grep (1) Grub (1) HR (2) html (23) HTS (8) IE (1) IE 8 (1) IIS (1) IMAP (3) Internet Explorer (1) java (3) JavaScript (22) jQuery (6) JSON (1) K3b (1) LED (3) Linux (112) Linux Mint (4) Load Balance (1) Microsoft (2) MIS (2) MM (51) MSSQL (1) MySQL (27) Network (1) NFS (1) Office (1) Oracle (125) Outlook (3) PDF (6) Perl (59) PHP (33) PL/SQL (1) PL/SQL Developer (1) PM (3) Postfix (2) postfwd (1) PostgreSQL (1) PP (50) python (1) QM (1) Red Hat (4) Reporting Service (28) ruby (11) SAP (234) scp (1) SD (16) sed (1) Selenium-WebDriver (5) shell (5) SQL (4) SQL server (8) SQuirreL SQL Client (1) SSH (2) SWOT (3) Symantec (2) T-SQL (7) Tera Term (2) tip (1) tiptop (22) Tomcat (6) Trouble Shooting (1) Tuning (5) Ubuntu (33) ufw (1) utf-8 (1) VIM (11) Virtual Machine (2) vnc (3) Web Service (2) wget (1) Windows (19) Windows (1) WM (6) youtube (1) yum (2)

2017年7月10日 星期一

如何防止某段時間寄同一人大量信件 (postfix 利用 postfwd2 達到限制寄件數量)

http://postfwd.org/quick.html

https://ssorc.tw/4296

我今天要來限制一個 Email 帳號一天只能寄 1000 封,超過了就會被擋掉無法再寄
Postfix 官網有提供幾個外掛使用,我拿 postfwd 來使用,postfwd 俗稱 postfix firewall daemon
另一個 policyd 可以參考 http://signalboxes.net/howto/policyd/
以下是 policyd 與 postfwd2 比較表
項目
Policyd v2 (cluebringer)
postfwd2
程式語言 Perl Perl
規則存放 Database FIle
參數調整 設定檔 程式參數
限制信件量 (per user, per domain) V V
ACL V V
Greylisting V V
Check HELO V
Support Amavis V
Check SPF V
WebUI V (沒有帳密驗證)
Date/time based rules
V
DNSBL
V
IPv6 出現格式錯誤 正常
文件 較為清楚 敘述較為模糊、複雜
安裝方式 RPM、手動 手動
設定 看似簡單,但需操作 DB 看似複雜,但邏輯容易理解
記錄檔 符合 Syslog 標準 符合 Syslog 標準
最後更新日期 2013-10-26 (2.014)
(與前一版幾乎沒有差異)
2013-04-18 (1.35)

postfwd 需要的 perl 套件
cpan -i Net::Server::Daemonize
cpan -i Net::Server::Multiplex
cpan -i Net::Server::PreFork
cpan -i Net::DNS
cpan -i IO::Multiplex
再來至 postfwd 下載套件,裡面包含 v1 與 v2 ,我要用 v2 版
解開後放到 /usr/local/postfwd (裡面就有 bin doc etc man plugins sbin tools 等目錄)
編輯 /usr/local/postfwd/bin/postfwd-script.sh,這是啟動檔
# 用 postfwd2
#PFWCMD=/usr/local/postfwd/sbin/postfwd
PFWCMD=/usr/local/postfwd/sbin/postfwd2
# rulesetconfig file 改名
PFWCFG=/etc/postfix/postfwd2.cf
# pidfile 改名
PFWPID=/tmp/postfwd2.pid
# 使用者換成 postfix
PFWUSER=postfix
PFWGROUP=postfix
# port 改成 10045
#PFWPORT=10040
PFWPORT=10045
# --shortlog 拿掉,因為 v2 不支援,加入 --keep_rates --save_rates /tmp/postfwd2.cache,才能有計數器功能,並額外記錄於 syslog
PFWARG="--summary=600 --cache=600 --cache-rbl-timeout=3600 --cleanup-requests=1200 --cleanup-rbls=1800 --cleanup-rates=1200 --keep_rates --save_rates /tmp/postfwd2.cache --logname postfwd2 --facility local0"
# 在 reload 的地方,把 -- reload 改成 --reload
放到 init.d 裡啟動
ln -s /usr/local/postfwd/bin/postfwd-script.sh /etc/init.d/postfwd2
編輯 /etc/postfix/main.cf,整合到 postfix 裡
# 如果有其它參數,這個一定要放在最前面
smtpd_recipient_restrictions = check_policy_service inet:127.0.0.1:10045
編輯 /etc/postfix/postfwd2.cf,這是放 rules 的地方,每設定一次就要 restart postfwd2
# 每天只允許同一寄件者只能寄 1000 封,多了就阻擋
# sender 是固定參數
# 1000 就是 1000 封
# 86400 就是 一天的時間 (秒)
# 後面的字串就是退信訊息
# Reject sender sends over 1000 per day
id=R01; action=rate(sender/1000/86400/REJECT sender $$sender exceeded limit of 1000 per day)
# 每天只允許同一來源 IP 只能寄 2000 封
# Reject client sends over 2000 per day
id=R02; action=rate(client_address/2000/86400/REJECT client $$client_address exceeded limit of 2000 per day)
編輯 /etc/rsyslog.conf,我把 log 額外放,預設是會放在 maillog 裡
*.info;mail.none;authpriv.none;cron.none;local0.none /var/log/messages
local0.* /var/log/postfwd2
service rsyslog restart
編輯 /etc/logrotate.d/syslog,把 log 檔作輪替
# 加入
/var/log/postfwd2
秀出定義在 conf 裡的 rule
/usr/local/postfwd/sbin/postfwd2 -f /etc/postfix/postfwd2.cf -C
查看計算結果
/usr/local/postfwd/sbin/postfwd2 --dumpcache
%rate_cache -> %client_address=127.0.0.1 -> @list -> 'R02+2000_86400'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @action -> 'REJECT client 127.0.0.1 exceeded limit of 2000 per day'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @count -> '1'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @maxcount -> '2000'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @rule -> 'R02'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @time -> '1391677750.95566'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @ttl -> '86400'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @type -> 'rate'
%rate_cache -> %client_address=127.0.0.1 -> %R02+2000_86400 -> @until -> '1391764150.95566'
%rate_cache -> %sender=cross@ssorc.tw -> @list -> 'R01+10_86400'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @action -> 'REJECT sender cross@ssorc.tw exceeded limit of 1000 per day'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @count -> '1'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @maxcount -> '1000'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @rule -> 'R01'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @time -> '1391677750.95566'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @ttl -> '86400'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @type -> 'rate'
%rate_cache -> %sender=cross@ssorc.tw -> %R01+10_86400 -> @until -> '1391764150.95566'
刪除計數結果,重新計算
/usr/local/postfwd/sbin/postfwd2 --delrate="sender=cross@ssorc.tw"
rate cache item 'sender=cross@ssorc.tw' removed
以上是清 sender,下面的就是清來源 IP 歸零
/usr/local/postfwd/sbin/postfwd2 --delrate="client_address=127.0.0.1"
rate cache item 'client_address=127.0.0.1' removed
如果成功外阻擋的話,maillog 會看到
Feb 6 16:51:35 ssorc postfix/smtpd[24633]: NOQUEUE: reject: RCPT from localhost[127.0.0.1]: 554 5.7.1 <cross@ssorc.tw>: Recipient address rejected: sender cross@ssorc.tw exceeded limit of 1000 per day; from=<cross@ssorc.tw> to=<cross@ssorc.tw> proto=ESMTP helo=<ssorc.tw>
至於 postfix 要怎麼新增 virtual domain
編輯 /etc/postfix/main.cf
smtpd_recipient_restrictions = check_policy_service inet:127.0.0.1:10045,permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
virtual_mailbox_domains = ssorc.tw
virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox_maps
virtual_mailbox_base = /var/vmail
virtual_uid_maps = static:1000
virtual_gid_maps = static:1000
編輯 /etc/postfix/virtual_mailbox_maps
cross@ssorc.tw ssorc.tw/cross/Maildir/
接著作完以下
postmap /etc/postfix/virtual_mailbox_maps
useradd -u 1000 -d /var/vmail -s /sbin/nologin vuser
mkdir /var/vmail/ssorc.tw/
chown -R vuser.vuser /var/vmail

postfwd 提供一個流程圖 可以看一下了解運作方式

http://postfwd.org/postfwd-ARCH.png

其它的限制也可以參考 postfwd rate limit examples
我上面的測試是針對所有 domain 的,但假如你要針對某個也是可以的
像它範例有提到 client_name=unknown 就針對來源是未知的
收件者是某某某 recipient_domain=XXX.tw
除了針對 sender 與 client_address 也可以針對 收件者名稱
id=R03; action=rate(recipient/20/86400/REJECT recipient $$recipient exceeded limit of 20 per day)
也可以針對信件大小 (不過我試不出來,從 cache 裡看不到相關資訊)
id=R04; action=size(recipient/2048000/86400/REJECT only allow 2mb per day)

Postfix 郵件過濾

https://blog.mikuru.tw/archives/36

這次我們講到如何利用 postfix 提供的種種過濾機制把討厭的 SPAM 擋在門外。
過濾的目標包括:來源、寄件者、收信者、附加檔、本文內容, etc.

[說明]
Postfix 本身就具備了兩種郵件過濾的機制:分別是標頭過濾(header)與本體過濾(body)
要使這兩個功能生效,你必須在 /usr/local/etc/postfix/main.cf 中加入:
header_checks = regexp:/usr/local/etc/postfix/header_checks
body_checks = regexp:/usr/local/etc/postfix/body_checks
header_checksbody_checks 分別代表了你的標頭過濾檔及本過濾檔。
過濾檢查的描述型態可以有三種方式
*hash:雜湊
*regexp:正規表示式(Regular Expression)
*pcre:相容於Perl之正規表示式(PCRE, Perl Compatable Regular Expression)
在本文中,我們將以 regexp 作為過濾檢查的描述型態。
[標頭過濾]
標頭,就是信件附帶的資訊,包含標題(Subject)、送件者 (From:)、收件者 (To:)及其他相關資訊,
甚至連你用什麼 mail client 來發送這封信件,都可以在標頭中看出端倪。
要設定標頭過濾的判斷條件,我們必須編輯 /usr/local/etc/postfix/header_checks
*對於發信者來源的過濾,我們可以加上:
/^From:.*badguy\.com/       DISCARD
*對於郵件標題的過濾,我們可以加上:
/^Subject:.*香豔刺激/        DISCARD
*對於途中經過轉寄主機的過濾,我們可以加上:
/^Received.*relay\.asshole\.com/  DISCARD
*對於郵件附加檔案的過濾,我們可以加上:
/filename\=.*\.pif/         DISCARD
/name\=.*\.pif/          DISCARD
[本體過濾]
本體,就是信件本身的內容囉。也就是發信者要呈現給收件者的訊息。
要設定本體過濾的判斷條件,我們必須編輯 /usr/local/etc/postfix/body_checks
*對於特定字串的過濾,我們可以加上:
/^dirty_words/           DISCARD