转载:原文链接

前言

关于邮件服务器的工作原理我就不再赘述了。Postfix是优秀的MTA,而Dovecot则是优秀的MDA。前者负责发信、收信,提供smtp服务;后者负责邮件保存到邮箱,提供pop3和imap服务。

这里介绍使用Postfix+Dovecot模式的邮件服务系统,同时Postfix使用Dovecot提供的SASL完成用户认证。用户使用MySQL存储的虚拟用户,而不是服务器的实际用户。同时使用opendkim完成邮件的dkim签名,SpamAssassin完成反垃圾邮件。也会阐述如何为smtp、pop3和imap配置SSL。

准备一台服务器

  1. 需要一台服务器,尽量使用有公网ip的服务器而不是使用内网穿透(否则发邮件的时候对方发现ip是非静态ip可能会当作垃圾邮件)。

  2. 要保证服务器的25端口开放。我选择了腾讯云的服务器,1核1G,申请开放了25端口(腾讯云申请比阿里云容易)。

  3. 主机名设置为你的域名或者mx.xxxx.com这样的子域名。

  4. 修改主机的时区,设为北京时间。

准备一个域名

准备一个域名,最好已经申请超过28天(否则容易被当作垃圾邮件)。

  1. 添加一个A记录(例如mx.xxxx.com)指向服务器的ip,添加一个mx记录(主机记录为@)指向上述添加的A记录(优先级可设定为5,具体作用可自行百度)。

  2. 可以为smtp、pop3和imap分别添加一些记录(例如smtp.xxxx.com),指向你的服务器(你也可以不这么做,这个看个人喜好,在登录邮箱的时候需要输入smtp服务器的地址,你可以输入ip也可以输入你现在设定的域名,如果要做SSL则最好是设定域名。你也可以smtp,pop3和imap都是用mx.xxxx.com这个域名)。

  3. 添加一个txt记录作为SPF记录(主机记录为@),内容可以写v=spf1 mx ~all。这表示当对方收到一封来自你这个域名的邮件时,先检查发件方对方的ip是否为mx记录中定义的ip(或A记录对应的ip),如果不是则标记为软拒绝。具体可以自行查询SPF记录的语法。如果你发邮件的机器没有公网ip,也就是你是通过本地机器内网穿透实现的邮件服务,那么SPF则写为v=spf1 +all表示接受所有的ip。

  4. 添加一个txt记录为DMARC记录(主机记录为_dmarc),内容可以写v=DMARC1; p=reject; fo=1; rua=mailto:你的邮箱。表示当出现仿造的邮件时,对方reject邮件,并通知你的邮箱。具体可以百度DMARC的语法。

申请SSL证书

如果不想使用SSL也可以跳过这一步骤。

  1. 申请一个SSL证书,包括上面步骤所创建的所有A记录(例如mx.xxxx.comsmtp.xxxx.com)。可以使用acme.sh在Let's或者ZeroSSL申请证书,我是在后者申请的。

  2. 证书的fullchain文件放到服务器的/etc/ssl/certs/xxxx.com.pem下。

  3. 证书的密钥文件放到服务器的/etc/ssl/private/xxxx.com.key下。

  4. 上述二者权限设置为400,属主设置为root:root

配置postfix和dovecot

  1. 安装postfix和dovecot
apt update
apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
  1. 安装配置MySQL,新建数据库mailserver(名字可以根据喜好来,下同),并创建用户mail,注意分配权限。

  2. 创建数据表:

CREATE TABLE `virtual_domains` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. 为数据库添加内容,具体按照自己喜好来
-- 插入一个域名(1表示序号, 注意递增)
insert into virtual_domains values(1,'xxxx.com') -- 插入用户(1表示序号, 注意递增)
insert into virtual_users values(1,域名序号,md5('密码'),'yyyy@xxxx.com'); -- 为用户设置一个别名(1表示序号, 注意递增),发送给zzzz的邮件都会发给yyyy了。
-- 注意这一步好像要先为zzzz插入一个用户,你也可以试一下不这么做,具体要不要我没试验过
insert into virtual_aliases values(1,域名序号,'zzzz@xxxx.com','yyyy@xxxx.com')
  1. 配置/etc/postfix/main.cf,这是postfix的主配置文件。

    1. 添加SSL代码
