[后端]郵件服務(wù)器搭建之virtual_users

背景

在上一篇講到了安裝完postfix之后,我們再服務(wù)器上有有了收發(fā)郵件的能力嘲碧。 然而因為我們只是做了一點微小的工作稻励,功能并不夠強大。只能使用root@example.com這個郵箱來進行收發(fā)。因為這時候郵件地址還是和linux服務(wù)器上的用戶一一對應(yīng)的望抽。并不能滿足筆者的需求加矛。筆者需要的是能夠隨意使用在本域下的任意郵箱的呀,所以本文就來探究如何在前篇的基礎(chǔ)上擴充郵件服務(wù)煤篙,使之具有承載虛擬用戶的能力斟览。

原理分析

postfix只是個MTA服務(wù)軟件,并不是一個真正的MDA軟件辑奈。postfix只是簡單將收到的郵件發(fā)給對應(yīng)用戶組下的郵件目錄中苛茂,以文件形式存儲下來。如果郵箱地址對應(yīng)的不是一個linux存在的用戶鸠窗,那么郵件就會被退回妓羊。如果需要很多虛擬用戶的話,就需要另尋他路了稍计,這里我們用dovecot來充當MDA的角色躁绸,來進行對虛擬用戶的操縱,并投遞到相應(yīng)虛擬用戶的目錄中臣嚣。而虛擬用戶的賬號净刮、別稱數(shù)據(jù)需要mysql來進行存儲。既然用mysql來進行存儲硅则,就要有賬號管理的應(yīng)用(注意dovecot只是從數(shù)據(jù)庫中讀取虛擬用戶的數(shù)據(jù)傳遞給postfix使用淹父,并不能很方便的創(chuàng)建和管理虛擬用戶的數(shù)據(jù)),這時候我們就可以使用postfixadmin來進行管理了抢埋。
因此本文所涉及到的是4個應(yīng)用
postfix(MTA) 負責郵件的傳輸
dovecot(MDA) 負責從mysql中讀取數(shù)據(jù)弹灭,轉(zhuǎn)發(fā)給postfix提供虛擬用戶的數(shù)據(jù)用以路由與驗證。
mysql(database) 負責存儲用戶數(shù)據(jù)揪垄。
postfixadmin 負責賬號的創(chuàng)建與管理穷吮,只是存儲數(shù)據(jù)庫的數(shù)據(jù),并不參與到郵件的轉(zhuǎn)發(fā)工作中饥努。

操作步驟

  • step1 配置服務(wù)器用戶
    為了安全起見捡鱼,我們要新配置一個用戶來管理這個郵件的收發(fā),我們叫vmail好了酷愧。
$ groupadd -g 5000 vmail   #組號為5000,組名為vamil
$ useradd -u 5000 -g vmail -s /usr/bin/nologin -d /home/vmail -m vmail  #用戶號為5000驾诈,屬于用戶組vmail,沒有登錄shell的權(quán)限溶浴,主目錄為/home/vmail并自動創(chuàng)建乍迄,最后這個用戶就叫vamil了。
  • step2 使用postfixadmin配置虛擬域名以及虛擬用戶
$ apt-get install postfixadmin 

安裝完以后士败,phpadmin就會彈出一個配置向?qū)斫o我們進行配置闯两。跟著操作來就好了褥伴,一般用默認配置就好了。postfixadmin會在數(shù)據(jù)庫中創(chuàng)建一個名字為postfixadmin的用戶漾狼,同時創(chuàng)建一個相應(yīng)的名字為postfixadmin的數(shù)據(jù)庫重慢。接著其就會自己進行配置和初始化了。
可以在安裝記錄的提示中看到數(shù)據(jù)庫創(chuàng)建的提示和配置文件所在目錄

granting access to database postfixadmin for postfixadmin@localhost: success.
Creating config file /etc/dbconfig-common/postfixadmin.conf with new version
Creating config file /etc/postfixadmin/dbconfig.inc.php with new version

