美文网首页
Linux邮件服务器搭建攻略(一文吃透Postfix+Dovec

Linux邮件服务器搭建攻略(一文吃透Postfix+Dovec

作者: Rockage | 来源:发表于2020-12-02 05:29 被阅读0次
    1.jpg

    今天来聊聊Linux邮件服务器的搭建,本以为电子邮件这种高度成熟的技术应该很容易部署,上手后才发现原来坑还真不少。本方案以主流的postfix + dovacot为基础,其中postfix用作smtp,dovecot用作pop3(或imap)。

    1. 工作模式
      用postfix构建的邮件系统至少有两种工作模式,第一种是利用本地Linux账号进行邮件收发,比如本地系统有用户root或someone,那么就有root@example.comsomeone@example.com两个email地址。 第二种相对复杂一些,为了管理的方便和系统安全,postfix的用户管理采用了虚拟用户方式,即postfix单独设立了许多用户,他们各自在系统中映射有独立的硬盘空间。但同时这些用户又跟本地Linux系统内固有的真实账号没有关联。本文所有讨论就是建立在这种模式下的,值得注意的是,这两种工作模式的部署方法差异极大,在参考网上教程的时候,首先要确认它是建立在哪个模式下的,否则容易张冠李戴,出现很多令人头疼的问题。

    2. 运行流程
      对于电子邮件,我们有可能存在的一个误区是,将smtp和pop3按照字面的意思去理解,即smtp只管发件,pop3则只负责收件。其实并不完全是这样。下面是一封电子邮件在互联网上的投递流程:

    • 发件人:me@qq.com 收件人:you@gmail.com
      me@qq.com 用邮件客户端(比如outlook)写了一封邮件给you@gmail.com,点下发送按钮后,邮件首先会发送到smtp.qq.com
    • smtp.qq.com 检索到这封邮件的收件人域名是gmail.com,于是通过互联网(WAN)将邮件发送到smtp.gmail.com
    • smtp.gmail.com确认收下邮件后,将它转存到邮件服务器的硬盘中待收。
      通过观察以上流程,你会发现smtp服务器其实身兼了 “收、发” 两个功能。 对于smtp.qq.com而言,是发送。 而从smtp.gmail.com的角度来看,则是接收。那么,咱们平时经常说起的 “收件服务器pop3” 又是怎么回事呢,整个流程似乎看不到它的身影?

    pop3(或imap服务器,与之性质相同)更多的是起一个中转作用,它将存储在邮件服务器硬盘中的邮件转移回邮件客户端(user agent),它只负责从邮件服务器到邮件客户端这段路径,而邮件在广域网上的收发则是smtp要做的事,与pop3没有关系。

    pop3与imap的区别是,pop3将邮件拉回本地后,即与服务器脱钩了。imap则更先进一些,它能做到实时将你在邮件客户端的操作反馈回邮件服务器,比如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱,看到的邮件以及状态都是一致的。


    pop3-smtp-imap-difference-00.jpg

    基础原理就这么点,下面开始进入实战环节。


    一、 准备工作

    前面说过,本文以虚拟邮件用户为基础,创建虚拟用户有很多方法,其中最容易也最易于扩展的方式莫过于采用数据库来管理邮件客户。比如说以后如果需要扩展Web Mail功能,就比较容易与现有系统无缝衔接。

    本文选用Centos下最常见的MariaDB作为数据库,它与MySQL是完全兼容的,关于MariaDB的部署不在本文讨论之内,网上有很多教程,也非常简单。
    首先将我的运行环境做一个说明:

    OS : Centos 8.2
    DB : MariaDB 10.3.17
    Postfix 3.3.1
    Dovecot 2.3.8
    编辑器:nano

    注意:

    • 文中所有出现example.com的地方,需要换成你自己的域名。
    • 文中凡出现nano开头的地方表达的意思就是编辑这个文件。

    准备工作部分我们要做三件事:

    1. 建立数据库
    2. 修改DNS设置
    3. 获取域名证书

    一步一步来,我们首先来创建数据库(默认你已经装好了MySQL或MariaDB):


    准备步骤1:创建数据库

    1. 建库
      mysql -u root -p 密码
      进入mysql,然后执行:
    create database servermail;
    GRANT SELECT ON servermail.* TO 'usermail'@'127.0.0.1' IDENTIFIED BY 'mailpassword';
    FLUSH PRIVILEGES;
    USE servermail;
    
    1. 建表
    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 NOT NULL AUTO_INCREMENT,
    `domain_id` INT 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. 生成一些初始数据
      创建域名:
    INSERT INTO `servermail`.`virtual_domains`
    (`id` ,`name`)
    VALUES
    ('1', 'example.com'),
    ('2', 'mail.example.com');
    

    生成两个初始email账号:
    其中,dmarck-reports@example.com是将来设置DKIM需要用到的,这是后话先别管它,创建了再说:

    INSERT INTO `servermail`.`virtual_users`
    (`id`, `domain_id`, `password` , `email`)
    VALUES
    ('1', '1', ENCRYPT('密码', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'webmaster@example.com'),
    ('2', '1', ENCRYPT('密码', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'dmarck-reports@example.com');
    

    生成一个别名:

    INSERT INTO `servermail`.`virtual_aliases`
    (`id`, `domain_id`, `source`, `destination`)
    VALUES
    ('1', '1', 'boss@example.com', 'webmaster@example.com');
    

    据库的基本操作完毕。


    准备步骤2:修改DNS服务器

    这需要登录你的域名管理界面,做几个简单的操作:

    1. 添加一个A记录,如图:


      image.png
    2. 添加一个MX记录,如图:


      image.png

    每个域名提供商的操作界面有可能不太一样,但都大同小异的。


    准备步骤3:申请证书

    接下来我们需要为邮件服务器获取域名证书,抛开安全性不谈,纯粹从装X的角度而言,这玩意就如同https一样,这年头你的网站还穿着http出来见人就真的有点丢人了,因此证书几乎是必备的。

    域名证书有很多获取方式,有收费的也有免费的,国内有一家通过网页申请的,可参见我写的另一篇博文:https://www.jianshu.com/p/b4b5ca1d88d6

    今天我们采用另一个方法,利用Letsencrypt在线生成,这个方案的好处是不用等待,证书立等可取,而且流程相对也比较简单。因为证书必须要对应一个真实存在的网站,所以我们还必须先装装样子,安装一个nginx,还好Letsencrypt对网站的实际内容没什么要求,nginx默认的初始页面也是可以的。

    1. 首先安装nginx
      dnf -y install nginx
      装好之后到浏览器输入你的域名,如果出现nginx欢迎页面,说明安装成功。

    2. 然后安装certbot
      dnf -y install certbot python3-certbot-nginx

    3. 生成证书
      certbot certonly -a nginx --agree-tos --staple-ocsp --email webmaster@example.com -d mail.example.com

    如果没有问题,系统将回显如下:

    • Congratulations! Your certificate and chain have been saved at:
      /etc/letsencrypt/live/mail.example.com/fullchain.pem
      Your key file has been saved at:
      /etc/letsencrypt/live/mail.example.com/privkey.pem
      Your cert will expire on 2021-02-27.

    这里面包括了公私钥的存放地址以及有效期之类的信息。
    至此,准备工作全部完成了,下面进入我们的核心部署环节!


    二、核心内容:Postfix篇

    首先我们需要安装postfix,在centos下这很简单,只需要一条命令:
    dnf -y install postfix postfix-mysql
    设置自启动:
    systemctl start postfix
    systemctl enable postfix
    安装完毕后,开始对postfix进行设置,其中关键的配置文件有两个:main.cf和master.cf。

    1. nano /etc/postfix/main.cf
    这是一个超复杂的配置文件,不过大多数都是注释。限于篇幅我就不把整个文件贴出来了,你可以将源文件完全清空,然后将以下内容原封不动地复制进去,保存即可。注意所有出现example.com的地方,需要换成你自己的域名(后面的所有配置文件都是如此,接下来我就不再强调了)

    mydomain = example.com
    myorigin = mail.example.com
    myhostname = mail.example.com
    mydestination = \$mydomain
    inet_interfaces = all
    message_size_limit=52428800
    mailbox_size_limit=0
    smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
    smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem
    smtpd_use_tls=yes
    smtpd_tls_auth_only = yes
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
    smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
    smtpd_banner = $myhostname ESMTP \$mail_name (Ubuntu)
    biff = no
    append_dot_mydomain = no
    readme_directory = no
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    relayhost =
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    mailbox_size_limit = 0
    recipient_delimiter = +
    virtual_transport = lmtp:unix:private/dovecot-lmtp
    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
    

    话说整个main.cf有相当多的设置项目,真正钻进去研究透彻需要花费大量时间,对于上述设置我只谈几个我已经看明白的:
    mydomain = example.com
    设置域名是example.com

    myorigin = example.com
    myorigin参数指定默认域名,该默认域名将附加到没有@domain部分的发件人和收件人地址。 需要将其值更改为example.com,因此邮件服务器上的发件人将具有@example.com地址。

    myhostname = mail.example.com
    与其他SMTP服务器通信时,Postfix使用此主机名来标识自己。 但是,操作系统主机名可能会更改,因此,最好直接在配置文件中设置。

    mydestination = \$mydomain
    mydestination参数指定服务器将其视为自身最终目的地的域列表。这个听起来有点拗口,说白了就是别人给您发信,哪些信你是接受的。比如12345@qq.com给您发一封信,收件人是webmaster@example.com,当你的smtp服务器接收到这封信的时候表示接受,对应的规则就是$mydomain。注意:此处如果设错了,有可能出现一个问题:你可以给别人发信,但是别人给你发的信你会收不到。

    smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
    smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem
    这两个是刚才我们生成的证书。

    message_size_limit=52428800
    mailbox_size_limit=0
    这两个设置比较实用,是指附件最大允许容量和邮箱的总容量,这里我们把最大附件设为50MB,邮箱总容量则不设限制(0)

    virtual_transport = lmtp:unix:private/dovecot-lmtp
    这是一条核心设置,表示通过lmtp (Local Mail Transfer Protocol)协议,将本地邮件传递到dovecot中,相当于告诉Postfix,将从广域网收到的邮件,最终传递到dovecot能控制的地方,以便我们用pop3或imap下载到邮件客户端。

    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
    这三行与数据库有关,表示邮箱的虚拟域,用户映射关系和别名映射关系,分别由哪三个SQL脚本做查询动作。

    1. 接下来我们就要创建这3个SQL脚本了,稍懂一点SQL语句的朋友一定也可以看出其中的关联,这里也不再展开讨论了:

    nano /etc/postfix/mysql-virtual-mailbox-domains.cf

    user = usermail
    password = mailpassword
    hosts = 127.0.0.1
    dbname = servermail
    query = SELECT 1 FROM virtual_domains WHERE name='%s'
    

    nano /etc/postfix/mysql-virtual-mailbox-maps.cf

    user = usermail
    password = mailpassword
    hosts = 127.0.0.1
    dbname = servermail
    query = SELECT 1 FROM virtual_users WHERE email='%s'
    

    nano /etc/postfix/mysql-virtual-alias-maps.cf

    user = usermail
    password = mailpassword
    hosts = 127.0.0.1
    dbname = servermail
    query = SELECT destination FROM virtual_aliases WHERE source='%s'
    

    创建好之后,用systemctl restart postfix 重启一次postfix,然后测试一下刚才建立的三个脚本。
    postmap -q example.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
    正确的话,应该返回:1

    postmap -q webmaster@example.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
    正确的话,应该返回:1

    postmap -q boss@example.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf
    正确的话,应该返回:webmaster@example.com

    2. nano /etc/postfix/master.cf
    这也是一个巨复杂的配置文件,不过你依然可以先把它彻底清空,然后原封不动把以下内容粘贴进去:

    smtp      inet  n       -       n       -       -       smtpd
    submission inet n       -       -       -       -       smtpd
      -o syslog_name=postfix/submission
      -o smtpd_tls_security_level=encrypt
      -o smtpd_sasl_auth_enable=yes
      -o smtpd_client_restrictions=permit_sasl_authenticated,reject
    smtps     inet  n       -       y       -       -       smtpd
      -o syslog_name=postfix/smtps
      -o smtpd_tls_wrappermode=yes
      -o smtpd_sasl_auth_enable=yes
      -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
      -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
      -o smtpd_sasl_type=dovecot
      -o smtpd_sasl_path=private/auth
    pickup    unix  n       -       n       60      1       pickup
    cleanup   unix  n       -       n       -       0       cleanup
    qmgr      unix  n       -       n       300     1       qmgr
    tlsmgr    unix  -       -       n       1000?   1       tlsmgr
    rewrite   unix  -       -       n       -       -       trivial-rewrite
    bounce    unix  -       -       n       -       0       bounce
    defer     unix  -       -       n       -       0       bounce
    trace     unix  -       -       n       -       0       bounce
    verify    unix  -       -       n       -       1       verify
    flush     unix  n       -       n       1000?   0       flush
    proxymap  unix  -       -       n       -       -       proxymap
    proxywrite unix -       -       n       -       1       proxymap
    smtp      unix  -       -       n       -       -       smtp
    relay     unix  -       -       n       -       -       smtp
      -o syslog_name=postfix/$service_name
    showq     unix  n       -       n       -       -       showq
    error     unix  -       -       n       -       -       error
    retry     unix  -       -       n       -       -       error
    discard   unix  -       -       n       -       -       discard
    local     unix  -       n       n       -       -       local
    virtual   unix  -       n       n       -       -       virtual
    lmtp      unix  -       -       n       -       -       lmtp
    anvil     unix  -       -       n       -       1       anvil
    scache    unix  -       -       n       -       1       scache
    

    master.cf这个文件主要掌管着postfix的各种服务,
    这个文件的与一般的配置文件不同,它是缩进敏感的。
    每一个顶格的行,代表一种服务,比如:
    submission inet n - - - - smtpd
    smtps inet n - y - - smtpd
    同时他们下面又有一些
    -o syslog_name=postfix/submission
    -o smtpd_tls_security_level=encrypt
    以-o开头的行,前面多了两空格,表示该服务下的具体设置。这两个空格不能删除,否则会报错,这就是所谓的缩进敏感。

    可以看到我们开启了smtp,smtps和submission这三个服务,分别对应端口25,465和587,功能分别是:传统smtp服务,加密的smtps服务,还有一个submission。这是一个与smtps类似的加密协议。smtps 和 submission从功能上而言极其雷同,关于这两个端口,历史上还有一些彼此争夺话语权的野史,感兴趣的可以自行搜索。题外话我们暂且不表,反正两个都开通就是了。

    至此,Postfix的设置工作就完成了,你可以通过以下命令用它发一封最简单的邮件,看看能否收到?
    echo "Hello world!" | sendmail 你的qq@qq.com


    三、核心内容:Dovecot篇

    1. 安装dovecot
    dnf -y install dovecot dovecot-mysql
    设置自启动:
    systemctl start dovecot
    systemctl enable dovecot


    2. nano dovecot.conf

    protocols = imap lmtp
    listen = *, ::
    mail_max_userip_connections = 50
    !include conf.d/*.conf
    !include_try local.conf
    

    这其实也是一个很复杂的配置文件,但是注释去掉之后也没什么内容。
    protocols = imap lmtp
    表示支持的协议,这里我们只开通了imap和lmtp,如果你需要pop3的话,加上去即可。
    注意:此处的lmtp必须打开,这是dovecot和postfix交流的通道。

    listen = *, ::
    表示监听所有地址,*是ipv4的表达方法,::则是ipv6的,如果你没有启用ipv6,直接listen = *也行

    mail_max_userip_connections = 50
    设置一个合理的数值,否则会报mail_max_userip_connections 错误。

    !include conf.d/*.conf
    !include_try local.conf
    没有太大的作用,表示此处将包含conf.d文件夹下的所有配置文件。

    3. nano /etc/dovecot/conf.d/10-mail.conf

    mail_location = maildir:/var/mail/vhosts/%d/%n
    mail_privileged_group = mail
    

    这个文件的原始体积也很大,但删掉注释之后只有2行,它设置的是邮箱对应硬盘的具体位置,%d表示域名,%n表示用户名,比如在本文中,webmaster@example.com这个用户在硬盘中的物理位置在:

    /var/mail/vhost/example.com/webmaster

    4. 创建用户组和用户:
    groupadd -g 5000 vmail
    useradd -g vmail -u 5000 vmail -d /var/mail
    创建一个用户组vmail并添加一个用户vmail,id为5000,
    用户vmail隶属于用户组vmail。起始目录为 /var/mail

    5. 创建域名目录:
    mkdir -p /var/mail/vhosts/example.com

    6. 修改/var/mail和/etc/dovecot的拥有者:
    chown -R vmail:vmail /var/mail
    chown -R vmail:dovecot /etc/dovecot
    chmod -R o-rwx /etc/dovecot

    7. 查看权限
    ls -ld /var/mail
    如果显示:

    lrwxrwxrwx. 1 vmail vmail 10 May 11 2019 /var/mail -> spool/mail

    说明权限设置成功,请注意:这一步非常重要,如果该目录持有者不是vmail的话,dovecot在收到邮件后无法保存,将会报错。

    8. nano /etc/dovecot/conf.d/10-auth.conf

    disable_plaintext_auth = yes
    auth_mechanisms = plain login
    !include auth-sql.conf.ext
    

    disable_plaintext_auth = yes
    表示登录密码必须加密,否则不通过,我们这个方案是全盘TLS加密的,因此此处把他打开,不允许明文密码。

    auth_mechanisms = plain login
    授权机制,表示允许明文密码授权和login密码授权,为啥此处我们选择明文密码呢?此明文非彼明文,此处的明文是指在SSL/TLS加密通道中的明文,因为本身就已经加密过了,所以我们不需要担心密码泄露问题,而此处的login方式,是专门为outlook准备的。此处可以选择cram-md5,专门用于加密密码,但本身我们已经是加密通道了,因此没有必要画蛇添足。

    !include auth-sql.conf.ext
    此行表示启用MySQL授权

    9. nano /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
    }
    

    当我们通过邮件客户端登录咱们的pop3(或imap)服务器准备取回邮件时,需要进行密码核对和用户名核对,那么dovecot是如何实现的呢?这个文件指定dovecot是如何获取用户密码和用户资料的,密码部分采用sql脚本方式。用户数据采用static (静态) 方式,通常,SQL数据库也可以做这件事,也可以通过它得到用户的UID,GID和主目录。但此处如果我们仅使用静态UID和GID,并且可以使用模板指定主目录,则可以改用静态方式,它会比SQL方式略快一些。

    10. nano /etc/dovecot/dovecot-sql.conf.ext

    driver = mysql
    connect = host=127.0.0.1 dbname=servermail user=usermail password=mailpassword
    default_pass_scheme = SHA512-CRYPT
    password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
    

    这个文件就是刚才我们说的SQL方式获取用户密码的脚本,很简单只有一句,相信大家都能看得懂。
    说句题外话,dovecot只能识别user和password字段,如果你的初始数据库用的并不是这两个字段的话,必须是用as修饰符强制将它们转换成user和password。

    11. nano /etc/dovecot/conf.d/10-master.conf

    service lmtp {
      unix_listener /var/spool/postfix/private/dovecot-lmtp {
       mode = 0600
       user = postfix
       group = postfix
      }
    }
    
    service auth {
      unix_listener /var/spool/postfix/private/auth {
        mode = 0666
        user = postfix
        group = postfix
      }
    
      unix_listener auth-userdb {
       mode = 0600
       user = vmail
      }
      user = dovecot
    }
    
    service auth-worker {
      user = vmail
    }
    

    这个文件主要作用是为了打通dovecot和postfix的关联,授权postfix通过lmtp协议访问属于dovecot的地盘,访问权限是0600,表示有读写权限,但无执行权限。这个文件的源文件也比较庞杂,里面对多个协议都有设定,但是如果你全部把它们删了也没关系,等于采用默认设置,比如你把imap这一段删了,那么dovacot会将imap设为默认端口993。

    11. nano /etc/dovecot/conf.d/10-ssl.conf

    ssl = required
    ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
    ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
    ssl_cipher_list = PROFILE=SYSTEM
    

    这个配置文件主要是设置SSL,
    ssl = required
    表示强制使用SSL加密通道,从密码到邮件内容全部加密,这就是前面咱们在“授权机制”那个步骤允许使用的plain(明文密码)的原因了,因为整个通道都已经被加密了,明文密码走在加密通道里面也可以认为是安全的,后面两行指定了我们在准备步骤生成的证书存放位置。请注意,这两个文件与Postfix里的设置是完全一致的,也就是说Postfix和Dovecot采用的是同一个证书,不仅如此,实际上这本证书还可以用于nginx用于加密你的Web网站,开通https等。

    12. nano /etc/dovecot/conf.d/15-mailboxes.conf

    namespace inbox {
      inbox = yes
      mailbox Drafts {
        auto = create
        special_use = \Drafts
      }
      mailbox Junk {
        auto = create
        special_use = \Junk
      }
      mailbox Trash {
        auto = create
        special_use = \Trash
      }
    
      mailbox Sent {
        auto = create
        special_use = \Sent
      }
      mailbox "Sent Messages" {
        auto = create
        special_use = \Sent
      }
    }
    

    这个文件是用来指定收件箱的命名空间的,auto = create表示当这些邮箱都没有的时候,就自动创建它,这里指定的都是常规的,比如收件箱,已发送,垃圾箱,已删除等等,如果需要别的种类,请自行研究。


    四、验证篇

    终于快大功告成了!
    现在我们需要验证一下服务器到底设置成功没有,首先重启一下postfix和dovecot:
    stystemctl restart postfix dovecot

    查看日志的方法是:
    tail -f /var/log/maillog
    请注意:postfix和dovecot的日志是合并在一起的,两者的变化都会记录在这个文件里。


    1. 初级判断:
    本文中,我们开通了smtp, smtps, imaps, lmtp, submission 这四个服务,分别对应端口:

    25/tcp smtp :负责广域网邮件传递,非加密
    465/tcp smtps :同上,加密
    143/tcp imap :负责将服务器的邮件传回邮件服务端,非加密
    993/tcp imaps :同上,加密
    587/tcp submission :同上,加密
    lmtp :为内部传输服务,不对外,无端口号

    最简单的,我们可以用:
    netstat -tunlp
    看看这些端口起来了没有,
    如果显示这样:

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 6717/master
    tcp 0 0 0.0.0.0:465 0.0.0.0:* LISTEN 6717/master
    tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN 6729/dovecot
    tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN 6729/dovecot
    tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 6717/master

    说明OK,如果指定的端口号不存在,那么说明服务有问题,需要排查。
    另外一个更高端的端口扫描器叫做nmap,也可以实现同样的功能,首先安装它:
    dng -y install nmap
    使用很简单:
    nmap mail.example.com


    2. 测试连通性:
    如果端口都存在,说明大毛病没有了,我们可以用telnet测一下,
    命令很简单,比如我们想测一下993端口:
    telnet mail.example.com 993
    如果返回:

    Trying 123.123.123.123...
    Connected to mail.example.com.
    Escape character is '^]'.

    说明没有大问题,输入quit或ctrl+c,退出。
    如果返回:

    Trying 123.123.123.123...
    telnet: connect to address 123.123.123.123: Connection refused
    则说明这个端口有毛病,需要排查。


    3. 高端测试
    利用openssl命令,我们可以对这些服务进行更深层次的检测。
    例如我们想查一下服务器的993端口(imap)加密通道到底正不正常:
    openssl s_client -connect mail.example.com:993
    如果返回一大堆类似密文的东西,说明基本OK,往上翻,如果出现类似这样的信息:

    depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
    verify return:1
    depth=0 CN = mail.example.com

    说明证书是OK的,由Let's Encrypt公司颁发,域名也跟你的实际域名对得上,说明SSL这一块大问题没有。

    如果输入了这条命令毫无反应,或报错,或者域名不是你的域名,你就要仔细排查你的域名证书是不是有问题了,因为dovecot装好之后本身有一本默认证书,但那不是你的域名的,尽管看上去好像没毛病,但实际那本证书是无法使用的。


    4. 常见错误

    • 问题: Error: namespace configuration error: inbox=yes namespace missing
      nano /etc/dovecot/conf.d/15-mailboxes.conf
    namespace inbox {
      inbox = yes #添加这一行,注意位置一定别搞错,只能加在这里
      mailbox Drafts {
        auto = create
        special_use = \Drafts
      }
    

    • 问题:Recipient address rejected: User unknown in local recipient table
      nano /etc/postfix/main.cf :
    mydestination = \$mydomain
    

    • 问题: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssh_dh=</path/to/dh.pem
      nano /etc/dovecot/dovecot.conf
      去掉pop3:
    protocols = imap lmtp
    

    pop3需要强制使用迪菲-赫爾曼密鑰(简称DH),因此你需要自己去建一个,相当耗时且麻烦,所以本文中干脆就不用pop3了,imap现在已经是主流协议了,而且功能更强大。


    • 其他认证类问题:
      基本上问题出在SSL,各种乱七八糟的报错都有,这里就不赘述了,实在不行就从源头开始查,从生成证书那一步就开始认真核对,比如输入域名的时候有没有敲错之类。

    • 更诡异的问题:
      大家不一定都能碰到,在此我只做一个记录:
      所有服务都运行正常,openssl测试也通过了,但是当我用客户端进行设置的时候foxmail就是报ssl错误,百思不得其解,更诡异的是,日志丝毫没有反应,连报错都没有,排查工作根本无从谈起。折腾了一晚上,第二天故障居然自行消失了!找不到问题这更让人窝火,后来通过慢慢回忆,我找出了问题所在:我在用foxmail客户端测试的时候忘记关FQ开关。因为采用的是tun2socks方式全局FQ,我猜测某些数据经过多层跳板是不是无法最终发送到服务器导致?

    • 目前的问题:
      Mozilla Thunderbird客户端无法使用,Foxmail却很完美,目前我也没有招,搜遍整个google,貌似不止我一个,初步判断是Thunderbird对加密证书有别的要求,反正平时我也是用Foxmail,这个问题先搁一边,以后有时间再慢慢研究。

    • 关于防火墙:
      firewalld和iptables本人不会用,只贴一个nft的简单版,放行了本文中所有涉及到的端口,关于端口放行的问题,不麻烦,请自行百度谷歌。
      我的简单防火墙脚本:
    flush ruleset
    table inet filter {
            chain input {
                    type filter hook input priority 0; policy drop;
                    ct state established,related accept
                    ct state invalid drop
                    iif lo accept
                    ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept
                    ip protocol igmp accept
                    tcp dport { ssh, http, https,smtp, smtps, imap, imaps} accept
            }
            chain forward {
                    type filter hook forward priority 0; policy drop;
            }
            chain output {
                    type filter hook output priority 0; policy accept;
            }
    }
    

    使用方法,先把上面的粘贴复制成一个文件,然后nft -f 文件名,即可。


    • 关于客户端设置:
      以Foxmail为例,如图:
    image.png image.png
    • 结束了吗?
      其实才刚开始,后面的事情还多着呢,还需要给我们的邮件服务器设置WEB Mail,设置SPF、DKIM、DMARC等等等等,SPF和DKIM可以参考我的前一篇博文:
      https://www.jianshu.com/p/736867371d28
      如何提高邮件服务器的“受尊重度”是一门大学问,而且还不怎么和技术直接挂钩,非常不省心,我的邮件服务器至今也没进得了gmail的法眼,尽管可以通过Postmark等第三方smtp代发机构解决这个难题,但如果大家有什么好方法让我们理直气壮被gmail认可的话,欢迎留言告知,交流,感谢!!

    相关文章

      网友评论

          本文标题:Linux邮件服务器搭建攻略(一文吃透Postfix+Dovec

          本文链接:https://www.haomeiwen.com/subject/sfxywktx.html