```
smtpd_tls_cert_file=/etc/ssl/certs/xxxx.com.pem
smtpd_tls_key_file=/etc/ssl/private/xxxx.key
smtpd_use_tls=yes
#smtpd_tls_auth_only = yes
smtp_tls_cert_file=/etc/ssl/certs/xxxx.com.pem
smtp_tls_key_file=/etc/ssl/private/xxxx.com.key
smtp_use_tls=yes smtpd_tls_CApath=/etc/ssl/certs
smtpd_tls_security_level=may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
```
2. 使用dovecot来做身份认证
```
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
# smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated reject_rbl_client reject_rhsbl_client reject_unknown_client
# smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_recipient_restrictions = permit_sasl_authenticated permit_mynetworks reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
```

restrictions结尾的是一些规则,表示smtp处理怎样的邮件。有兴趣的可以百度一下

3. 其次是域名的一些配置和一些常规配置
```
myhostname = xxxx.com
myorigin = $myhostname
mydomain = $myhostname
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
smtp_helo_name = xxxx.com
```
其中,myhostname设置为主机名,myorigin和mydomain设置为邮箱的域名(yyyy@xxxx.com的那个xxxx.com)。mynetworks指定来自哪里的ip允许直接发邮件,不需要SASL认证。如果你使用内网穿透,需要把mynetworks设置为空,否则经过内网穿透下来的请求来自的ip都会变成127.0.0.1,这样他们就统统不用走SASL就能发邮件了。 4. 最后设置一些和Dovecot以及MySQL协同工作所需要的选项。
```
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
```
  1. 配置Postfix的MySQL文件
  2. 创建/etc/postfix/mysql-virtual-mailbox-domains.cf,内容如下:
 user = admin
password = 123456
hosts = 127.0.0.1:3306
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
  1. 创建/etc/postfix/mysql-virtual-mailbox-maps.cf,内容如下
 user = admin
password = 123456
hosts = 127.0.0.1:3306
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
  1. 最后创建/etc/postfix/mysql-virtual-alias-maps.cf,内容如下:
 user = admin
password = 123456
hosts = 127.0.0.1:3306
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
  1. 重启服务(systemctl restart postfix),然后做一些验证
postmap -q xxxx.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
# 输出1 postmap -q yyyy@xxxx.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
# 输出1 postmap -q zzzz@xxxx.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# 输出zzzz是谁的别名
  1. 配置/etc/postfix/master.cf文件

    1. 取消注释submission,开启587端口的服务,后面的inet, n, y, -o等可看作是参数
    submission inet n       -       y       -       -       smtpd
    -o syslog_name=postfix/submission
