別名可用于創(chuàng)建郵遞列表(mailing list)。在上面的例子中,別名Webmaster實(shí)際上就是一個(gè)本地郵件管理員的郵遞列表。對(duì)于大型的或是經(jīng)常改動(dòng)的名單,可以利用:include的別名形式指示sendmail從文件中來(lái)讀取名單的成員。如果別名文件包含行
friends::include:/home/zhang/friends.aliases
并且文件/home/zhang/friends.aliases包含
zhang
li
liu
deng
其效果與下面的別名相同: friends:zhang,li,liu,deng
這一指令對(duì)于經(jīng)常變動(dòng)的郵遞列表或哪些由用戶而非郵件管理員管理的郵遞列表非常方便。如果經(jīng)常要求改變郵件別名,用戶一般希望把它置于自己的控制之下。
別名文件也可被用于向某個(gè)程序發(fā)送郵件的內(nèi)容。例如,許多郵遞列表的設(shè)立使用戶可以獲取所列的信息或通過(guò)向某一特定地址list-request發(fā)送信件來(lái)訂閱信息。這種信件的主體通常只包含一個(gè)單詞,比如help或subscribe等。假設(shè)zhang的郵遞列表具有名為zhang-request的一個(gè)地址: zhang-request:|/usr/local/lib/auto-zhang-reply
上面表達(dá)式的管道號(hào)(|)通知sendmail使用程序的郵件發(fā)送器,它通常被定義為/bin/sh。sendmail將把信息提供給/usr/local/lib/auto-zhag-reply的標(biāo)準(zhǔn)輸入,如果它存在,sendmail便考慮投遞信件。
用戶還可以創(chuàng)建一個(gè)使sendmail向文件發(fā)送郵件的別名。下面是別名nobody的一個(gè)例子,它在運(yùn)行NFS的系統(tǒng)上是經(jīng)常用到: nobody:/dev/null
指定文件的別名讓sendmail把它的消息追加到被指定的文件中。由于這一特殊的文件/dev/null是Linux/UNIX的“黑洞”,因此這一別名的作用其實(shí)是把郵件清除掉。
4.配置sendmail
sendmail是通過(guò)sendmail.cf文件來(lái)配置的。這個(gè)文件通常在目錄/etc下面(有些系統(tǒng)是在/etc/lib目錄下)。sendmail.cf文件使用的語(yǔ)法與其他配置文件不同,而且比較復(fù)雜。 配置文件的每一行都以一個(gè)單一的命令字符開頭,這一字符用來(lái)說(shuō)明這一行的功能和語(yǔ)法。以#開始的行是注釋行;空行被忽略;以空格或制表符開始的行是上一行的續(xù)行,不過(guò)通常應(yīng)該盡量避免續(xù)行。
下面介紹命令字符及它們的功能。
以下為引用的內(nèi)容: (1)# 注釋符,以#開始的行是注釋行。例如: # This file is a sample for sendmail.cf (2)D 使用格式為:DX string。其功能是把宏X定義為字符串string,例如: DM mail.somedomain.gov (3)C 使用格式為:CX word1、word2。其功能是把類X定義為wor1、word2。例如: Cw localhost my_host (4)F 使用格式為:FX/file。其功能是把類X定義為從文件中讀取的值。例如: Fw/etc/hosts (5)H 使用格式為:H?mailerflag?name:template。其功能是定義郵件頭。例如: H?F?From:\ $ q (6)O 使用格式為:OX option arguments。其功能是設(shè)置選X,例如: OL8# sets the log level to 8 (7)P 使用格式為:Pclass=n。其功能是根據(jù)郵件的類來(lái)設(shè)置郵件投遞的優(yōu)先級(jí)。例如: Pjunk=100 (8)V 使用格式為:Vn。其功能是把配置文件的版本級(jí)別通知給V8 sendmail。例如: V3 (9)K 使用格式為:Kname class arguments。其功能是定義一個(gè)關(guān)鍵字文件(數(shù)據(jù)庫(kù)映像)。例如: Kuucphosts dbm/etc/uuphosts (10)M 使用格式為:Mname,f1=v1,...。其功能是定義一個(gè)郵件發(fā)送器。例如: Mpop,P=/bin/sh,F(xiàn)=lsD,A=sh-c $ u (11)S 使用格式為:Sun。其功能是開始一個(gè)新的規(guī)則集。例如: S22 (12)R 使用格式為:Rlhs rhs comment。其功能是定義一個(gè)匹配/改寫規(guī)則。例如: R $ + $>jg call ruleset jg |
上面簡(jiǎn)要地列出操作符的類型,現(xiàn)在對(duì)它們進(jìn)行詳細(xì)介紹。
· D操作符
宏類似于shell變量,當(dāng)為一個(gè)宏定義了值后,可以在配置文件的后面對(duì)它進(jìn)行引用,宏將會(huì)被它的值所取代。例如,一個(gè)配置文件可能有多個(gè)行包含假設(shè)的郵件中心mailer.somedomain.gov,為了避免一次次地輸入這一名字,可以像下面這樣為它定義一個(gè)宏R(代表中繼郵件發(fā)送器): DRmailer.somedomain.gov
當(dāng)sendmail在sendmail.cf中遇到$ R時(shí),sendmail將把它替換為字符串mailer.somedomain.gov。
宏的名字通常是一個(gè)單字符。sendmail定義有許多宏,這些宏不應(yīng)該被再次定義,否則將會(huì)出現(xiàn)一些問(wèn)題。sendmail使用小寫字母來(lái)定義自己的宏;大寫字母可以被自由地使用。
· C和F操作符
類與宏類似,但是在改寫規(guī)則中用于不同目的。與宏一樣,類的名字也是一個(gè)單字符,小寫字母由sendmail使用,大寫字母用于由用戶定義的類。一個(gè)類包含有一個(gè)或多個(gè)單詞。例如,可以像下面這樣定義一個(gè)包含本地域中所有主機(jī)的類H:
CH host1 host2 host3
為了方便起見,大型的類可以續(xù)行定義。下面對(duì)類H的定義與前面定義的結(jié)果相同:
CH host1
CH host2
CH host3
另外,還可以通過(guò)從某個(gè)文件中讀取它的單詞來(lái)定義一個(gè)類:
CF/usr/usr/localhosts
如果/usr/localhosts文件包含host1、host2和host3,并且是每行包含一個(gè),那么這一定義與前面的兩個(gè)定義等價(jià)。
使用宏和類最主要的優(yōu)點(diǎn)是它們可以集中配置文件中信息。在上面的例子中,如果決定把郵件中心由mailer.somedomain.gov改變?yōu)閙ail1.somedomain.gov,只需要改變宏$ R的定義就可以了,配置文件僅需作很少的改動(dòng)。否則名字mailer.somedomain.gov散布在文件的各處,那么可能會(huì)在某些位置忘記對(duì)它們進(jìn)行修改。另外,集中的重要信息,可以在單獨(dú)的一個(gè)位置詳細(xì)地對(duì)它進(jìn)行注釋。由于配置文件一般比較難于理解,因此如果很長(zhǎng)一段時(shí)間之后對(duì)自己所做的某種修改感到迷惑時(shí),在配置文件中添加詳細(xì)的注釋是很有幫助的。
· H操作符
一般情況下,不需要對(duì)V8 sendmail的配置文件所提供的郵件頭進(jìn)行修改,因?yàn)樗鼈円呀?jīng)遵從了公認(rèn)的標(biāo)準(zhǔn)。下面是一些郵件頭的示例:
H? D? Date:$ a
H? F? Resent-From:$ q
H? F? From:$ q
H? x? Full-Nnme:$ x
可以看出,在郵件頭的定義中可以使用宏。當(dāng)插入到某封信中時(shí),這些宏將被擴(kuò)充,由它相應(yīng)的值取代。例如,在上面的例子中,用于郵件頭定義Full-Name:中的宏$ x將被取代為寄件人的全名。在郵件頭的定義中,可選的?mailerflag?結(jié)構(gòu)用來(lái)通知sendmail只有在被選擇的郵件發(fā)送器具有這一郵件發(fā)送器標(biāo)志時(shí)才插入郵件頭。
假如在用戶的本地郵件發(fā)送器的定義中具有一個(gè)標(biāo)志Q,并且sendmail選擇了這一郵件發(fā)送器來(lái)投遞某一信件,如果配置文件包含一個(gè)像下面這樣的郵件頭定義,那么sendmail將把這一郵件頭插入到通過(guò)本地郵件發(fā)送器被傳遞的信件中,并利用相應(yīng)的值來(lái)取代宏$ F:
H? Q? It-is-a-wonderful-day:$ F
為什么要使用?mailerflag這一特性呢?這是因?yàn)椴煌膮f(xié)議可能會(huì)需要不同的郵件頭。另外,由于它們也需要不同的郵件發(fā)送器,因此可以通過(guò)在郵件發(fā)送器定義中定義相應(yīng)的郵件發(fā)送器標(biāo)志并使用郵件頭定義中的?mailerflag?結(jié)構(gòu),來(lái)通知sendmail是否要插入相應(yīng)的郵件頭。
·0操作符
sendmail具有許多選項(xiàng),這些選項(xiàng)用來(lái)改變sendmail的操作或者用來(lái)通知所使用的文件的位置。大部分選項(xiàng)既可以通過(guò)命令行提供,也可以在配置文件中給出。例如,用戶既可以在命令行也可以在配置文件中指定別名文件的位置;要是在命令行上指定別名文件,可以使用-o選項(xiàng):
$ sendmail-oA/etc/aliases[other arguments...]
要是在配置文件指定別名文件,可在配置文件中添加如下一行代碼:
OA/etc/aliases
這兩種方法是等價(jià)的。但由于像別名文件的位置這種選項(xiàng)很少改變,因此人們通常在配置文件sendmail.cf中設(shè)置它們。V8 sendmail的所有選項(xiàng)在SIOG中有詳細(xì)的說(shuō)明。
·P操作符
用戶可以在郵件中包含用來(lái)指示郵件的相對(duì)重要性的標(biāo)題,sendmail可以根據(jù)這些標(biāo)題來(lái)確定信件的優(yōu)先級(jí)。假設(shè)為V8 sendmail提供的優(yōu)先級(jí)如下:
Pemergent=100
Pimportant=0
Pnormal=-30
如果用戶在他們的信息中含有標(biāo)題Drecedence:normal,那么sendmail為這些郵件提供的優(yōu)先級(jí)要低于利用標(biāo)題Precedence:importangt的郵件。
·V操作符
隨著V8 sendmail的發(fā)展,許多Linux愛好者不斷地為它添加新的特性。 V操作符能夠使V8 sendmail知道在配置文件中它可以找到哪些特性。老版本的sendmail不能夠識(shí)別這一命令。在SIOG中,對(duì)配置文件的版本級(jí)別有詳細(xì)的說(shuō)明。
注意:配置文件的版本級(jí)別與sendmail的版本級(jí)別并不是一回事。V8 sendmail能夠理解從版本1到5的配置文件,而版本8的配置文件并不存在。
·K操作符
sendmail使用了一些關(guān)鍵字?jǐn)?shù)據(jù)庫(kù),例如別名數(shù)據(jù)庫(kù)。假如給定了關(guān)鍵詞Webmaster,sendmail將查找與這一關(guān)鍵詞相關(guān)的數(shù)據(jù),V8 sendmail把這一概念擴(kuò)充為任意的數(shù)據(jù)庫(kù),包括NIS mps(Sun的網(wǎng)絡(luò)信息服務(wù),以前稱為Yellow Pages或YP)。K操作符可用來(lái)向sendmail通知數(shù)據(jù)庫(kù)的位置、類別以及訪問(wèn)方法。V8 sendmail支持的數(shù)據(jù)庫(kù)類別有:dbm、btree、hash和NIS。當(dāng)在Linux下編譯時(shí),使用的缺省類別是dbm格式。
· M操作符
前面已經(jīng)介紹,郵件發(fā)送器或者是MTA或者是最終投遞代理。針對(duì)每種目標(biāo),可以定義一個(gè)專門的郵件發(fā)送器。即使SMTP,MTA被內(nèi)置,它也必須有一個(gè)郵件發(fā)送器定義來(lái)定制sendmail的SMTP操作。郵件發(fā)送器的定義是很重要的,因?yàn)樗惺占说牡刂繁仨氃?號(hào)規(guī)則集中解析到一個(gè)郵件發(fā)送器。解析到本地郵件發(fā)送器將通過(guò)定義在其中的最終投遞代理(例如/bin/mail)把信件發(fā)送給某個(gè)本地用戶,解析到SMTP郵件發(fā)送器將通過(guò)定義在其中的sendmail固有的SMTP傳輸器把信件發(fā)送給另一個(gè)主機(jī)。下面將介紹一個(gè)定義郵件發(fā)送器的具體例子,由于sendmail需要一個(gè)本地郵件發(fā)送器,因此給出下面的例子:
Mlocal,P=/bin/mail,F(xiàn)=lsDFMfSn,S=10,R=20, A=mail-d$u
所有郵件發(fā)送器的定義都以M操作符和郵件發(fā)送器的名字開頭(在本例中是local),其他字段在后面并且分別由逗號(hào)隔開。每個(gè)字段由字段名和它的值組成,字段名和它的值之間由等號(hào)(=)隔開,允許使用的字段在SIOG中有詳細(xì)的說(shuō)明。在上面本地郵件發(fā)送器的定義中,P=用來(lái)提供投遞郵件的程序所處位置的路徑名/bin/mail,字段F=用來(lái)為本地郵件發(fā)送器提供sendmail標(biāo)志。這些標(biāo)志并不是要傳遞給字段P=中所指定的命令,而是由sendmail用來(lái)根據(jù)它所選擇的郵件發(fā)送器來(lái)修改自己的操作。例如,sendmail通常在調(diào)用郵件發(fā)送器之前放棄它的超級(jí)用戶身份,但可以利用S郵件發(fā)送器標(biāo)志通知sendmail為某些郵件發(fā)送器保持這一身份。
字段S=和R=用來(lái)為sendmail指定在改寫寄件人和收件人地址時(shí)用到的規(guī)則集。由于可以為所定義的每個(gè)郵件發(fā)送器提供不同的R=和S=標(biāo)志,因此可以針對(duì)每個(gè)郵件發(fā)送器的不同特點(diǎn)來(lái)改寫地址。例如,如果用戶的UUCP鄰居運(yùn)行的是一個(gè)不理解域?qū)ぶ返年惻f軟件,就需要專門為他的站點(diǎn)說(shuō)明一個(gè)特殊的郵件發(fā)送器,并編寫針對(duì)特殊郵件發(fā)送器的規(guī)則集,從而把地址轉(zhuǎn)化為它的郵件發(fā)送器能夠理解的形式。S=和R=字段還可以指定用來(lái)改寫信封和郵件頭地址的各種規(guī)則集,像S=21/31這種表達(dá)式將通知sendmail利用21號(hào)規(guī)則集改寫寄件人的信封地址,利用31號(hào)規(guī)則集改寫寄件人的郵件頭地址。這一功能對(duì)于要求不同地顯示信封地址和郵件頭地址的郵件發(fā)送器是很有用的。
A=字段用來(lái)為被運(yùn)行的程序(在本例中是/bin/mail)提供變量向量(命令行)。在這一例子中,sendmail將運(yùn)行命令mail-d $ u,其中的宏$ u將被替換為被投遞的用戶名:
/bin/mail-d zhang
用戶可以在命令提示符下把與此完全相同的命令輸人到shell中。
另外,還可以使用其他郵件發(fā)送器標(biāo)志來(lái)調(diào)節(jié)郵件發(fā)送器。例如,可以根據(jù)不同的郵件發(fā)送器限制信息的最大尺寸。
· S和R操作符
配置文件sendlnail.cf由一系列規(guī)則集組成。規(guī)則集用來(lái)探測(cè)錯(cuò)誤的地址,把地址改寫為遠(yuǎn)程郵件發(fā)送器能夠理解的形式,以及把郵件路由到sendmail內(nèi)部的某個(gè)郵件發(fā)送器。sendmail按照固有的順序向規(guī)則集傳送地址,而規(guī)則集可以不按固有順序調(diào)用其他規(guī)則集。固有順序與處理的郵件地址以及選擇用來(lái)投遞信件的郵件發(fā)送器有關(guān)。
規(guī)則集由S命令宣布,跟在它后面的是用來(lái)標(biāo)識(shí)規(guī)則集的編號(hào)。sendmail將收集下面的R(規(guī)則)行,直到它發(fā)現(xiàn)另一個(gè)S操作符或配置文件的結(jié)尾為止。下面的例子定義了編號(hào)為11的規(guī)則集:
# Ruleset 11
S11
R $+$:$>22$ I call ruleset 22
sendmail分三種途徑來(lái)處理地址:一種用來(lái)選擇投遞代理,一種用來(lái)處理寄件人地址,一種用于處理收件人地址。
所有郵件地址首先被傳送到3號(hào)規(guī)則集進(jìn)行預(yù)處理從而變?yōu)橐?guī)范的形式,以便其他規(guī)則集能夠容易地處理它們。不論地址多么復(fù)雜,3號(hào)規(guī)則集的任務(wù)是確定某個(gè)郵件應(yīng)該被發(fā)送到的下一個(gè)主機(jī),3號(hào)規(guī)則集將盡力在地址中查找那一主機(jī)并利用尖括號(hào)來(lái)標(biāo)記它。例如,在一種最簡(jiǎn)單的情況下,一個(gè)像zhang@somedomain.gov這樣的地址將變?yōu)閦nahg<@simedomain.gov>。接下來(lái),0號(hào)規(guī)則集將確定用于每個(gè)收件人的正確的投遞代理(郵件發(fā)送器)。例如,一封由li@othedomain.com發(fā)給zhang@somedomain.gov(一個(gè)Internet站點(diǎn))和posthost!zhao(一個(gè)老式的UUCP站點(diǎn))的信件需要兩個(gè)不同的郵件發(fā)送器:一個(gè)用于somedomain.gov的SMTP郵件發(fā)送器,一個(gè)用于posthost的老式UUCP郵件發(fā)送器。郵件發(fā)送器的選擇決定以后對(duì)寄件和收件人的地址進(jìn)行處理的方式。因?yàn)樘峁┰?ldquo;S=”和“R=”郵件發(fā)送器標(biāo)志中的規(guī)則集根據(jù)郵件發(fā)送器的不同而不同。
經(jīng)過(guò)0號(hào)規(guī)則集的地址必須解析到一個(gè)郵件發(fā)送器。因此,當(dāng)某個(gè)地址匹配lhs時(shí),rhs將提供一個(gè)由郵件發(fā)送器、用戶和主機(jī)組成的三元組。下面這行代碼表示的是解析到某個(gè)郵件發(fā)送器的規(guī)則的語(yǔ)法:
Rlhs $ # mailer $ @host $:user some comment here...
上面的mailer是利用M命令定義的一個(gè)郵件發(fā)送器的名字,例如SMTP。host和user通常是來(lái)自lhs的位置宏。
當(dāng)sendmail在0號(hào)規(guī)則集中選擇了一個(gè)郵件發(fā)送器后,它將通過(guò)1號(hào)規(guī)則集(通常是空的)來(lái)處理寄件人的地址,然后把它們發(fā)送到由這個(gè)郵件發(fā)送器中的S=標(biāo)志所提供的規(guī)則集。
類似地,sendmail將把收件人的地址發(fā)送到2號(hào)規(guī)則集(通常也是空的)中進(jìn)行處理,然后再把它們發(fā)送到郵件發(fā)送器的標(biāo)志R=所提供的規(guī)則集。
最后,sendmail將在4號(hào)規(guī)則集中對(duì)所有地址進(jìn)行后處理。4號(hào)規(guī)則集將把在3號(hào)規(guī)則集中插入的尖括號(hào)刪除。
為什么不同的郵件發(fā)送器具有不同的S=和R=標(biāo)志呢?考慮前面向zhang@somedomain.gov和posthost!zhao發(fā)送信件的例子。如果li@othedomain.com發(fā)送郵件,它必須針對(duì)每個(gè)收件人以不同的形式出現(xiàn)。對(duì)于zhang,它應(yīng)該是一個(gè)域地址li@otherdomain.com;對(duì)于zhao,由于otherdomain.com希望老式的UUCP地址(假設(shè)它具有一個(gè)連向posthost的UUCP鏈接并且otherdomain.com的UUCP主機(jī)名是posthost),因此返回地址應(yīng)該是otherdomain!li。zhang的地址也必須為posthost的UUCP郵件發(fā)送器進(jìn)行改寫,并且zhang的副本必須包括他的郵件發(fā)送器可以處理的posthost的地址。
當(dāng)sendmail把一個(gè)地址傳遞給某個(gè)規(guī)則集后,規(guī)則集中的每一個(gè)規(guī)則行將逐行地對(duì)它進(jìn)行處理。如果某個(gè)規(guī)則行的lhs與地址相匹配,地址將被Ihs改寫;如果它不匹配,sendmail將繼續(xù)到下一個(gè)規(guī)則,直到達(dá)到規(guī)則集的末尾為止。在規(guī)則集的最后,sendmail將把被改寫的地址返回給調(diào)用規(guī)則集的規(guī)則集或是固有執(zhí)行順序的下一個(gè)規(guī)則集。
如果某個(gè)地址與lhs相匹配并且被rhs改寫,這一規(guī)則將再次被調(diào)用——一個(gè)隱式循環(huán)。
如前面介紹,每一個(gè)改寫規(guī)則都由R命令引人并且具有三個(gè)字段——左端(lhs或匹配端)、右端(rhs或改寫端)以及可選的注釋,各個(gè)字段之間必須由制表符隔開:
Rlhs rhs coment
sendmail將把地址和規(guī)則的lhs解析成標(biāo)記,然后再逐個(gè)標(biāo)記地把地址和lhs進(jìn)行比較。宏$o包含sendmail用來(lái)把地址分隔成標(biāo)記的字符,它通常具有如下的定義:
#address delimiter characters
Do.:%@?。?[]
$o中的所有字符,既是標(biāo)記分隔符,又是標(biāo)記。sendmail獲取像xie@rainbow.org這樣的地址,然后根據(jù)宏o中的字符把它分解成多個(gè)標(biāo)記,就像下面這樣:
“xie”“@”“rainbow”“.”“org”
sendmail也把改寫規(guī)則lhs分解為標(biāo)記,從而使它們可以同輸人的地址一個(gè)個(gè)地相比較,以確定是否匹配。例如,lhs $ -@rainbow.org分解后的內(nèi)容如下:
$-”“@”“rainbow”“.”“org”
其中“$-”是一個(gè)模式匹配操作符,類似于shell通配符,它用來(lái)匹配任何單一的標(biāo)記符。現(xiàn)在可以把兩組標(biāo)記放在一起來(lái)揭示sendmail如何確定一個(gè)地址是否與規(guī)則的lhs相匹配。
“xie”“@”“rainbow”“.”“org”
“$”“@”“rainbow”“.”“org”
在此例中,由于來(lái)自地址的每個(gè)標(biāo)記都匹配一個(gè)常量字符串(例如rainbow)或一個(gè)模式匹配操作符($-),因此地址和lhs相匹配并且sendmail將使用rhs來(lái)改寫這一地址。接下來(lái),考查一個(gè)改變$o值的效果。sendmail把地址xie@rainbow.org分解為五個(gè)標(biāo)記;然而,如果@字符不在$o中,這一地址將完全不同地被分解為三個(gè)標(biāo)記:
“xie@rainbow”“.”“org”
由此看來(lái),改變$o將對(duì)sendmail的地址解析產(chǎn)生極大的影響。因此除非用戶對(duì)自己所做的事情非常有把握,否則應(yīng)該保持它的原狀。
· 規(guī)則的左端(lhs)
lhs是sendmail用來(lái)與輸入地址進(jìn)行對(duì)比的模式,lhs既可以包含普通的文本,又可以包含任何模式匹配操作符。
lhs的模式匹配操作符主要包括:$-(匹配一個(gè)標(biāo)記)、$+(匹配一個(gè)或多個(gè)標(biāo)記)、$ *(匹配零個(gè)或多個(gè)標(biāo)記)、$@(匹配空的輸入,用來(lái)調(diào)用錯(cuò)誤郵件發(fā)送器)。
在lhs中,還可以利用下列宏和類的匹配操作符:$ X(匹配宏X的值)、$=C(匹配類C中的任何一個(gè)詞)、$~C(匹配不屬于類C的任何一個(gè)標(biāo)記)。
模式匹配操作符以及宏和類的匹配操作符是十分必要的,因?yàn)榇蠖鄶?shù)規(guī)則必須匹配許多不同的輸入地址。例如,某個(gè)規(guī)則可能需要匹配所有以somedomain.gov結(jié)尾、以一個(gè)或多個(gè)其他任何內(nèi)容開頭的地址。
· 規(guī)則的右端(rhs)
rhs是改寫規(guī)則,其作用是通知sendmail如何來(lái)改寫一個(gè)與lhs相匹配的地址。lhs可以包含文本、宏及對(duì)匹配內(nèi)容在lhs中的位置把它匹配的內(nèi)容賦值給一個(gè)數(shù)字宏$ n。例如,假設(shè)地址zhang@hostl.somedomain.gov被傳遞給下面的規(guī)則:
R $+@$+$:$1<@ $ 2>foucus on domain
在此例中,由于zhang與$+(一個(gè)或多個(gè)任何內(nèi)容的標(biāo)記)相匹配,因此sendmail將字符串zhang賦值給$ l;地址中的@與lhs中的@相匹配,但常量字符串不被賦值給位置宏;字符串hostl.somedomain.gov中的標(biāo)記與第二個(gè)$十相匹配,因此它被賦值給了$ 2。這樣被改寫后的地址是$ l<@$ 2>,也就是zhang<@ hostl.somedomain.gov>。
現(xiàn)在考查下面的這條規(guī)則:
R $ * $:$ 1<@ $ j>add local domain
當(dāng)在rhs改寫一個(gè)地址后,sendmail將把改寫過(guò)的地址再與當(dāng)前規(guī)則的lhs相對(duì)比。在本例中,由于$*可以與0個(gè)或多個(gè)任何內(nèi)容的標(biāo)記相匹配,因此無(wú)論rhs如何改寫地址,它將始終與$ *相匹配,因此這一匹配規(guī)則將無(wú)限制地循環(huán)下去。為了避免sendmail在這條規(guī)則上進(jìn)人死循環(huán),引用了$:,它用來(lái)通知sendmail只對(duì)這一規(guī)則使用一次。
當(dāng)希望一個(gè)規(guī)則集立即終止并把地址返回給調(diào)用這一規(guī)則集的規(guī)則集或sendmail固有順序中的下一個(gè)規(guī)則集時(shí),可以在規(guī)則的rhs之前添加$@,它將使sendmail在rhs改寫地址之后立即退出這一規(guī)則集。
一個(gè)規(guī)則集可以通過(guò)在rhs前面添加$>向另一個(gè)規(guī)則集傳遞地址,考查下面這一條規(guī)則:
R $ * $:$>22 $ 1 call ruleset 22
rhs的$ *匹配零個(gè)或多個(gè)標(biāo)記,因此sendmail將不斷地執(zhí)行rhs,但由于在rhs前具有$:,所以這一規(guī)則只被使用一次。在這一規(guī)則中,$>22 $ 1 將以 $ 1 為輸入地址調(diào)用22號(hào)規(guī)則集。由于$ 1匹配的內(nèi)容正是lhs中的內(nèi)容,因此這一條規(guī)則只是把當(dāng)前的輸入地址原封不動(dòng)地傳遞給22號(hào)規(guī)則集。22號(hào)規(guī)則集返回的任何內(nèi)容都將傳遞給這一規(guī)則集中的下一條規(guī)則。
8.2.3 測(cè)試sendmail
在安裝一個(gè)新的或經(jīng)過(guò)修改的sendmail.cf之前,必須對(duì)它進(jìn)行徹底的測(cè)試,因?yàn)榧词故呛苄〉?、看起?lái)不會(huì)造成危害的修改也可能會(huì)導(dǎo)致嚴(yán)重的后果。
測(cè)試的第一步是創(chuàng)建一些地址,這些地址應(yīng)該是用戶的站點(diǎn)需要用到的有效地址。例如,在沒(méi)有UUCP連接Internet站點(diǎn)somedomain.gov處,下面的地址有效。
zhang
zhang@host1.somedomain.gov
znang@somedomain.gov
即使somdomain.gov具有一個(gè)UUCP連接,也應(yīng)該測(cè)試這些地址。其他一些需要考慮的地址包括各種別名(例如,Webmaster,include:列表,用來(lái)向文件郵寄的別名,用來(lái)向程序郵寄的別名)、非本地地址、源路由地址等等。
當(dāng)創(chuàng)建好測(cè)試地址的列表后,可以使用-C和-bt選項(xiàng)來(lái)查看將要發(fā)生的情況。這些地址至少應(yīng)該被傳遞3號(hào)規(guī)則集和0號(hào)規(guī)則集,從而確定它們是否能夠被路由到正確的郵件發(fā)送器。完成這一任務(wù)的比較簡(jiǎn)單的方法是,創(chuàng)建一個(gè)包含被調(diào)用的規(guī)則集以及測(cè)試地址的文件,然后對(duì)它執(zhí)行sendmail。例如,如果文件sdml.test包含下面的行:
3,0 zhang
3,0 zhang@hostl.somedomain.gov
3,0 zhang@somedomain.gov
那么,可以通過(guò)輸入下面的命令來(lái)測(cè)試配置文件test.cf:
$ sendmail-Ctest.cf-bt< sdml.test
rewrite:ruleset 3 input: zhang
rewrite: ruleset 3 retruns:zhang
[etc.]
還可以對(duì)一個(gè)或多個(gè)地址執(zhí)行改寫過(guò)程進(jìn)行全面測(cè)試。例如,如果某個(gè)地址被解析到SMTP郵件發(fā)送器。并且這個(gè)郵件發(fā)送器指定R=21,那么可以通過(guò)使用3,2,21,4等來(lái)測(cè)試收件人地址的改寫是否正確。
如果到目前為止sendmail.cf的工作正常,那么可以準(zhǔn)備發(fā)送一些真正的信件。執(zhí)行如下命令:
$ sendmail-v-oQ/tmp-Ctest.cf recipient</dev/null
這里的一v選項(xiàng)使得sendmall以冗余方式顯示信息,從而使用戶可以看到所發(fā)生的事情??吹降膬?nèi)容或者像zhang…Sen這樣的簡(jiǎn)單信息或者是一個(gè)完整的SMTP對(duì)話框。-oQ/tmp用來(lái)通知sendmail使用/tmp作為它的隊(duì)列目錄。使用這一選項(xiàng)很必要。因?yàn)楫?dāng)利用-C選項(xiàng)運(yùn)行時(shí),sendmail將放棄它的超級(jí)用戶權(quán)限,并且不能把隊(duì)列文件寫到正常的郵件隊(duì)列目錄中。由于這里使用了-C和-oQ選項(xiàng),因此sendmail在信件中也將包含如下的警告標(biāo)題,從而向收件人提醒一些偽造的郵件:
X-Authentieation-Warning:somedomain.gov:Processed from queue/tmp
X-Authentication-Warning:somdomain.gov:Processed by zhang with-C srvr.cf
sendmail也將在信件中插入標(biāo)題Apparemt;u-tp:zhang,這是因?yàn)殡m然在命令上指定了收件人,但信件中卻沒(méi)有任何內(nèi)容。在本例中,由于信件來(lái)自空文件/dev/null,因此沒(méi)有可用的To:標(biāo)題。如果以超級(jí)用戶的身份執(zhí)行測(cè)試任務(wù),那么就可以不使用-oQ選項(xiàng),sendmail便不會(huì)插人警告標(biāo)題。通過(guò)創(chuàng)建像下面的文件并利用它作為輸入來(lái)代替/dev/null,可以避免“Apparently-to:”標(biāo)題的插入。
To:recipient
test
收件人是用戶自己,以便檢查郵件頭的正確性。在一些特殊的情況下,返回地址行必須為SMTP包含一個(gè)FQDN。因此像From:zhang@somedomain這樣的標(biāo)題是不正確的,因?yàn)樗话值挠蛎糠?,但像From:zhang@somedomain.gov這樣的標(biāo)題是正確的。
3 sendmail的工作方式
sendmail應(yīng)用廣泛而且靈活,它有多種工作方式,能充當(dāng)多種角色。sendmail可以作為郵件路由器、SMTP客戶程序和SMTP服務(wù)程序。不過(guò),它不執(zhí)行最終的郵件投遞。
sendmail的主要角色是充當(dāng)一個(gè)郵件路由器。即通過(guò)它獲取信件、檢查收件人地址并確定發(fā)送信件的最好路徑。sendmail是如何來(lái)執(zhí)行這一任務(wù)呢?
sendmail可以確定它自己的一些信息,例如當(dāng)前的時(shí)間和它運(yùn)行所在的主機(jī)名,但它的大部分智能是由用戶(“郵件管理員”)通過(guò)配置文件sendmail.cf的形式來(lái)提供的。這個(gè)配置文件確切地告訴sendmail如何來(lái)處理各類郵件,它非常靈活和強(qiáng)大,并且乍看起來(lái)似乎難于理解。
但是,正像上面介紹的那樣,V8 sendmail具有一套模塊化的配置文件構(gòu)造塊,大多數(shù)站點(diǎn)都能夠利用這些模塊輕易地構(gòu)造出配置文件,并且還包括許多示例。
像前面提到的那樣,sendmail可以作為一個(gè)MTA運(yùn)行,因?yàn)樗斫釹MTP協(xié)議(V8 sendmail還理解ESMTP)。由于SMTP是一個(gè)面向連接的協(xié)議,因此客戶程序和服務(wù)程序(也稱為發(fā)送器和接收器)總是存在。SMTP客戶程序可以向SMTP服務(wù)程序投遞信件,SMTP服務(wù)程序?qū)⒉粩嗟乇O(jiān)聽計(jì)算機(jī)的SMTP端口。sendmail可以是一個(gè)SMTP客戶程序,也可以是一個(gè)SMTP服務(wù)程序。當(dāng)sendmail被MUA運(yùn)行時(shí),它成為一個(gè)SMTP客戶程序,并把客戶端SMTP通知給SMTP服務(wù)程序(不必是另一個(gè)sendmail程序);當(dāng)系統(tǒng)引導(dǎo)并且sendmail以守護(hù)進(jìn)程模式啟動(dòng)時(shí),它不停地運(yùn)行,為新發(fā)來(lái)的郵件監(jiān)聽著SMTP端口,這時(shí)sendmail就是一個(gè)服務(wù)程序了。
sendmail所不做的一件事情是郵件的最終投遞。sendmail把這一任務(wù)留給了其他程序。sendmail是一個(gè)大型的、復(fù)雜的、利用超級(jí)用戶權(quán)限運(yùn)行的程序,因此需要有一些方法來(lái)解決安全性的問(wèn)題,有關(guān)安全性的問(wèn)題在sendmail的過(guò)去已經(jīng)發(fā)生過(guò)許多次。郵件投遞的額外復(fù)雜性是sendmail有待解決的最后一個(gè)問(wèn)題。