郵件列表黃金搭檔——Qmail+Ezmlm 凌雲志 ·郵件列表是一種通過電子郵件進行專題信息交流的網絡服務。 ·每個列表由專人管理,所有成員都可以看到發給這個列表的所有信件。 ·一般電子郵件的發送都是“一對一”或“一對多”,郵件列表中可以實現“多對多”通信。 ·郵件列表是完全基於電子郵件系統的,信息的發送/接收方式都與普通的電子郵件相同。 Qmail與郵件列表服務 提供郵件列表服務的計算機稱為郵件列表服務器,主要通過電子郵件收集和發布信息,郵件列表的實現也是依賴於郵件系統的核心MTA(郵件傳輸代理)的,而郵件列表也是大型電子郵件系統中除基本郵件服務之外的一項十分有用的附加服務。支持郵件列表是Qmail的強項,它是一個能提供比一般UNIX(包括Linux、FreeBSD等)系統下常用的電子郵件系統Sendmail更安全、可靠而高效的MTA。它也是一個完全免費使用的自由軟件,可以在網上找到專門介紹它的主頁,並且可以找到、下載它的最新版本。在《中國計算機報·電腦工作室》2000年第59期中對Qmail的性能、安裝和配置有詳細的介紹(http://media.ccidnet.com/ media/isapi/ ViewCiw.dll?qh=947&&bm_id= 2)。 在Qmail下建立郵件列表與其他的MTA(如:Sendmail)相比有以下幾大優點: ·每個Qmail用戶都可以實現自己的郵件列表,向user-whatever的投遞會轉向~user/.qmail-whatever進行處理; ·可以非常方便地設置郵件列表的擁有者,比如用戶user用命令toUChe一個空文件~user/.qmail-whatever-owner,所有這個郵件列表的彈回信件會發給他自己; ·Qmail支持VERP(Variable Envelope Return Path,可變信封返回路徑),可將用戶預定郵件列表的地址與彈回的地址相關聯,可以可靠地自動處理任何大小的郵件列表的彈回; ·Qmail處理郵件列表投遞的速度大大高於Sendmail,例如,郵件列表中的每個郵件可以在76秒內投遞到分布於世界各地的1000個主機上; ·Qmail可以自動防止郵件列表的循環,即使是跨主機的郵件列表; ·Qmail對郵件列表的大小沒有任何限制,多大都可以; ·Qmail以相同的簡單機制處理別名和轉發,例如:Postmaster是由文件~alias/.qmail- postmaster來控制的,這就意味著跨主機的郵件列表循環檢測也包括對別名的檢測。 什麼是VERP呢?當一封郵件無法投遞時,MTA會將它彈回到信封返回地址(Envelope Return Path,簡稱ERP)。一個完整的彈回信件中應該被加上原收信人地址、未能完成投遞的原因、問題是暫時的還是長期的等信息。 有些MTA不能在彈回信件時指明郵件的收信人地址,對於一般單個用戶到用戶的應用來說,這也許不算一個什麼大問題:收到彈回信件的人可以從郵件內容、彈回時間等信息中分析出郵件是從哪裡被彈回的。對於郵件列表的管理來說,這個問題就比較嚴重了,如果訂閱郵件列表的用戶的E-mail地址發生變更,他將所有自己的郵件轉發到一個新的地址上,如果這個新地址的投遞發生問題,將郵件彈回到郵件列表服務器,郵件列表的管理者從彈回的郵件中是看不出這個郵件原來是發給哪一個訂閱者的,因為彈回的信息中只顯示了用戶變更後的新地址,而沒有顯示原來用戶訂閱郵件列表時登記的地址。如果這個用戶長期無法進行投遞,也就不能及時將他從訂閱名單中刪除掉,因為不知道是哪一個,這給郵件列表的管理帶來了麻煩。 為了解決這個問題,Qmail 的作者DJB提出了VERP的方法通過將用戶預定郵件列表的地址與彈回的地址相關聯,使得發往每一個訂閱者的郵件都有一個單獨的返回地址,這樣郵件列表管理者在處理彈回的郵件時可以輕松識別出是哪個訂閱者的郵件被彈回並可靠地自動處理任何大小的郵件列表的彈回。 正確的彈回處理很重要,比如,一個典型不支持VERP的郵件列表得到的返回地址的格式是listname-owner@ domain,而支持VERP的郵件列表得到的返回地址比較長,其中包括了用戶訂閱郵件列表時使用的訂閱地址,其格式為:listname-owner- subscriber= sdomain@ldomain,用戶原來訂閱郵件列表時的地址subscriber@sdomain嵌入到了返回地址中,為了符合對郵件地址有關語法規定,用“=”替換了原來的“@”號。 郵件列表管理軟件Ezmlm實戰 對郵件列表的自動維護是通過運行服務器上的郵件列表管理軟件(Mailing-list managers簡稱 MLM)來完成的,MLM幫助郵件列表的擁有者維護按照專題組成的郵件列表,它的主要任務是管理訂閱郵件列表的訂閱者名單,並控制郵件列表中向訂閱者的郵件發送。郵件列表一般都以某種專題為主題,都有自己專門的電子郵箱地址。當用戶希望加入某個郵件列表時,可以按照規定的格式給指定電子郵箱發一封申請加入的電子郵件,該用戶的電子郵件地址就會被自動加入該組的通信列表中。一旦加入,這個用戶就會不斷收到這個郵件列表以電子郵件方式發來的各種信息。如果用戶希望退出,只需給指定的電子郵箱發送一封請求退出的電子郵件即可。所以一個MLM應該包括用戶預定和退訂的處理、對發送郵件的過濾與限制(如只允許郵件列表的成員向列表發送郵件),對郵件列表文件整理歸檔,以及智能化的彈回處理等管理功能。 Ezmlm簡介 Qmail可以與UNIX下各種郵件列表管理軟件相配合實現郵件列表服務。目前Internet上常使用Sendmail+Majordomo來實現郵件列表服務,Majordomo仍是目前使用最多的郵件列表管理軟件。 雖然Qmail也能很好地支持這個軟件,但是Qmail的作者DJB發現它存在安全及效率方面的嚴重問題,於是開發了基於Qmail的更加安全、可靠、高效和易於使用的郵件列表管理軟件Ezmlm,從它的命名(Easy+MLM)就可以看出作者非常強調它的易用性。Ezmlm充分利用了Qmail的優勢,可以輕松實現彈回處理、訂閱請求和郵件歸檔等功能。DJB為它建立網頁:http://cr.yp.to/ezmlm.Html,可以從那裡下載軟件的最新版本。還有一個關於Ezmlm 的重要的網址:http://www.ezmlm.org/,這裡提供ezmlm-idx:Ezmlm的功能增強版,它為Ezmlm增加了很多實用的功能。 與Qmail一樣,Ezmlm的安全性和可靠性非常高。即使面對系統的崩潰,Ezmlm依然能保證很高的可靠性。每次向Qmail報告成功之前,它會將每一個訂閱、每一個郵件都安全地寫到硬盤上。Ezmlm對郵件列表的尺寸沒有任何限制,訂閱地址清單不會一下子全部調入內存。Ezmlm會首先將訂閱地址清單分割(hash)化為一系列單獨的文件,以加速處理訂閱工作。由於使用Qmail的高速並行的SMTP投遞,其投遞速度也是很快的。 在Ezmlm下用戶可以充分利用Qmail地址的層次結構,除了系統管理員可以在別名目錄下建立系統一級的郵件列表外,每個用戶都可以方便地在自己的目錄下建立和管理用戶級的郵件列表。Ezmlm利用VERPs來自動、可靠地處理郵件列表的彈回問題。它還可以為出現暫時投遞問題的訂閱者提供一份錯過郵件的清單,以便他們以後可以從郵件列表檔案中找回這些錯過的內容。當發給某個訂閱者的郵件被彈回時,Ezmlm會進行記錄,等待10天後,給這個訂閱者發出一個所有被彈回的郵件的清單以示警告,如果這個警告仍被彈回,Ezmlm會發出一個探針(Probe)去檢查這個地址,如果探針也被彈回,則自動將這個訂閱者刪除。 一般的郵件列表分為兩種類型。一類是單向通信的,又稱訂閱型郵件列表,也就是一般的電子期刊。加入這類郵件列表的目的主要是希望定期接收以電子郵件方式發來的信息,而不參與討論。訂閱型郵件列表一般不接受用戶的投稿。另一類是雙向通信的,參加的用戶不但可以接收到郵件列表發來的信息,還可以將自己的信息發送給全組的所有其他成員,讓大家參與討論。這類郵件列表又分為仲裁(moderator list)和非仲裁(non moderator list)兩種類型。仲裁型郵件列表設有仲裁人(moderator)。仲裁人在閱讀收到的用戶信件後,有權決定是否將它轉發給全組成員。非仲裁型郵件列表則將收到的郵件直接轉發給本組的其他成員。 Ezmlm通過將用戶地址加入DIR/allow/和DIR/deny/數據庫中來允許或禁止用戶發送郵件。另一個重要的數據庫是保存仲裁人地址的DIR/mod/,Ezmlm 的仲裁機制除可以決定是否將一個郵件轉發給郵件列表的其他成員外,還可以由仲裁人決定是否接收一個新的訂閱申請,以及向仲裁人提供遠程管理功能。用戶在使用ezmlm-make命令時配合不同的參數可以建立不同類型的郵件列表。 對於一些大型的郵件列表,由於訂閱的用戶很多,每天都要發送上百封信件,流量非常大,給郵件列表服務器帶來很大的負擔,對訂閱郵件列表的用戶來說,每天收到這麼多郵件也是很麻煩的。在郵件列表管理上建立郵件摘要(digest)可以解決這個問題。摘要是郵件列表中一組郵件的集合,將多個郵件打包後再發給用戶,可以減輕服務器和訂閱者的負擔。 在Ezmlm中可以建立摘要型郵件列表,每兩天自動生成一次郵件摘要。如果自上次摘要後有30個新郵件或者有總共大於64kB的郵件,則提前建立摘要,當然這些具體值是可以調節的。對於只對郵件列表中某些特定主題感興趣的用戶,收到經過分類的摘要比每次收到單個郵件更方便一些,這些用戶可以直接訂閱郵件列表摘要,而不用訂閱郵件列表本身。 Ezmlm會自動將所有新郵件標上序列號進行歸檔,訂閱者可以按序列號查找已經歸檔的郵件,如:訂閱者發一個郵件到地址joe-sos-get.123可以得到第123號郵件。郵件歸檔的格式支持快速檢索,即使郵件數量很多,也能保證速度。Ezmlm為用戶提供了非常方便的手段對自己的郵件列表進行管理和控制,比如:Joe可以編輯~/sos/text/來修改發往訂閱者的管理信息,刪除~/sos/public和~/sos/archived就可以關閉自動訂閱和歸檔功能,編輯~/sos/{headeradd,headerremove}可以發出郵件的郵件頭。Ezmlm中還有其他一些應用程序供用戶手工檢查和管理自己的郵件列表。 Ezmlm的安裝 在安裝Ezmlm之前,首先要安裝Qmail,具體的安裝方法參考在《中國計算機報·電腦工作室》2000年第59期的內容及Qmail軟件包中的Install等文檔。然後下載Ezmlm軟件包,開始進行安裝。 1. 編譯程序: % make 2. 格式化手冊頁: % make man 3. 安裝程序和手冊頁: # make setup Ezmlm的默認安裝路徑為:/usr/local/bin/Ezmlm,可以修改conf-bin來改變安裝路徑;手冊頁的默認安裝路徑為:/usr/local /man,修改文件conf-man來改變它的安裝路徑。如果Qmail沒有安裝在默認的路徑/var/qmail,需要修改文件conf-qmail指向它的安裝路徑。安裝完成後需進行以下測試: 1. 將ezmlm-make加入你的路徑中,建立一個簡單的郵件列表: % ezmlm-make ~/testlist ~/.qmail-testlist me-testlist host 將這裡的“me”和“host”換為你的郵件地址。 2.手工將自己的地址加入郵件列表: % ezmlm-sub ~/testlist me@host 3.發一個郵件到郵件列表: % echo subject:testing qmail-inject me-testlist@host 應該在訂閱郵件的地址me@host收到一份這個郵件的拷貝。 4.查看郵件列表成員: % ezmlm-list ~/testlist 應該只有一行,就是你自己剛才訂閱時的地址。 5.通過電子郵件將自己從郵件列表中退訂: % qmail-inject me-testlist -unsubscribe@host < /dev/null 當你收到要退訂的確認時,回答它以便完成退訂。再用ezmlm-list 命令查看郵件列表成員是否已為空。 6.從歸檔文件中查找剛才發出的郵件: % qmail-inject me-testlist -get.1@host < /dev/null 你應該收到剛才發送的主題為testing的郵件。 如果一切正常,說明Ezmlm安裝成功了!以上的測試中,我們使用了幾條常用的Ezmlm命令,有些主要功能除了可以命令來實現外,也可以通過電子郵件的形式來完成。除了郵件列表的擁有者可以管理自己的郵件列表外,還可以通過設置仲裁人,給仲裁人以較高的權限,讓他通過電子郵件來遠程管理郵件列表。 Ezmlm的命令 郵件列表服務的提供者可以利用Ezmlm的命令在郵件服務器上自己的目錄下建立和管理各種類型的郵件列表,Ezmlm的命令清單見表1。 Ezmlm下的郵件列表的建立和管理 在Qmail下建立郵件列表最大的好處就是每個用戶都可以方便地在自己的目錄下建立和管理用戶級的郵件列表,而不像在Sendmail這類系統下只能由郵件管理員建立系統一級的郵件列表。Qmail下的系統一級的郵件列表是建立在系統別名目錄下的,必須由郵件管理員建立: ezmlm-make ~alias/sos ~alias/.qmail-sos sos isp.net chown -R alias ~alias/sos 會在/var/qmail/alias目錄下建立一個子目錄sos,保存關於這個郵件列表的所有文件及配置。用戶可以使用前面介紹的方法來使用它,比如:所有發往地址sos- [email protected]的郵件都會自動進行訂閱,如果訂閱者向地址[email protected]或sos-help@ isp.net發出郵件,Ezmlm會自動給他們回復郵件列表使用說明。 表1 ezmlm的命令清單 命令 功能 ezmlm-make 建立郵件列表目錄及相應的文件。 ezmlm-sub和 ezmlm-unsub 進行訂閱和退訂管理。 ezmlm-manage 自動處理管理請求。 ezmlm-send 向郵件列表的所有用戶發一封郵件,如果郵件列表的配置要求,還將保留一份郵件檔案和郵件主題索引。 ezmlm-reject 拒絕那些主題為空或只有一個命令字的郵件。 ezmlm-return 處理彈回。 ezmlm-warn 警告那些郵件被彈回的用戶,並最終將郵件總是被彈回的用戶從郵件列表刪除。 ezmlm-idx 從一個已存在的郵件列表檔案中產生一個主題索引。 ezmlm-get 郵件管理:從檔案中重獲索引和線索,建立郵件摘要。 ezmlm-cron 定時運行,生成郵件摘要。 ezmlm-store 排列等待仲裁的郵件,向仲裁人發出仲裁請求。 ezmlm-moderate 處理仲裁請求,隊列中的郵件經過批准通過ezmlm-send發到郵件列表,不被批准的郵件退回給發送者。 ezmlm-clean 清除等待仲裁的郵件隊列,返回給郵件發送者超時信息。 ezmlm-gate 對於發送者地址在允許直接發送的數據庫中的郵件,直接發往郵件列表,其他的郵件則申請仲裁。 ezmlm-check 用於檢查、診斷ezmlm郵件列表的配置問題。 ezmlm-issub ezmlm-issubn 判斷一個sender(發信人)是不是本郵件列表的用戶,或是某個地址集合的成員。 ezmlm-tstdig 通過郵件的數量和總的大小及上次生成摘要後過的時間來判斷是否應該生成新的摘要。 ezmlm-request 可做為與其它mlm的通用接口,可用於方便地移植其他mlm命令。 ezmlm-glmake 建立通用接口。 ezmlm-glconf 為你的郵件隊列的通用接口建立一個配置文件。 ezmlm-archive 建立一個線索索引,ezmlm-cgi 可以用來允許通過http服務器訪問郵件隊列的檔案。 對於普通用戶來說,使用的是Qmail提供的擴展地址方式,在Qmail中向user-whatever的投遞會轉向~user/.qmail-whatever進行處理,比如:有一個用戶Joe,輸入命令: ezmlm-make ~/sos ~/.qmail-sos joe-sos isp.net 就可以在自己的目錄下建立起一個全功能的郵件列表:[email protected],所有有關郵件列表的信息都保存在新建立的子目錄(~/sos)之下,用戶以擴展地址方式來訂閱和訪問這個郵件列表,如所有發往地址[email protected]的郵件都會自動進行訂閱。 Ezmlm的命令中最重要和靈活的就是ezmlm-make,通過配合不同的參數,可以建立各種不同類型的郵件列表。比如: ezmlm-make -d ~joe/sos ~joe/.qmail-sos joe-sos isp.net 加上了參數“- d”,可建立一個有自動摘要功能的郵件列表。在默認參數下建立的郵件列表,是完全公開的,大家可以隨意地訂閱、退訂以及訪問郵件檔案,用戶也可以通過ezmlm-make命令隨時修改以前建好的郵件列表的類型,比如:加上參數“-m”表示要建立對郵件列表內郵件投遞的仲裁;加上參數“-s” 表示只有經過仲裁人批准,新的用戶才能加入郵件列表。而這些參數改為大寫,則表示相反的意思,如“-M”表示要建立非仲裁型的郵件列表。比如: ezmlm-make -emrldn ~joe/sos 如果將這個郵件列表改為允許遠程管理的仲裁型郵件列表,可以用以下命令為這個郵件列表加入仲裁人: ezmlm-sub ~joe/sos/mod mod1@host1 mod2@host2 ... 一般用戶的使用方法 對於一般的郵件列表用戶可以使用不同類型的郵件地址來方便地實現各種功能,只要向特定的地址發一封空的郵件(郵件的內容和主題都被忽略,將實現不同的功能)。 1.mailinglist-subscribe@ example.org 表示我要訂閱!Ezmlm會發給你一個確認請求,一旦你回復了確認,就將你的地址加入郵件列表。 2.mailinglist-subscribe- [email protected] 以地址[email protected]來進行訂閱。這時是以地址[email protected]來訂閱郵件,而非你發送訂閱請求的地址,可以在這裡使用任意地址來替換[email protected],將地址中的“@” 用“=”號來替換就可以了。當然,Ezmlm會向[email protected]發送確認請求。 3.mailinglist-unsubscribe@ example.org 表示我要退訂。Ezmlm會先發給你一個確認請求,一旦你回復了確認,就將你的地址從郵件列表中刪除。 4.mailinglist-unsubscribe- [email protected] 退訂地址[email protected]。 5.mailinglist-query@ example.org() 查詢地址是否在郵件列表中。 6.mailinglist-get.123@ example.org 從歸檔的郵件中取得第123號郵件。如果你指明的郵件序列號大於目前已歸檔的郵件的最大序列號,你會收到最新的郵件。 [email protected](*) 從歸檔的郵件中取得最近的30個郵件。對於建立了摘要的郵件列表,則返回最近一次摘要之後的新郵件(最近一次摘要中的最後一個郵件也被返回,所以至少會返回一個郵件)。 8.mailinglist-get.45_67@ example.org() 從歸檔的郵件中取得從第45到第67號的郵件。每次請求返回的郵件數目不超過100個。如果第一個參數大於目前已歸檔的郵件的最大序列號,會給你返回最近的30個郵件。對於建立了摘要的郵件列表,則返回最近一次摘要之後的新郵件,或者這次摘要之中的最後30個郵件。 9.mailinglist-index@example .org() 發送最近100~200條郵件的主題和作者,每次請求的回復不超過2000行。 10.mailinglist-index.300_ [email protected]() 發送第300~399條郵件的主題和作者。 11.mailinglist-thread.45@ example.org() 收到與第45號郵件相同主題的經過組織的郵件集。 12.mailinglist-info@example .org() 發給我有關這個郵件列表的有關信息 (郵件列表的的主人決定返回什麼樣的具體內容)。 13.mailinglist-faq@example .org() 發給我有關這個郵件列表的FAQ及回答(郵件列表的的主人決定返回什麼樣的具體內容)。 14.mailinglist-digest-sub [email protected]() 訂閱[email protected]這個郵件列表的摘要。 15.mailinglist-digest-un [email protected]() 退訂郵件列表摘要。