最後更新: 2018-07-19
目錄
- smtpd_recipient_restrictions
- smtpd_sender_restrictions
- RBL
- check_client_access
- check_recipient_access
- check_sender_access - BlockList Domain / User
- Lookup Tables
- hash Table
- cidr Table
- regexp (read-only)
- 限制收自己 Domain 的信
- Block Bogus Domain (localhost.localdomain)
- Cheat List
smtpd_recipient_restrictions
smtpd_recipient_restrictions 在 "RCPT TO" 後會作出相應的反應
smtpd_recipient_restrictions = <-- default: permit_mynetworks, reject_unauth_destination permit_mynetworks, <-- 自己人, 做什麼也可以 permit_sasl_authenticated, check_policy_service inet:127.0.0.1:7777, reject_non_fqdn_helo_hostname, <-- 連Helo 都不會的 Mail Server 是很可悲的 ..... reject_unknown_helo_hostname, reject_invalid_helo_hostname, reject_unknown_sender_domain, <-- DNS 都未攪好, 同樣可悲 reject_unknown_recipient_domain, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unlisted_recipient, <-- 對 "RCPT TO" 做限制, 非本地的不接, default: yes (即收件者不在 $local_recipient_maps, $virtual_mailbox_maps) reject_unauth_destination, (See the smtpd_reject_unlisted_recipient parameter description for details.) check_policy_service inet:127.0.0.1:10031
reject_unknown_sender_domain & reject_unknown_recipient_domain
MAIL FROM 的 Domain 沒有 DNS A / MX record, RCPT TO 的 Domain 沒有 DNS / MX record
以上兩者除本地是 final destination 外
Troubleshoot:
明明 x.x 有 A record 及 MX record, 但仍有以下 Error
450 4.1.8 <[email protected]>: Sender address rejected: Domain not found
建決
cp -a /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
reject_unlisted_recipient
Reject the request when the RCPT TO address is not listed in the list of valid recipients for its domain class.
smtpd_reject_unlisted_recipient (default: yes)
Request that the Postfix SMTP server rejects mail for unknown recipient addresses,
even when no explicit reject_unlisted_recipient access restriction is specified.
address classes
- The local domain class
- The virtual alias domain class
- The virtual mailbox domain class
- The relay domain class
- The default domain class
reject_unauth_destination
This setting helps prevent your mail server from being used as an open relay by spammers.
RCPT TO 的 E-Mail Address 不在以下 tables 時將會被 reject ( relay_domains_reject_code = 554)
- $relay_domains
- $mydestination
- $virtual_alias_domains
- $virtual_mailbox_domains
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
reject_invalid_helo_hostname
HELO 及 EHLO 的 hostname 要有 DNS A 或 MX record
配合 smtpd_helo_required = yes, 強制 client 要說 helo
而且要是正常的 Hostname
permit_auth_destination
RCPT TO domain matches $relay_domains / final destination
Summary
smtpd_recipient_restrictions 沒有 allow (permit_sasl_authenticated, permit_mynetworks ...)到時,
就會 log 到 "Client host rejected: Access denied;"
smtpd_sender_restrictions
applies in the context of a client "MAIL FROM" command
Default: empty, permit everything
P.S.
reject_unknown_sender_domain 用在 smtpd_sender_restrictions 效果會更加好
smtpd_sender_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain, permit_mynetworks, reject_sender_login_mismatch, permit_sasl_authenticated
RBL
postfix setting
smtpd_recipient_restrictions = ...
reject_rbl_client bl.spamcop.net,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org
常用的 RBL 供應商
- bl.spamcop.net
- sbl.spamhaus.org
- cbl.abuseat.org
- opm.blitzed.org
- dul.dnsbl.sorbs.net
- dun.dnsrbl.net
- ix.dnsbl.manitu.net
spamhaus 的 zen 是一個比較特別的 RBL 來, 因為它的返回 IP 是有特別意義的
- zen.spamhaus.org
詳見: http://www.spamhaus.org/zen/
check_client_access
# Search the specified access(5) database for source IP address
Example:
main.cf:
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_client_access hash:/etc/postfix/relay_ip, reject_unauth_destination, check_client_access hash:/etc/postfix/norbl, reject_rbl_client bl.spamcop.net, reject_rbl_client sbl.spamhaus.org, reject_rbl_client cbl.abuseat.org
[1] 無條件為某 IP 做 relay
relay_ip:
# 表達 subnet 時, IP 尾後不能加 "."
192.168.1 OK # local network R.R.R.R OK # remote ip
[2] Block IP / bypass RBL
norbl:
1.2.3.4 REJECT "Local Block List" 1.2.3 OK
Block log:
554 5.7.1 <unknown[1.2.3.4]>: Client host rejected: "Local Block List"
P.S.
postmap 一次即可, 不用 postfix reload
接受的 Action
- OK Accept the address
- REJECT [optional text]
- DISCARD
較小使用
- DUNNO
- BCC user@domain
- FILTER transport:destination
- HOLD [text]
- PREPEND headername: headervalue
- REDIRECT user@domain
- INFO text
- WARN text
DB 版
proxy_read_maps = ... $smtpd_recipient_restrictions ... smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, check_client_access proxy:mysql:/etc/postfix/mysql/block_ip.cf, ...
/etc/postfix/mysql/block_ip.cf
hosts = localhost dbname = sf user = sf password = ??? table = pf_block_ip query = SELECT CONCAT(action, " ", msg) FROM pf_block_ip where ( ip="%s" AND enable=1 ) limit 1
schema
CREATE TABLE IF NOT EXISTS `pf_block_ip` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ip` varchar(15) COLLATE utf8_bin NOT NULL DEFAULT 'xxx.xxx.xxx.xxx', `action` varchar(10) COLLATE utf8_bin NOT NULL DEFAULT 'REJECT', `msg` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT 'Block By Our Block List', `enable` tinyint(1) NOT NULL DEFAULT '1', `remark` varchar(255) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ip` (`ip`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
check_recipient_access
對 "RCPT TO" 的 address 進行查表, 之後可以使用 ACCESS(5) 內的可用的 Action
應用 1: 對某些收件人的不查 RBL
smtpd_recipient_restrictions =
...
permit_sasl_authenticated,
reject_unauth_destination,
check_recipient_access hash:/etc/postfix/alway_accept
...
reject_rbl_client zen.spamhaus.org,
reject_rbl_client bl.spamcop.net
建立 hash file:
postmap hash:/etc/postfix/alway_accept
alway_accept 內容:
abuse@ OK postmaster@ OK webmaster@ OK hostmaster@ OK
P.S.
postmap -q [email protected] hash:/etc/postfix/alway_accept 是沒有 result 的 !!
應用 1: 抗收到某 Mailbox 的信.
main.cf
smtpd_recipient_restrictions = ... check_recipient_access hash:/etc/postfix/recipient_access, ...
recipient_access
user@domain REJECT "Temporary closed."
postmap hash:/etc/postfix/recipient_access
mail log
... postfix/smtpd[20342]: NOQUEUE: reject: RCPT from unknown[s.s.s.s]:
554 5.7.1 <r@r>: Recipient address rejected:
"This email is no longer active. Please contact DB directly via cell.";
from=<s@s> to=<r@r> proto=ESMTP helo=<sender_server>
telnet 測試時看到的 msg
554 5.7.1 <r@r>: Recipient address rejected: "Temporary closed."
check_sender_access
Search the specified access(5) database for the MAIL FROM address, domain, parent domains, or localpart@,
and execute the corresponding action.
whitelist - sender
MySQL
user = policyd password = ????? hosts = 127.0.0.1 port = 3306 dbname = policyd query = SELECT action FROM whitelist_sender where ( _whitelist=concat('@',"%d") OR _whitelist="%s" ) limit 1
在 DB: policyd 的 table: whitelist_sender 上加入 feild: action
最後在 main.cf 修改 smtpd_recipient_restrictions
smtpd_recipient_restrictions = ... check_sender_access proxy:mysql:/etc/postfix/mysql/check_sender_access.cf ...
reject_unknown_sender_domain
設定 "unknown_address_reject_code" 用來設定 return code (default: 450)
MAIL FROM domain has
1) no DNS MX
2) no DNS address record
unknown_address_tempfail_action
The parameter specifies the action after a temporary DNS error(default: defer_if_permit)
Action:
defer_if_permit
Defer the request if some later restriction would result in an explicit or implicit PERMIT action.
Lookup Table
# To find out what types of lookup tables your Postfix system supports
postconf -m
btree cidr environ fail hash ...
hash Table (BlockList Domain / User)
* By default the lookup key is mapped to lowercase to make the lookups case insensitive
* hash table 不支援 ".", "*" 的 (所以用 regexp 會方便一點 )
* lookup 係整字的. "adoman.com" 是不會中 "domain.com" 的
* 不可以設定 lookup default value 項目
Remark: pcre 的 lookup example
check_sender_access pcre:/etc/postfix/blocklist.pcre
#### LAST ROW #### /./ FILTER amavis:[127.0.0.1]:10024
Example: BlockList Domain / User
main.cf
smtpd_recipient_restrictions = ... check_sender_access hash:/etc/postfix/blocklist ...
blocklist
/etc/postfix/blocklist
# adomain.com 是不中 blocklist 的 domain.com REJECT Block by our blocklist [email protected] REJECT Block by our blocklist
建立 hash 了的 file
postmap hash:/etc/postfix/blocklist
# blocklist --> blocklist.db
P.S.
在 SMTP Session 的 DATA 前會被 reject 的
cidr Table
cidr - Classless Inter-Domain Routing (CIDR)
這裡的 cidr 是指 cidr block
P.S.
Classful addressing = A(/8), B(/16), C(/24)
此 tables 可以在 check_client_access 使用
i.e.
smtpd_recipient_restrictions =
permit_mynetworks,
check_client_access cidr:/etc/postfix/blacklist_by_ip.cidr,
permit_sasl_authenticated,
check_recipient_access mysql:/etc/postfix/mysql-virtual_recipient.cf,
reject_unauth_destination,
# RBL
check_client_access cidr:/etc/postfix/bypass_rbl_by_ip.cidr,
reject_rbl_client b.barracudacentral.org,
reject_rbl_client bl.spamcop.net,
reject_rbl_client zen.spamhaus.org
* 注意 reject_unauth_destination 必須在 check_client_access 前
* 修改 *.cidr (blacklist_ip.cidr, whitelist_ip.cidr) 後要 postfix reload
* bypass_rbl_by_ip.cidr 比 blacklist_ip.cidr 係可以方便測試
Table Format
- network_address/prefix_length
- 0.0.0.0/0 matches every IPv4 address
- Rule order matters
i.e.
bypass_rbl_by_ip.cidr
192.168.1.1 OK 192.168.0.0/16 REJECT
regexp (read-only)
格式:
/pattern/flags result
!/pattern/flags result
flags:
- x # extended expression syntax (Default: on)
- i # sensitivity (Default: on)
- m # multi-line mode (Default: off)
* By default, matching is case-insensitive(即是 flag 的 i)
- .*
- \.
- ^
- $
e.g.
main.cf
check_recipient_access regexp:/etc/postfix/check_recipient_access,
check_recipient_access
/^postmaster@/ OK
# Disallow sender-specified routing.
/[%!@].*[%!@]/ 550 Sender-specified routing rejected
DOC:
http://www.postfix.org/regexp_table.5.html
http://www.postfix.org/DATABASE_README.html
限制收自己 Domain 的信(Reject incoming emails that use your own domain as sender)
方案1: check_policy_service - SPF
這是最好的方法, 因為 "Return-Path:" 與 "From:" 可能不一樣
smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_pipelining,
reject_invalid_hostname, reject_non_fqdn_hostname,
reject_unknown_recipient_domain,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf,
....
方案2: check_sender_access on smtpd_recipient_restrictions
main.cf
smtpd_recipient_restrictions = reject_unknown_sender_domain,
reject_unknown_recipient_domain,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unlisted_recipient,
permit_mynetworks,
permit_sasl_authenticated,
check_client_access hash:/etc/postfix/client_access,
check_sender_access hash:/etc/postfix/sender_access,
reject_unauth_destination,
reject_rbl_client zen.spamhaus.org,
reject_rbl_client bl.spamcop.net
check_client_access hash:/etc/postfix/client_access
1.2.3.4 OK # mx server
/etc/postfix/sender_access
somedomain.com REJECT "temporary close"
* msg 不是必須 "..." 的
方案 3: smtpd_sender_restrictions on smtpd_sender_restrictions
mail.cf
smtpd_sender_restrictions = permit_mynetworks, reject_non_fqdn_sender, reject_sender_login_mismatch, permit_sasl_authenticated, check_sender_access hash:/etc/postfix/sender_access, permit
/etc/postfix/sender_access
datahunter.org Reject 530 SMTP authentication is required
postmap hash:/etc/postfix/sender_access
Cheat List
main.cf
smtpd_recipient_restrictions = reject_non_fqdn_recipient, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policyd-spf, # RBL Whitelist check_client_access cidr:/etc/postfix/bypass_rbl_by_ip.cidr, check_sender_access hash:/etc/postfix/bypass_rbl_by_domain.hash, reject_rbl_client bl.spamcop.net, reject_rbl_client sbl.spamhaus.org, reject_rbl_client cbl.abuseat.org # Block List check_client_access cidr:/etc/postfix/bypass_rbl_by_ip.cidr, check_sender_access hash:/etc/postfix/block_by_domain.hash # 決定使用那 filter (連那個 port) check_client_access cidr:/etc/postfix/amavis_filter_by_ip.cidr
Notes
- SPF 有它自己的 whitelist file, 所以不用在 postfix 內 bypass
- 最後沒被 block 才決定用那個 filter
/etc/postfix/amavis_filter_by_ip.cf
# 以下 IP bypass 了 amavis 1.1.1.1 DUNNO #### LAST ROW #### 0.0.0.0/0 FILTER amavis:[127.0.0.1]:10024