postfix - smtpd_recipient_restrictions(rbl, check_??_access)

最後更新: 2018-07-19

目錄

 


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."

 * SMTP Status Code

 


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

Creative Commons license icon Creative Commons license icon