這樣我們就基本安裝好了postfixadmin逊躁,接著我們就可以從web的方式在網(wǎng)頁上進行配置了似踱。postfixadmin的目web配置文件在/usr/share/postfixadmin/目錄下,我們要把其映射web服務(wù)器的可訪問目錄下稽煤。如果是用apache那么就自動配置好了核芽,只要訪問yourdomain/postfixadmin/index.php就好了,然而筆者用的nginx念脯,所以要自己額外映射一發(fā)狞洋。我們新開一個端口映射到域名下,那么我們訪問https://yourdomain:1234/index.php就可以了
在/etc/nginx/sites-available目錄下新建一個yourdomain_1234_postfixadmin

server {
        listen 1234;
        listen [::]:1234;

        server_name yourdomain;

        root /usr/share/postfixadmin;
        index index.html;

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }

        location / {
                try_files $uri $uri/ =404;
        }
}

然后配置一下重啟nginx就好了

$ cd /etc/nginx/sites-enabled
$ ln -s ../sites-available/st0rm23.com_3789_postfixadmin
$ nginx -t
$ /etc/init.d/nginx restart

完了以后绿店,訪問一下先訪問一下https://yourdomain:1234/setup.php吉懊,看是否都配置成功。
筆者就悲傷的發(fā)現(xiàn)mysql這一塊失敗了

Error: Can't connect to database
Please edit the $CONF['database_*'] parameters in config.inc.php.

看了一下原因假勿,原來是我使用的是mysqli而不是mysql借嗽,然后我在dbconfig.inc.php里面改了一下type類型就就可以正常使用了。

修好以后转培,又發(fā)現(xiàn)初始化數(shù)據(jù)庫的時候執(zhí)行失敗了恶导,找了一下原因,是因為postfixadmin的bug浸须,日期的地方默認值填的是0惨寿,然而數(shù)據(jù)庫版本使用的strict模式,就執(zhí)行失敗了(后來postfixadmin修了這個bug删窒,然而筆者做的時候裂垦,這個bug修好了只在issue里面,還沒有release出來)肌索。于是筆者就手工修改了mysql去掉了嚴格模式蕉拢。
在/etc/mysql/conf.d/目錄下新建一個disable_strict_mode.cnf文件,輸入

[mysqld]
sql_mode=IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

保存后诚亚,使用/etc/init.d/mysql restart重啟加載配置就好了晕换。這樣重新刷新setup.php文件就可以發(fā)現(xiàn)數(shù)據(jù)庫都加載好了。配置好密碼后站宗,就愉快地訪問你的鏈接吧https://yourdomain:1234/index.php闸准。

  • setup3 使用postadmin的web界面進行配置虛擬用戶
    在經(jīng)過上一步之后,我們就可以從web界面進行配置了梢灭,那么登錄到https://yourdomain:1234/index.php就可以看到下述界面夷家。

    QQ截圖20161126115438.png

    進去之后可以添加域和虛擬用戶腕唧。先創(chuàng)建一個hello@example.com的賬號進行后續(xù)使用

  • setup4 配置dovecot以及相應(yīng)的sasl
    我們?nèi)绻邮軄碜酝庥虻泥]件,我們還要配置一個dovecot來管理外部郵件到虛擬用戶的映射瘾英。注意在前幾步中,我們只是添加postfixadmin來管理虛擬用戶颂暇,然而郵件是外域接受并傳遞到虛擬用戶這個過程并沒有被實現(xiàn)缺谴。所以我們就需要用dovecot來實現(xiàn)這個過程。

先安裝一下dovecot相關(guān)的包

$ apt-get install dovecot-common
$ apt-get install dovecot-pop3d
$ apt-get install dovecot-imapd
$ apt-get install dovecot-mysql

然后配置dovecot的配置文件/etc/dovecot/dovecot.conf耳鸯,注意如果有舊的的dovecot.conf湿蛔,那么把舊的文件刪掉,并不需要舊的那個了

