Gentoo Logo
Gentoo Logo Side

使用 Postfix 架設虛擬郵件主機系統指引

Contents:

1. 介紹

對大多數 gentoo 使用者來說,一個簡單的郵件客戶端程式加上 fetchmail 就能滿足需求了,但是如果您的系統需要管理一個網域,您就會需要一套功能完整的 MTA(郵件傳輸代理人 Mail Transfer Agent),如果您管理多個網域,那麼您絕對會需要更為穩健的工具來處理所有使用者的郵件。這個系統的設計將為這個問題提供一個典雅的解決方案。

虛擬郵件系統要能夠處理眾多網域裡面,不同使用者透過各式各樣的介面所傳送接收的郵件。要達到此目標,我們需要處理一些議題,舉例來說,您要怎麼處理分處不同網域的兩位使用者希望使用同一用戶名稱的情況?如果您要提供 imap 存取和 smtp-auth,您要怎樣整合不同的認證程序成為一個系統?您該如何為系統中這麼多原複雜的元件提供安全機制?您要如何管理整個系統?

這份文件將會告訴您如何建立一個能支援任意多個網域(只要您的硬體能處理)中郵件的郵件系統,支援不需要 shell 帳號的虛擬郵件使用者,擁有特定網域使用者名稱,可以用單一資料庫認證 web、imap、smtp 和 pop3 用戶,運用 ssl 做到傳輸層安全,具有 web 介面,可以在機器上處理任何網域的 mailing lists,並且可以用一個簡單易用的中心 mysql 資料庫作控制。

要設定一個虛擬郵件主機系統有很多不同的方法,在這麼多選擇中,也許另一種方法才最能符合您特定的需求,請考慮閱讀 http://www.qmail.org/http://www.exim.org/ 來挖掘您所擁有的選項。

下列套件會在本文件所述的設定過程中使用到:apache, courier-imap, pam_mysql, postfix, mod_php, phpmyadmin, squirrelmail, cyrus-sasl, mysql php, 和 mailman。

在編譯這些套件之前,請確認下列的 USE 變數在 /etc/make.conf 中有開啟:USE="mysql pam-mysql imap libwww maildir sasl ssl",否則您很可能需要重編譯這些程式來取得所有協定的支援。更進一步,關閉其他郵件和網路相關變數如 ipv6,是比較好的作法。

Important: 這份文件是針對 postfix-2.0.x 而寫,如果您使用的是 postfix < 2,這份文件中的提到的一些變數會有不同的名稱,因此我們建議您升級到新版本。其他在這份文件中提到的套件,有些也有版本間差異的問題,建議您如果遇到這類問題時,請閱讀套件的說明文件。

Important: 這份文件使用 apache-1.3.x,雖然 Apache-2 已經被標誌為 portage 中的穩定支系,還是有些與 php 整合上的問題存在,在 apache-2.0.x 對 php 的支援被標誌為穩定之前,這份指引仍將繼續使用 1.3.x 版本。

Important: 您需要有網域名稱才能執行一個公開的郵件伺服器,或者最起碼要有個網域的 MX 記錄。最理想的狀況是您擁有兩個以上的網域控制權,這樣才能真正發揮新架設的虛擬網域的功能。

Important: 請確認 /etc/hostname 有您郵件伺服器正確的主機名稱。確定您的主機名稱用 hostname 設定正確。另外也請檢查在 /etc/hosts 中沒有彼此衝除的條目。

Note: 建議您先閱讀完原整份文件並且熟悉所有的步驟,再嘗試安裝架設。如果您在任何步驟遇到問題,請參考這份指引後段的問題排除章節。另外,並非所有參考到的套件都是必要的,這個架設流程有很大的彈性,舉例來說,如果您不想要網頁介面,您可以略過 squirrelmail 一節。

2. Postfix 基礎

Code listing 2.1: 安裝 postfix

# emerge postfix

Warning: 請檢查您沒有安裝其他的 MTA 如 ssmtp, exim, 或是 qmail,否則您一定會遇到大問題。

postfix 安裝完後,就是要作設定的時候了。將 /etc/postfix/main.cf 中的下列選項作合適的更動:

Code listing 2.2: /etc/postfix/main.cf

myhostname = $host.domain.name
mydomain = $domain.name
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain $mydomain
mynetworks = my.ip.net.work/24, 127.0.0.0/8
home_mailbox = .maildir/
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10 

接下來將 /etc/postfix/master.cf 坐下述改變,這會開啟 debug 的 verbose output 功能:

Code listing 2.3: /etc/postfix/master.cf

# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (50)
#
==========================================================================
smtp      inet  n       -       n       -       -       smtpd -v

