一、郵件系統的安裝
1、軟件包安裝
Postfix+Courier-IMAP+Cyrus-SASL+PAM_MySQL+MySQL這種安裝方式簡單易行,在Debian下的安裝更加方便:
# apt-get install courier-pop postfix-mysql postfix-tls courier-authdaemon\
courier-authmysql libpam-mysql libsasl7 libsasl-modules-plain courier-imap
如果你的系統本身沒有mysql,那么在上面的列表里還要加上mysql-server。apt在安裝過程中會有簡單的提示,要求填上系統的域名等信息。
2、postfix的配置
修改main.cf:
添加:
home_mailbox = Maildir/
告訴postfix使用Maildir方式
mydestination = $myhostname, $transport_maps
告訴postfix發送$myhostname(本機)和$transport_maps(transport表里的域名)的郵件。
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
relocated_maps = mysql:/etc/postfix/mysql-relocated.cf
transport_maps = mysql:/etc/postfix/mysql-transport.cf
virtual_maps = mysql:/etc/postfix/mysql-virtual.cf
告訴postfix從哪里找這些表。
local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname
postfix傳遞給本地收件人的幾種方法。
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_uid_maps = mysql:/etc/postfix/mysql-virtual-uid.cf
virtual_gid_maps = mysql:/etc/postfix/mysql-virtual-gid.cf
虛擬用戶的信息。
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
啟用sasl,必須驗證才能發信。
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unknown_recipient_
domain,reject_non_fqdn_recipient,check_relay_domains
發信限制。
還可以加上一些其他的參數:
disable_vrfy_command = yes
將vrfy功能關掉。
3、與MySQL結合的配置及數據表結構
注意:配置mysql相關部分要寫127.0.0.1而不要寫localhost,如果使用localhost,postfix會嘗試socket連接。debian的postfix使用socket連接好像有問題。mysql不能使用skip-networking選項,要使用--bind-address=127.0.0.1讓它監聽在127.0.0.1。(非常感謝Martin List-Petersen指點)
還有要注意的是如果是自己編譯的mysql,建議在啟動的時候加上--socket=/var/run/mysqld/mysqld.sock參數,因為pam-mysql又需要使用這個socket。如果你的apache+php是自己編譯的話,php又需要重新編譯,配置的時候需要加上--with-mysql-sock=/var/run/mysqld/mysqld.sock參數。
是不是比較煩?這不過是個開始。
MySQL的數據表:
CREATE TABLE alias (
id int(11) unsigned NOT NULL auto_increment,
alias varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE relocated (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE transport (
id int(11) unsigned NOT NULL auto_increment,
domain varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id),
UNIQUE KEY domain (domain)
) TYPE=MyISAM;
CREATE TABLE users (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
clear varchar(128) NOT NULL default '',
name tinytext NOT NULL,
uid int(11) unsigned NOT NULL default '1011',
gid int(11) unsigned NOT NULL default '1011',
homedir tinytext NOT NULL,
maildir tinytext NOT NULL,
quota tinytext NOT NULL,
postfix enum('Y','N') NOT NULL default 'Y',
PRIMARY KEY (id),
UNIQUE KEY email (email)
) TYPE=MyISAM;
CREATE TABLE virtual (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
/etc/postfix目錄下各mysql配置文件:
mysql-aliases.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = alias
select_field = destination
where_field = alias
hosts = 127.0.0.1
mysql-relocated.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = relocated
select_field = destination
where_field = email
hosts = 127.0.0.1
mysql-transport.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = transport
select_field = destination
where_field = domain
hosts = 127.0.0.1
TLS支持
通過修改/usr/lib/ssl/misc/CA.pll腳本實現,以下修改后CA1.pl和未修改CA.pl之間的對比:
*** CA.pl
--- CA1.pl
***************
*** 59,69 ****
} elsif (/^-newcert$/) {
# create a certificate
! system ("$REQ -new -x509 -keyout newreq.pem -out newreq.pem $DAYS");
$RET=$?;
print "Certificate (and private key) is in newreq.pem\n"
} elsif (/^-newreq$/) {
# create a certificate request
! system ("$REQ -new -keyout newreq.pem -out newreq.pem $DAYS");
$RET=$?;
print "Request (and private key) is in newreq.pem\n";
} elsif (/^-newca$/) {
--- 59,69 ----
} elsif (/^-newcert$/) {
# create a certificate
! system ("$REQ -new -x509 -nodes -keyout newreq.pem -out newreq.pem $DAYS");
$RET=$?;
print "Certificate (and private key) is in newreq.pem\n"
} elsif (/^-newreq$/) {
# create a certificate request
! system ("$REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS");
$RET=$?;
print "Request (and private key) is in newreq.pem\n";
} elsif (/^-newca$/) {
現在就可以使用修改的CA1.pl來簽發證書:
# cd /usr/local/ssl/misc
# ./CA1.pl -newca
# ./CA1.pl -newreq
# ./CA1.pl -sign
# cp demoCA/cacert.pem /etc/postfix/CAcert.pem
# cp newcert.pem /etc/postfix/cert.pem
# cp newreq.pem /etc/postfix/key.pem
修改main.cf,添加:
smtpd_tls_cert_file = /etc/postfix/cert.pem
smtpd_tls_key_file = /etc/postfix/privkey.pem
smtpd_use_tls = yes
tls_random_source = dev:/dev/urandom
tls_daemon_random_source = dev:/dev/urandom
重起postfix后就可以看到250-STARTTLS
很多郵件客戶端對TLS的支持并不是非常好,建議使用stunnel來實現相應的smtp和pop3加密。
# apt-get install stunnel
證書:
# openssl req -new -x509 -days 365 -nodes -config /etc/ssl/openssl.cnf -out stunnel.pem -keyout stunnel.pem
# openssl gendh 512 >> stunnel.pem
服務端:
# stunnel -d 60025 -r 25 -s nobody -g nogroup
# stunnel -d 60110 -r 110 -s nobody -g nogroup
如果使用-n pop3等參數就只能用郵件客戶端收信。
客戶端:
建一個stunnel.conf文件:
client = yes
[pop3]
accept = 127.0.0.1:110
connect = 192.168.7.144:60110
[smtp]
accept = 127.0.0.1:25
connect = 192.168.7.144:60025
然后啟動stunnel.exe,在郵件客戶端的smtp和pop3的服務器都填127.0.0.1就可以了,這樣從你到郵件服務器端的數據傳輸就讓stunnel給你加密了。
4、測試用戶
# mkdir -p /home/vmail/test.org/san/
# chown -R nobody.nogroup /home/vmail
# chmod -R 700 /home/vmail
mysql> use postfix
mysql> insert into transport set domain='test.org', destination='
virtual:';
mysql> insert into users set email='san@test.org',clear='test',name='',uid='65534',gid='65534',
homedir='home/vmail',maildir='test.org/san/';
然后就可以使用客戶端收發郵件,記得用戶名是email地址。
mysql-virtual.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = virtual
select_field = destination
where_field = email
hosts = 127.0.0.1
mysql-virtual-maps.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = users
select_field = maildir
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1
mysql-virtual-uid.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = users
select_field = uid
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1
mysql-virtual-gid.cf
user = mysql-postfix-user
password = mysql-postfix-pass
dbname = postfix
table = users
select_field = gid
where_field = email
additional_conditions = and postfix = 'y'
hosts = 127.0.0.1
修改Courier相關設置,/etc/courier/imapd:
AUTHMODULES="authdaemon"
IMAP_CAPABILITY="IMAP4rev1 CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT
THREAD=REFERENCES SORT AUTH=CRAM-MD5 AUTH=CRAM-SHA1 IDLE"
修改/etc/courier/pop3d
AUTHMODULES="authdaemon"
POP3AUTH="LOGIN CRAM-MD5 CRAM-SHA1"
修改/etc/courier/authdaemonrc
authmodulelist="authmysql authpam"
使用mysql驗證和pam驗證。
修改/etc/courier/authmysqlrc
MYSQL_SERVER 127.0.0.1
MYSQL_USERNAME mysql-postfix-user
MYSQL_PASSWORD mysql-postfix-pass
#MYSQL_SOCKET /var/run/mysql/mysql.sock
MYSQL_PORT 0
MYSQL_OPT 0
MYSQL_DATABASE postfix
MYSQL_USER_TABLE users
MYSQL_LOGIN_FIELD email
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD uid
MYSQL_GID_FIELD gid
MYSQL_HOME_FIELD homedir
MYSQL_MAILDIR_FIELD maildir
SASL library
創建/etc/postfix/sasl/smtpd.conf:
pwcheck_method: PAM
PAM-MySQL
創建/etc/pam.d/smtp:
auth optional pam_mysql.so host=localhost db=postfix user=
mysql-postfix-user passwd=mysql-postfix-pass table=users
usercolumn=email passwdcolumn=clear crypt=n
account required pam_mysql.so host=localhost db=postfix user=mysql-postfix-user passwd=mysql-postfix-pass usercolumn=email passwdcolumn=clear crypt=n