Postfix sasl身份驗證功能
基本的smtp協議沒有驗證用戶身份的能力。雖然信封上的寄件人地址已經隱含了發信者的身份,然而,由于信封地址實在太容易假造,所以不能當成身份憑據。 為了判斷客戶端是否有權使用轉發服務(relay),服務器端必須確認客戶端(寄件人)是否當真是對方所自稱的那個人。在不能以寄件人地址為身份證書的前 提下,smtp勢必需要其他補充機制,才能驗證客戶端的身份。那我們就來看看Postfix sasl身份驗證機制,是如何運行的。
從postfix的角度看,它需要扮演兩種角色:當它身為smtp server時,需要能夠驗證用戶個人的身份(讓他們能使用smtp server寄出郵件);當它身為smtp client時,它需要能夠提供出自己的身份證書給其他mta檢驗(以便通過遠程mta將郵件遞送到最終目的地)。因此,我們也會解釋如何設定 postfix,使其能通過其他mta的身份驗證。
大多數郵件系統只容許內部網絡上的客戶端使用轉發服務,換言之,ip地址成了客戶端身份的識別 憑據。然而,并非所有合法用戶都具有固定ip地址。比方說,帶著筆記本電腦出差遠方的同事,他們可能使用領近isp或飯店旅館提供的臨時性ip地址;或 者,有些在家工作的用戶,他們位于辦公室之外的網絡,但是需要透過辦公室里的郵件系統來寄信。不管你是否能夠事先知道用戶的ip地址,sasl都能提供可 靠的身份驗證。
RFC 2554 “smtp service extension for authentication”制定了如何在基本smtp協議上增加驗證功能的機制,此機制使得smtp能使用sasl協議來驗證客戶端身份。我們將示范 如何使用carnegie mellon大學開發的cyrus sasl函數庫來擴充postfix,使其具備sasl驗證能力。
由于cyrus sasl以“函數庫”的形式存在,要讓你的postfix支持sasl,你必須在編譯postfix時就將cyrus sasl函數庫鏈接進去,此外,遠程用戶也必須設定他們的mua,使其在通過你的郵件系統轉發郵件時,能送出正確的標識信息。
sasl概論
有 許多客戶機/服務器協議沒有驗證能力,sasl就是用于加強或增加這類協議的一種通用方法。當你設定sasl時,你必須決定兩件事;一是用于交換“標識信 息”(或稱身份證書)的驗證機制;一是決定標識信息存儲方法的驗證架構。sasl驗證機制規范client與server之間的應答過程以及傳輸內容的編 碼法,sasl驗證架構決定服務器本身如何存儲客戶端的身份證書以及如何核驗客戶端提供的密碼。如果客戶端能成功通過驗證,服務器端就能確定用戶的身份, 并借此決定用戶具有怎樣的權限。對postfix而言,所謂的“權限”指的就是轉發服務的訪問權。你也可以決定通過驗證的用戶在轉發郵件時,是否要使用特 定的寄件人地址。
選擇適當的驗證機制
cyrus sasl支持多種驗證機制,至于要使用哪一種驗證機制,客戶端與服務器雙方必須事先取得共識。以下是一些比較常見的機制;
plain
plain是最簡單的機制,但同時也是最危險的機制,因為身份證書(登錄名稱與密碼)是以base64字符串格式通過網絡,沒有任何加密保護措施。因此,使用plain機制時,你可能會想要結合tls。
login
login不是其正式支持的機制,但某些舊版的mua使用這種機制,所以cyrus sasl讓你可選擇其是否支持login機制。如果你的用戶仍在使用這類老掉牙的mua,你必須在編譯sasl函數庫時,指定要包含login的支持。 login的證書交換過程類似plain。
otp
otp是一種使用“單次密碼”的驗證機制。此機制不提供任何加密保護,因為沒必要--每個密碼都只能使用一次,每次聯機都要改用新密碼。smto client必須能夠產生otp證書。
digest-md5
使用這種機制時,client與server共享同一個隱性密碼,而且此密碼不通過網絡傳輸。驗證過程是從服務器先提出challenge(質詢)開始, 客戶端使用此challenge與隱性密碼計算出一個response(應答)。不同的challenge,不可能計算出相同的response;任何擁 有secret password的一方,都可以用相同的challenge算出相同的response。因此,服務器只要比較客戶端返回的response是否與自己算 出的response相同,就可以知道客戶端所擁有的密碼是否正確。由于真正的密碼并沒有通過網絡,所以不怕網絡監測。
kerberos
kerberos是一種網絡型驗證協議。除非你的網絡已經使用kerberos,否則你應該用不到kerberos機制;相對的,如果你的網絡已經架設了kerberos驗證中心,sasl就能完美的將smtp驗證整合進現有的體系。
anonymous
anonymous機制對smtp沒有意義,因為smtp驗證的用意在于限制轉發服務的使用對象,而不是為了形成open relay,sasl之所以提供這種機制,主要是為了支持其他協議。
當 客戶端鏈接到一個支持sasl的郵件服務器時,服務器會以優先級列出可用的機制供客戶端選擇。如果客戶端也支持多鐘機制,則當第一種機制驗證失敗時,客戶 端可能會繼續嘗試第二種機制,直到通過驗證或是所有機制都失敗為止。如果雙方在一開始就無法協調出共同的機制,驗證過程就算失敗。
一旦雙方在使用哪種機制上達成共識,就開始進行驗證過程。實際的交互過程隨機制而定,但通常包含一次或多次應答過程。驗證協議本身也規定了應答內容的編碼格式。
選擇適當的驗證架構
sasl驗證架構可以使用現有的unix系統密碼,也可用smtp用戶專用密碼文件。如果你的網路上kerberos之類的中間控制式驗證構架,也可以使用。
哪 一種驗證架構最適合你,取決于你的服務器從何、如何取得證書信息。舉例來說,如果smtp與pop/imap的所有用戶的證書數據都是儲存在系統密碼文 件,并通過pam來驗證,那么sasl就應該透過pam來取得證書數據。另一方面,如果所有smtp user都只有虛賬戶,你或許應該將證書數據存放在專用的數據庫,并設定sasl與POP/IMAP server從該數據庫取得證書數據。
postfix與sasl
在開始使用sasl之前,你應該決定好,要采用哪一種機制與架構的組合,因為你的決定將影響編譯、安裝、設定的過程。首先,你必須先將sasl函數庫安裝 到你的系統上,或是確定sasl函數庫的安裝目錄與版本。接著,使用你收集到的sasl安裝信息來設定postfix的編譯選項,然后重新編譯 postfix,使其具備sasl驗證能力。某些系統平臺可能已經預先安裝了sasl函數庫,甚至提供支持sasl的postfix包,不過,大部分預先 編譯好的postfix包都不支持sasl。因此,如果你使用現成的postfix包,最好先研讀相關說明文件,或是按照本章“測試驗證配置”一節所說的 測試方法,確認你的postfix確實支持sasl。此外,你也要確認你的sasl函數庫支持客戶端可能使用的每一種驗證機制。比方說,若你的用戶中還有 人使用老版的outlook express,你的sasl函數庫就必須支持login驗證機制。
cyrus sasl函數庫的研發進度,目前分為兩條線路,即sasl與saslv2。其中,sasl已經逐漸被saslv2所取代。在未來,postfix可能只支 持saslv2,所以本章只討論saslv2。此外,postfix與sasl函數庫兩者的版本都必須正確,才能組合在一起。
postfix從1.17-20020331實驗版開始支持saslv2函數庫,在這之前的版本,只能使用saslv1。理論上,最新版的postfix與最新版的cyrus saslv2應該可以順利結合在一起。
postfix的sasl配置
假設你已經安裝好sasl函數庫,而且postfix也支持sasl,并下定決心要使用哪一種驗證機制與架構的組合。現在,讓我們逐步設定postfix,使其能夠使用sasl來驗證用戶的身份。
設定驗證架構
對于每個使用cyrus sasl函數庫的應用系統,cyrus sasl各提供一個獨立的配置文件。影響postfix的sasl配置文件是smtpd.conf。此文件通常位于 /usr/local/lib/sasl2/smtpd.conf。基本上,smtpd.conf至少要指出所要使用的驗證架構。我們打算討論兩種最常用 的架構:unix系統密碼以及獨立的sasl專用密碼。
unix系統密碼
通常,讓sasl直接使用現有的系統密碼來驗證用戶身份是最方便的。傳統的系統密碼文件應該是/etc/passwd,但是講究安全性的現代系統則比較可 能使用/etc/shadow、pam或諸如此類的證書數據庫。由于這類密碼文件只有特權進程才能訪問,而postfix卻被刻意設計成避開特權身份,所 以postfix不能直接訪問系統密碼文件。
cyrus函數庫對于這個問題的解決辦法,是提供一個特殊的驗證服務器程序,稱為saslauthd,它能夠代替postfix來取得密碼數據。 saslauthd eaemon本身需要特權身份,不過,由于它是一個獨立于postfix之外的進程,而且通常不必于外界進行網絡通信,所以安全性的危害已經被降到最低。 如果你打算讓sasl使用unix系統密碼,你必須啟動cyrus sasl包隨附的saslauthd daemon。請注意,使用saslauthd來訪問unix系統密碼,表示你只能使用明文密碼,因為asalauthd需要實際密碼才能進行核驗。
要讓sasl知道postfix將通過saslauthd daemon來訪問證書數據庫,你必須將下列內容加入smtpd.conf配置文件:
pwcheck_method: saslauthd
cyrus sasl包隨附的saslauthd應該會被安裝在$PATH環境變量所列的某個目錄下。你必須先在后臺啟動saslauthd daemon,postfix才能使用它來驗證客戶端。當你啟動saslauthd時,你必須使用-a選項指定密碼系統的類型最常見的類型包括pam、 shadow或getpwent。舉例來說,在一個使用pam的系統上,你應該使用下列命令來啟動saslauthd daemon:
saslauthd -a pam
sasl專用密碼
如果你不想使用系統密碼來驗證smtp client,你刻意另外建一個無關系統密碼的獨立賬戶數據庫。當你的postfix系統純粹用于提供寄信服務,而不用于接收外來郵件,用戶也不用登錄服 務器系統本身時,使用sasl密碼可能是個好主意。請將下列內容加入你的smtpd.conf配置文件:
pwcheck_method: auxprop
在cyrus的術語中,auxprop的意義是auxiliary property plug-ins(輔助性的專屬外掛模塊),其作用是使用外部程序來進行驗證。默認的輔助外掛模塊是sasldb(這也是cyrus sasl包隨附的程序之一),它應該能滿足postfix的所有需求。關鍵字auxprop只是要求使用外部的sasl密碼文件。
使用sasl密碼時,不需要用到saslauthd daemon,但是你必須將所有的smtp client賬戶與密碼存放在一個專用的外部密碼文件中。sasl默認使用的密碼文件是/etc/sasldb2。postfix smtp server至少要具備能讀取此文件的權限;如果你使用cyrus sasl的auto_transition功能,則postfix將需要能夠寫此文件的權限;如果你用不到auto_transition功能,最好不要 將寫權限開放給postfix。
如果還有其他進程也需要能夠訪問sasl密碼文件(比方說,pop/imap server),你必須適當調整該文件的擁有權與訪問權限,讓相關進程都能訪問它。舉例來說,你可以建立一個sasl組,并確定postfix與其他需要 訪問該文件的賬戶都隸屬于此組。如果有任何去他進程需要更新該文件,則只讀模式可能太嚴格,而你必須提供寫權限給必要的進程。下列命令將 /etc/sasldb2的訪問模式設定為440,這使得sasl組的所有成員都能夠讀取該文件,除此之外的其他進程則沒有訪問權:
chown postfix:sasl /etc/sasldb2
chmod 440 /etc/sasldb2
cyrus sasl包所提供的saslpasswd2工具,可用來產生、維護/etc/sasldb2密碼文件。對于每一個賬戶,你必須提供三項信息:登錄名稱、 sasl網域名稱、密碼。就postfix而言,網域名稱必須與myhostname參數的值吻合。所以,最保險的設定方法,就是利用postconf -h myhostname來決定網域名稱,如下:
saslpasswd2 -c -u `postconf - h myhostname` kdent
-c選項要求saslpasswd2創建(create)一個賬戶。“-u”選項指出該賬戶所屬的網域,其值直接取自postfix的配置文件。
設定postfix
所有與sasl密碼驗證相關的postfix參數,全部都是以smtpd_sasl*(關于smtp server的參數)或smtp_sasl*(關于smtp client的參數)為前綴。對于服務器端的配置,你至少需要設定smtpd_sasl_auth_enable參數,并且將 permit_sasl_authenticated限制條件列在某一個smtpd_*_restriction的過濾規則里。
啟用sasl驗證
smtpd_sasl_auth_enable參數決定postfix smtp server是否支持sasl驗證:
smtpd_sasl_auth_enable = yes
有些老的mua沒有完全遵守smtp驗證協議。依照規范說明書的標準規定,當smtp client送出ehlo命令之后,smt server應該要列出其驗證機制支持列表,而且此列表是出現在關鍵字auth與一個空格之后。
不過,有些mua卻期待收到auth與一個等號;
postfix容許你接受這種不遵守規定的行為:
broken_sasl_auth_clients = yes
設定此參數之后,postfix會分別以標準與非標準兩種格式來列出它所支持的smtp驗證機制。
由于兩種格式都出現在smtp server的響應中,所以既不會影響標準的mua,同時又能讓那些不標準的mua使用smtp sasl驗證。
避免寄件人冒名
當客戶端通過postfix寄信時,要如何確定客戶端使用的真實的寄件人地址?比方說,某人以A身份通過smtp驗證,但是卻以B為發行人地址,要如何避 免這種冒名情況?postfix容許你設定寄件地址與sasl登錄身份的對應關系。舉例來說,假設某人的郵件地址是kdent@example.com, 其sasl登錄身份為kdent,如果你希望kdent只能以該地址的名義來發郵件,而不能使用其他寄件地址,你應該將下列對應關系定義在一個查詢表中:
kdent@example.com kdent
這是一個普通的postfix查詢表,你可以逐一列出每一個地址與每一位sasl用戶的對應關系,也可以使用正則表達式來表示郵件地址的人名部分或網域部分。制作好查詢表之后,請將main.cf的smtpd_sender_login_maps參數指向此表:
smtpd_sender_login_maps = hash:/etc/postfxi/sasl_senders
下一步是將reject_sender_login_mismatch限制條件納入某個smtpd_*_restrictions過濾規則組合里,這樣一 來,如果kdent通過sasl驗證,但是他卻試圖以mary@example.com的名義寄出郵件,那么postfix將拒絕幫他寄信。
核準授權用戶
如果你的ube過濾規則里包含了smtpd_recipient_restrictions,你得使postfix準許通過驗證得用戶使用轉發服務,也就是將permit_sasl_authenticated安插在限制條件里得適當位置。
設定驗證機制
當客戶端聯機到smtp server時,有哪些密碼驗證機制可使用,由smtpd_sasl_security_options參數決定。完整得機制選項,取決于你得系統上有哪 些機制可用以及你得sasl函數庫支持哪些機制。如果不指定任何選項,默認值是接受包括明文密碼在內得所有可用機制,但匿名登錄除外。如果使用了 saslauthd daemon,就必須接受明文密碼,所以,默認值的設想是合情合理的。如果你指定了任何選項,則默認值無效,所以你的選項里必須包含 noanonymous。例如:
smtpd_asal_security_options = noanonymous, noplaintext
#p#
以下是通用的機制選項:
noplaintext
此選項將plaintext密碼驗證排除在外。這使得sasl選項challenge/response技術來使用。如果你的安全政策不容許密碼以明文形 式流經網絡,那就指定noplaintext選項吧,但是這也表示你不能使用saslauthd。
noactive
此選項將可能遭受“主動攻擊”的密碼機制排除在外。在“主動攻擊”中,攻擊者想辦法將他們安插到client與server之間,所以,某些類型的主動攻 擊又被稱為"中間人攻擊“。攻擊者可以讀取或改變數據,讓client或server誤以為數據真的是對方送過來的。
nodictionary
此選項將可能遭受”字典攻擊“的密碼機制排除在外。在”字典攻擊“中,攻擊者使用預編的密碼數據庫,逐一測試哪個密碼”恰好“能闖入你的系統。這類密碼數 據庫通常由城市、團隊、寵物、常見人名、字典詞匯,加上各種明顯的詞匯變化等組成,所以稱為”字典攻擊“。
noanonymous
排除匿名登錄。smtp驗證的最主要目的,就是要確認用戶的身份,所以”匿名登錄“對smtp server是沒有意義的。postfix的默認行為是禁止匿名登錄。如果你指定了其他選項,你必須明確設定noanonymous。
mutual auth
要求使用互證機制--client與server雙方都要提供證明自己身份的證據。
設定步驟匯整
在postfix系統中添加sasl功能所涉及的步驟有點繁復。總結本章前述的知識,以下是我們整理出來的設定步驟:
1、決定你打算支持的驗證機制與架構。
2、安裝sasl函數庫,并重新編譯postfix,使其包含sasl。或者取得已經內含sasl的postfix包,以及相關的sasl驗證機制。
3、重新安裝postfix
4、創建/usr/local/lib/sasl2/smtpd.conf配置文件,將pwcheck_method參數設定為saslauthd(如果使用sasl saslauthd與系統密碼的話)或auxprop(如果使用sasl的專屬密碼文件的話)。
5、如果你選擇的驗證架構是unix系統密碼,請啟動saslauthd daemon,并且指出你的系統所用的驗證方式;否則,使用saslpasswd2命令在你的系統上創建smtp client的賬戶與密碼。
6、編輯main.cf,啟動sasl驗證功能,并指出驗證方式。基本的設定至少需要下列兩項參數:
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks,
permit_sasl_authicated, reject_unauth destination
7、重新加載postfix,使我們在main.cf配置文件所做的改變生效:
postfix reload
測試sasl驗證配置
經過重重難關之后完成安裝,要如何要確定所有步驟都沒有出錯,證明postfix確實真的已依照我們的要求來進行驗證?等到用戶旅行到外地了以后,看看他 們會不會打長途電話回來抱怨,肯定不是好辦法。最好的辦法,是直接觀察smtp server的交互情況,實際體驗驗證過程,并立刻查閱日志文件留下的線索。
要想聯機到smtp server,最容易的方法是使用telnet工具程序,然后與服務器進程smtp對話。最容易測試的plain機制,如果你禁用這項機制,建議你暫時先啟用它,等完成測試實驗之后再關掉它。
先讓我們了解plain機制的細節,然后再開始動手做實驗。plain機制要求你在auth命令之后提供一個身份標識串,此字符串編碼成base64格 式。構成此字符串的各項數據的次序是“登錄身份”,其后跟著一個null字符,然后是“密碼擁有者的身份”,再跟一個null字符,最后是“密碼”本身。 通常,“登錄身份”與“密碼擁有者的身份”是相同的。舉例來說,假設用戶kdnet的密碼為rumpelstiltskin,而且其登錄身份與密碼擁有者 身份相同,那么,他的身份標識符串是“kdent\okdent\orumpelistiltskin”(編碼前的格式)。
麻煩之處,在于如何將標識符串編碼成base64格式且不包含字符串末端的CR字符。如果你的系統上有mmcncode與printf命令,這步驟應該不 難。printf命令能顯出指定格式的字符串,但是不會像echo之類的命令那樣,自動在字符串末端補一個換行字符。mmencode命令能將輸入字符串 編碼成各種mime格式,且其默認格式正好是我們所需要的base64。
所以,我們可用下列命令來產生base64格式的標識符串:
printf 'kdent\0kdent\0rumpelstiltskin' | mmencode
某些系統平臺的printf可能不能正確地處理字符串中間地null字符(\0),要想知道自己系統上地printf有沒有這個毛病,只要看base64編碼結果是否比原字符串短。如果你地printf有問題,不妨使用echo -n來代替printf。
smtp客戶端驗證
本章前半段地討論,著重于postfix如何扮演smtp驗證地服務器端角色--驗證遠程mua或mta地身份,借此判斷對方是否有權使用轉發服務。現 在,我們要換個角度,討論postfix如何扮演客戶端角色--提出自己地身份證明,借此獲得遠程mta地轉發服務地使用權。
首先,你得提供一個密碼文件給postfix,其中包含能通過遠程服務器得證書數據。此密碼文件得每一筆記錄,各包含一個代表遠程服務器的網域以及一組能通過該服務器驗證的賬戶與密碼,格式如下:
destination username:password
當postfix要寄出一封郵件時,它先檢查收件地址的網域部分,如果不能在密碼文件中找到完全相符的destination,再尋找打算聯機的主機名 稱。這種檢查過程使得postfix可以輕易連接共享相同賬戶數據庫的多個mx主機。決定密碼文件位置的參數是 smtp_sasl_password_maps。
決定客戶端行為的是smtp_sasl_security_options參數,其設定方法與服務器端的smtpd_sasl_security_options參數相同,所以不再贅述。如果你沒指定任何選項,則默認行為是容許系統上所有能找到的機制,唯獨匿名登錄除外。
smtp客戶端驗證的設定過程
讓我們舉個例子來示范要如何設定postfix,才能使其在通過遠程系統轉發郵件時,提出自己的身份證明。在這個例子中,假設我們有一組可以通過ora.com網域的所有服務器主機的賬戶以及一組可以通過mail.postfix.org主機的賬戶。
1、創建/etc/postfix/sasl_passwd密碼文件,并填入我們擁有的賬戶與密碼,例如:
ora.com kdent:rumpelstiltskin
mail.postfix.org kyle:quixote
2、使用postmap產生數據庫文件:
postmap /etc/postfix/sasl_passwd
3、編輯main.cf配置文件,啟動客戶端驗證功能。請注意,這次要設定的參數是smtp_sasl_auth_enable,而不是 smtpd_sasl_auth_enable(后者用于啟動服務器端驗證)。接著,在smtp_sasl_password_maps參數中指出密碼文 件的位置:
smtp_asal_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
4、重新加載postfix,使我們所做的改變生效:
postfix reload
現在,每當postfix smtp client試圖通過/etc/postfix/sasl_passwd所列的任何網域或主機來轉發郵件時,它就會提供對應的驗證書籍。比方說,如果你的 postfix smtp client聯機到mail.ora.com服務器,則它會使用kden與rumpelstiltskin這組賬戶與密碼。
通過文章的介紹,我們知道把Postfix sasl身份驗證機制會好,那以后就不用發愁郵件的安全性了。
【編輯推薦】
- Postfix利用擋信機制來消除垃圾郵件的隱患
- Postfix郵件轉發詳解
- Postfix虛擬網絡域名
- Postfix里的POP與Imap介紹
- Postfix中的地址操作大全
- 使用 Kerberos 進行 SharePoint 身份驗證
- 修改SQL Server身份驗證模式的方法
- IIS服務中五種身份驗證的靈活運用