// 只要在上面 smtpd 那一行後面加 "-v"

接下來,編輯 /etc/mail/aliases,加入您本端的別名,最起碼要有一個 root 的別名像是 root: your@email.address

Code listing 2.4: 首次啟動 postfix

# /usr/bin/newaliases
// 這會安裝新的別名(aliases),您只需要
// 在升級或安裝別名時這麼作。
		
# /etc/init.d/postfix start

現在 postfix 已經在執行了,開啟您最喜愛的郵件客戶端主控台並寄封電子郵件給您自己。我使用 mutt 來處理我所有的主控台信件。確認 postfix 有將信件傳送給本端使用者,這個動作完成之後,我們就可以進行下一步。

Note: 我強烈建議您先確認這個基本的 postfix 設定正常運作,再繼續這份文件的下一個步驟。

3. Courier-imap

Code listing 3.1: 安裝 courier-imap

# emerge courier-imap

Code listing 3.2: Courier-imap 設定

# cd /etc/courier-imap
// 如果您想要使用 courier-imap 或 pop3 的 ssl 功能,
// 您會需要為此建立認證。
// 建議您執行這個步驟,如果您不想要使用 ssl,請跳過此步。

# nano -w pop3d.cnf
# nano -w imapd.cnf
// 改變 C, ST, L, CN, 和電子郵件參數來配合您的伺服器。

# mkpop3dcert
# mkimapdcert

Code listing 3.3: 啟動您需要的 courier 服務

# /etc/init.d/courier-imapd start
# /etc/init.d/courier-imapd-ssl start
# /etc/init.d/courier-pop3d start
# /etc/init.d/courier-pop3d-ssl start

開啟您喜愛的郵件客戶端程式,確認所有的連線都可以接收和傳送信件。現在基礎已經設好,我們將要進行一堆工作來讓系統其他部份跑起來。

4. Cyrus-sasl

接下來我們要安裝 cyrus-sasl。Sasl 將會扮演實際傳遞 auth 變數給 pam的角色,pam 會繼而將資訊傳給 mysql 執行 smtp 使用者認證。在這份說明中,我們將不會在 mysql 設定好並且有個測試使用者之前檢驗 sasl 是否正常運作,這不會造成問題,因為我們將在最後利用 mysql 進行認證。

Note: 由於某種理由,現在 sasl 將不會與 pam 好好合作處理影子檔(shadow file),我絞盡腦汁想了很長一段時間,如果有人知道目前 gentoo 實作中 sasl 無法使用影子檔的原因,請 email 給我,我很希望知道這個問題的解決方法。

Code listing 4.1: 設定並安裝 cyrus-sasl ebuild

(我們沒有安裝 ldap,而且我們要使用 sasl 的 mysql 功能,所以
  我們需要設定合適的 USE 旗標,但是這只有當您的 USE 旗標沒有包含 mysql USE 
  旗標時,而且不要加入 ldap)
# mkdir /etc/portage
# echo "dev-libs/cyrus-sasl -ldap mysql" >> /etc/portage/package.use
# emerge cyrus-sasl

接下來,編輯 /etc/sasl2/smtpd.conf

Code listing 4.2: 啟動 sasl

# nano -w /etc/sasl2/smtpd.conf
pwcheck_method: auxprop
auxprop_plugin: sql
sql_engine: mysql
sql_hostnames: localhost
sql_user: mailsql
sql_passwd: <password>
sql_database: mailsql
sql_select: select clear from users where email = '%u@%r'
mech_list: plain login
pwcheck_method: saslauthd
mech_list: LOGIN PLAIN
// 關掉我們沒有使用的認證方法是很重要的。
// 它們會為某些郵件客戶端造成問題。
# /etc/init.d/saslauthd start

5. Postfix 和 Apache 的 SSL Certs

接著我們將為 postfix 和 apache 建立 ssl 憑證。

Code listing 5.1

# cd /etc/ssl/
# nano -w openssl.cnf

// 針對您的網域變更下列的預設值:
countryName_default
stateOrProvinceName_default
localityName_default
0.organizationName_default
commonName_default
emailAddress_default.

// 如果變數不存在,就將它們加到合適的位置。


# cd misc
# nano -w CA.pl
// 我們需要將 -nodes 加到 # 建立憑證 和 # 建立憑證請求 指令,
// 讓我們新的 ssl certs 不需要密碼就可以載入,否則當您重新
// 開機時您的 ssl certs 將沒有辦法使用。

# 建立憑證
system ("$REQ -new -nodes -x509 -keyout newreq.pem -out newreq.pem $DAYS");

