運維筆記21 (郵件服務器的搭建)

概述:

雖然即時通訊工具諸如qq,微信之類的工具已經是大家和朋友溝通的首選了,但是在一些情況下,我們一定會使用到電子郵件這個東西,基本上國內大一點的互聯網公司都有電子郵件的服務,我們使用電子郵件的時候感覺非常便利,只用編輯標題,發件人,內容之後點擊發送,郵件就被送到了目的地,但其實這發郵件的過程中有一些很有意思的原理。下面我用圖片來描述一下用戶[email protected]發郵件給[email protected]的過程。


這個圖上面出現了幾個名詞,分別是,MUA,MDA,MTA,box(mailbox),MUA(Mail User Agent)就是郵件的客戶端,諸如網易的閃電郵,Mozilla的雷鳥等。MTA(Mail Transfer Agent)是郵件中轉站的意思,比如我們登陸網易的閃電郵客戶端,給一個使用qq郵箱的朋友發郵件,郵件傳輸的過程就是,先從我們的閃電郵客戶端本地發送到網易的MTA,接下來網易的MTA轉發給騰訊的MTA,騰訊的MTA再把郵件送給qq郵箱的用戶,MTA上運行的軟件是smtp協議的實現,比如老牌的有sendmail,但現在大家長使用的是postfix,我們在後面會詳細介紹postfix的配置。MDA(Mail Delivery Agent)是分析所受到的郵件表頭或內容等數據,來決定郵件的去向,根據他的功能,他可以對垃圾郵件進行過濾。box(Mailbox)顧名思義,就是存儲客戶郵件的一般在/var/spool/mail/用戶賬號下。

1.postfix的簡單配置

就算大家沒有搭建過郵件服務器,也一定聽說了,搭建郵件服務器,需要DNS的支持,我簡略的說下原因。郵箱的地址大家一定見過,就是形如[email protected]這樣的,@前面的是用戶名字或者賬號,後面的則是郵件服務器的域名,有了域名就需要解析成爲ip地址,這下大家明白了吧,至於反向DNS對郵件服務器的作用,大家只要記住是可以防範垃圾郵件的就可以。

[root@mail ~]# hostnamectl | sed -n '1p' ; ifconfig | grep inet |sed -n '1p'
   Static hostname: mail.yan.com
        inet 172.25.254.203  netmask 255.255.255.0  broadcast 172.25.254.255
[root@mail ~]# hostnamectl | sed -n '1p' ; ifconfig | grep inet |sed -n '1p'
   Static hostname: mail.momo.com
        inet 172.25.254.103  netmask 255.255.255.0  broadcast 172.25.254.255

這是我的作爲MTA的兩臺主機,並且已經把各自域的MX記錄填寫好。

接下來介紹postfix的配置,咱們先看yan.com這臺的

 75 myhostname = mail.yan.com
 83 mydomain = yan.com
 99 myorigin = $mydomain
113 inet_interfaces = all
119 inet_protocols = all
164 mydestination = $myhostname, $mydomain, localhost

第一個參數myhostname和mydomain相當於變量的聲明,後面會有很多選項用到這兩個變量。myorigin(我的源頭)按照自面理解,就是源端地址的意思,也就是從這裏發出的郵件,源端地址都是xxx@$mydomain。inet_interfaces

就是你監聽的端口,默認情況他只監聽lo也就是本地迴環接口,也就是隻能收到自己給自己發的郵件,如果想收到別人發給你的,需要改成all。inet_protocols是監聽的協議,有ipv4和ipv6我們選擇全部監聽。最後這個mydestination非常重要,是我們接收名字爲什麼樣子的郵件,按照我這裏的寫法,我只會接收[email protected] [email protected] xxx@localhost的郵件。

上面修改的文件是/etc/postfix/main.cf文件,只要兩臺主機都修改了這幾個選項我們就可以進行郵件的發送和接收了,來讓我們測試下

[root@mail postfix]# mail [email protected]
Subject: hello
test
.
EOT
在yan.com主機下給momo.com的root用戶發送郵件

