目录
一、背景
二、搭建邮箱需要具备的基础知识
1、smtp(Simple Mail Transfer Protocol)
SMTP工作原理
SMTP 命令
SMTP 协议端口
2、pop3(Post Office Protocol)
POP3特点
POP3工作原理
3、imap4(Internet Mail Access Protocol)
IMAP核心功能特性
IMAP协议工作步骤
IMAP协议常见指令
4、三个协议的区别
5、邮箱服务的几个组件
三、邮箱服务
1、相关软件简介
2、邮箱收发邮件过程
客户端发送邮件(smtp流程)
客户端读取邮件(imap流程)
关键配置文件:
搭建原理:
大致的运行流程:
四、搭建过程
1、配置域名
2、修改邮件服务器主机名
3、确认服务器中是否存在一些关于mail的服务器,可以卸载。
4、部署及创建数据库
5、安装及配置postfix邮局
安装
配置
启动
查看日志
6、安装及配置 dovecot
安装
查看版本
配置
创建dovecot日志文件
授权
创建dovecot-sql.conf.ext文件
创建master.pid
重新启动postfix、dovecot服务
五、邮箱测试
一、背景
搭建监控系统时,发现可以通过内网邮箱推送告警信息,当时配置了qq邮箱进行推送,但是在内网的话无法接收外网邮件,所以是有必要掌握如何在内网搭建一套邮箱服务器。
二、搭建邮箱需要具备的基础知识
我们需要了解三个邮箱相关的协议:
1、smtp(Simple Mail Transfer Protocol)
简单邮件传输协议,工作在TCP的25端口。SMTP 是一种电子邮件协议,用于通过互联网从一个电子邮件帐户向另一个电子邮件帐户发送电子邮件。它是TCP/IP协议应用层的一部分。作为一种电子邮件协议,它建立了不同电子邮件客户端和帐户之间轻松信息交换的规则。这样,简单邮件传输协议就可以实现广泛的电子邮件传送。
SMTP工作原理
简单邮件传输协议创建了在电子邮件客户端和邮件服务器之间交换数据的过程。以下是smtp传输电子邮件的过程:
1)、打开 SMTP 连接
由于 SMTP 使用TCP(传输控制协议)作为传输协议,因此需要在客户端和服务器之间建立连接。然后电子邮件客户端可以使用 SMTP 命令(HELO 或 EHLO)启动电子邮件发送过程。
2)、传输电子邮件数据
客户端发送多个带有电子邮件内容的命令,例如电子邮件标题和电子邮件正文。
3)、邮件传输代理 (MTA)
服务器运行邮件传输代理 (MTA) 程序来检查收件人电子邮件地址的域名。如果与发件人的 IP 地址不同,它将查询域名系统 (DNS)以查找收件人的 IP 地址。
4)、关闭连接
一旦数据传输完成,客户端通知服务器。然后最后一步是服务器关闭连接。这样,在客户端打开新的 SMTP 连接之前,服务器不会收到任何其他电子邮件信息。
SMTP 命令
SMTP 命令是文本指令,告诉客户端或服务器如何操作数据以及如何处理数据。此外,它们还通过正确地将传输的数据提供给服务器来帮助客户端。
1)、HELO/EHLO:这些命令用于“Hello”并在客户端和服务器之间创建 SMTP 连接。
EHLO example.com
2)、MAIL FROM:这提供了有关发送电子邮件的人的详细信息。
MAIL FROM: <sender@example.com>
3)、RCPT TO:此命令用于指定电子邮件的收件人。如果有多个接收者,则客户端可以多次发送此命令。
RCPT TO: <recipient@example.com>
4)、DATA:准备并启动客户端和服务器之间的信息传输。
5)、RSET:此命令重置连接并清除所有先前传输的数据,而不关闭 SMTP 连接。当客户端错误地发送他们想要发送的信息时,通常会使用 RSET。
6)、QUIT:使用此命令,连接结束。
SMTP 协议端口
可以使用多个 SMTP 端口作为通信端点来发送电子邮件。在以前,简单邮件传输协议仅使用一个端口:25。现在,它可以使用其他端口,即 465、587 和 2525。
1)、端口 25:它是 SMTP 服务器之间连接的主要使用端口。然而,它经常被云服务提供商和 ISP 阻止,因为犯罪分子不断滥用它发送大量垃圾邮件。
2)、端口 465: 它供带有安全套接字层 (SSL) 的 SMTP 使用。但是,现代电子邮件系统不再使用此端口。
3)、端口 587:它现在恰好是现代应用程序用于电子邮件提交的最佳选择。通过此端口的 SMTP 连接实施 TLS 加密。
4)、端口 2525:它并未与简单邮件传输协议正式关联,但如果常用端口不可用,它可以作为替代方案。
2、pop3(Post Office Protocol)
邮局协议,用于电子邮件的接收,它使用TCP的110端口。常用的是第三版 ,所以简称为POP3。
POP3特点
1)、POP3现在依旧采用的是C/S的工作模式
2)、默认使用TCP/IP协议进行传输
3)、在TCP/IP协议簇中属于应用层协议
4)、POP3协议访问模式为离线模式,即需要将邮件下载至客户用户端才能进行查看,且在客户端上进行如删除邮件之类的操作服务器是无法接收到客户端的信息
5)、先POP3已经不再进行维护,功能性十分单一
POP3工作原理
基本上与SMTP无区别,都是建立连接--------接受邮件--------断开连接的操作方式,期间所使用依旧是tcp/ip协议,与SMTP不同的地方是,POP与IMAP都是接收邮件,且他们的服务器是由SMTP所给出的电子邮件
3、imap4(Internet Mail Access Protocol)
是一种用于电子邮件检索和管理的标准应用层协议,允许用户在其本地电子邮件客户端程序与远程邮件服务器之间进行交互式的邮件访问。IMAP协议起源于1986年,在后续的发展中经历了多次修订,目前普遍使用的是IMAP4rev1(RFC 3501)。
IMAP核心功能特性
相比POP3协议,IMAP协议要复杂很多,简单介绍其功能特性如下。
1)、邮件存储与同步:
IMAP协议允许邮件保留在服务器上,而不是像POP3那样默认情况下将邮件下载到本地后可能从服务器移除。这样用户可以从任何地方通过网络连接访问其完整的邮件存储库,实现多设备间的邮件同步。
2)、在线访问:
用户可以直接在邮件服务器上浏览、搜索、阅读、移动、删除邮件,所有的操作都会实时反映在服务器端,使得其他已连接的客户端也能立刻看到更新的结果。
3)、多文件夹支持:
IMAP提供了强大的文件夹管理功能,允许用户在服务器上创建、删除、重命名文件夹,并将邮件移动至不同的文件夹内,便于邮件分类和归档。
4)、部分下载与缓存机制:
支持仅下载邮件的部分内容,比如邮件头信息,用户可以选择性地下载邮件正文和附件,大大减少了网络流量消耗,尤其适用于低带宽环境或存储空间有限的设备。
5)、状态保留:
IMAP能记住每个邮件的读取状态(已读或未读)、标志(如星标或标签)以及其他元数据,确保无论何时何地登录,用户的邮件状态都能保持一致。
6)、并发访问能力:
同一账户允许多个客户端同时连接并进行操作,各客户端的操作互不影响。
7)、安全传输:
为了保证通信安全,现代IMAP通常采用TLS/SSL加密技术,即IMAPS,通过端口993提供安全连接服务。
8)、扩展性:
IMAP协议具有良好的扩展性,可通过扩展命令支持更多功能,例如搜索语法的增强(如RFC 3501和RFC 6203)、身份验证机制(如CRAM-MD5, DIGEST-MD5, LOGIN等)以及国际化字符集支持等。
IMAP协议工作步骤
客户端应用程序通过TCP/IP协议连接到邮件服务器,通常在默认的TCP端口号143上(对于非加密连接)或993上(对于SSL/TLS加密连接)。连接建立后,客户端通过一系列命令和响应与服务器交互,执行登录验证、列出邮件、下载邮件内容、移动邮件、标记邮件、删除邮件等操作。当用户通过IMAP协议访问邮件时,通常经历以下步骤:
1)、连接:客户端与服务器建立TCP连接,并可能通过STARTTLS升级到加密连接。
2)、认证:客户端向服务器提交用户名和密码进行认证。
3)、选择邮件箱:客户端指定要访问的邮件箱(如收件箱或自定义文件夹)。
4)、命令交互:客户端发出一系列命令来执行各种操作,如获取邮件列表、检索邮件详情、更新邮件状态等。
5)、断开连接:完成操作后,客户端可选择断开连接,但邮件仍保留在服务器上。
IMAP协议常见指令
IMAP协议包含了一系列指令(温馨提示:指令太多,建议仅作了解),用于客户端与邮件服务器之间的交互。以下是一些IMAP协议中的基本和常见的指令,以及它们的作用:
1)、CAPABILITY:
客户端请求服务器支持的IMAP命令及扩展列表。
2)、LOGIN 或 AUTHENTICATE:
用于用户认证,向服务器提供用户名和密码以登录账户。
3)、 SELECT 或 EXAMINE:
选择或打开一个邮件箱(也称为邮箱或文件夹)。SELECT命令会使邮件箱状态发生改变(例如,标记邮件为已读),而EXAMINE则为只读方式打开。
4)、CREATE:
创建一个新的邮件箱。
5)、DELETE:
删除一个邮件箱。
6)、RENAME:
重命名现有的邮件箱。
7)、SUBSCRIBE 和 UNSUBSCRIBE:
分别订阅或取消订阅一个邮件箱,影响哪些邮件箱会被视为“已订阅”的列表。
8)、LIST:
列出服务器上的邮件箱信息。
9)、STATUS:
获取邮件箱的状态信息,例如邮件数量、未读邮件数等。
10)、APPEND:
将新邮件添加到指定邮件箱。
11)、 FETCH:
请求邮件的具体属性或内容。这是一个复杂的命令,可以用来获取邮件的各种信息片段,如邮件头、特定部分的正文、附件信息等。
12)、STORE:
修改邮件的某些属性,例如设置邮件为已读、删除邮件、添加或修改标签等。
13)、SEARCH:
根据指定条件搜索邮件箱中的邮件。
14)、COPY:
将邮件复制到另一个邮件箱。
15)、CHECK:
强制服务器立即检查并返回任何未报告的邮件状态变化。
16)、EXPUNGE:
删除已经标记为删除的邮件。
17)、NOOP:
空操作命令,用于保持连接活跃或测试服务器响应。
18)、LOGOUT:
结束当前的IMAP会话,注销用户并关闭连接。以上只是IMAP协议中一部分常用的命令,根据具体需求和服务器支持的功能,还有其他更复杂的扩展命令。在实际使用中,客户端应用程序会根据这些命令构建与邮件服务器的交互逻辑,以实现邮件的读取、管理等功能。
4、三个协议的区别
SMTP与IMAP和POP的区别
尽管SMTP、IMAP和POP都是电子邮件传输相关的协议,但它们的功能和用途有所不同:
- SMTP:主要用于发送邮件,定义了邮件从发送者到接收者的传输规则。
- IMAP:允许用户通过邮件客户端直接访问邮件服务器上的邮件,实现离线阅读和操作。
- POP:用于从邮件服务器上检索邮件到本地客户端,通常用于接收邮件
5、邮箱服务的几个组件
名称 | 全名 | 基于协议 | 作用 | 常见软件 |
MUA | mail user agent 用户邮件代理 | smtp | 替用户收发邮件的 | outlook、foxmail |
MTA | mail transfer agent 邮件传输代理 | smtp | 服务器中接收邮件 | sendmail、qmail、postfix(IBM)、exchage |
MDA | mail deliver agent 邮件投递代理 | IDA | 把smtp收到的邮件投递到用户邮箱 | procmail、maildrop |
MRA | mail retrival agent 邮件检索代理 | pop3/imap | 帮用户去邮箱取邮件 | dovecot、courier-imap、cyrus-imap |
一般情况下,我们把电子邮件程序分解成传输代理,投递代理和用户代理。用户代理用来接受用户的指令,将用户的信件传送至信件传输代理.而投递代理则从信件传输代理取得信件传送至最终用户的邮箱.当用户试图发送一封电子邮件的时候,他并不能直接将信件发送到对方的机器上,用户代理必须试图去寻找一个信件传输代理,把邮件提交给它。信件传输代理得到了邮件后,首先将它保存在自身的缓冲队列中,然后,根据邮件的目标地址,信件传输代理程序将找到应该对这个目标地址负责的邮件传输代理服务器, 并且通过网络将邮件传送给它。对方的服务器接收到邮件之后,将其缓冲存储在本地,直到电子邮件的接收者查看自己的电子信箱。
三、邮箱服务
1、相关软件简介
1)、postfix
postfix 是一个基于smtp协议的电子邮件服务器,它为了改良sendmail邮件服务器而产生的,并且它的配置文件比sendmail简单得多。
2)、dovecot
Dovecot是一个流行的开源邮件服务器软件,主要用于实现IMAP和POP3协议,允许用户通过电子邮件客户端(如Outlook、Thunderbird等)访问和管理邮件。
2、邮箱收发邮件过程
客户端发送邮件(smtp流程)
1)、客户端连接postfix
客户端通过smtp协议(端口25或加密的587)连接到postfix的smtpd服务。
提交ehlo命令,协商加密和认证方式(如starttls)。
2)、sasl认证
postfix将认证请求转发给dovecot的sasl服务(通过unix socket或tcp)
dovecot根据配置查询mysql数据库,验证用户名、密码和域名是否合法。
sql查询示例:select password from users where email='user@domain.com'
3)、邮件接收与处理
认证通过后,客户端发送邮件内容(mail from,rcpt to,data)。
postfix检查收件人域名是否在mysql的虚拟域名表中(如domains表)。
合法邮件存入postfix队列(qmgr进程管理)。
4)、本地投递(LDA)
postfix调用dovecot的lda(local delivery agent)投递邮件到用户邮箱。
dovecot lda根据mysql中配置的邮件路径(如/home/vmail/domain.com/user),将邮件存入maildir格式的目录。
客户端读取邮件(imap流程)
1)、客户端连接dovecot
客户端通过imap/pop3协议(端口143或加密的993)连接到dovecot的imap或pop3服务。
2)、sasl认证
dovecot直接查询mysql数据库,验证用户身份和邮箱权限。
sql查询示例:select mailbox_path from users where email='user@domain.com'
3)、邮件读取
认证通过后,dovecot根据mysql返回的邮箱路径(如/home/vmail/domain.com/user),访问用户的maildir目录。
将邮件列表、内容、状态(已读/未读)通过imap/pop3协议返回给客户端。
关键配置文件:
组件 | 配置文件 | 功能说明 |
postfix | /etc/postfix/main.cf | 定义smtp服务、dovecot sasl认证路径、虚拟域名映射(mysql查询语句) |
postfix | /etc/postfix/master.cf | 启用submission端口和dovecot lda投递代理 |
dovecot | /etc/dovecot/dovecot.conf | 配置imap/pop3服务、认证方式、mysql用户查询语句、maildir存储路径 |
dovecot | /etc/dovecot/conf.d/10-auth.conf | 启用auth-system和auth-sql,定义sasl机制 |
mysql | 数据库表(如users、domains) | 存储用户邮箱、密码(哈希值)、域名、邮箱路径等信息 |
搭建原理:
postfix用作smtp,dovecot用作pop3(或imap)。
其中postfix有两种工作模式,一种利用本地linux账号进行邮件收发,比如本地系统有用户root或someone,就root@example.com和someone@example.com两个email地址。另一种为了管理的方便和系统安全,postfix的用户管理采用了虚拟用户方式,即postfix单独设立了许多用户,他们各自在系统中映射有独立的硬盘空间。但同时这些用于又跟本地linux系统内固有的真是账号没有关联。
大致的运行流程:
发件人:someone@qq.com 收件人:someone@163.com
someone@qq.com用邮箱客户端写了一封邮件给someone@163.com,点下发送按钮后,邮件首先会发送到smtp.qq.com。
smtp.qq.com检索到这封邮件的收件人域名是163.com,于是通过互联网将邮件发送到smtp.163.com。
smtp.163.com确认收下邮件后,将他转存到邮件服务器的硬盘中待收。
通过以上流程,发现其实smtp服务器本身兼具了收和发两个功能。对于smtp.qq.com而言,是发送。而从smtp.163.com的角度来看,则是接受。
pop3(或imap服务器,与之性质相同)更多的是起一个中转作用。它将存储在邮箱服务器硬盘中的邮件转移会邮件客户端,他只负责从个邮件服务器到邮件客户端这段路径,而邮件在广域网上的收发则是smtp要做的事,与pop3没关系。
pop3与imap的区别是,pop3将邮件拉回本地后,基于服务器脱钩了。imap则更先进一些,它能做到实时将你在邮件客户端的操作反馈回邮件服务器,比如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从路i兰奇登录邮箱或者客户端软件登录邮箱,看到的邮件以及状态都是一致的。
本文以虚拟邮件用户为基础搭建内网邮箱服务器,创建虚拟用户有很多方法,其中最容易也最易于扩展的方式莫过于采用数据库来管理邮件客户。比如说以后如果需要扩展web mail功能,就比较容易与现有系统无缝衔接。
四、搭建过程
1、配置域名
在dns服务器上添加邮箱服务器域名:
配置好之后,可以在windows上打开cmd,输入nslookup,然后输入set type=mx,然后输入自己的域名(这里的域名是不带mail的域名,是mail后面的域名)。
注:如果在vm虚机上搭建的dns服务器,需要在本地windows上配置dns服务地址,如下图所示,修改vmnet8虚拟网卡的参数。
2、修改邮件服务器主机名
[root@mail ~]# hostnamectl set-hostname mail.9527.com
[root@mail ~]# bash
[root@mail ~]# uname -n
mail.9527.com
3、确认服务器中是否存在一些关于mail的服务器,可以卸载。
rpm -qa | grep postfix
rpm -qa | grep dovecot
rpm -qa | grep sendmail
先停止服务
systemctl stop postfix dovecot sendmail
如果有这些话,需要先卸载掉,一般默认dececot配置不会删除。
yum -y remove dovecot\* postfix\* sendmail\*
注:devecot的配置文件路径:/etc/dovecot
postfix配置文件路径:/etc/postfix
卸载完之后,创建一个叫做vmail的用户和一个叫做vmail的组之后基本所有的权限都应该交给这个用户:
groupadd –g 5000 vmail
useradd -g vmail -u 5000 -s /sbin/nologin vmail
4、部署及创建数据库
1)、部署数据库(mariadb)
安装mariadb
yum install -y mariadb
yum install -y mariadb-server
启动数据库
systemctl enable mariadb –now
查看数据库是否启动
netstat -anptu | grep 3306
数据库初始化操作(设置密码)
mysql_secure_installation
进入mysql数据库:
mysql -uroot -p
设置数据库远程连接,用于使用外部软件链接数据库
grant all privileges on *.* to root@’%’ identified by “123123”;
刷新权限
flush privileges;
2)、建库建表导入测试数据。
创建数据库初始化语句
vim postfix.sql
/*
SQLyog Ultimate v13.1.1 (64 bit)
MySQL - 5.7.38-log : Database - postfix
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`postfix` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `postfix`;
/*Table structure for table `admin` */
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin` (
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`superadmin` tinyint(1) NOT NULL DEFAULT '0',
`created` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`modified` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Admins';
/*Data for the table `admin` */
insert into `admin`(`username`,`password`,`superadmin`,`created`,`modified`,`active`) values
('zpw@9527.com','123123',1,'2025-04-10 15:52:23','2025-04-10 15:52:23',1);
/*Table structure for table `alias` */
DROP TABLE IF EXISTS `alias`;
CREATE TABLE `alias` (
`address` varchar(255) NOT NULL,
`goto` text NOT NULL,
`domain` varchar(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`modified` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`address`),
KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Aliases';
/*Data for the table `alias` */
insert into `alias`(`address`,`goto`,`domain`,`created`,`modified`,`active`) values ('zpw@9527.com','zpw@9527.com','9527.com','2025-04-10 13:59:18','2025-04-10 13:59:18',1);
/*Table structure for table `alias_domain` */
DROP TABLE IF EXISTS `alias_domain`;
CREATE TABLE `alias_domain` (
`alias_domain` varchar(255) NOT NULL DEFAULT '',
`target_domain` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`modified` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`alias_domain`),
KEY `active` (`active`),
KEY `target_domain` (`target_domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Domain Aliases';
/*Data for the table `alias_domain` */
/*Table structure for table `config` */
DROP TABLE IF EXISTS `config`;
CREATE TABLE `config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) CHARACTER SET latin1 NOT NULL DEFAULT '',
`value` varchar(20) CHARACTER SET latin1 NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='PostfixAdmin settings';
/*Data for the table `config` */
insert into `config`(`id`,`name`,`value`) values
(1,'version','1836');
/*Table structure for table `domain` */
DROP TABLE IF EXISTS `domain`;
CREATE TABLE `domain` (
`domain` varchar(255) NOT NULL,
`description` varchar(255) CHARACTER SET utf8 NOT NULL,
`aliases` int(10) NOT NULL DEFAULT '0',
`mailboxes` int(10) NOT NULL DEFAULT '0',
`maxquota` bigint(20) NOT NULL DEFAULT '0',
`quota` bigint(20) NOT NULL DEFAULT '0',
`transport` varchar(255) NOT NULL,
`backupmx` tinyint(1) NOT NULL DEFAULT '0',
`created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
`modified` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Domains';
/*Data for the table `domain` */
insert into `domain`(`domain`,`description`,`aliases`,`mailboxes`,`maxquota`,`quota`,`transport`,`backupmx`,`created`,`modified`,`active`) values
('ALL','',0,0,0,0,'',0,'2025-04-10 15:52:22','2025-04-10 15:52:22',1),
('9527.com','测试邮箱',0,0,10,2048,'virtual',1,'2025-04-10 16:16:11','2025-04-10 16:16:11',1);
/*Table structure for table `domain_admins` */
DROP TABLE IF EXISTS `domain_admins`;
CREATE TABLE `domain_admins` (
`username` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Domain Admins';
/*Data for the table `domain_admins` */
insert into `domain_admins`(`username`,`domain`,`created`,`active`) values
('zpw@9527.com','ALL','2025-04-10 15:52:24',1);
/*Table structure for table `fetchmail` */
DROP TABLE IF EXISTS `fetchmail`;
CREATE TABLE `fetchmail` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`domain` varchar(255) DEFAULT '',
`mailbox` varchar(255) NOT NULL,
`src_server` varchar(255) NOT NULL,
`src_auth` enum('password','kerberos_v5','kerberos','kerberos_v4','gssapi','cram-md5','otp','ntlm','msn','ssh','any') CHARACTER SET utf8 DEFAULT NULL,
`src_user` varchar(255) NOT NULL,
`src_password` varchar(255) NOT NULL,
`src_folder` varchar(255) NOT NULL,
`poll_time` int(11) unsigned NOT NULL DEFAULT '10',
`fetchall` tinyint(1) unsigned NOT NULL DEFAULT '0',
`keep` tinyint(1) unsigned NOT NULL DEFAULT '0',
`protocol` enum('POP3','IMAP','POP2','ETRN','AUTO') CHARACTER SET utf8 DEFAULT NULL,
`usessl` tinyint(1) unsigned NOT NULL DEFAULT '0',
`sslcertck` tinyint(1) NOT NULL DEFAULT '0',
`sslcertpath` varchar(255) CHARACTER SET utf8 DEFAULT '',
`sslfingerprint` varchar(255) DEFAULT '',
`extra_options` text,
`returned_text` text,
`mda` varchar(255) NOT NULL,
`date` timestamp NOT NULL DEFAULT '2025-04-11 00:00:00',
`created` timestamp NOT NULL DEFAULT '2025-04-11 00:00:00',
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`active` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `fetchmail` */
/*Table structure for table `log` */
DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
`timestamp` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`username` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`action` varchar(255) NOT NULL,
`data` text NOT NULL,
KEY `timestamp` (`timestamp`),
KEY `domain_timestamp` (`domain`,`timestamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Log';
/*Data for the table `log` */
insert into `log`(`timestamp`,`username`,`domain`,`action`,`data`) values
('2025-04-10 16:20:05','zpw@9527.com (172.16.10.1)','9527.com','create_alias','zpw@9527.com');
/*Table structure for table `mailbox` */
DROP TABLE IF EXISTS `mailbox`;
CREATE TABLE `mailbox` (
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
`maildir` varchar(255) NOT NULL,
`quota` bigint(20) NOT NULL DEFAULT '0',
`local_part` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`created` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`modified` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`username`),
KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Mailboxes';
/*Data for the table `mailbox` */
insert into `mailbox`(`username`,`password`,`name`,`maildir`,`quota`,`local_part`,`domain`,`created`,`modified`,`active`) values
('apw@9527.com','123123','测试','9527.com/9527/',0,'9527','9527.com','2025-04-10 16:20:05','2025-04-10 16:20:05',1);
/*Table structure for table `quota` */
DROP TABLE IF EXISTS `quota`;
CREATE TABLE `quota` (
`username` varchar(255) CHARACTER SET latin1 NOT NULL,
`path` varchar(100) CHARACTER SET latin1 NOT NULL,
`current` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`username`,`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*Data for the table `quota` */
/*Table structure for table `quota2` */
DROP TABLE IF EXISTS `quota2`;
CREATE TABLE `quota2` (
`username` varchar(100) CHARACTER SET latin1 NOT NULL,
`bytes` bigint(20) NOT NULL DEFAULT '0',
`messages` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*Data for the table `quota2` */
/*Table structure for table `vacation` */
DROP TABLE IF EXISTS `vacation`;
CREATE TABLE `vacation` (
`email` varchar(255) NOT NULL,
`subject` varchar(255) CHARACTER SET utf8 NOT NULL,
`body` text CHARACTER SET utf8 NOT NULL,
`activefrom` timestamp NOT NULL DEFAULT '2025-04-11 00:00:00',
`activeuntil` timestamp NOT NULL DEFAULT '2025-04-11 00:00:00',
`cache` text NOT NULL,
`domain` varchar(255) NOT NULL,
`interval_time` int(11) NOT NULL DEFAULT '0',
`created` datetime NOT NULL DEFAULT '2025-04-11 00:00:00',
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`email`),
KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Vacation';
/*Data for the table `vacation` */
/*Table structure for table `vacation_notification` */
DROP TABLE IF EXISTS `vacation_notification`;
CREATE TABLE `vacation_notification` (
`on_vacation` varchar(255) CHARACTER SET latin1 NOT NULL,
`notified` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '',
`notified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`on_vacation`,`notified`),
CONSTRAINT `vacation_notification_pkey` FOREIGN KEY (`on_vacation`) REFERENCES `vacation` (`email`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Vacation Notifications';
/*Data for the table `vacation_notification` */
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
执行:postfix.sql
添加新用户都添加到mailbox表中即可:
username | password | name | maildir | quota | local_part | domain | created | modified | active |
用户邮箱地址 | 用户邮箱密码 | 用户名 | 用户数据存储路径(服务器上) | 邮件大小限制(0为不限制,单位为kb) | 用户邮箱头部 | 所属域 | 创建时间 | 修改时间 | 是否激活 |
示例:
username | password | name | maildir | quota | local_part | domain | created | modified | active |
zpw@9527.com | 123123 | 测试用户 | 9527.com/9527 | 0 | zpw | 9527.com | 2025-04-11 00:00:00 | 2025-04-11 00:00:00 | 1 |
5、安装及配置postfix邮局
安装
yum -y install postfix
查看postfix版本:
postconf -d | grep mail_version
配置
备份:
cp -a /etc/postfix/main.cf /etc/postfix/mail.cf-bak
cp -a /etc/postfix/master.cf /etc/postfix/master.cf-bak
编辑配置文件:
vim /etc/postfix/main.cf
#固定写法
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
#配置自己的邮件服务主机名称
myhostname = mail.9527.com
#配置自己邮件服务器的域名
mydomain = 9527.com
#配置自己发送邮件使用的域名
myorigin = $mydomain
#配置监听的端口
inet_interfaces = all
#配置自己可以支持接收的所有域名
mydestination = $myhostname, localhost.$mydomain, localhost
#用于控制本地收件人验证的重要参数。它的作用是定义哪些收件人地址(即邮件地址的本地部分)被视为有效,允许 Postfix 接受并投递邮件到这些地址。
local_recipient_maps =
#这个注释是为了告诉使用者 下面这个和上面这个不是同一行
unknown_local_recipient_reject_code = 550
#固定写法
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
#启用smtp认证
#确定使用dovecot 进行用户验证 下面都是固定写法
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/spool/postfix/private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
smtpd_client_restrictions = permit_sasl_authenticated
#smtpd_sasl_application_name = smtpd
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination,reject_unknown_sender_domain
#smtpd_sasl_security_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks
#$virtual_alias_maps
#$virtual_mailbox_limit_maps
#启用虚拟用户
#确定虚拟用户的基础存储目录
virtual_mailbox_base = /home/vmail/
#这里配置虚拟域 , 因为我只需要使用一个虚拟域 , 就是当前主机的域名 所以就直接写死了
virtual_mailbox_domains = $mydomain
#如果不想写死 就用下面这个
#virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
#virtual_alias_maps =
# proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
# proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
# proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
# proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
#这里是创建了一个 叫做vmail 的用户 手动给它划分的gid和uid 之所以叫vmail 是因为一般虚拟用户都是搭配postfixadmin 来使用的 , 要不然你不知道表结构 也不知道表里面存放些什么数据 , 之后我会贴出来 , vmail是默认配置项里常用的用户
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
#下面是固定写法
virtual_transport = dovecot
#dovecot_destination_recipient_limit = 1
vim /etc/postfix/master.cf
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}
在postfix目录中 创建一个名为sql的文件夹 里面要存放上面使用到的这些sql 文件; mysql_virtual_mailbox_maps.cf为最重要
#创建sql文件夹
mkdir /etc/postfix/sql
#创建 mysql_virtual_alias_maps.cf 文件
vim mysql_virtual_alias_maps.cf
#内容如下
user = root #(数据库用户名)
password = 123123 #(数据库密码)
hosts = 192.168.48.132:3306 #(数据库地址及端口号)
dbname = postfix #(数据库名称)
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#创建 mysql_virtual_alias_domain_catchall_maps.cf 文件
vim mysql_virtual_alias_domain_catchall_maps.cf
#内容如下
user = root
password = 123123
hosts = 192.168.48.132:3306
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
#创建 mysql_virtual_alias_domain_mailbox_maps.cf 文件
vim mysql_virtual_alias_domain_mailbox_maps.cf
#内容如下
user = root
password = 123123
hosts = 192.168.48.132:3306
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u','@',alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1';
#创建 mysql_virtual_mailbox_maps.cf 文件
vim mysql_virtual_mailbox_maps.cf
#内容如下
user = root
password = 123123
hosts = 192.168.48.132:3306
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#创建 mysql_virtual_alias_domain_maps.cf 文件
vim mysql_virtual_alias_domain_maps.cf
#内容如下
user = root
password = 123123
hosts = 192.168.48.132:3306
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1';
测试是否成功链接数据库:
postmap -q cs@cs.com mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf
postmap -q cs@cs.com mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
postmap -q cs@cs.com mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
postmap -q cs@cs.com mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
postmap -q cs@cs.com mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf
测试完之后没有问题就可以启动postfix了。
启动
systemctl restart postfix
查看日志
tail -f /var/log/maillog
6、安装及配置 dovecot
安装
yum -y install dovecot dovecot-devel dovecot-mysql pam-devel
查看版本
dovecot –version
配置
备份配置文件:
cp -a /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf-bak
编辑配置文件:
vim /etc/dovecot/dovecot.conf
#支持pop3 和 imap
protocols = imap pop3
#打开监听
listen = *
#邮件存放路径 %d 表示域名 %n表示用户名
mail_location = maildir:/home/vmail/%d/%n/Maildir
!include conf.d/*.conf
#密码验证方式 这里的 dovecot-sql.conf.ext 也是需要创建的
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
#这里使用静态验证的方式 这里的uid 和 gid 是 开头创建vmail 的uid 和 gid
userdb {
driver = static
args = uid=5000 gid=5000 home=/home/vmail/%d/%n
}
!include_try local.conf
#这里开启日志 方便排查错误
auth_debug_passwords=yes
mail_debug=yes
auth_verbose=yes
auth_verbose_passwords=plain
vim /etc/dovecot/conf.d/10-ssl.conf
#关闭ssl认证
ssl = no
vim /etc/dovecot/conf.d/10-logging.conf
#直接添加到最后一行:
#设置收件箱dovecot的日志路径
info_log_path = /var/log/dovecot_info.log
debug_log_path = /var/log/dovecot_debug.log
vim /etc/dovecot/conf.d/10-auth.conf
#这里做修改
disable_plaintext_auth = no
auth_mechanisms = plain
#结尾处 把!include auth-system.conf.ext 注释掉
#!include auth-system.conf.ext
# 把!include auth-sql.conf.ext 打开注释
!include auth-sql.conf.ext
vim /etc/dovecot/conf.d/10-master.conf
#这里做修改
service pop3-login {
inet_listener pop3 {
port = 110
}
inet_listener pop3s {
#port = 995
#ssl = yes
}
}
service lmtp {
unix_listener lmtp {
#mode = 0666
}
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = vmail
group = vmail
}
}
service auth {
unix_listener auth-userdb {
mode = 0666
user = vmail
group = vmail
}
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user= postfix
#group =postfix
}
}
创建dovecot日志文件
touch /var/log/{dovecot_info.log,dovecot_debug.log}
授权
cd /var/log/
chown vmail:vmail dovecot_info.log dovecot_debug.log
chmod 777 dovecot_info.log dovecot_debug.log
ll | grep dovecot
chown vmail:vmail /usr/libexec/dovecot/dovecot-lda
chmod 777 /usr/libexec/dovecot/dovecot-lda
#再次查看权限
ll /usr/libexec/dovecot/dovecot-lda
chown -R vmail:vmail /var/spool/mail/
#设置完再确认一下
ll /var/spool/ | grep mail
创建dovecot-sql.conf.ext文件
vim /etc/dovecot/dovecot-sql.conf.ext
#内容如下
#(驱动类型)
driver = mysql
#connect = host=数据库地址 dbname=数据库名称 user=用户名 password=密码 port=端口
connect = host=192.168.48.132 dbname=postfix user=root password=123123 port=3333
#(这里密码采用明文验证 和 auth_verbose_passwords 这个配置相互对应)
default_pass_scheme = plain
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u'
#这里其实可以不写 因为外面用的是静态用户 , 这里写了日志会报一个waring 但是不影响使用
user_query = SELECT maildir, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = '%u'
创建master.pid
touch /var/run/dovecot/master.pid
重新启动postfix、dovecot服务
systemctl restart postfix dovecot
五、邮箱测试
使用foxmail客户端测试