# 建立憑證請求
system ("$REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS");
		
# ./CA.pl -newca
# ./CA.pl -newreq
# ./CA.pl -sign
# cp newcert.pem /etc/postfix
# cp newreq.pem /etc/postfix
# cp demoCA/cacert.pem /etc/postfix
// 現在我們對 apache 做同樣的動作

# openssl req -new > new.cert.csr
# openssl rsa -in privkey.pem -out new.cert.key
# openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 365
// 暫時把產生的憑證留在這裡。
// 我們會在 Apache 安裝之後將它們裝起來。

6. 增加 Postfix 的 SSL 和 SASL 支援

現在編輯 postfix 的設定檔,讓它知曉您新的 sasl 和 ssl 功能。將下列參數加到檔案的尾端,這樣可以輕易地找到。

Code listing 6.1: /etc/postfix/main.cf

# nano -w /etc/postfix/main.cf

smtpd_sasl_auth_enable = yes
smtpd_sasl2_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_local_domain =

// broken_sasl_auth_clients 選項和登入認證方式只有 outlook 和 
// outlook express 會用到,而且沒有文件說明。要為了又笨又破碎的 
// M$ BS 解構軟體是不是很棒呢?smtpd_sasl_local_domain 會在使用 
// smtp-auth 的客戶末端加上一個網域名稱。請確認他是空白的,否則
// 您的使用者會被 postfix 攪亂而無法認證。
// (譯注:不知道 BS 是什麼就算了,這是為你好 :P)

smtpd_recipient_restrictions =
	permit_sasl_authenticated,
	permit_mynetworks,
	reject_unauth_destination
	

smtpd_use_tls = yes
#smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/newreq.pem
smtpd_tls_cert_file = /etc/postfix/newcert.pem
smtpd_tls_CAfile = /etc/postfix/cacert.pem
smtpd_tls_loglevel = 3
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

// smtpd_tls_auth_only 被註解起來是為了系統測試的方便。如果您想要,
// 可以在稍後將它開啟。

# postfix reload

現在我們要確認 postfix 有讀到新增的設定檔。

Code listing 6.2: 確認 sasl 和 tls 支援

# telnet localhost 25

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.domain.com ESMTP Postfix
EHLO domain.com
250-mail.domain.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-XVERP
250 8BITMIME
^]
telnet> quit

確認上列的 AUTH 和 STARTTLS 行文字現在出現在您的 postfix 安裝中。就如同我前面所說,現在的 AUTH 行不通,這是因為由於某種不明原因,sasl 會嘗試用自己的 sasldb 進行認證工作,而不是使用影子檔(我們還沒設定好)。所以我們現在要想辦法設定 mysql,讓它儲存我們所有的認證和虛擬網域資訊。

7. MySQL

接著我們要安裝並設定 mysql。您需要 genericmailsql.sql 這個傾倒檔來進行此步設定。

Code listing 7.1: 安裝並設定 MySQL

# emerge mysql

# /usr/bin/mysql_install_db
// 在這個指令執行之後,遵照螢幕上的指示用 mysql 指令,不要用 
// mysqladmin,加入 root 密碼,否則您的資料庫會門戶大開。

# /etc/init.d/mysql start
# mysqladmin -u root -p create mailsql
# mysql -u root -p mailsql < genericmailsql.sql

# mysql -u root -p mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE
	->     ON mailsql.*
	->     TO mailsql@localhost
	->     IDENTIFIED BY '$password';

	->     quit
// 確認新的 mailsql 使用者可以連線到 mysql 伺服器。

# mysql -u mailsql -p mailsql

您的新資料庫有為兩個網域設定好預設值和表格,它會包含有下列表格:

  • alias - 本端電子郵件別名和 mailman 別名資訊
  • relocated - 重置使用者電子郵件位址對照表
  • transport - 您管理的所有網域的預設郵件傳輸資訊
  • users - 所有使用者帳號資訊
  • virtual - 虛擬網域電子郵件別名對照表

Code listing 7.2: alias table 範例

id   alias    destination
1    root     foo@bar.com
2  postmaster foo@bar.com

Code listing 7.3: user table 範例

// 自動折行是為了清晰起見
id email            clear     name     uid     gid     homedir     \
	maildir                                quota  postfix
10 foo@virt-bar.org $password realname virtid  virtid  /home/vmail \
	/home/vmail/virt-bar.org/foo/.maildir/        y
13 foo@bar.com      $password realname localid localid /home/foo   \
	/home/foo/.maildir/                           y

Code listing 7.4: transport table 範例

id   domain       destination
1    bar.com      local:
2    virt-bar.org virtual:

