前文演示了通过Samba和NFS实现文件共享,本篇演示使用Postfix和Dovecot在局域网实现电子邮件收发系统。

电子邮件系统是我们日常生活和工作中非常重要的一个网络服务,在windows下收发电子邮件系统工具很多,相信大家一定接触过,比如qq邮箱、163邮箱等等。本文讲解在Linux下通过部署Postfix和Dovecot来实现电子邮件的收发。

一、电子邮件系统前世今生

1.1 产生背景

大家今天熟知的互联网起源于美国的ARPANET科研项目,这是20世纪60年代美国国防部发起的科研项目。阿帕网是当今互联网的雏形,它也是世界上第一个运营的封包交换网络。

在阿帕网发展几年之后,到1971年遇到了严峻的问题,当时参与该项目的科学家分布在美国的不同地区,并且不同地区存在时差,这就导致了不能及时分享各自的科研成功,因此需要一种能够借助网络在计算机之间传输数据的方法。

看到这里估计很多同学懵圈了,前文不是才讲了ftp文件传输以及文件共享吗?是的,他们虽然可以实现文件的传输,但是使用场景却不一样,他们就像打电话一样,需要服务器和客户端同时在线才能完成数据传输。手机上的语音信箱相信大家用过吧?邮件系统就类似语音信箱,即使你手机没电或关机了,等你再次开机的时候,你仍然可以第一时间收到语音留言。

基于这种背景,当时参与阿帕网项目的成员中有一位来自麻省理工大学的教授,用了近一年时间完成了电子邮件的设计,在1971年秋通过sndmsg软件向自己的另外一台计算机发出了人类历史上第一封电子邮件。

1.2 电子邮件相关概念

1.2.1 电子邮件地址

就像平时收发快递一样,电子邮件要准确发送给他人,那就需要对方提供明确唯一的收件地址。设计者规定电子信箱格式为“姓名@计算机主机名称”,它选择@符号作为间隔符的原因是,设计者认为人类的额名字和计算机主机名字中应该不会包含@这个特殊字符。

这很好理解,比如我们平时见到的邮箱:xxxx@qq.com、xxx@163.com等等。

1.2.2 电子邮件协议

电子邮件系统基于邮件协议来完成电子邮件的传输,常见邮件协议有:SMTP、POP3、IMAP4等。

SMTP(Simple Mail Transfer Protocol):简单邮件传输协议,用于发送和中转发出的电子邮件,占用TCP端口25。

POP3(Post Office Protocol 3):邮局协议版本3,用于将电子邮件存储到本地主机,占用TCP端口110。

IMAP4(Internet Message Access Protocol 4):Internet消息访问协议版本4,用于在本地主 机上访问邮件,占用TCP端口143。

1.2.3 电子邮件传输过程

电子邮件在传输过程中涉及到几个角色:MUA、MTA、MDA

MUA(Mail User Agent):邮件用户代理,作用是替用户收发邮件的服务器。

MTA(Mail Transfer Agent):邮件传输代理,作用是转发处理不同电子邮件服务供应商之间的邮件,把来自于 MUA 的邮件转发到合适的 MTA 服务器。

MDA(Mail Delivery Agent):邮件投递代理,作用是把来自于MTA的邮件保存到本地的收件箱中。

举个例子,假设你用一个新浪信箱给一个谷歌信箱发送一封电子邮件,其传输过程如下图:

如前所述,电子邮件系统不同于文件传输需要双方同时保持在线,当用户发送邮件后,无需等待投递工作完成就可以下线。上图中假设如果对方邮件服务器(谷歌的MTA)宕机或离线,则发件服务器(新浪的MTA)就会把要发送的内容自动暂时保存到他本地,等检测到对方邮件服务器恢复后再次投放,随后收件人(MUA)就能在自己的邮箱中找到这封邮件了。

1.2.4 Linux下电子邮件收发程序