查看發送郵件隊列

[root@mail postfix]# mailq
Mail queue is empty
發送隊列已經空了,說明郵件發送出去了。

查看momo.com主機收到郵件了嗎

>U  5 root                  Thu Dec  8 03:32  22/704   "hello"
& 5
Message  5:
From [email protected]  Thu Dec  8 03:32:37 2016
Return-Path: <[email protected]>
X-Original-To: [email protected]
Delivered-To: [email protected]
Date: Thu, 08 Dec 2016 03:32:37 -0500
To: [email protected]
Subject: hello
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: [email protected] (root)
Status: RO

test
這就是momo.com收到的郵件內容。

接下來切換第三臺主機

[root@foundation3 ~]# hostname
foundation3.ilt.example.com
通過telnet遠程登陸到yan.com上向momo.com發送郵件。

[root@foundation3 ~]# telnet 172.25.254.103 25
mail from:[email protected]
250 2.1.0 Ok
rcpt to:[email protected]
250 2.1.5 Ok
data   
354 End data with <CR><LF>.<CR><LF>
hello
.
250 2.0.0 Ok: queued as A60AE2462A8
這樣郵件就發送過去了。

查看一下momo.com上有沒有收到郵件

& 6  
Message  6:
From [email protected]  Thu Dec  8 03:49:38 2016
Return-Path: <[email protected]>
X-Original-To: [email protected]
Delivered-To: [email protected]
Status: R

hello
確實收到了。

2.postfix的詳細配置
2.1)限制發件人ip

需要編輯/etc/postfix下的access文件

在最後一行添加

477 172.25.254.3    REJECT
將access變成postfix可以讀的格式。

[root@mail postfix]# ls
access     canonical  header_checks  master.cf  transport
access.db  generic    main.cf        relocated  virtual
這個access.db就是postfix可以讀的格式

接下來告知主配置文件,要加載這個access文件

[root@mail postfix]# postconf -d
這個命令可以顯示main.cf的所有選項,通過這我們過濾下需要的選項

[root@mail postfix]# postconf -e "smtpd_client_restrictions = check_client_access hash:/etc/postfix/access"
通過這個命令可以給main.cf文件添加選項。

重啓postfix

在第三臺主機上遠程登陸yan.com並且選擇發送郵件給momo.com

mail from:[email protected]
250 2.1.0 Ok
rcpt to:[email protected]
554 5.7.1 <unknown[172.25.254.3]>: Client host rejected: Access denied

發送失敗,因爲第三臺主機的ip被限制了。

2.2)限制客戶端用戶

首先編輯sender文件(如果沒有自行創建,其實也不一定是這個名字)內容如下:

[root@mail postfix]# cat sender
[email protected] REJECT
[root@mail postfix]# postmap sender
加密sender文件

向main.cf添加限制接收者的選項

[root@mail postfix]# postconf -e "smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender"
從第三臺主機遠程登陸yan.com,並以[email protected]爲發送者,[email protected]爲接收者

mail from:[email protected]
250 2.1.0 Ok
rcpt to:[email protected]
554 5.7.1 <[email protected]>: Sender address rejected: Access denied

發現以momo.com的root用戶爲發送者身份無法發送

2.3)限制收信人
還是先添加參數

[root@mail postfix]# postconf -e "smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/dest"

dest文件編輯同上一步的sender文件
mail from:[email protected]
250 2.1.0 Ok
rcpt to:[email protected]
554 5.7.1 <[email protected]>: Recipient address rejected: Access denied
[email protected]發送郵件發現無法發送

3.郵件接收服務器

剛纔一直介紹的是郵件發送服務器postfix,一個完整的郵件服務器體系,不止需要發送郵件,還需要接收郵件,發送郵件使用的是smtp協議端口號25;接收郵件所使用的協議有pop3,imap等使用的端口號分別是110,143。而實現這一協議的軟件我們使用dovecot(豆腐塊)。但是這兩個協議都是明文傳輸,隨着人們越來越重視網絡安全,出現了這兩個協議的安全版本,端口號分別是995,993。
首先下載軟件

