MTA的反垃圾郵件功能,實(shí)際上就是在MTA處理過(guò)程中對(duì)會(huì)話進(jìn)行過(guò)濾。這個(gè)過(guò)濾不但過(guò)濾了發(fā)往自身的垃圾郵件,而且還防止了自身被惡意利用發(fā)送垃圾郵件。Postfix實(shí)現(xiàn)了目前所有主要的MTA過(guò)濾技術(shù)。。
MTA過(guò)濾分為兩類(lèi):郵件數(shù)據(jù)發(fā)送前過(guò)濾和郵件數(shù)據(jù)發(fā)送后過(guò)濾。
一、數(shù)據(jù)前過(guò)濾
數(shù)據(jù)前過(guò)濾是指在SMTP會(huì)話中,DATA指令發(fā)送前進(jìn)行的過(guò)濾。在這個(gè)階段,有四種不同子階段的過(guò)濾:SMTP連接時(shí)過(guò)濾、
HELO/EHLO指令過(guò)濾、MAIL FROM指令過(guò)濾和RCPT
TO指令過(guò)濾。根據(jù)這四個(gè)子階段接收到的信息的不同,它們也分別稱(chēng)作SMTP客戶(hù)端限制、HELO/EHLO主機(jī)名限制、發(fā)送者地址限制和接收者地址限
制。
過(guò)濾默認(rèn)是在RCPT TO指令后生效的,這是因?yàn)橐恍¦indows上的郵件客戶(hù)端不處理在RCPT
TO指令前的過(guò)濾動(dòng)作??梢酝ㄟ^(guò)將smtpd_delay_reject設(shè)置為no來(lái)使過(guò)濾動(dòng)作立刻生效。這個(gè)參數(shù)還影響了在不同的指令上可以使用的過(guò)濾
規(guī)則參數(shù)。
1、過(guò)濾規(guī)則
這四個(gè)子階段的過(guò)濾是分別通過(guò)四個(gè)配置語(yǔ)句來(lái)指定過(guò)濾規(guī)則的。它們都接收一系列的規(guī)則參數(shù)列表,參數(shù)間可以用空格或逗號(hào)分隔開(kāi)。在默認(rèn)狀態(tài)下
smtpd_delay_reject的值是yes,它們可以接受所有支持的規(guī)則,不過(guò)需在RCPT
TO指令后才能全部生效;如果把smtpd_delay_reject設(shè)置為no,它們只可以接受五個(gè)公共的規(guī)則參數(shù)、之前子階段的過(guò)濾規(guī)則參數(shù)和該子階
段的規(guī)則參數(shù)。
它們接受的公共的規(guī)則參數(shù)如下:
permit
允許該連接進(jìn)行。該規(guī)則通常置于規(guī)則列表的最后面使規(guī)則更清晰。
defer
通知客戶(hù)端現(xiàn)在不能繼續(xù)會(huì)話,稍后再進(jìn)行SMTP連接請(qǐng)求。這常用于服務(wù)器需要進(jìn)行一些DNS檢查,但是(由于DNS查詢(xún)超時(shí))沒(méi)有及時(shí)獲得結(jié)果時(shí),通知客戶(hù)端稍后再進(jìn)行連接。該規(guī)則通常置于規(guī)則列表的最后面使規(guī)則更清晰。
reject
拒絕該連接請(qǐng)求。在這個(gè)階段就斷開(kāi)了連接,有效的節(jié)約了垃圾郵件造成的帶寬和處理能力的浪費(fèi)。該規(guī)則通常置于規(guī)則列表的最后面使規(guī)則更清晰。
拒絕動(dòng)作默認(rèn)不會(huì)在匹配了拒絕規(guī)則后就立刻斷開(kāi)連接,而是在rcpt
to指令處理完之后再斷開(kāi)的,這是由于一些windows上有缺陷的郵件程序不處理在rcpt
to指令前的發(fā)回的拒絕狀態(tài)碼??梢酝ㄟ^(guò)smtpd_delay_reject設(shè)置為no來(lái)立刻發(fā)送拒絕狀態(tài)碼斷開(kāi)連接。
reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是554)。
warn_if_reject
改變其后規(guī)則的拒絕動(dòng)作為警告,即如果其后存在滿(mǎn)足拒絕的條件,并不實(shí)際拒絕,而是發(fā)出一條警告信息(reject_warning)到日志文件中(通常是/var/log/maillog)。它常用于在實(shí)際運(yùn)行的郵件服務(wù)器上測(cè)試郵件過(guò)濾規(guī)則。
reject_unauth_pipelining
拒絕在Postfix支持指令流水線前發(fā)送SMTP指令流水線的客戶(hù)端連接。指令流水線是一些郵件客戶(hù)端為了快速發(fā)送郵件所采用的技術(shù)。
以下就四個(gè)子階段分別講述過(guò)濾規(guī)則
A、SMTP連接時(shí)過(guò)濾(SMTP客戶(hù)端限制)
Postfix可以在接受客戶(hù)端的SMTP連接請(qǐng)求時(shí)進(jìn)行過(guò)濾檢查。
通過(guò)Postfix的smtpd_client_restrictions指令可以指定這個(gè)階段的過(guò)濾規(guī)則。這個(gè)階段可用的過(guò)濾規(guī)則除公共規(guī)則外還有:
reject_unknown_client
拒絕客戶(hù)的地址沒(méi)有對(duì)應(yīng)的DNS的A記錄或PTR記錄的連接。通常有些機(jī)器,尤其是個(gè)人撥號(hào)用戶(hù)的機(jī)器沒(méi)有對(duì)應(yīng)的A記錄或PTR記錄,所以要注意漫游
用戶(hù)的使用(漫游用戶(hù)是指不在$mynetworks中,比如在別的ISP撥號(hào)上網(wǎng)的用戶(hù)。通常用SMTP認(rèn)證來(lái)解決這個(gè)問(wèn)題)。
unknown_client_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是450)。
permit_mynetworks
允許來(lái)自其IP地址屬于$mynetworks所定義網(wǎng)絡(luò)的客戶(hù)端的連接。通??捎糜贗SP為自己的撥號(hào)用戶(hù)提供SMTP服務(wù)時(shí),通過(guò)$mynetworks參數(shù)指定自己的網(wǎng)絡(luò)并允許自己的網(wǎng)絡(luò)內(nèi)的機(jī)器發(fā)送郵件。
reject_rbl_client domain.tld和reject_rhsbl_client domain.tld
拒絕來(lái)自屬于RBL和RHSBL列表中的地址進(jìn)行連接。通過(guò)檢查一個(gè)IP地址或域名是否存在于domain.tld的RBL或RHSBL中,可以判斷
該客戶(hù)端是否被列入了domain.tld的實(shí)時(shí)黑名單,從而決定是否接受連接。有關(guān)實(shí)時(shí)黑名單可以參考本站的【反垃圾郵件技術(shù)參考>>實(shí)時(shí)
黑名單技術(shù)】。
maps_rbl_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是554)。
check_client_access maptype:mapname
搜索名為mapname的maptype類(lèi)型的訪問(wèn)數(shù)據(jù)庫(kù)??梢愿鶕?jù)客戶(hù)端的主機(jī)名、父域、IP地址或部分IP地址來(lái)匹配。關(guān)于訪問(wèn)數(shù)據(jù)庫(kù)請(qǐng)參閱下面的附錄。
例子:
smtpd_client_restrictions = hash:/etc/postfix/access,
reject_rbl_client relays.ordb.org,
reject_rhsbl_client dsn.rfc-ignorant.org,
permit_mynetworks,
reject_unknown_client
其中relays.ordb.org和dsn.rfs-ignorant.org都是國(guó)外比較權(quán)威的免費(fèi)RBL和RHSBL服務(wù)器。
B、HELO/EHLO指令過(guò)濾(HELO/EHLO主機(jī)名限制)
在接受了SMTP連接后,可以對(duì)HELO或EHLO指令所發(fā)送的信息進(jìn)行過(guò)濾檢查。
有些郵件客戶(hù)端在通訊時(shí)并不發(fā)送HELO/EHLO指令,可以通過(guò)smtpd_helo_required設(shè)置為yes強(qiáng)制要求發(fā)送HELO/EHLO指令(默認(rèn)Postfix不要求發(fā)送HELO/EHLO)。
通過(guò)Postfix的smtpd_helo_restrictions指令可以指定這個(gè)階段的過(guò)濾規(guī)則。這個(gè)階段可用的過(guò)濾規(guī)則除公共規(guī)則和smtpd_client_restrictions的規(guī)則外還有:
reject_invalid_hostname
拒絕無(wú)效格式的主機(jī)名的連接。
invalid_hostname_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是501)。
reject_unknown_hostname
拒絕未知的主機(jī)名的連接。所謂未知的主機(jī)名是指該主機(jī)沒(méi)有DNS的A記錄或MX記錄。由于很多撥號(hào)用戶(hù)的機(jī)器并沒(méi)有對(duì)應(yīng)的A記錄或MX記錄,所以要注意漫游用戶(hù)的使用。
unknown_hostname_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是450)。
reject_non_fqdn_hostname
拒絕主機(jī)名不是FQDN格式(完全限定域名格式,即用點(diǎn)分隔開(kāi)的包括域名和主機(jī)名的主機(jī)全名)的連接。
non_fqdn_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)時(shí)504)。
permit_naked_ip_address
允許直接使用IP地址的連接。通常在HELO/EHLO中使用主機(jī)名而不是IP地址。
check_client_access maptype:mapname
搜索名為mapname的maptype類(lèi)型的訪問(wèn)數(shù)據(jù)庫(kù)??梢愿鶕?jù)HELO/EHLO發(fā)送的主機(jī)名、父域來(lái)匹配。關(guān)于訪問(wèn)數(shù)據(jù)庫(kù)請(qǐng)參閱下面的附錄。
C、MAIL FROM指令過(guò)濾(發(fā)送者地址限制)
在接受了SMTP連接,客戶(hù)端發(fā)送了HELO/EHLO指令后(該指令可選),應(yīng)該通過(guò)MAIL FROM指令聲明發(fā)送者的身份。可以對(duì)發(fā)送者身份進(jìn)行過(guò)濾檢查。
按照RFC規(guī)范,在MAIL FROM指令和下面的RCPT TO指令中應(yīng)該使用RFC 821格式的郵件地址(例如:<user@domain.tld>),
但是由于有許多的郵件客戶(hù)端的不規(guī)范,往往不使用標(biāo)準(zhǔn)的RFC
821格式。Postfix默認(rèn)接受任何可以理解的郵件地址,如:丟失了地址里的一對(duì)尖括號(hào)、可以包含RFC 822格式的注釋等。如果希望打開(kāi)對(duì)RFC
821格式的限制,可以將strict_rfc821_envelopes設(shè)置為yes。
通過(guò)Postfix的smtpd_sender_restrictions指令可以指定這個(gè)階段的過(guò)濾規(guī)則。這個(gè)階段可用的過(guò)濾規(guī)則除了公共規(guī)則和
smtpd_client_restrictions的規(guī)則和smtpd_helo_restrictions的規(guī)則外還有:
reject_unknown_sender_domain
拒絕發(fā)送者郵件的域沒(méi)有DNS的A記錄或MX記錄的連接。
unknown_address_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是450)。當(dāng)進(jìn)行DNS查詢(xún)出現(xiàn)臨時(shí)錯(cuò)誤時(shí)(如查詢(xún)超時(shí))也總是返回450。
reject_rhsbl_sender domain.tld
拒絕發(fā)送者郵件的域?qū)儆赗HSBL黑名單的連接。通過(guò)檢查一個(gè)域名是否存在于domain.tld的RHSBL中,可以判斷該客戶(hù)端是否被列入了domain.tld的實(shí)時(shí)黑名單,從而決定是否接受連接。
maps_rbl_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是554)。
check_sender_access maptype:mapname
搜索名為mapname的maptype類(lèi)型的訪問(wèn)數(shù)據(jù)庫(kù)。可以根據(jù)發(fā)送者郵件的郵件地址、名字、域和父域來(lái)匹配。關(guān)于訪問(wèn)數(shù)據(jù)庫(kù)請(qǐng)參閱下面的附錄。
reject_non_fqdn_sender
拒絕發(fā)送者郵件的域不是FQDN格式的連接。
non_fqdn_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)時(shí)504)。
reject_sender_login_mismatch
拒絕發(fā)送者在$smtpd_sender_owner_maps中所匹配的用戶(hù)名和SASL登錄名不一致的連接。
D、RCPT TO指令過(guò)濾(接收者地址限制)
在MAIL FROM指令后要通過(guò)RCPT TO指令指定郵件接收者。可以對(duì)接收者身份進(jìn)行過(guò)濾檢查。
通過(guò)Postfix的smtpd_recipient_restrictions指令可以指定這個(gè)階段的過(guò)濾規(guī)則。同以上的檢查指令不同,為了避免開(kāi)
放轉(zhuǎn)發(fā),這個(gè)指令有默認(rèn)值:permit_mynetworks,reject_unauth_destination。這個(gè)階段可用的過(guò)濾規(guī)則除了公共
規(guī)則和smtpd_client_restrictions的規(guī)則和smtpd_helo_restrictions的規(guī)則和
smtpd_sender_restrictions的規(guī)則外還有:
permit_auth_destination
允許發(fā)往默認(rèn)轉(zhuǎn)發(fā)和默認(rèn)接收的連接。
Postfix默認(rèn)轉(zhuǎn)發(fā)以下的郵件:
來(lái)自$mynetworks中地址發(fā)送的郵件
發(fā)往$relay_domains中的域或其子域的郵件。但是不能包含郵件路由(如user@elsewhere@domain.tld)。
Postfix默認(rèn)接收最終投遞目標(biāo)符合如下條件的郵件:
目標(biāo)在$inet_interfaces
目標(biāo)在$mydestinations
目標(biāo)在$virtual_alias_domains
目標(biāo)在$virtual_mailbox_domains
reject_unauth_destination
拒絕不是發(fā)往默認(rèn)轉(zhuǎn)發(fā)和默認(rèn)接收的連接。
relay_domain_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是554)。
permit_mx_backup
允許接收本地主機(jī)是郵件投遞目標(biāo)的MX地址的郵件。但是不能包含郵件路由(如user@elsewhere@domain.tld)。
check_recipient_access maptype:mapname
搜索名為mapname的maptype類(lèi)型的數(shù)據(jù)庫(kù)。可以根據(jù)接收者郵件的郵件地址、名字、域和父域來(lái)匹配。 關(guān)于訪問(wèn)數(shù)據(jù)庫(kù)請(qǐng)參閱下面的附錄。
check_recipient_maps
拒絕接收者不匹配如下列表的連接:
$local_recipient_maps($mydestinations和$inet_interfaces)
$virtual_alias_maps($virtual_alias_domains)
$virtual_mailbox_maps($virtual_mailbox_domains)
$relay_recipient_maps($relay_domains)
空的$local_recipient_maps和$local_recipient_maps表示不對(duì)接收者地址進(jìn)行過(guò)濾檢查。
Postfix默認(rèn)在接收者檢查列表的最后做check_recipient_maps檢查。
reject_unknown_recipient_domain
拒絕接收者郵件的域沒(méi)有DNS的A記錄或MX記錄的連接。
unknown_address_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是450)。當(dāng)進(jìn)行DNS查詢(xún)出現(xiàn)臨時(shí)錯(cuò)誤時(shí)(如查詢(xún)超時(shí))也總是返回450。
reject_rhsbl_recipient domain.tld
拒絕接收者郵件的域?qū)儆赗HSBL黑名單的連接。通過(guò)檢查一個(gè)域名是否存在于domain.tld的RHSBL中,可以判斷該客戶(hù)端是否被列入了domain.tld的實(shí)時(shí)黑名單,從而決定是否接受連接。
maps_rbl_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)是554)。
reject_non_fqdn_recipient
拒絕接收者郵件的域不是FQDN格式的連接。
non_fqdn_reject_code指定了拒絕的返回狀態(tài)碼(默認(rèn)時(shí)504)。
permit_sasl_authenticated
允許通過(guò)了SASL認(rèn)證的用Х⑺陀始?Mü齋ASL協(xié)議(包括SASL1和SASL2)實(shí)現(xiàn)的SMTP認(rèn)證功能需要在編譯Postfix時(shí)編譯進(jìn)
SASL支持,并在main.cf中將smtpd_sasl_auth_enable設(shè)置為yes。有關(guān)SASL及如何在Postfix中實(shí)現(xiàn)SASL
認(rèn)證請(qǐng)參閱下面的附錄。通過(guò)SASL認(rèn)證可以對(duì)漫游用戶(hù)提供發(fā)信支持,是關(guān)閉Open-Relay的重要手段。
一個(gè)smtpd_recipient_restrictions的例子:
smtpd_recipient_restrictions = reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
reject_unauth_pipelining,
permit_mynetworks,
reject_unauth_destination,
check_client_access hash:/etc/postfix/client_checks,
check_client_access regexp:/etc/postfix/client_checks.re,
check_helo_access hash:/etc/postfix/helo,
check_sender_access hash:/etc/postfix/sender,
check_recipient_access regexp:/etc/postfix/recipient.re,
reject_rbl_client relays.ordb.org,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client blackholes.easynet.nl,
reject_rhsbl_client dsn.rfc-ignorant.org,
permit
這里要注意,有可能由于對(duì)reject_non_fqdn_*和reject_unknown_*的檢查而導(dǎo)致一些主機(jī)名沒(méi)有正常解析的機(jī)器不能正確發(fā)信。另外,在應(yīng)用這個(gè)規(guī)則前,可以在規(guī)則列表頭加上warn_if_reject來(lái)檢查一下。
2、多階段過(guò)濾和單階段過(guò)濾
由于一些windows上有缺陷的郵件程序不處理在RCPT
TO指令前的發(fā)回的拒絕狀態(tài)碼,所以Postfix默認(rèn)不會(huì)在匹配了拒絕規(guī)則后就立刻斷開(kāi)連接,而是在RCPT
TO指令處理完之后再斷開(kāi)的。可以通過(guò)smtpd_delay_reject設(shè)置為no來(lái)立刻發(fā)送拒絕狀態(tài)碼斷開(kāi)連接(默認(rèn)是yes)。
視乎smtpd_delay_reject設(shè)置為yes或no的不同,Postfix的過(guò)濾有多階段過(guò)濾和單階段過(guò)濾兩種形式。
A、多階段過(guò)濾
當(dāng)選項(xiàng)smtpd_delay_reject設(shè)置為yes時(shí),過(guò)濾是分為多個(gè)階段進(jìn)行的。比如,即便在上一個(gè)子階段該連接被判定為需要被拒絕,但是由
于拒絕被延遲了,所以會(huì)接著進(jìn)行本子階段的過(guò)濾,如果在本子階段又允許了該連接,那么上一個(gè)子階段的拒絕結(jié)果就會(huì)覆蓋。
從結(jié)果上看,這相當(dāng)于無(wú)論上一個(gè)子階段的過(guò)濾結(jié)果如何,都會(huì)進(jìn)行所有定義了的過(guò)濾規(guī)則。所以我們稱(chēng)之為多階段過(guò)濾。其邏輯模型如下:
STATUS = CLIENT:{rule1 || rule2 || ...} * HELO:{rule1 || rule2 ||
...} * SENDER:{rule1 || rule2 || ...} * RECIEPIENT:{rule1 || rule2 ||
...} * permit
這里的“||”表示如果一個(gè)規(guī)則有返回值(即進(jìn)行了匹配,無(wú)論返回permit還是reject)那么就不進(jìn)行該子階段的其后的規(guī)則檢查。
B、單階段過(guò)濾
當(dāng)選項(xiàng)smtpd_delay_reject設(shè)置為no時(shí),相當(dāng)于把這四個(gè)子階段的過(guò)濾規(guī)則都依序排列連接成一個(gè)單一的過(guò)濾規(guī)則列表。比如,如果在某個(gè)階段該連接被判定為需要被拒絕,那么會(huì)立刻拒絕,而根本不處理其后規(guī)則和其后子階段的規(guī)則。
從結(jié)果上看,這相當(dāng)于如果某個(gè)規(guī)則發(fā)生了匹配,那么其后的規(guī)則和子階段都被短路了,就像只有一個(gè)子階段的檢查一樣。所以我們稱(chēng)之為單階段過(guò)濾。其邏輯模型如下:
STATUS = CLIENT:{rule1 || rule2 || ...} || HELO:{rule1 || rule2 ||
...} || SENDER:{rule1 || rule2 || ...} || RECIEPIENT:{rule1 || rule2 ||
...} || permit
這里的“||”表示如果一個(gè)規(guī)則或子階段有返回值(即進(jìn)行了匹配,無(wú)論返回permit還是reject)那么就不進(jìn)行該子階段的其后的規(guī)則和子階段檢查。
在單階段過(guò)濾中,由于smtpd_recipient_restrictions可以接受所有的數(shù)據(jù)前過(guò)濾的規(guī)則,所以通常會(huì)把所有的過(guò)濾規(guī)則都放在
這里。注意在單階段過(guò)濾,所有排在前面的過(guò)濾規(guī)則被先處理,而且會(huì)形成短路。比如,如果你在smtpd_client_restrictions里就應(yīng)用
了RBL服務(wù),但是RBL里面有一個(gè)地址是你希望接收來(lái)自那里的郵件的,那么根本沒(méi)有機(jī)會(huì)來(lái)檢查發(fā)送者地址就會(huì)被拒絕了。解決地方法就是在
smtpd_sender_restrictions(或smtpd_recipient_restrictions)中先做一個(gè)
check_sender_access,然后再做RBL檢查。
二、數(shù)據(jù)后過(guò)濾
有時(shí)候僅僅通過(guò)在郵件數(shù)據(jù)發(fā)送前的信息還不足以判斷一封郵件是否是垃圾郵件。那么更進(jìn)一步可以通過(guò)郵件數(shù)據(jù)中包含的信息來(lái)判斷是否是垃圾郵件而決定如
何處理。雖然在SMTP會(huì)話已經(jīng)完成了數(shù)據(jù)接收后進(jìn)行過(guò)濾并不能節(jié)省下被浪費(fèi)的帶寬和處理能力,但是這樣減少了垃圾郵件占用的空間、用戶(hù)判斷刪除垃圾郵件
而浪費(fèi)的精力,而且對(duì)于一些現(xiàn)在流行的通過(guò)郵件傳遞的蠕蟲(chóng)病毒也減少了用戶(hù)誤中并繼續(xù)擴(kuò)散的可能性。
數(shù)據(jù)后過(guò)濾一般分為信頭過(guò)濾和信體過(guò)濾兩種。
1、信頭過(guò)濾
簡(jiǎn)單地說(shuō),在SMTP會(huì)話中,DATA指令發(fā)送的數(shù)據(jù)以一個(gè)空行分隔開(kāi),前面的部分稱(chēng)為信頭,后面的稱(chēng)為信體。通常在郵件中,包括三種類(lèi)型的信頭:
郵件主信頭
MIME頭(包括主信頭中的和多部分分隔串之后的)
郵件中附帶的郵件的信頭
信頭過(guò)濾可以通過(guò)以下配置來(lái)配置:
head_checks = maptype:mapname
它匹配所有的三種信頭。
mime_head_checks = maptype:mapname
它僅僅匹配MIME頭。
nested_head_checks = maptype:mapname
它僅僅匹配郵件中附帶的郵件的信頭。
信頭過(guò)濾模板有兩種類(lèi)型:ISO標(biāo)準(zhǔn)正則表達(dá)式regexp和Perl兼容正則表達(dá)式pcre,這兩者在語(yǔ)法上有一定的差異,使用任何一種都可以。過(guò)濾模板中的過(guò)濾規(guī)則格式如下:
/模式表達(dá)式/ 動(dòng)作
模式表達(dá)式是用regexp或pcre寫(xiě)的用來(lái)匹配郵件頭的表達(dá)式。
動(dòng)作有如下幾種(和訪問(wèn)數(shù)據(jù)庫(kù)中所支持的動(dòng)作不完全一致,比如不支持[45]NN、數(shù)字、DUNNO和規(guī)則等):
REJECT [text]
拒絕該郵件,可選的消息被發(fā)給發(fā)信人并記錄到maillog中。
OK
對(duì)于這個(gè)信頭行不再進(jìn)行其他的匹配規(guī)則處理,繼續(xù)處理下一行信頭。
IGNORE
從信頭中刪除該信頭行。常被用來(lái)刪除一些特定的信頭行,如Received。
WARNING [text]
將該信頭行和可選的消息記錄到maillog中。常用來(lái)測(cè)試過(guò)濾規(guī)則。
HOLD [text]
將該郵件放入hold隊(duì)列中,并記錄該信頭行和可選的消息到maillog中。放入hold隊(duì)列的郵件可以通過(guò)postcat命令來(lái)查看,或通過(guò)postsuper來(lái)刪除或遞交。
DISCARD [text]
成功接收郵件后并不遞交,而是悄悄地將該郵件丟棄,并記錄該信頭行和可選的消息到maillog中。
FILTER transport:nexthop
將該郵件發(fā)到一個(gè)郵件過(guò)濾器中進(jìn)行處理。
另外注意,信頭過(guò)濾在對(duì)Subject處理時(shí),中文(8位編碼)會(huì)被編碼為MIME編碼或UUENCODE編碼,請(qǐng)做相應(yīng)轉(zhuǎn)換處理。
2、信體過(guò)濾
信體是除了主信頭之外的郵件內(nèi)容(包括MIME頭,不過(guò)將多行的MIME頭作為多個(gè)單行處理)。信體過(guò)濾通常不檢查全部的信體,只檢查
body_checks_max_size所指定的大小(以字節(jié)為單位,默認(rèn)是50K)。信體過(guò)濾是針對(duì)行來(lái)處理的,對(duì)于超長(zhǎng)的行,只檢查
line_length_limi所指定的長(zhǎng)度(默認(rèn)2048字節(jié))。
信體過(guò)濾可以通過(guò)以下配置來(lái)配置:
body_checks = maptype:mapname
信體過(guò)濾模板同信頭過(guò)濾模板一樣。
三、附錄
1、訪問(wèn)數(shù)據(jù)庫(kù)
訪問(wèn)數(shù)據(jù)庫(kù)是Postfix用來(lái)判斷拒絕或接受郵件的數(shù)據(jù)庫(kù)。通過(guò)訪問(wèn)數(shù)據(jù)庫(kù)可以拒絕或接收特定的主機(jī)名、域名、網(wǎng)絡(luò)地址和郵件地址。
通常訪問(wèn)數(shù)據(jù)庫(kù)是一個(gè)由postmap命令從一個(gè)文本文件輸入生成的db或dbm格式的HASH文件。也有NIS,LDAP,SQL和正則表達(dá)式方式的其它數(shù)據(jù)庫(kù),它們和HASH文件以相同的方式工作,但是不需要用postmap來(lái)生成。
數(shù)據(jù)庫(kù)的格式如下:
模式表達(dá)式 動(dòng)作
當(dāng)匹配了模式表達(dá)式時(shí),就觸發(fā)了相應(yīng)的動(dòng)作。
數(shù)據(jù)庫(kù)中的空行和以“#”開(kāi)頭的行被忽略掉。以空格開(kāi)始的行是上一行的續(xù)行。
A、郵件地址
非正則表達(dá)式用來(lái)表示郵件地址時(shí)有如下格式:
匹配特定的郵件地址
domain.tld
匹配特定郵件的域。如果在parent_domain_matches_subdomains指定了smtpd_access_maps(默認(rèn)),那么也會(huì)匹配該域的子域;否則就需要使用.doamin.tld格式(注意前面的點(diǎn))來(lái)單獨(dú)匹配子域。
user@
匹配所有本地部分(郵件用戶(hù)名)是user的郵件地址
<>
匹配無(wú)郵件地址。這個(gè)值是通過(guò)smtpd_null_access_lookup_key來(lái)指定的。
B、主機(jī)名和地址
非正則表達(dá)式用來(lái)表示主機(jī)名和地址時(shí)有如下格式:
domain.tld
匹配特定郵件的域。如果在parent_domain_matches_subdomains指定了smtpd_access_maps(默認(rèn)),那么也會(huì)匹配該域的子域;否則就需要使用.doamin.tld格式(注意前面的點(diǎn))來(lái)單獨(dú)匹配子域。
net.work.addr.ess
net.work.addr
net.work
net
匹配網(wǎng)絡(luò)地址。注意CIDR(無(wú)類(lèi)網(wǎng)絡(luò)地址,network/netmask格式)不被支持。
C、動(dòng)作
訪問(wèn)數(shù)據(jù)庫(kù)支持如下動(dòng)作:
[45]NN text
拒絕該郵件并返回?cái)?shù)字的拒絕狀態(tài)碼和消息。
REJECT [text]
拒絕該郵件并返回拒絕狀態(tài)碼和消息,如果沒(méi)有指定消息就返回通用的消息。
OK
接受該郵件。
數(shù)字
同OK一樣,接受該郵件。
DUNNO
跳過(guò)該規(guī)則,繼續(xù)處理下面的規(guī)則。
HOLD [text]
將該郵件放入hold隊(duì)列中,并記錄可選的消息或通用的消息到maillog中。放入hold隊(duì)列的郵件可以通過(guò)postcat命令來(lái)查看,或通過(guò)postsuper來(lái)刪除或遞交。
DISCARD [text]
成功接收郵件后并不遞交,而是悄悄地將該郵件丟棄,并記錄可選的消息或通用的消息到maillog中。
FILTER transport:nexthop
將該郵件發(fā)到一個(gè)郵件過(guò)濾器中進(jìn)行處理。
UCE規(guī)則
應(yīng)用UCE規(guī)則,如permit、reject_unauth_destination和smtpd_restriction_classes定義的規(guī)則類(lèi)。
2、SMTP認(rèn)證(SASL認(rèn)證)
如上所述,漫游用戶(hù)需要通過(guò)SMTP認(rèn)證方式來(lái)使用發(fā)信服務(wù)。Postfix默認(rèn)是不支持SASL協(xié)議,即不支持SMTP認(rèn)證,需要通過(guò)額外指定
SASL庫(kù)的位置并打開(kāi)SASL認(rèn)證功能才能支持SMTP認(rèn)證。以下以Postfix-2.0.13和Cyrus-Sasl-2.1.1為例簡(jiǎn)單說(shuō)明如何
使用SMTP認(rèn)證。
首先下載Postfix-2.0.13和Cyrus-Sasl-2.1.1,并安裝cyrus-sasl-2.1.1。默認(rèn)cyrus-
sasl安裝到了/usr/local下,它的庫(kù)在/usr/local/lib下,它的頭文件在/usr/local/include/sasl下。
然后解開(kāi)Postfix-2.0.13的源代碼包,并使用如下命令編譯:
% make tidy
% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl"
AUXLIBS="-L/usr/local/lib -lsasl2"
如果需要你還可以加上其他的編譯選項(xiàng),如對(duì)MySQL的支持等。
編譯完成后安裝,然后修改/etc/postfix/main.cf,添加如下配置:
smtpd_sasl_auth_enable = yes
來(lái)打開(kāi)SASL認(rèn)證功能,然后在smtpd_recipient_restrictions中添加permit_sasl_authenticated規(guī)則:
smtpd_recipient_restrictions = permit_sasl_authenticated
來(lái)允許通過(guò)了SASL認(rèn)證的用戶(hù)發(fā)信,你還可以在這里增加其它需要的規(guī)則。
修改/usr/local/lib/sasl2/smtpd.conf(如沒(méi)有請(qǐng)創(chuàng)建),設(shè)定你需要的認(rèn)證方式,如auxprop、pwcheck、saslauthd等,這依賴(lài)于你的具體需求。
在配置好Postfix后,重新啟動(dòng)Postfix。
然后就可以通過(guò)支持SMTP認(rèn)證的郵件客戶(hù)端進(jìn)行認(rèn)證發(fā)信了。你也可以通過(guò)Telnet方式來(lái)測(cè)試你SMTP認(rèn)證是否成功。
有關(guān)SASL認(rèn)證的更詳細(xì)的細(xì)節(jié),請(qǐng)參閱Postfix源代碼包中的README_FILES目錄中的SASL_README文件。 |
|
來(lái)自: star_xiong > 《linux》