您的位置:首页 > 运维架构

运维笔记21 (邮件服务器的搭建)

2016-12-09 16:40 507 查看
概述:

虽然即时通讯工具诸如qq,微信之类的工具已经是大家和朋友沟通的首选了,但是在一些情况下,我们一定会使用到电子邮件这个东西,基本上国内大一点的互联网公司都有电子邮件的服务,我们使用电子邮件的时候感觉非常便利,只用编辑标题,发件人,内容之后点击发送,邮件就被送到了目的地,但其实这发邮件的过程中有一些很有意思的原理。下面我用图片来描述一下用户A@xxx.com发邮件给D@xxx.com的过程。



这个图上面出现了几个名词,分别是,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的支持,我简略的说下原因。邮箱的地址大家一定见过,就是形如moxxxxx@xx.com这样的,@前面的是用户名字或者账号,后面的则是邮件服务器的域名,有了域名就需要解析成为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非常重要,是我们接收名字为什么样子的邮件,按照我这里的写法,我只会接收xxx@mail.yan.com xxx@yan.com xxx@localhost的邮件。

上面修改的文件是/etc/postfix/main.cf文件,只要两台主机都修改了这几个选项我们就可以进行邮件的发送和接收了,来让我们测试下

[root@mail postfix]# mail root@momo.com
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 root@yan.com  Thu Dec  8 03:32:37 2016
Return-Path: <root@yan.com>
X-Original-To: root@momo.com
Delivered-To: root@momo.com
Date: Thu, 08 Dec 2016 03:32:37 -0500
To: root@momo.com
Subject: hello
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: root@yan.com (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:root@yan.com
250 2.1.0 Ok
rcpt to:root@momo.com
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 root@yan.com  Thu Dec  8 03:49:38 2016
Return-Path: <root@yan.com>
X-Original-To: root@momo.com
Delivered-To: root@momo.com
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:root@yan.com
250 2.1.0 Okrcpt to:root@momo.com
554 5.7.1 <unknown[172.25.254.3]>: Client host rejected: Access denied


发送失败,因为第三台主机的ip被限制了。

2.2)限制客户端用户

首先编辑sender文件(如果没有自行创建,其实也不一定是这个名字)内容如下:

[root@mail postfix]# cat sender
root@momo.com 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,并以root@momo.com为发送者,root@yan.com为接收者
mail from:root@momo.com

250 2.1.0 Ok

rcpt to:root@yan.com

554 5.7.1 <root@momo.com>: 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:root@yan.com

250 2.1.0 Ok

rcpt to:root@momo.com

554 5.7.1 <root@momo.com>: Recipient address rejected: Access denied

给root@momo.com发送邮件发现无法发送
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://dov@172.25.254.203用于和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                    |

+---------------+----------+---------+----------------------------+

| admin@yan.org | 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
之后向admin@yan.org发送邮件,就可以在目录中查找到信的内容了,在发送之前也可以使用postmap -q 查询一下这些数据库查询文件,看结果是否正确。
postmap -q "yan.org" mysql:/etc/postfix/mysql-domains.cf -q
yan.org
[root@mail mail]# postmap -q "admin@yan.org" mysql:/etc/postfix/mysql-mailboxs.cf
/home/vmail/yan.org/admin/
[root@mail mail]# postmap -q "admin@yan.org" mysql:/etc/postfix/mysql-alias.cf
admin@yan.org
由于一开始的配置问题我们的mail发送队列积攒了好多发送失败的邮件,我们可以选择从新发送,也可以选择删除
[root@mail mail]# mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
3B84C26BFD9      409 Thu Dec  8 08:07:31  root@yan.com
(user lookup error)
/home/vmail/yan.org/admin/@yan.com

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

4692F26BFAF      409 Thu Dec  8 08:10:44  root@yan.com
(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 admin@yan.org
-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 admin@yan.org
+OK
pass 123
+OK Logged in.
list
+OK 2 messages:
1 495
2 270
.


可以看到登陆成功,而且有两封邮件。
6.使用雷鸟客户端



















                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息