Code listing 7.5: virtual table 範例

id   email            destination
3   root@virt-bar.org other@email.address

8. Apache 和 phpMyAdmin

下一步是設定 apache 並新增一個方便與資料庫互動的介面。

Code listing 8.1: 設定 apache 和 phpmyadmin

# emerge apache mod_php phpmyadmin

說明如何設定 apache 與 php 的文件資源已經非常豐富,例如這份:http://www.linuxguruz.org/z.php?id=32,在 http://forums.gentoo.org 中也有為數眾多的討論帖詳細說明如何解決安裝上的問題(搜尋 'apache php'),所以我將不會在此講述這個主題。請把 apache 和 php 安裝並設定完成,然後繼續這份文件。現在,給句智者的建言:將您放置 phpmyadmin 的目錄用 .htaccess 作存取控管,如果您不這樣做,搜尋引擎的蜘蛛(search engine spiders)就會跑來把這個頁面索引起來,這樣一來就表示任何人都可以透過 google 找到您的 phpmyadmin 頁面,所以就能夠進來隨心所欲地更動您的資料庫,這是 很糟糕的!有許多指引文件解說這個議題,包括:http://www.csoft.net/docs/micro/htaccess.html.en

現在我們將要安裝前面步驟做好的 Apache 憑證,您要使用這些憑證會用到的 Apache-SSL 指令有:

  • SSLCertificateFile /path/to/certs/new.cert.cert
  • SSLCertificateKeyFile /path/to/certs/new.cert.key

Code listing 8.2: 安裝 Apache SSL 憑證

# cp /etc/ssl/misc/new.cert.cert /etc/apache/conf/ssl/
# cp /etc/ssl/misc/new.cert.key /etc/apache/conf/ssl/
# nano -w /etc/apache/conf/vhosts/ssl.default-vhost.conf
// 改變下列參數

ServerName host.domain.name
ServerAdmin your@email.address
SSLCertificateFile /etc/apache/conf/ssl/new.cert.cert
SSLCertificateKeyFile /etc/apache/conf/ssl/new.cert.key

# /etc/init.d/apache restart

Note: 如果您已經有安裝好了的 apache,要安裝新的憑證,您可能需要執行一次完整的伺服器重開機。檢查您的記錄檔來確認 apache 成功的重新啟動。

下一步,設定 phpMyAdmin。

Code listing 8.3: 設定 phpMyAdmin

# nano -w /var/www/localhost/htdocs/phpmyadmin/config.inc.php
// 改變下列參數

$cfg['Servers'][$i]['host'] = 'localhost';          // MySQL 主機名稱
$cfg['Servers'][$i]['controluser'] = 'mailsql';     // MySQL control user 設定
                                                    // (這個使用者存取 "mysql/usr" 和 
$cfg['Servers'][$i]['controlpass'] = '$password';   // "mysql/db" 表格的權限一定要是
                                                    // 只能讀取 read-only)
$cfg['Servers'][$i]['user'] = 'mailsql';            // MySQL 使用者
$cfg['Servers'][$i]['password'] = '$password';      // MySQL 密碼

現在進入 phpmyadmin 頁面來瀏覽這些表格。您會想要加入您的本端別名,編輯您的使用者表格,加入一個測試使用者,並且在您的傳輸表格(transport table)中加入有關您網域的資訊,在傾倒檔中提供的預設值應該足夠指引您有哪些資訊需要輸入。請確定您放入資料庫的任何資訊都是正確的,舉例來說,請確認本端使用者的家目錄存在,而且有正確的 uid/gid。郵件目錄(maildirs)應該會在使用者收到他們的第一封電子信件時,由 postfix 自動產生,所以,通常來說,在您建立他們的帳號之後,寄送一封 "歡迎" 信件來確保 .maildir 目錄的建立是個好主意。

9. vmail 使用者

在這個時候,您也許會想知道虛擬郵件使用者要用哪個使用者名稱和目錄,這很正確,就讓我們把這設定起來。

Code listing 9.1: 新增 vmail 使用者

# adduser -d /home/vmail -s /bin/false vmail
# uid=`cat /etc/passwd | grep vmail | cut -f 3 -d :`
# groupadd -g $uid vmail
# mkdir /home/vmail
# chown vmail: /home/vmail

所以現在當您在設定 vmail 帳號時,使用 vmail 的 uid, gid, 和家目錄,當您要建立本端帳號時,就用該使用者的 uid, gid, 和家目錄。我們在整個過程中一直想要建立一個 php admin 頁面來做這個設定的工作,但還沒有進到這一步,因為 phpmyadmin 通常就很夠用了。