一个最基础的电子邮件系统至少要能提供发件服务和收件服务。在Linux下使用基于SMTP协议的Postfix服务程序来提供发件服务功能,使用基于POP3协议的Dovecot服务程序提供收件服务功能。部署Postfix和Dovecot服务程序后,就可以使用邮件客户端(如Foxmail、Outlook等)进行收发邮件。

在RHEL5、6及早期的Linux系统中,默认的发件服务是Sendmail,在RHEL7系统中替换成了Postfix。相对而言Postfix在稳定性、并发性方面有了很大改进,并且减少了很多不必要的配置步骤,使用更简单。

二、Linux局域网部署电子邮件系统

2.1 准备工作

2.1.0 主机规划及邮件系统架构

(1)主机及网络规划

开始之前我们邮件系统规划如下:

主机名称 操作系统 IP地址
电子邮件系统及DNS服务器 Centos7 192.168.0.101
客户端主机(outlook) win7 192.168.0.111
客户端主机(foxmail) win10 192.168.0.112

域名采用heimatengyun.com (由于此演示是在局域网,自己单击DNS服务器,因此域名可以任意写一个)

Centos7是虚拟机,win10是虚拟机的宿主机,win7是另外一台物理机,他们之间组成一个局域网。虚拟机centos7作为电子邮件系统以及DNS服务器,设置其网络模式为:桥接模式,目的是直连主机物理网络,以此构成一个局域网。

(2)电子邮件系统基础架构

如1.2.4所述,我们采用Postfix和Dovecot来搭建一个基础的电子邮件系统,其工作流程如下:

通常情况下,我们的邮箱地址看起来应该形如:test@heimatengyun.com 也就是按照“用户名@主机地址或域名”的格式来进行规范。

为了提高可读性不直接采用形如:test@192.168.0.1这种ip地址的形式。这种ip地址的方式一是因为不容易记住,另外还容易产生误解(看起来有点像SSH远程连接的地址),因此我们还需要先部署bind服务程序来为电子邮件服务器和客户端提供NDS域名解析服务。

篇幅所限,在此不具体分析Bind服务的使用和配置,只给出具体的操作步骤。

下边就来演示下bind服务程序的配置及管理

2.1.1 配置服务器主机名称

需要保证centos服务器主机名称与发信域名保持一致

[root@email ~]# hostnamectl set-hostname mail.heimatengyun.com
[root@email ~]# hostname
mail.heimatengyun.com
[root@mail ~]# cat /etc/hostname
mail.heimatengyun.com
[root@mail ~]#

设置主机名称也可以直接修改/etc/hostname文件。

另外可以看到修改后的主机名称只显示了域名前边部分([root@mail ~]),而非完整的域名([root@mail.heimatengyun.com ~])。

2.1.2 防火墙策略设置

清空iptables防火墙默认策略,避免因防火墙中默认存在的策略阻止了客户端DNS解析域名及收发邮件。

[root@mail ~]# iptables -F
[root@mail ~]#

要是嫌麻烦或为了避免干扰,也可以直接先关掉防火墙和selinux。

2.1.3 使用bind服务为电子邮件系统提供域名解析

(1)安装bind服务

[root@mail ~]# yum install bind-chroot
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
...省略部分内容
Complete!
[root@mail ~]#

(2)主配置文件配置

bind服务程序的名称为named,因此需要找到对应的配置文件/etc/named.conf,按如图方式进行修改。

[root@mail ~]# vim /etc/named.conf

将上图2处都改为any,表示服务器上所有的IP都可以提供DNS域名解析服务,允许所有人对本地服务器发送DNS查询请求。

(3)区域配置文件配置

区域配置文件为/etc/named.rfc1912.zones,为了给用户提供配置参考,该文件中已默认有了一些无关紧要的解析参数,我们可以直接把文件清空或将我们的内容添加到文件末尾即可

[root@mail ~]# vim /etc/named.rfc1912.zones
zone "heimatengyun.com" IN {
type master;
file "heimatengyun.com.zone";
allow-update {none;};
};

直接在文件末尾添加上述配置,保存并退出。

(4)域名数据文件配置

创建前一步中配置的数据文件:heimatengyun.com.zone

