Qmail

Qmail

qmail是一個網際網路郵件傳送代理(簡寫為MTA),它運行在linux/Unix兼容系統下,是一個直接代替UNIX下Sendmail軟體的郵件傳送程序。qmail使用SMTP協議與其它系統上的MTA交換郵件。

介紹


Qmail
Qmail
作為Linux下面主流的郵件系統內核,大量著名的商業郵件系統都是在Qmail內核下開發,比如Hotmail 等。Qmail具有安裝方便、安全性高、郵件結構合理、支持SMTP服務、隊列管理、郵件反彈、基於域名的郵件路由、SMTP傳輸、轉發和郵件列表、本地(郵件)傳送、POP3 服務等強大的功能。它已經逐漸替代傳統的Sendmail成為linux下郵件系統內核的主流選擇。qmail是面向安全而設計的,作者曾經懸賞500美元來找出qmail的安全漏洞,但是直到2006年,還是沒有人能領取這筆獎金。
qmail的主要競爭對手是Exim以及Postfix。與它的競爭對手不同的是,Qmail已經許多年沒有更新了,用戶已經習慣於通過第三方的插件及補丁來使qmail增加新的功能。
qmail 的源代碼現已開放為公有領域。

總體架構


Before delving too deeply into further configuration and tailoring of qmail, it is important to understand the basic structure of qmail. Qmail is often referred to as merely a mail server software package. While this may be accurate in one sense, it is more accurate to think of qmail as a mail delivery architecture whose architect has thoughtfully provided a basic implementation of all the components of that architecture. 在深入探索qmail的配置和調節之前,了解一些qmail的基礎架構是重要的。Qmail經常被僅僅歸類為一個郵件伺服器軟體包。這可能只在某一點上是正確的,將qmail考慮為一個郵件分發體系會更加準確,這個體系結構的構建者為這個體系的所有組件深入的提供了一些基礎介面。
Qmail is very modular—it consists of a series of simple programs communicating via specific and limited interfaces. Each simple program has a specific and limited task to perform. This architecture allows each component program to be easily replaced or new programs to be inserted between the basic components. Qmail是非常模塊化的——它包含了一系列通過特定且受限的介面來互相溝通的簡單程序。每個簡單的程序都有一個特定且受限的任務需要完成。這個體系結構允許每個組件都被容易的替代或讓新的程序插入到基礎組件之中。
Additionally, this architecture limits the security impact of any one of the components. Each program is further separated from the others, whenever possible, by giving each program a different UNIX user and specific permissions so that it can"t affect anything it is not supposed to. Because the communication interfaces are limited, it is significantly more difficult to attack the software and achieve much—attacking a component that does not have enough privileges to do anything other than what it is supposed to do is much less useful for an attacker. 另外,這個體系限制了所有組件的安全影響。任何一個程序都與另外的程序隔離開來,在任何可能的情況,給每個程序一個不同的UNIX用戶和特定許可權來確保它不會做任何它不應該做的事。因為通訊介面被限制了,因此顯然更難去攻擊軟體或更多別的——攻擊一個沒有足夠許可權來做任何它不應該做的事的組件對攻擊者來說是很沒有用處的。
qmail
qmail
The simplest example is receiving email from the network. The trail of programs in basic qmail is as follows: tcpserver to qmail-smtpd to qmail-queue. The tcpserver program has two tasks: open up a port to listen to the network, and run qmail-smtpd as the appropriate user for every connection. Because listening to low ports (such as the SMTP port, 25) requires root permissions, tcpserver generally runs as root. However, because tcpserver doesn"t attempt to understand the communication, it is very difficult to attack. The qmail-smtpd program has only two tasks as well: speaking the SMTP protocol sufficiently to receive email messages, and sending these email messages to qmail-queue. As such, qmail-smtpd need not do anything with the on-disk queue or the network. This allows qmail-smtpd to be run as a user with very limited permissions, and also allows qmail-smtpd to be a much simpler, and easier to verify and debug, program than it would be otherwise, even though it has to interact directly with user (or attacker) input. The qmail-queue program has only one task—to write messages to the on-disk queue prepended with a Received header. It need not talk to the network, or understand the contents of the messages it writes to disk, making the program simple and easy to verify and thus hard for an attacker to break. 最簡單的例子是從網路上收郵件。一個基礎的qmail實驗如下:tcpserver到qmail-smtpd到qmail-queue。tcpserver程序有兩個任務:打開一個埠來監聽網路,並對每個連接以正確的用戶來啟動qmail-smtpd。因為監聽低埠(如SMTP的埠:25)要求root許可權,所以tcpserver通常以root用戶運行。然而,因為tcpserver並不試圖理解通訊,所以很難被攻擊。qmail-smtpd程序也只有兩個任務需要運行:充分使用SMTP協議來接收消息,併發送這些郵件消息到qmail-queue。就這個而言,qmail-smtpd本身並不需要對磁碟上的隊列或網路做任何事情。這允許qmail-smtpd能被一個許可權非常受限的用戶來運行,而且允許qmail-smtpd成為一個非常簡單,而且容易被驗證和排錯的程序,即使它需要與用戶(或攻擊者)輸入直接溝通。qmail-queue程序則只有一個任務——將消息寫到已經有了接收頭的磁碟隊列上。它無需和網路溝通,或者了解它寫到磁碟上的消息的內容,使得程序簡單並容易被驗證,從而使得攻擊者更難破壞它。 Note that this architecture can be easily extended. The tcpserver program can execute any program, which can in turn execute qmail-smtpd as necessary. This might be useful, for example, to make decisions about whether to permit a connection to reach qmail-smtpd or to set and unset environment variables before qmail-smtpd is executed. It could even be used to sanitize data before it gets to qmail-smtpd. Similarly, while qmail-smtpd normally executes qmail-queue, it may invoke any program. This program can then execute qmail-queue as necessary, which might be useful, for example, to filter out email messages that contain viruses. 要注意的是這個體系結構很容易被擴展。tcpserver程序可以執行輪流執行所需的qmail-smtpd的任何程序。這可能很有幫助,例如,決定在qmail-smtpd被運行前是否允許一個連接到達qmail-smtpd或設置或取消一個環境變數。它甚至可以用來對數據在到達qmail-smtpd前進行安全過濾。類似的,當qmail-smtpd正常的運行qmail-queue時,它可以調用任何程序。這個程序可以執行所需的qmail-queue,這可能會有用,來過濾哪些包含病毒的郵件消息。
As another example, the qmail-start program executes several programs: qmail-send, qmail-lspawn, qmail-rspawn, and qmail-clean. Each of these programs has a specific task. qmail-send must monitor the on-disk queue of mail and route mail appropriately by commanding either qmail-lspawn or qmail-rspawn to deliver the message depending on whether the message should be delivered to a local user or a remote user, respectively. Once messages have been delivered, it commands qmail-clean to remove the message from the queue. Both qmail-lspawn and qmail-rspawn receive delivery commands and spawn the necessary number of instances of qmail-local and qmail-remote to do the actual delivery. The qmail-remote program is a simple program that reads an email from standard input, and delivers it to the hosts and recipients specifi ed to it by arguments. It does not have sufficient permissions to read out of the queue itself, and so must be handed the message to deliver. It can even be used alone as follows:
echo message | qmail-remote smtp.example.xcom senderexample.xcom recipient example.xxx 又如另一個例子,qmail-start程序執行一些程序:qmail-send,qmail-lspawn,qmail-rspawn和qmail-clean。以上每個程序都有一個特定的任務。qmail-send必須監控磁碟上的郵件隊列,並且分別根據是要將郵件投遞給本地用戶還是遠程用戶來執行qmail-lspawn或qmail-rspaw來正確的按路由發送。一旦郵件被發送,它就會運行qmail-clean來清除隊列中的消息。qmail-lspawn和qmail-rspawn都會收到發送命令併產生運行qmail-local和qmail-remote的實例所需的數字,這些程序實例會真正開始發送郵件。qmail-remote程序是一個簡單的程序,它從標準輸入讀取郵件,然後將它發送給由它的參數指定的主機和收件人。它沒有足夠的許可權來讀取隊列本身之外的任何東西,因此必須親手發送郵件。它甚至可以像下面這樣單獨使用:
The qmail-local program is also simple; its task is to read an email from standard input and deliver it to the specified local user, using the procedures detailed in that user"s .qmail files. Like qmail-remote, it does not have sufficient permissions to read or modify the on-disk queue. qmail-local程序也很簡單,它的任務是讀取來自標準輸入的郵件並將之發送給指定的本地用戶,依據這個用戶的.qmail文件所描述的具體步驟。和qmail-remote一樣,它也沒有足夠的許可權去讀取或修改
Each of these programs is independent of the others, and relies only on the interface provided to it. By restricting the permissions that each component has, both attacking the system as well as achieving much with a single compromised component is made significantly more difficult. This is the fundamental concept behind the privilege-separation security technique employed by qmail.
這些程序都相互獨立,並且只依賴於提供給它的介面。通過限制每個組件的許可權,使得攻擊系統或通過攻擊一個組件來獲取更多都變得極其困難。這就是被qmail使用的在其基礎概念之後的許可權分離安全技術。