10. 設定 MySQL 的認證和 vhosts

接下來我們要重新設定讓我們的認證使用 courier-imap 和 postfix 的 mailsql 資料庫。在下面所有的範例中,用您設定的 mailsql mysql 使用者密碼代換 $password

Code listing 10.1

# emerge pam_mysql
# nano -w /etc/pam.d/imap
// 註解掉既有的 auth 行文字,加入下面所列文字。

#auth       required     pam_nologin.so
#auth       required     pam_stack.so service=system-auth
#account    required     pam_stack.so service=system-auth
#session    required     pam_stack.so service=system-auth

auth     optional       pam_mysql.so host=localhost db=mailsql user=mailsql \
  passwd=$password table=users usercolumn=email passwdcolumn=clear crypt=0
account  required       pam_mysql.so host=localhost db=mailsql user=mailsql \
  passwd=$password table=users usercolumn=email passwdcolumn=clear crypt=0

# nano -w /etc/pam.d/pop3
# nano -w /etc/pam.d/smtp
// 對 pop3 和 smtp 檔案作同樣的改變。

下一步,我們需要編輯 courier 的認證設定檔。

Code listing 10.2

# nano -w /etc/courier-imap/authdaemonrc
authmodulelist="authmysql authpam"

# nano -w /etc/courier-imap/authdaemond.conf
AUTHDAEMOND="authdaemond.mysql"

# nano -w /etc/courier-imap/authmysqlrc
MYSQL_SERVER            localhost
MYSQL_USERNAME       mailsql
MYSQL_PASSWORD      $password
MYSQL_DATABASE          mailsql
MYSQL_USER_TABLE        users
#MYSQL_CRYPT_PWFIELD    crypt (make sure this is commented out since we're storing plaintext)
MYSQL_CLEAR_PWFIELD     clear
MYSQL_UID_FIELD         uid
MYSQL_GID_FIELD         gid
MYSQL_LOGIN_FIELD       email
MYSQL_HOME_FIELD        homedir
MYSQL_NAME_FIELD        name
MYSQL_MAILDIR_FIELD     maildir

# /etc/init.d/authdaemond restart
# /etc/init.d/saslauthd restart

我們快完成了,我保證!接著,把 postfix 與資料庫互動所需的其他設定檔設定好,滿足其他所有傳輸需求。

Code listing 10.3: /etc/postfix/mysql-aliases.cf

# nano -w /etc/postfix/mysql-aliases.cf
# mysql-aliases.cf

user         	= mailsql
password     	= $password
dbname       	= mailsql
table        	= alias
select_field 	= destination
where_field  	= alias
hosts        	= unix:/var/run/mysqld/mysqld.sock

Code listing 10.4: /etc/postfix/mysql-relocated.cf

# nano -w /etc/postfix/mysql-relocated.cf
# mysql-relocated.cf

user         	= mailsql
password     	= $password
dbname       	= mailsql
table        	= relocated
select_field 	= destination
where_field  	= email
hosts        	= unix:/var/run/mysqld/mysqld.sock

Code listing 10.5: /etc/postfix/mysql-transport.cf(選擇性)

# nano -w /etc/postfix/mysql-transport.cf		
# mysql-transport.cf

user         	= mailsql
password     	= $password
dbname       	= mailsql
table        	= transport
select_field 	= destination
where_field  	= domain
hosts        	= unix:/var/run/mysqld/mysqld.sock

Code listing 10.6: /etc/postfix/mysql-virtual-gid.cf(選擇性)

# nano -w /etc/postfix/mysql-virtual-gid.cf
#myql-virtual-gid.cf

user          	= mailsql
password        = $password
dbname        	= mailsql
table           = users
select_field    = gid
where_field     = email
additional_conditions = and postfix = 'y'
hosts         	= unix:/var/run/mysqld/mysqld.sock

Code listing 10.7: /etc/postfix/mysql-virtual-maps.cf

# nano -w /etc/postfix/mysql-virtual-maps.cf
#myql-virtual-maps.cf

user        	= mailsql
password        = $password
dbname          = mailsql
table           = users
select_field    = maildir
where_field   	= email
additional_conditions = and postfix = 'y'
hosts           = unix:/var/run/mysqld/mysqld.sock

Code listing 10.8: /etc/postfix/mysql-virtual-uid.cf(選擇性)

# nano -w /etc/postfix/mysql-virtual-uid.cf
# mysql-virtual-uid.cf

user            = mailsql
password        = $password
dbname          = mailsql
table           = users
select_field    = uid
where_field    	= email
additional_conditions = and postfix = 'y'
hosts           = unix:/var/run/mysqld/mysqld.sock