[root@mail ~]# cp -a /var/named/named.localhost /var/named/heimatengyun.com.zone
[root@mail ~]# vim /var/named/heimatengyun.com.zone

注意使用cp命令时记得添加-a参数,保留原始文件的所有者、所属组、权限等信息。这样bind服务程序才能顺利读取文件内容。

按照如下提示根据自身需要修改即可

如上配置,对应的服务器主机名即为mail.heimatengyun.com,而邮件域为@heimatengyun.com。

需要注意,域名后有一个点,如果配置文件配错了会导致后边重启bind服务的时候启动不起来。如果遇到启动不起来的情况请仔细检查配置文件。

配置好后需要重启bind服务使其生效。

[root@mail ~]# systemctl restart named
[root@mail ~]# systemctl enable named
ln -s '/usr/lib/systemd/system/named.service' '/etc/systemd/system/multi-user.target.wants/named.service'
[root@mail ~]#

(5)DNS服务器地址配置

通过nmtui命令将DNS服务器地址配置为本地的IP地址。忘记操作步骤的请看“linux入门系列11--Centos7网络服务管理”2.2节。

修改完成后重启网络服务使配置生效。

[root@mail ~]# systemctl restart network
2.1.4 测试域名解析

通过nslookup命令测试本地DNS是否生效

[root@mail ~]# nslookup
> mail.heimatengyun.com
Server: 192.168.0.101
Address: 192.168.0.101#53
Name: mail.heimatengyun.com
Address: 192.168.0.101
> exit
[root@mail ~]#

说明本地DNS解析服务已经生效了,接下来就开始部署电子邮件系统了。

2.2 Postfix发件系统

Postfix是一款由IBM资助研发的免费开源电子邮件服务程序,能够很好地兼容 Sendmail 服务程序,由许多小模块组成,每个小模块都可以完成特定的功能,因此可在生产工作环境中根据需求灵活搭配它们。

2.2.1 安装Postfix服务
[root@mail ~]# rpm -q postfix
postfix-2.10.1-6.el7.x86_64
[root@mail ~]#

可以看到,在RHEL7中已经默认安装了Postfix。

防火墙禁用

2.2.2 配置Postfix服务

主配置文件为/etc/postfix/main.cf,其中主要的参数如下:

参数 作用
myhostname 邮局系统的主机名
mydomain 邮局系统的域名
myorigin 从本机发出邮件的域名名称
inet_interfaces 监听的网卡接口
mydestination 可接收邮件的主机名或域名
mynetworks 设置可转发哪些主机的邮件
relay_domains 设置可转发哪些网域的邮件
[root@mail ~]# vim /etc/postfix/main.cf

总共有5处需要修改,分别如下:

myhostname = mail.heimatengyun.com

此处定义一个myhostname 的变量,用来保存服务器的主机名称,以供后边的参数调用。

mydomain = heimatengyun.com

定义一个名为 mydomain 的变量,用来保存邮件域的名称,以供后边的参数调用。

myorigin = $mydomain

调用前面的mydomain变量,用来定义发出邮件的域。这样通过调用变量的好处是避免重复写入信息,以及便于日后统一修改。

inet_interfaces = all

定义网卡监听地址,可以指定要使用服务器的哪些IP地址对外提供电子邮件服务;也可以写成 all,代表所有IP地址都能提供电子邮件服务。

mydestination = $myhostname , $mydomain

定义可接收邮件的主机名或域名列表。这里可以直接调用前面定义好的 myhostname 和 mydomain变量。

2.2.3 创建电子邮件系统登录用户

与之前提到的vsftp服务程序一样,postfix可以使用本地系统的账号密码进行登录。(创建的创建应该添加nologin禁止登陆,但此处为了后边方便演示,使其允许登录)

[root@mail ~]# useradd heima
[root@mail ~]# echo "123456" | passwd --stdin heima
Changing password for user heima.
passwd: all authentication tokens updated successfully.
2.2.4 重启服务并加入开机启动
[root@mail ~]# systemctl restart postfix
[root@mail ~]# systemctl enable postfix