```
2. 取消smtps,开启SSL的465端口的服务
```
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
```
  1. 配置/etc/dovecot/dovecot.conf,确保有如下内容:
!include conf.d/*.conf
protocols = imap lmtp pop3
  1. 创建一个用户,用户名和组名可以自己喜好决定,Home目录可放在/var/mail或者/home/mail。下文以/var/mail为例。
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /家目录
chown -R vmail:vmail /家目录
  1. 修改/etc/dovecot/conf.d/10-mail.conf,确保配置为(注意/var/mail为上文所说的家目录,mail_privileged_group的值为mail是固定的,不是上文所创建的组名):
mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail
  1. 修改/etc/dovecot/conf.d/10-auth.conf,确保配置为
disable_plaintext_auth = no
auth_mechanisms = plain login

有的教程把disable_plaintext_auth设置为yes,这表示拒绝明文密码登录,会使得一些客户端登陆不上,所以我选择为no。

拖动到最下方,确保启用SQL设置,其他注释掉。

#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext
  1. 修改/etc/dovecot/conf.d/auth-sql.conf.ext,确保如下配置:
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

其中,vmail、/var/mail为上面步骤创建的用户的相关信息。

  1. 修改/etc/dovecot/dovecot-sql.conf.ext,确保如下配置,connect表示mysql的登录信息
driver = mysql
connect = host=127.0.0.1 port=3306 dbname=mailserver user=xxxx password=xxxx
default_pass_scheme = MD5
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
  1. 修改/etc/dovecot/conf.d/10-master.conf,确保存在配置:
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
} # Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
} service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
} unix_listener auth-userdb {
mode = 0600
user = vmail
#group =
} user = dovecot
} service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
user = vmail
}
  1. 修改/etc/dovecot/conf.d/10-ssl.conf,以开启ssl认证,确保存在一下配置
ssl = required
ssl_cert = <fullchain位置
ssl_key = <密钥位置

ssl使用required应该是说ssl是必须的意思,也可以使用yes表示开启ssl也允许非ssl。

ssl_cert和ssl_key的<符号是必须的,位置写绝对路径

 1. `ssl=no`: SSL/TLS 完全禁用。

 2. `ssl=yes` 且 `disable_plaintext_auth=no`: SSL/TLS 提供给客户端,但客户端不需要使用它。即使在连接上未启用 SSL/TLS,客户端也可以使用纯文本身份验证登录。这是不安全的,因为明文密码暴露在互联网上。

 3. `ssl=yes` 且 `disable_plaintext_auth=yes`: SSL/TLS 提供给客户端,但客户端不需要使用它。不允许客户端使用明文身份验证,除非先启用 SSL/TLS。但是,如果启用了非明文身份验证机制,即使没有 SSL/TLS,它们仍然是允许的。根据它们的安全程度,身份验证要么是完全安全的,要么可能有一些方法使其受到攻击。

 4. `ssl=required`:即使使用非明文身份验证机制,也始终需要 SSL/TLS。任何在启用 SSL/TLS 之前进行身份验证的尝试都将导致身份验证失败。请注意,此设置与 STARTTLS 命令无关 - 允许使用隐式 SSL/TLS 或 STARTTLS 命令。
  1. 修改/etc/dovecot的权限,其中vmail为上面创建的用户
chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
  1. 重启postfix和dovecot,如此一postfix和dovecot就配置完成了。

    * OpenDKIM配置

    1. 安装OpenDKIM
    sudo apt install opendkim opendkim-tools
    1. 修改配置文件/etc/opendkim.conf,确保有以下内容
    Domain                  xxxx.com
    KeyFile /etc/dkimkeys/dkim.key
    Selector dkim
    SOCKET inet:8891@localhost

    其中,SOCKET的端口可以使用8891,也有人使用8892,我没发现区别。

    1. 修改/etc/default/opendkim,确保有以下内容
    SOCKET="inet:8891@localhost"
    1. 生成dkim密钥对(一般在用户的家目录下生成,再复制到指定位置)
    sudo opendkim-genkey -t -s dkim -d xxxx.com

    然后执行移动操作

    sudo mv dkim.key /etc/dkimkeys/
    sudo chown opendkim:opendkim dkim.key
    1. 在postfix的配置文件/etc/postfix/main.cf添加如下配置
    smtpd_milters = inet:localhost:8891
    non_smtpd_milters = inet:localhost:8891
    milter_protocol = 2
    milter_default_action = accept
    1. 关注到第四步生成密钥对时产生的dkim.txt文件。
    dkim._domainkey IN      TXT     ( "v=DKIM1; k=rsa; t=y; "
    "p=xxxxxxxxxx" ) ; ----- DKIM key dkim for Example Domain

    复制双引号的内容,去除双引号和换行,整理为:v=DKIM1; k=rsa; t=y; p=xxxxxxxxxx的形式。在域名添加为txt记录(主机记录为dkim._domainkey)。

    1. 重启postfix和opendkim,如此一来就配置完成了。
* 配置SpamAssassin

  SpamAssassin为Postfix实现反垃圾的功能。

  1.  安装SpamAssassin
```
sudo apt-get install spamassassin spamc
```
2. 添加用户
```
sudo adduser spamd --disabled-login
```
3. 修改配置文件`/etc/default/spamassassin`,确保有如下配置:
```
ENABLED=1
SAHOME="/var/log/spamassassin/"
OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir /home/spamd/ -s /home/spamd/spamd.log"
PIDFILE="/var/run/spamd.pid"
CRON=1
```
4. 修改`/etc/spamassassin/local.cf`,确保有如下配置:
```
rewrite_header Subject ***** SPAM _SCORE_ *****
required_score 5.0
use_bayes 1
bayes_auto_learn 1
```
5. 修改`/etc/postfix/master.cf`文件 添加配置: ```
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}
```
为smtp,smtps和submission添加参数
```
-o content_filter=spamassassin
```
有些教程只为smtp添加参数,我认为应该都添加。 添加之后,应该看上去像:
```
smtp inet n - y - - smtpd
-o content_filter=spamassassin
```
6. 执行`update-rc.d spamassassin enable`,然后重启postfix和spamassassin即可完成配置。

客户端连接服务器

客户端可以使用FoxMail或者雷鸟。

填写登录名为yyyy@xxxx.com以及密码,然后输入正确的smtp和pop3服务器地址以及端口号即可。

  1. smtp默认25端口,SSL则是465端口。

  2. pop3默认110端口,SSL则是995端口。

  3. imap默认143端口,SSL则是993端口。

写在最后

以上是根据我配置邮件服务器的过程所总结的文章,我也折腾了快两个星期了。可能会有错误,欢迎留言咨询也以便我更正错误。

Ubuntu搭建邮件服务器的更多相关文章

  1. Ubuntu安装邮件服务器

    Ubuntu搭建邮件服务器 此文我们使用Postfix来搭建邮箱服务器,Postifx是一个SMTP服务器.SMTP服务器也被称为MTA(message transfer agent) 一.安装pos ...

  2. kubuntu+roundcube搭建邮件服务器(包含LAMP)

    好久之前写的了,偶然翻到然后拿出来看看,里面文字图片都没改,有错误请见谅 步骤: 一.关于ubuntu的安装二.ubuntu配置LAMP(Linux+Apache+Mysql+Perl/PHP/Pyt ...

  3. Postfix+Dovecot+MySQL搭建邮件服务器

    网上有很多使用Postfix搭建邮件服务器的文章,但目前貌似没有看到较为完整的一篇.本例将尝试在Ubuntu系统中使用Postfix+Dovecot+MySQL搭建邮件服务器. 说到邮件服务器,网上有 ...

  4. CentOS利用postfix搭建邮件服务器

    之前我用nodemailer通过163邮箱来发送邮件,不过没过几天就一直ETIMEDOUT,不知道什么原因,想着还是自己搭一个来发邮件可能靠谱点(flag?) 安装postfix CentOS 7 自 ...

  5. Windows Server 2003搭建邮件服务器

    Windows Server 2003搭建邮件服务器 由于Windows Server 2003默认是没有安装我们搭建邮件服务器所需要的POP3和SMTP服务的,因此需要我们自己来安装.方法如下: 1 ...

  6. ubuntu搭建svn服务器并htpp访问版本库并svn与web同步

    Ubuntu搭建SVN服务器多版本库 1  介绍   Subversion是一个自由,开源的版本控制系统,这个版本库就像一个普通的文件服务器,不同的是,它可以记录每一次文件和目录的修改情况.这样就可 ...

  7. Ubuntu搭建Anki服务器

    Ubuntu搭建Anki服务器 第一步安装Anki 阿里云的服务器,xshell远程登录上 #以root用户进行操作 #安装Akni服务 easy_install AnkiServer #添加名为an ...

  8. Ubuntu搭建NFS服务器,NFS协议详细分析

    目录 1. Ubuntu搭建NFS服务器 2. NFS协议分析 2.1 实验拓扑: 2.2 在kali抓包分析 1. Ubuntu搭建NFS服务器 ​ NFS(Network FileSystem,网 ...

  9. 阿里云CentOS Linux服务器上搭建邮件服务器遇到的问题

    参考文章: 阿里云CentOS Linux服务器上用postfix搭建邮件服务器 Linux系统下邮件服务器的搭建(Postfix+Dovecot) 本来想自己搭建邮件服务器,但是看到一篇资料表示阿里 ...

  10. 使用hMailServer搭建邮件服务器

    本文没有什么高深的技术内容,只是使用hMailServer,介绍搭建邮件服务器的全过程,供参考. 一.安装邮件服务器组件 打开软件,点下一步 选择存储数据的数据库,这里有两种选择, 一种是使用嵌入型数 ...

随机推荐

  1. SQL函数升序Asc,降序Desc使用总结

    关键字-升序Asc及降序Desc的使用语法 对某一结果集按列进行升序或降序排列即:结果集 Order by 列名/数字 Asc/Desc. 一.Asc,Desc排序讲以下5点 1.不写关键字Asc/D ...

  2. 模块化打包工具-初识Webpack

    1. 为什么需要模块化打包工具 在上一篇文章中提到的ES Module可以帮助开发者更好地组织代码,完成js文件的模块化,基本解决了模块化的问题,但是实际开发中仅仅完成js文件的模块化是不够的,尤其是 ...

  3. np.random.uniform()

    np.random.uniform(start,end,second) start:开始数 end:结束数 second:次数,也就是选择几次. 代码结果如下所示: import numpy as n ...

  4. 【docker简略学习】

    [docker简略学习] Docker是一个应用打包.分发.部署工具,相当于一个轻量级虚拟机.相比较VM虚拟机,可移植性更强. 一.Docker安装 下载链接:https://docs.docker. ...

  5. 【问题复盘】在Ubuntu 20.04下安装OFED驱动

    复盘:在Ubuntu 20.04下安装OFED驱动 起因 最近收到两台服务器,都搭载了ConnectX-5 EX网卡.由于供应商预装了Ubuntu 20.04操作系统,而我们的后端代码也是基于Ubun ...

  6. 【scipy 基础】--积分和微分方程

    对于手工计算来说,积分计算是非常困难的,对于一些简单的函数,我们可以直接通过已知的积分公式来求解,但在更多的情况下,原函数并没有简单的表达式,因此确定积分的反函数变得非常困难. 另外,相对于微分运算来 ...

  7. Java之对象内存分析

    相信大家有时候在读代码的时候应该都会有以下情况: 这个对象本定义在上面,乱跑什么?怎么又到下面去了? 欸?我明明改变了这个对象的值,怎么没变呢? 要想搞清楚某一对象在程序中是怎样活蹦乱跳的,首先我们要 ...

  8. Mockito - java单元测试

    原文地址 一.简介 Mockito是mocking框架,它让你用简洁的API做测试,简单易学,可读性强并且验证语法简洁. 官网: http://mockito.org 项目源码:https://git ...

  9. Windows10下的hexo搭建

    用hexo搭建个人博客 查看效果:慢蜗牛博客 目录 用hexo搭建个人博客 准备环境 Github Node.js和Git 连接Github 安装hexo 安装插件 部署 Hexo 到 GitHub ...

  10. 【VMware vCenter】使用cmsso-util命令进行链接、删除、修改多个vCenter Server(VCSA)的SSO域。

    VMware vCenter Server 支持新安装的时候选择将vCenter SSO域加入到另外一个现有的SSO域中,同时也支持使用cmsso-util命令将现有的两个或多个vCenter SSO ...