Code listing 10.9: /etc/postfix/mysql-virtual.cf

# nano -w /etc/postfix/mysql-virtual.cf
# mysql-virtual.cf

user         	= mailsql
password     	= $password
dbname       	= mailsql
table        	= virtual
select_field 	= destination
where_field  	= email
hosts        	= unix:/var/run/mysqld/mysqld.sock

最後,再一次編輯 /etc/postfix/main.cf

Code listing 10.10: /etc/postfix/main.cf

# nano -w /etc/postfix/main.cf
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
relocated_maps = mysql:/etc/postfix/mysql-relocated.cf

local_transport = local
local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname

virtual_transport = virtual
virtual_mailbox_domains =
	virt-bar.com,
	$other-virtual-domain.com

virtual_minimum_uid = 1000
virtual_gid_maps = static:$vmail-gid
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual.cf
virtual_uid_maps = static:$vmail-uid
virtual_mailbox_base = /
#virtual_mailbox_limit =

基於安全上的理由,您需要變更許多 /etc/mail/mysql-*.cf 的存取權限:

Code listing 10.11: 更改檔案權限

# chmod 640 /etc/postfix/mysql-*.cf
# chgrp postfix /etc/postfix/mysql-*.cf

對於 Postfix 2.0.x,有許多重大的改變與 1.1.x 版本不同,值得注意的有不再需要 transport, virtual-gid, 和 virtual-uid 表格,這些表格還是有包裹在內如果您想要用的話。

Note: 建議您閱讀包含在 postfix 文件中的 VIRTUAL_README 來取得進一步的資訊。

Code listing 10.12

# postfix reload

現在,如果一切進行順利,您就應該會擁有一個運作正常的郵件主機,使用者應該可以使用完整的電子郵件位址,透過 sql 資料庫,進行 pop3, imap, 還有 smtp 的認證。我非常建議您要確定所有事情在這個時候都已經正常運作,如果您遇到問題(進行了這麼多設定動作,這是很可能的),請查閱這份文件的問題排除章節。

11. Squirrelmail

Code listing 11.1

# emerge squirrelmail
// 我喜歡在 htdocs 中加入一個 url 短一點的連結

# ln -s /var/www/localhost/htdocs/squirrelmail/ /var/www/localhost/htdocs/mail
# cd /var/www/localhost/htdocs/mail/config
# perl ./conf.pl
// 更改 squirrelmail 中的組織名稱、伺服器和目錄設定。現在您應該可以登入到 squirrelmail,
// 同樣是用您完整的電子郵件位址,並使用新的 webmail 設定。

12. Mailman

最後一個步驟: mailman。新版本的 mailman 有非常好的虛擬網域支援,這也就是我選擇它的原因,更不用說它原本就已經是個很棒的套件。要安裝這個套件並讓它正確運作虛擬網域需要一些破解處理(hacking),我非常建議您閱讀所有 mailman 的文件,包括 README.POSTFIX.gz,以真正了解接下來執行的動作是在做什麼。

一個小備忘錄:目前的 mailman 版本會安裝到 /usr/local/mailman,如果您像我一樣希望變更預設安裝位置,可以改變 ebuild 檔內的 INSTALLDIR 變數。

Code listing 12.1: /usr/portage/net-mail/mailman/mailman-$ver.ebuild

# nano -w /usr/portage/net-mail/mailman/mailman-$ver.ebuild
MAILGID="280"
// 將 mailman 的群組設為 MAILGID 而不是 nobody
// 這是為了 postfix 整合需要

Code listing 12.2

# emerge mailman
// 這個套件目前同樣被封鎖,所以您需要將之解封鎖,或是用 ebuild 路徑進行 emerge。
// 一旦安裝完成,遵照 README.gentoo.gz 中的指示,但是不要在 /etc/mail/aliases 中
// 加入您使用的別名,我們將會把整個別名資料庫連結到 postfix。

# zless /usr/share/doc/mailman-$ver/README.gentoo.gz

Code listing 12.3: 設定預設值:Mailman/Defaults.py

#  nano -w /var/mailman/Mailman/Defaults.py
// 依據您主網域變更下列數值,下一步會設定虛擬網域。
DEFAULT_EMAIL_HOST = 'domain.com'
DEFAULT_URL_HOST = 'www.domain.com'

Code listing 12.4: mailman 設定:mm_cfg.py