[root@mail postfix]# yum install dovecot
編輯配置文件/etc/dovecot/dovecot.conf
 24 protocols = imap pop3 lmtp
 49 disable_plaintext_auth=no
兩個選項分別爲可以使用的郵件接收協議和開啓明文傳輸(使用明文傳輸是爲了服務器的配置方便)。
編輯郵件存儲位置。
/etc/dovecot/conf.d/10-mail.conf
mail_location = mbox:~/mail:INBOX=/var/mail/%u
重啓豆腐塊服務,讓我們來測試一下。
測試的話當然要有工具了,我們的工具就是一個郵件客戶端,我們先使用mutt這個字符界面的管理工具。後面會介紹圖形的客戶端。

[root@foundation3 ~]# mutt -f imap://[email protected]
用於和yan.com上的郵件服務器連接
但是發現出現了Permission deny錯誤
在服務端查看/var/log/maillog的日誌

Dec  8 06:38:49 mail dovecot: imap-login: Login: user=<dov>, method=PLAIN, rip=172.25.254.3, lip=172.25.254.203, mpid=9736, TLS, session=<Fxa+FCRDAgCsGf4D>
Dec  8 06:38:49 mail dovecot: imap(dov): Error: chown(/home/dov/mail/.imap, group=12(mail)) failed: Operation not permitted (egid=1001(dov), group based on /var/mail/dov - see http://wiki2.dovecot.org/Errors/ChgrpNoPerm)
Dec  8 06:38:51 mail dovecot: imap(dov): Disconnected: Logged out in=70 out=862
發現是dov的權限無法讀取/home/dov/mail/.imap
我們先進入/home/dov/mail

[root@mail mail]# ls -a
.  ..
原來就根本沒有.imap這個目錄,這就需要我們創建了,並在這個下面創建一個INBOX文件,而且注意屬組,屬主都要是dov。


這樣就可以遠程使用郵箱了,而且這個郵件就是剛纔發給dov的。
但是我們發現每個用戶如果都需要這個郵箱功能,那麼是不是每個用戶的家目錄都要上面新創建的文件呢?如何添加呢?只要在/etc/skel文件中添加好後,以後創建的用戶都會有上述的文件了

4.postfix+mysql郵箱的虛擬用戶
我們郵件的用戶不應該是真機上的一個真實用戶,而應該只是數據庫中的一行數據,所以我們使用mysql和postfix搭配,創建虛擬用戶。
首先安裝好mariadb,之後創建好用戶數據庫

+---------------+----------+---------+----------------------------+
| username      | password | domain  | maildir                    |
+---------------+----------+---------+----------------------------+
| [email protected] | 123      | yan.org | /home/vmail/yan.org/admin/ |
+---------------+----------+---------+----------------------------+
並且給admin用戶授權查找,創建,更新授權。

接下來修改配置postfix的配置文件

virtual_mailbox_base = /home/vmail
virtual_uid_maps=static:666
virtual_gid_maps=static:666
virtual_alias_maps=mysql:/etc/postfix/mysql-alias.cf
virtual_mailbox_domains=mysql:/etc/postfix/mysql-domains.cf
virtual_mailbox_maps=mysql:/etc/postfix/mysql-mailboxs.cf
第一行代表郵箱的基文件目錄,所以其實上面數據庫中的maildir可以改成/yan.org/admin/
第二,三行代表虛擬用戶在主機中的真實用戶的uid和gid。
最後三行分別是數據庫查詢文件
根據username查找username
根據domain查domain
根據username查maildir
相應的文件寫法:

[root@mail postfix]# cat mysql-alias.cf 
hosts=localhost
user=admin
password=123
dbname=email
table=mailuser
select_field=username
where_field=username
mysql-alias.cf
[root@mail postfix]# cat mysql-domains.cf 
hosts=localhost
user=admin
password=123
dbname=email
table=mailuser
select_field=domain
where_field=domain
mysql-domains.cf
[root@mail postfix]# cat mysql-mailboxs.cf
hosts=localhost
user=admin
password=123
dbname=email
table=mailuser
select_field=maildir
where_field=username
mysql-mailboxs.cf
之後向[email protected]發送郵件,就可以在目錄中查找到信的內容了,在發送之前也可以使用postmap -q 查詢一下這些數據庫查詢文件,看結果是否正確。
postmap -q "yan.org" mysql:/etc/postfix/mysql-domains.cf -q
yan.org
[root@mail mail]# postmap -q "[email protected]" mysql:/etc/postfix/mysql-mailboxs.cf 
/home/vmail/yan.org/admin/
[root@mail mail]# postmap -q "[email protected]" mysql:/etc/postfix/mysql-alias.cf
[email protected]
由於一開始的配置問題我們的mail發送隊列積攢了好多發送失敗的郵件,我們可以選擇從新發送,也可以選擇刪除
[root@mail mail]# mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
3B84C26BFD9      409 Thu Dec  8 08:07:31  [email protected]
                                                           (user lookup error)
                                         /home/vmail/yan.org/admin/@yan.com

4310C2462A9      405 Thu Dec  8 08:13:57  [email protected]
                                                           (user lookup error)
                                         /home/vmail/yan.org/admin/@yan.com

4692F26BFAF      409 Thu Dec  8 08:10:44  [email protected]
                                                           (user lookup error)
                                         /home/vmail/yan.org/admin/@yan.com
。。。省略

使用postsuper -d 郵件序列號可以刪除郵件

[root@mail mail]# postsuper -d 13DC924747C
postsuper: 13DC924747C: removed
postsuper: Deleted: 1 message

使用postqueue -f 可以重新發送
但是現在卻只能在文件中看一看郵件,可不可以用客戶端看呢?當然不可以,因爲我們只是把發送郵件,也就是smtp部分弄好了,但是收郵件部分還不可以。

5.dovecot+mysql

編輯

[root@mail conf.d]# vim /etc/dovecot/conf.d/10-auth.conf 
#!include auth-sql.conf.ext
將這一行前面的註釋去掉

根據auth-sql.conf.ext的內容

# Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
  args = /etc/dovecot/dovecot-sql.conf.ext

我們去例子文件中找一個dovecot-sql.conf.ext文件複製到/etc/dovecot下
對這個dovecot-sql.conf.ext文件進行修改

32 driver = mysql
70 connect = host=localhost dbname=email user=admin password=123
76 default_pass_scheme = PLAIN
105 password_query = \
106   SELECT username, domain, password \
107   FROM mailuser WHERE username = '%u' AND domain = '%d'
125 user_query = \
126  SELECT maildir,666 AS uid ,666 AS gid  \
127   FROM mailuser WHERE username = '%u'

接下來對conf.d/10-mail.conf修改

369 mail_location = maildir:/home/vmail/%d/%n
168 first_valid_uid = 666
175 first_valid_gid = 666

這時候重啓dovecot服務發現日誌中有一行很奇怪

Dec  8 09:29:42 mail dovecot: auth: Fatal: Unknown database driver 'mysql'
郵件竟然不知道有mysql,這時我們才知道我們少下載了一個插件。
yum install dovecot-mysql.x86_64


現在可以使用telnet來驗證我們是否成功將dovecot和mysql聯合在了一起

+OK Dovecot ready.
user [email protected]
-ERR [AUTH] Plaintext authentication disallowed on non-secure (SSL/TLS) connections.
quit

出現了這樣一行,分析日誌後發現原因是在dovecot的主配置文件中沒有開放對ip。

 48 login_trusted_networks = 0.0.0.0/0
就是這樣的一行。添加過後我們再來測試
+OK [XCLIENT] Dovecot ready.
user [email protected]
+OK
pass 123
+OK Logged in.
list
+OK 2 messages:
1 495
2 270
.

可以看到登陸成功,而且有兩封郵件。

6.使用雷鳥客戶端














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章