簡單配置


目錄

qmail 安裝部署 1
一、準備工作 1
二、 LAMP殘留(執行即可) 1
三、上傳所需安裝包 2
四、檢查DNS配置 2
五、設置或關閉防火牆 2
六、卸載已有的郵件系統 3
七、解壓縮netqmail-1.05.tar.gz 3
八、安裝daemontools 3
九、安裝ucspi-tcp 3
十、創建所需的用戶 4
十一、準備安裝qmail 4
十二、 qmail編譯安裝 5
十三、設置管理員的郵箱地址 5
十四、開啟SPF設置 5
十五、添加qmail的幫助手冊 5
十六、為qmail服務建立監控目錄和日誌文件 5
十七、檢查服務 6
十八、安裝vpopmail 7
十九、檢查服務 9
二十、用POP3和SMTP測試 10
二十一、安裝qmailadmin 14

過程

過程一:Qmail的安裝。
1. 獲得Qmail程序。
Qmail是自由軟體,在Internet上可以獲得它的源代碼(C源代碼)及基於各種平台和操作系統的二進位文件。二進位文件可以不須編譯直接使用,但要注意選擇與您的平台和操作系統版本一致的文件,否則可能不能使用。源代碼可以在您的任何環境下工作(UNIX)但需要自己進行編譯安裝。這裡我們選擇源代碼。從Internet上下載的源代碼通常是以tar程序打的包然後再用壓縮軟體進行壓縮。如:qmail-1.03.tar.gz 這裡使用的是gzip進行壓縮的(假設你的機器上已安裝了gzip)。使用 gzip -d qmail-1.03.tar.gz 解壓縮成qmail-1.03.tar 然後再用tar -xvf qmail-1.03.tar解包成qmail-1.03目錄。那麼源代碼文件均在此目錄中了。
2. 編譯安裝Qmail。
Qmail源代碼文件中有幾個配置文件可以修改以適合您的環境。
conf-qmail :此文件包含Qmail的安裝目錄,默認值是 /var/qmail/
conf-users:此文件包含Qmail需要使用的用戶,默認用戶是 root,alias,(這兩個用戶在unix下應該已經由系統建立好了,下面的用戶應該自己創)qmails,qmaild,qmaill, qmailr,qmailq,qma-ilp。
conf-groups:此文件包含Qmail 需要使用的組,默認的組為qmail(qmails,qmaild,qmaill,qmailr,qmailq,qmailp要屬於此組)。
conf-cc:此文件包含Qmail使用的編譯器,默認使用cc編譯器,如須使用其它C編譯器,應該將其替換為此編譯器如 gcc.
conf-ld:此文件包含Qmail使用的編譯器,默認使用cc編譯器,如須使用其它C編譯器,應該將其替換為此編譯器如 gcc
在進行安裝前系統應該已經安裝了make命令。
定製好這些文件后,在/var/qmail/下使用命令:make。make命令將編譯源代碼、連接.obj 文件。如果此過程中斷或出錯,應參考上面配置文件正確與否。用戶和組建立的正確與否。如果此過程沒有問題使用命令:make check setup。此命令將安裝所有文件到/var/qmail/(在執行此命令前先用 makedir /var/qmail 創建該目錄)下。
另外需要安裝checkpasswd,它的獲得和安裝和Qmail一樣。此程序用於用戶使用POP3協議收取郵件時對用戶的密碼驗證。
過程二:Qmail的初級配置
Qmail安裝好了以後將在/var/qmail/下生成若干文件和目錄。
1.用vi編輯器打開文件 /etc/inetd.conf,並在文件尾添加如下行:
smtp stream tcp nowait qmaild /var/qmail/bin/tcp-env
tcp-env /var/qmail/bin/qmail-smtpd (和上面一行同在一行)
pop3 stream tcp nowait root /var/qmail/bin/qmail-popup
qmail-popup yourname /bin/checkpassword
/var/qmail/bin/qmail-pop3d Maildir(和上面兩行同在一行)
其中yourname是您的完整的Internet主機名,Maildir 是採用的郵箱格式(這裡我們使用較流行的Maildir格式)
2.檢查/etc/services文件中是否有如下兩行,如沒有則添加進去:
smtp 25/tcp mail
pop3 110/tcp # Post Office
3. DNS中有關Qmail的設置.
如果Qmail的郵件是與Internet上的其它郵件伺服器交互的話(否則只能此伺服器的郵件用戶相互收發郵件了),還需要在DNS伺服器中設置有關 Qmail的條目(如果使用別人的DNS伺服器,應向DNS管理員申請添加條目)即添加一條關於郵件交換的條目(具體的設置請向DNS管理員諮詢)
4.控制文件的創建
Qmail的控制文件放在/var/qmail/control/下,如果不與Internet上的郵件伺服器互傳郵件的話,需要配置很多的文件。否則最簡單的只需配置一個文件:me
它的內容是此郵件伺服器的完整Internet主機名即:yourname
過程三:郵件用戶的創建
郵件用戶就是系統用戶,所以您應該向系統添加用戶,為了安全和管理的需要,最好創建一個E-mail用戶組,將E-mail用戶歸屬於此組,創建用戶目錄時最好在同一個文件系統下創建在同一個目錄下(當然此文件系統不夠大時可以創建在其它文件系統的某個目錄下)
然後,在每個用戶的初始目錄下用命令:/var/qmail/bin/maildirmake創建郵箱目錄並賦予適當的許可權,您可以使用Shell腳本來完成每個用戶郵箱的創建,下面是此腳本的一個簡單的例子:
if test $1
then
echo "Creating $1's directory and file..."
useradd -d /usr/email-users/$1 -g emusers -s /bin/passwd $1
cd /usr/email-users/
mkdir $1
chown $1 $1
cd $1
/var/qmail/bin/maildirmake Maildir
echo ./Maildir/ > .qmail
chown $1 Maildir
chown $1 Maildir/*
chown $1 .qmail
echo "Please input $1's email password"
passwd $1
echo "$1's account has been created!!!"
else
echo "Please input the user'name!"
fi
系統管理員可以使用emuadd email_user_name (此腳本的文件名,並將此文件存放在/bin下)來傳建email_user_name的郵箱
過程四:Qmail系統的使用
當上述過程結束后重新啟動計算機。
在郵件客戶端程序中設置如下:(假如E-mail伺服器的主機名為your,name,DNS中設置的郵件交換管理的域為mail.domain,注意:通常mail.domain與.name相同,以E-mail用戶user為例)
電子郵件地址:[email protected]
SMTP伺服器地址:yourname
POP3伺服器地址:yourname
POP3賬號:user
POP3賬號密碼:(由管理員給你,可以自己修改)

啟動設置


Qmail 運行有兩種方式。tcpserver,xinet。當域名解析有問題的時候,tcpserver運行會有問題。
qmail1.0.8,ucspi-tcp-0.88
(1) tcpserver方式
# pop3 設置
/usr/local/bin/tcpserver -P -H -R 0 pop-3 /var/qmail/bin/qmail-popup /home/vpopmail/bin/vchkpw /var/qmail/bin/qmail-pop3d Maildir 2>&1 | /var/qmail/bin/splogger &
# smtpd 設置
/usr/local/bin/tcpserver -H -R -t 1 -v -P -x/etc/qmail/tcp.smtp.cdb -u 511 -g 506 smtp /var/qmail/bin/qmail-smtpd /home/vpopmail/bin/vchkpw /bin/true | /var/qmail/bin/splogger &
(2) xinetd方式
/etc/xinetd.d/pop3-3
service pop-3
{
disable = no
socket_type = stream
wait = no
user = root
server = /var/qmail/bin/qmail-popup
nice = 10
server_args = home/vpopmail/bin/vchkpw /var/qmail/bin/qmail-pop3d Maildir &
}
/etc/xinetd.d/smtp
service smtp
{
disable = no
socket_type = stream
wait = no
user = vpopmail
server = /var/qmail/bin/qmail-smtpd
nice = 10
server_args = /home/vpopmail/bin/vchkpw /bin/true
}

運行程序


qmail是一個模塊化設計的郵件系統,每一個子功能都是由一個運行程序來實現的,而每個程序的屬性以及運行方式由一個或多個配置文件和環境變數來控制的。在qmail安裝成功和啟動以後,qmail的相關進程一直在內存中駐留,qmail會不斷掃描郵件隊列,並且把郵件投遞到正確的目的地址。
運行ps命令可以查看到qmail的相關進程:
#ps –ax | grep qmail
0:00.00 grep qmail
23282 con- I 0:00.77 qmail-send
23289 con- I 0:00.21 splogger qmail
23290 con- I 0:00.13 qmail-lspawn ./Mialdir/
23291 con- I 0:00.03 qmail-rspawn
23292 con- I 0:00.05 qmail-clean
qmail所有的運行程序都安裝在/var/qmail/bin目錄下。比較重要的運行程序如下:
1.qmail-smtpd
它的作用是接收遠端主機投遞的郵件,然後將郵件傳遞給qmail-queue進行處理。qmail-smtpd是通過SMTP協議和遠端主機驚醒通訊的。qmail-smtpd並不是常駐內存的,他需要一個外部程序來激活,本文所做的系統是使用tcpserver來激活的。Tcpserver監視著系統的IP連接請求,如果檢測到有SMTP的連接請求,tcpserver就會自動的激活qmail-smtpd,然後將IP連接的控制權交給qmail-smtpd,一旦qmail-smtpd和遠端主機建立起SMTP連接后,遠端主機就可以將郵件投遞到本地的郵件伺服器了。
2.qmail-inject
它的作用是接收本地生成並投遞的郵件,並把郵件傳遞給qmail-queue來處理。在郵件傳遞給qmail-queue之前,qmail-inject先掃面郵件的郵件頭,來查看郵件頭是否符合RFC822標準,如果不符合它將會自動的更改和修正這個郵件的郵件頭。
3.qmail-send
當一個郵件被放入郵件隊列之後,qmail-send就開始對該郵件進行處理,。它會檢查郵件隊列中的每一個郵件的狀態,對於沒有投遞過的和投遞暫時失敗的郵件,對於沒有投遞過和投遞暫時失敗的郵件,qmail-send會將目標地址是本地主機的傳遞給qmail-lspawn,目標地址是遠端主機的傳遞給qmail-rspawn,對於投遞永久失敗的郵件,qmail-send將會把該郵件傳遞給qmail-clear,讓這個程序永久刪除這個郵件。qmail-send是一個常駐內存進程程序,如果qmail-send中止,qmail的其他進程將會自動中止。
4.qmail-clean
它的作用是從郵件隊列中刪除投遞永久失敗的郵件。qmail使用多種狀態標示來標記郵件,每個郵件在每一次被處理后它的狀態表示都會被改變。如果系統當機,系統重新啟動以後,qmail-send仍然可以找到郵件隊列中上次最後一次成功處理過的郵件的位置,並且從這裡重新開始處理郵件隊列。如果由於其他原因造成qmail-send不能處理的郵件隊列,qmail-send會調用qmail-clean從郵件隊列中刪除郵件。qmail-clean也是常駐內存的進程。
5.qmail-rspawn
當qmail-send判明郵件目標地址是遠端郵件伺服器時,qmail-send就會將郵件交給qmail-rspawn,qmail-rspawn的作用是調度郵件的投遞時間和順序,然後激活qmail-remote來進行投遞。qmail-rspawn還有一個作用是決定每一個郵件的目標郵件伺服器,每次和遠端郵件伺服器的連接都會調用qmail-remote一次。qmail-rspawn也是常駐內存的進程。
6.qmail-lspawn
功能和qmail-rspawn類似,qmail-lspawn也是被qmail-send調度來投遞郵件的,不過qmail-lspawn是負責目標地址是為本地郵件伺服器的郵件。
7.qmail-remote
它的作用是通過SMTP協議將郵件投遞到遠端的用戶。郵件是通過qmail-rspawn傳遞過來的,qmail-remote每次只可以同一個遠端主機連接,不過在連接時qmail-remote可以投遞這個遠端主機上的多個接收者的郵件。投遞當中的調度是由qmail-rspamwn來負責的。
8.qmail-local
它的作用是投遞本地郵件伺服器的郵件。這個程序通常是用來檢測因為轉發命令使用不當造成的郵件循環故障。
9.qmail-queue
他處理從qmail-inject和qmail-smtpd傳遞過來的郵件,並把這些郵件傳遞到郵件隊列中,它會掃描每個郵件的發送者和接收者的地址,一般傳遞給qmail-queue的郵件的標示都是為0,如果為1時,它會認為這個郵件的發送者和接收者的地址要經過特殊格式的處理。