# nano -w /var/mailman/Mailman/mm_cfg.py
MTA = "Postfix"
POSTFIX_STYLE_VIRTUAL_DOMAINS = ['virt-domain.com', 'virt.domain2.com']	
add_virtualhost('www.virt.domain.com', 'virt.domain.com')
add_virtualhost('www.virt.domain2.com', 'virt.domain2.com')
// 要 mailman 能在您的虛擬網域上運作,這步是必須的。

Code listing 12.5

// 一旦完成,加入您第一個列表。

# su mailman
# cd ~
# bin/newlist test
Enter the email of the person running the list: your@email.address
Initial test password:
Hit enter to continue with test owner notification...
// 虛擬網域列表可以用 list@domain.com 樣式的列表名稱指定。
# bin/genaliases
// 現在您的別名已經產生好了,確認它們有成功的被加入。

# nano -w data/aliases
# STANZA START: test
# CREATED:
test:             "|/var/mailman/mail/mailman post test"
test-admin:       "|/var/mailman/mail/mailman admin test"
test-bounces:     "|/var/mailman/mail/mailman bounces test"
test-confirm:     "|/var/mailman/mail/mailman confirm test"
test-join:        "|/var/mailman/mail/mailman join test"
test-leave:       "|/var/mailman/mail/mailman leave test"
test-owner:       "|/var/mailman/mail/mailman owner test"
test-request:     "|/var/mailman/mail/mailman request test"
test-subscribe:   "|/var/mailman/mail/mailman subscribe test"
test-unsubscribe: "|/var/mailman/mail/mailman unsubscribe test"
# STANZA END: test

# /etc/init.d/mailman start
# rc-update add mailman default
// 讓 mailman 在每次開機時會自行啟動

Code listing 12.6: 為 postfix 加入 mailman alias 支援

# nano -w /etc/postfix/main.cf
owner_request_special = no
recipient_delimiter = +
// 閱讀 README.POSTFIX.gz 關於此設定的細節

alias_maps     =
	hash:/var/mailman/data/aliases,
	mysql:/etc/postfix/mysql-aliases.cf

virtual_alias_maps =
	hash:/var/mailman/data/virtual-mailman,
	mysql:/etc/postfix/mysql-virtual.cf
// 這為 postfix 加入 mailman 別名檔案支援,您當然可以使用 mysql 表格
// 達到同樣的目的,但是我討厭要手動這樣做。另外,如果您沒有使用虛擬
// 網域,加入虛擬別名對照表到 postfix 可能會造成問題,請您要注意這個
// 警告。

您現在應該能夠為機器上的任何網域設定郵件列表。最後提醒一點,確定您以 mailman 身份(su mailman)執行過所有 mailman 指令,否則存取權限會有錯誤,您就必須修改它們。請閱讀 mailman 的文件,取得更多設定和管理 mailman 列表的資訊。

13. 內容過濾和防毒

即將加入…本來應該已經完成的,但是我需要一些 perl 上的幫忙,並且還需要作些測試。如果您願意幫忙,請 email 給我。

14. 總結

好了,您已經將一切處理妥當,編輯 /etc/postfix/master.cf,然後關閉 verbose 模式以利正式上線使用。您也許會想要增加服務到起始例行工作(startup routine)中,以確保重新開機的情況下,所有的服務都會如常回到工作崗位。確認您把所有使用到的服務都加進去 - apache, mysql, saslauthd, postfix, courier-imapd, sourier-imapd-ssl, courier-pop3d, 還有 courier-pop3d-ssl 都是您可以選擇提供的服務,通常我會把所有服務都開啟。

Code listing 14.1: 總結

# postfix reload
# rc-update add $service default

祝您玩的愉快!

15. 問題排除

介紹 

問題排除:這是個短短的問題排除指引,針對我們說明的安裝步驟而寫,它並不完全,目的是輔助您釐清問題的所在。對於這麼複雜的設定程序,將發生問題的地方縮小到特定組成組件是絕對必要的。通常我會進行下列步驟,從系統的基礎開始,一步步往上找,排除掉運作正常的組件,直到您發現出問題的組件。

步驟 1:檢查設定檔 

打錯字是頭號殺手,尤其在處理認證系統的時候。掃描您的設定檔和 mailsql 資料庫,檢查有沒有錯字,您想要怎樣除錯都可以,但是如果您沒有傳遞正確的資訊給您的郵件系統,並取得正確的回傳訊息,系統就無法正確運作。如果您有改變某個服務的任何設定檔,請確認您重新啟動該服務,讓設定檔中的改變生效。

Code listing 15.1

# /etc/init.d/service restart

步驟 2:是否所有必要的服務都真的在執行? 