2.3 Dovecot收件系统

Dovecot是一款能够为Linux系统提供IMAP和POP3电子邮件服务的开源服务程序,安全性高、配置简单、执行速度快并且占用资源少,推荐使用。

2.3.1 安装Dovecot
[root@mail ~]# yum install dovecot
...省略部分内容
Installed:
dovecot.x86_64 1:2.2.36-3.el7_7.1
Complete!
[root@mail ~]#
2.3.2 配置Dovecot

(1)主配置文件

Dovecot服务程序的主配置文件为/etc/dovecot/dovecot.conf 。

[root@mail ~]# vim /etc/dovecot/dovecot.conf

一般情况下有2处需要修改

第一处:

protocols = imap pop3 lmtp
disable_plaintext_auth = no

找到以上行并取消注释,并在其下添加一行,允许用户使用明文进行密码验证。

之所以这样操作,是因 为 Dovecot 服务程序为了保证电子邮件系统的安全而默认强制用户使用加密方式进行登录, 而由于当前还没有加密系统,因此需要添加该参数来允许用户的明文登录。

第二处:

 #login_trusted_networks =192.168.78.0/24

找到login_trusted_networks,根据需要来选择取消注释并配置允许登录的网段地址。我们可以在这里限制只有来自于某个网段的用户才能使用电子邮件系统。如果想允许所有人都能使用,则不用修改本参数。

为了演示方便,此处我们不修改,使其允许所有人都能使用。

(2)其他配置文件

将配置文件/etc/dovecot/conf.d/10-ssl.conf的ssl设置为no

[root@mail ~]# vim /etc/dovecot/conf.d/10-ssl.conf
...省略部分内容
ssl = no

这步如果不设置的话,客户端通过outlook无法接受邮件。我在这里踩了个大坑,希望大家注意。

2.3.3 配置邮件格式与存储路径

在子配置文件/etc/dovecot/conf.d/10-mail.conf 中,找到mail_location并把注释去掉即可

[root@mail ~]# vim /etc/dovecot/conf.d/10-mail.conf
mail_location = mbox:~/mail:INBOX=/var/mail/%u

修改后保存并退出。

切换到刚才建立的heima账号,并在其家目录中创建用于保存邮件的目录。

[root@mail ~]# su - heima
[heima@mail ~]$ mkdir -p mail/.imap/INBOX
[heima@mail ~]$ exit
logout
[root@mail ~]#

最后记得重启dovecot服务

[root@mail ~]# systemctl restart dovecot
[root@mail ~]# systemctl enable dovecot
ln -s '/usr/lib/systemd/system/dovecot.service' '/etc/systemd/system/multi-user.target.wants/dovecot.service'
[root@mail ~]#

至此基本的电子邮件系统就安装完毕,接下来进行测试收发电子邮件。

2.4 测试收发邮件

经过上边的操作,基本的电子邮件系统以及构建好了,如何验证该电子邮件系统是否可用呢?以下三种方法中根据个人喜好选取一种即可,为了保持完整性,分别进行了测试。

2.4.1 采用mail命令简单测试收发

用mial命令就可以实现收发邮件,不同用户登录到系统中用mail命令,就可以看到收发的邮件了。理论上不同用户登录系统只能看到自己的邮件,比如当前用户如果是root,那他只能看到别人发给他的邮件(一种特殊情况是可以设置邮件别名,这样就可以看到其他人的邮件),如果当前用户是heima,那也只能看到它自己的邮件。

用root用户分别给自己发邮件并查看

[root@mail ~]# echo "msg" | mail -s "first email to root" root@heimatengyun.com
[root@mail ~]# mail
... 省略部分内容
N 10 root Tue Feb 4 22:22 18/609 "first email to root"
& exit
You have mail in /var/spool/mail/root
[root@mail ~]#

root给heima发邮件并切换到heima账户查看邮件