protocols = imap pop3
auth_mechanisms = plain
passdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}
userdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}

service auth {
    unix_listener /var/spool/postfix/private/auth {
                    group = postfix
                    mode = 0666
                    user = postfix
    }
    user = root
}
mail_home = /home/vmail/%d/%n
mail_location = maildir:~
ssl_cert = </etc/ssl/private/yourca.crt
ssl_key = </etc/ssl/private/yourca.key

接著配置一下/etc/dovecot/dovecot-sql.conf县爬,讓dovecot能夠訪問數(shù)據(jù)庫

driver = mysql
connect = host=localhost dbname=postfixadmin user=postfixadmin password=password
# It is highly recommended to not use deprecated MD5-CRYPT. Read more at http://wiki2.dovecot.org/Authentication/PasswordSchemes
default_pass_scheme = SHA512-CRYPT
# Get the mailbox
user_query = SELECT '/home/vmail/%d/%n' as home, 'maildir:/home/vmail/%d/%n' as mail, 5000 AS uid, 5000 AS gid, concat('dirsize:storage=',  quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1'
# Get the password
password_query = SELECT username as user, password, '/home/vmail/%d/%n' as userdb_home, 'maildir:/home/vmail/%d/%n' as userdb_mail, 5000 as  userdb_uid, 5000 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1'
# If using client certificates for authentication, comment the above and uncomment the following
#password_query = SELECT null AS password, %u AS user                                                  

注意阳啥,這里我用的是private/auth這一套,有些文檔使用的是auth-client那一套财喳,然而我并沒有成功察迟,總是提示找不到對應(yīng)的文件。

  • step5 配置postfix耳高,使得postfix通過dovecot來代理郵件到虛擬用戶的分發(fā)
    配置/etc/postfix/main.cf扎瓶,在末尾加上
relay_domains = $mydestination
virtual_alias_maps = proxy:mysql:/etc/postfix/virtual_alias_maps.cf #數(shù)據(jù)庫的連接文件,后面要創(chuàng)建的
virtual_mailbox_domains = proxy:mysql:/etc/postfix/virtual_mailbox_domains.cf #數(shù)據(jù)庫的連接文件泌枪,后面要創(chuàng)建的
virtual_mailbox_maps = proxy:mysql:/etc/postfix/virtual_mailbox_maps.cf #數(shù)據(jù)庫的連接文件概荷,后面要創(chuàng)建的
virtual_mailbox_base = /home/vmail
virtual_mailbox_limit = 512000000
virtual_minimum_uid = 5000
virtual_transport = virtual
virtual_uid_maps = static:5000  #這里就是之前創(chuàng)建的vmail的uid 5000
virtual_gid_maps = static:5000
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps
transport_maps = hash:/etc/postfix/transport
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth  #這里要注意,是和上面dovecot配置的時候緊密相關(guān)的碌燕,通過這個路徑才能進行sasl的認證误证。
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_received_header = yes
smtpd_tls_cert_file = /etc/ssl/private/www.st0rm23.com.crt
smtpd_tls_key_file = /etc/ssl/private/www.st0rm23.com.key
smtpd_sasl_local_domain = $mydomain
broken_sasl_auth_clients = yes
smtpd_tls_loglevel = 1

同時完成/etc/postfix/virtual_alias_maps.cf、/etc/postfix/virtual_mailbox_domains.cf修壕、/etc/postfix/virtual_mailbox_maps.cf三個文件的數(shù)據(jù)庫配置愈捅。
/etc/postfix/virtual_alias_maps.cf

user = postfixadmin
password =  password #你的密碼
hosts = localhost
dbname = postfixadmin
table = alias
select_field = goto
where_field = address

/etc/postfix/virtual_mailbox_domains.cf

user = postfixadmin
password =  password #你的密碼
hosts = localhost
dbname = postfixadmin
table = domain
select_field = domain
where_field = domain

/etc/postfix/virtual_mailbox_maps.cf

user = postfixadmin
password =  password #你的密碼
hosts = localhost
dbname = postfixadmin
table = mailbox
select_field = maildir
where_field = username

這樣用/etc/init.d/postfix restart 重啟完postfix后就可正式生效了。我們可以用公共的郵箱向在step3中建立的虛擬郵箱hello@example.com用戶發(fā)一封郵件叠殷。就會發(fā)現(xiàn)郵件可以成功發(fā)送了改鲫。

碰到的問題

一路上還是碰到不少問題的,特別是搭建dovecot的時候林束,由于很陌生像棘,各個文檔的說法都不一致碰到過很多問題。這里有一個很有效的調(diào)試方法壶冒,發(fā)一封郵件缕题,然后看/var/log/mail.log下的日志

$ tail /var/log/mail.log -n 20

很明顯能夠看到失敗的原因,這里分享幾個錯誤和解決的方法胖腾。

  • postfix/smtpd[19476]: warning: SASL: Connect to /var/run/dovecot/auth-client failed: No such file or directory
    這個我也不知道為什么postfix和dovecot在auth-client的文件上找不到烟零。后來我就改成了private/auth的接入方式(理論上兩種方式都可以的瘪松,只是兩個程序內(nèi)部的管道數(shù)據(jù)流罷了)。就是在/etc/dovecot中unix_listener的地方改成/var/spool/postfix/private/auth锨阿,同時在/etc/postfix/main.cf的smtpd_sasl_path改成private/auth宵睦。重啟兩個服務(wù)就可以了
  • dovecot: auth: Fatal: Unknown database driver 'mysql'
    這個是由于沒有安裝dovecot-mysql組件的原因,用aptget-install安裝一下就好了
  • Temporary lookup failure
    這個導(dǎo)致的原因多種多樣墅诡,我的原因是因為我在/etc/postfix/main.cf中同時開了virtual_transport和transport_maps壳嚎。前者是虛擬轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)到虛擬用戶末早,而后者是真實地路由到其他的服務(wù)器烟馅。所以把后者注釋掉了,就可正常接收郵件了然磷。否則由于我沒有transport.db文件郑趁,就會報錯收不到郵件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姿搜,一起剝皮案震驚了整個濱河市寡润,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痪欲,老刑警劉巖悦穿,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異业踢,居然都是意外死亡栗柒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門知举,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瞬沦,“玉大人,你說我怎么就攤上這事雇锡」渥辏” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵锰提,是天一觀的道長曙痘。 經(jīng)常有香客問我,道長立肘,這世上最難降的妖魔是什么边坤? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮谅年,結(jié)果婚禮上茧痒,老公的妹妹穿的比我還像新娘。我一直安慰自己融蹂,他們只是感情好旺订,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布弄企。 她就那樣靜靜地躺著,像睡著了一般区拳。 火紅的嫁衣襯著肌膚如雪拘领。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天樱调,我揣著相機與錄音院究,去河邊找鬼。 笑死本涕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的伙窃。 我是一名探鬼主播菩颖,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼为障!你這毒婦竟也來了晦闰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤鳍怨,失蹤者是張志新(化名)和其女友劉穎呻右,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鞋喇,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡声滥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了侦香。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片落塑。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖罐韩,靈堂內(nèi)的尸體忽然破棺而出憾赁,到底是詐尸還是另有隱情,我是刑警寧澤散吵,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布龙考,位于F島的核電站,受9級特大地震影響矾睦,放射性物質(zhì)發(fā)生泄漏晦款。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一顷锰、第九天 我趴在偏房一處隱蔽的房頂上張望柬赐。 院中可真熱鬧,春花似錦官紫、人聲如沸肛宋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酝陈。三九已至床玻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沉帮,已是汗流浹背锈死。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留穆壕,地道東北人待牵。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像喇勋,于是被迫代替她去往敵國和親缨该。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容