如果服務沒有在執行,啟動它,要除錯一個沒有在跑的服務是極度困難的。有時一個服務會表現地像是已經啟動但是沒有效果的樣子。有時,使用不良的設定檔,或是郵件組件發生傳輸不佳的狀況,服務會停滯,並阻止其他程序使用這個通訊阜。有時候您可以用 netstat 偵測,或者,如果您已經偵錯好一段時間了,休息一下並且利用此時讓您的機器重開機,那會清理掉任何停滯的服務,然後您可以精神奕奕地回來,再試一次。

Code listing 15.2

# /etc/init.d/$service status
# netstat -a | grep $service (or $port)

步驟 3:是否所有的服務都使用目前的設定檔? 

如果您最近曾經更動到設定檔,重新啟動這個服務來確認它使用的拭目前的版本,有些組件會傾印它們目前的設定給你,像是 postfix。

Code listing 15.3

# apachectl fullstatus(需要安裝 lynx)
# apachectl configtest(檢查設定的合理性)
# postconf -n(這會告訴您 postfix 正在使用的確切參數)
# /etc/init.d/$service restart

步驟 4:檢查記錄檔 

跟著我重複一次,記錄檔是我的朋友。我下一個排除問題的步驟總是記錄檔。有時,重試一次失敗的操作,然後檢查記錄檔,這時錯誤訊息會出現在最尾端(或是最開頭,看您使用哪個記錄器),而不是被埋在一堆訊息中。看記錄檔裡面是否有任何資訊可以幫助您診斷問題所在,或是最起碼找到出問題的組件。

Code listing 15.4

# kill -USR1 `ps -C metalog -o pid=`(關閉 metalog 緩衝功能)
# nano -w /var/log/mail/current
# cat /var/log/mysql/mysql.log
# tail /var/log/apache/error_log

您也會發現在 main.cf 找到 debug_peer 參數很有幫助。設定這些參數會增加記錄的輸出,比 verbose 模式多一些。

Code listing 15.5: 增加 debug_peer 支援

# nano -w /etc/postfix/main.cf
debug_peer_level = 5
debug_peer_list = $host.domain.name
// 去掉某個建議的除錯器指令前的注解記號。

步驟 5:自己與服務對談 

SMTP, IMAP, 和 POP3 都會回應 telnet 連線,如我們之前檢驗 postfix 設定檔時所見,有時候開個 telnet 連線到服務本身去看看發生什麼事是很有幫助的。

Code listing 15.6

# telnet localhost $port
// SMTP 是 25,IMAP 是 143,POP3 是 110。您最少應該會收到一個 OK 字串,
// 讓您知道這個服務正在執行並且已經準備好回應任何請求。

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK Courier-IMAP ready. Copyright 1998-2002 Double Precision, Inc.

步驟 6:有時就是只有拿出殺手澗才能給您所需要的資訊:strace 

不管怎樣,您應該已經安裝好這個工具,這是個無價的除錯軟體。您可以從指令模式用 strace 執行這個指令,觀察所有發生的系統呼叫。它常會傾印巨量的資訊,所以您需要在使用郵件系統重試一個失敗的交易時即時觀看,不然就是傾印這些輸出到一個檔案來檢視。

Code listing 15.7

# emerge strace
# strace $command
# strace -p `ps -C $service -o pid=`

步驟 7:研究 

在您擁有這些資訊之後,如果您可以診斷並解決問題,太好了!如果沒有,您可能需要在網路中挖掘能幫您解決問題的資訊。這裡是個網站列表,您可以上去看看是否您遇到的錯誤已經有人解決了,另外也提供一份關於設定 smtp-auth 的文件,寫得相當好,裡面有些很好的除錯方法。



line
Updated 2004-11-08
line
Ken Nowack
Author

Ezra Gorman
Author

Zack Gilburd
Editor

LY Lai
Translator

line
Summary: 這份文件詳細描述如何使用 postfix, mysql, courier-imap, 和 cyrus-sasl 建立一個虛擬主機系統。
line

Donate to support our development efforts.

line
The Gentoo Linux Store
line
php|architect

php|architect is the monthly magazine for PHP professionals, available worldwide in print and electronic format. A percentage of all the sales will be donated back into the Gentoo project.

line
Tek Alchemy

Tek Alchemy offers dedicated servers and other hosting solutions running Gentoo Linux.

line
DDR Memory at Crucial.com

Purchase RAM from Crucial.com and a percentage of your sale will go towards further Gentoo Linux development.

line
Win4Lin at NeTraverse

Win4Lin from NeTraverse lets you run Windows applications under Gentoo Linux at native speeds.

line
Copyright 2001-2003 Gentoo Technologies, Inc. Questions, Comments, Corrections? Email www@gentoo.org.