[root@mail ~]# echo "msg" | mail -s "first email to heima" heima@heimatengyun.com
[root@mail ~]# su - heima
Last login: Tue Feb 4 15:43:52 CST 2020 on :1
ABRT has detected 1 problem(s). For more info run: abrt-cli list --since 1580802239
[heima@mail ~]$ mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/heima": 2 messages 1 new
1 Mail System Internal Tue Feb 04 20:15 13/562 "DON'T DELETE THIS MES"
>N 2 root Tue Feb 4 22:22 18/613 "first email to heima"
& exit
You have mail in /var/spool/mail/heima
[heima@mail ~]$ exit
logout
[root@mail ~]#

可以看到收件和发件都正常。

但是这样还不够,这是在Centos服务器内部,还需要客户端进行测试,以下outlook和foxmail任选其一即可

2.4.2 采用outlook测试

在win7上安装outlook2007来进行测试,先将win7的dns设置为centos的ip地址,即192.168.0.101

安装并配置outlook,过程如下:

(1)运行outlook

点击下一步按钮

(2)配置电子邮件,保持默认即可

点击下一步按钮

(3)选择电子邮件服务协议类型,保持默认即可

点击下一步按钮

(4)填写账户信息

姓名任意取,电子邮件为前边创建的系统用户heima加上发件域,即为:heima@heimatengyun.com,密码为heima账户的登录密码。

点击下一步按钮

(5)电子邮件服务登录验证

之前我们配置Dovecot为使用明文登录电子邮件服务,而Outlook软件默认会通过SSL加密协议尝试登录,因此会提示加密连接不可用。

再次点击“下一步”按钮。

顺利的话,就会出现这个配置成功的界面。实际可能你的操作过程中会遇到一些问题,此处如果账号密码有问题或者登陆远程邮件系统有问题都会弹出测试界面,如果遇到问题请严格按照前边的步骤进行检查。笔者此处就曾遇到只能发件不能收件的问题,原因是由于未开启ssl,需要在docovet中将其关闭。

添加成功后,就可以像自己以及向root用户发送邮件了。其操作步骤给发qq邮件是一直的,相信大家一定用过qq邮件,所以就不在多嘴了。

截图为证

2.4.3 采用foxmail测试

在win10上安装foxmail进行测试,同理先将win10dns设置为centos的ip地址。

foxmail官方地址:https://www.foxmail.com/

(1)安装foxmail

非常简单,直接根据向导即可。

(2)设置邮件账号

安装完成后,设置邮件账号,选择“其他邮箱”

输入账号密码

点击创建按钮,在界面中选择接收服务器类型为POP3

点击创建按钮

点击完成按钮,即可完成安装和设置。

设置成功后就可以正常收发邮件了。

截图为证

通过对比,个人感觉foxmail不如outlook稳定,并且收件较慢。

通过本文的演示,大家应该理解电子邮件系统的基本原理和流程,并可以在局域网搭建一个基本的电子邮件收发系统。

下一篇文章将演示apache服务搭建静态web网站。

linux入门系列17--邮件系统之Postfix和Dovecot的更多相关文章

  1. linux入门系列13--磁盘管理之RAID、LVM技术

    前一篇文章学习了磁盘分区.格式化.挂载等相关知识,本文将讲解RAID和LVM技术. 磁盘管理操作主要是运维人员用的较多,如果只是单纯的开发人员,可以先略过本文.但是在很多小公司里往往都是一人多用,运维 ...

  2. linux入门系列14--ssh服务及主机远程管理

    通过前面十余篇文章的介绍,相信已经初步入门Linux本地管理的基本方法了,后续的文章将介绍Linux中常用的服务部署以及如何为外部提供相应的服务. 系列文章第三篇"linux入门系列3--l ...

  3. linux入门系列16--文件共享之Samba和NFS

    前一篇文章"linux入门系列15--文件传输之vsftp服务"讲解了文件传输,本篇继续讲解文件共享相关知识. 文件共享在生活和工作中非常常见,比如同一团队中不同成员需要共同维护同 ...

  4. linux入门系列12--磁盘管理之分区、格式化与挂载

    前面系列文章讲解了VI编辑器.常用命令.防火墙及网络服务管理,本篇将讲解磁盘管理相关知识. 本文将会介绍大量的Linux命令,其中有一部分在"linux入门系列5--新手必会的linux命令 ...

  5. linux入门系列18--Web服务之Apache服务1

    前面系列文章讲解了Linux下通过文件传输.文件共享.邮件系统来分享和获取资源,本文讲解网络资源获取和共享的另外一种形式,通过Apache服务程序来提供Web服务. 本文先讲解目前主流的Web服务程序 ...

  6. linux入门系列20--Web服务之LNMP架构实战

    作为本入门系列最后一篇文章,将演示如何在CentOS7环境下搭建LNMP环境来构建个人博客网站. 常见搭建网站的方式有LAMP.LNMP.IIS.Nginx.Tomcat等等,本文演示比较流行的基于L ...

  7. linux入门系列2--CentOs图形界面操作及目录结构

    上一篇文章"linux入门系列1--环境准备及linux安装"直观演示了虚拟机软件VMware和Centos操作系统的安装,按照文章一步一步操作,一定都可以安装成功.装好系统之后, ...

  8. linux入门系列4--vi/vim编辑器

    上一篇文章"linux入门系列3--linux远程登陆工具"讲解了如何使用常用的工具远程连接和管理linux服务器,要管理服务器必然会涉及到脚本文件的创建.编辑工作,因此在介绍命令 ...

  9. linux入门系列5--新手必会的linux命令

    上一篇文章"linux入门系列4--vi/vim编辑器"我们讨论了在linux下如何快速高效对文本文件进行编辑和管理,本文将进一步学习必须掌握的linux命令,掌握这些命令才能让计 ...

随机推荐

  1. 迅为iTOP-3399开发板Ubuntu基本设置

    基于迅为iTOP3399开发板虚拟机需要根据用户的实际情况,进行网络设置以及其他一些基本的设置.VMware10.0.1 和 Vmware8.0.3 联网和基本设置类似.下面先详细讲解一下,虚拟机的一 ...

  2. day27-控制台输出彩色文字

    格式:\033[显示方式;前景色;背景色m 说明:显示方式           意义-------------------------  0             终端默认设置  1         ...

  3. Java 线程池(二)

    简介 在上篇 Java 线程池(一) 我们介绍了线程池中一些的重要参数和具体含义,这篇我们看一看在 Java 中是如何去实现线程池的,要想用好线程池,只知其然是远远不够的,我们需要深入实现源码去了解线 ...

  4. JVM 的内存布局

    这是jdk7以后的版本 1. Heap(堆区) Heap OOM 障最主要的发源地, 它存储着几乎所有的实例对象, 堆由垃圾收集器自动回收, 堆区由各子线程共享使用.通常情况下 它占用的空间是所有内存 ...

  5. vue项目中net::ERR_CONNECTION_TIMED_OUT错误

    我出错的原因时network地址与我本机ip地址不一致 Network: http://192.168.13.30:8080/ 处理方法: 在vue项目中新建一个vue.config.js文件 配置上 ...

  6. smarty应用1 之 模板进行数学运算,保留小数位数

    例子1 乘法除法运算: 1格式:{$number|number_format} 保留小数点后2位小数. {$v/$total*100|string_format:"%0.2f"|c ...

  7. GitHub之初始化

    1.github上新建repository. 2.本地 mkdir git-init-demo. 3.cd git-init-demo. 4.git clone https://github.com/ ...

  8. vue使用日记

    使用vue-cli生成单页应用框架, npm run serve之后即可开始修改src目录下面的js css文件(index.html可以保持不动), 自动热部署 , 前端框架就已经搭起来了. web ...

  9. Qt 延时处理的几种办法

    有些时候,我们需要程序延时一会儿: 这里提供四种方法: 1.多线程程序使用QThread::sleep()或者QThread::msleep()或QThread::usleep()或QThread:: ...

  10. Python:扫描目录下的所有文件

    扫描目录下的所有文件并返回文件的绝对路径 def fileListFunc(filePathList): fileList = [] for filePath in filePathList: for ...