基于postfix和dovecot搭建个人邮件服务器

1 准备工作

  • 首先你需要一个 LinuxVPS ,以及一个可以用的域名。 VPS 的操作系统可以选 Ubuntu 或者 centos 等主流的 Linux 系统。 同时删除原来系统里面的 sentmail 相关的 package
  • 在你的域名供应商的平台上配置好你的域名解析。 一般情况下,需要配置3种域名解析类型, 分别是 A, MX, TXT 下面是我的配置, 我用的是阿里云的域名服务: domain_configure.png
  • VPS 上安装好 postfixdovecotsasl-dev 等软件。 libsaslpostfixdovecot 认证用的。你需要根据你的 VPS 操作系统的类型选择对应的包管理工具安装这些包。

    postfix-2.10.1-7.el7.x86_64
    dovecot-2.2.36-3.el7_7.1.x86_64
    dovecot-mysql-2.2.36-3.el7_7.1.x86_64
    cyrus-sasl-lib-2.1.26-23.el7.x86_64
    cyrus-sasl-plain-2.1.26-23.el7.x86_64
    cyrus-sasl-2.1.26-23.el7.x86_64
    
  • VPS 上创建一个用户,你的邮箱就是这个用户名,目前没有尝试用 LDAP 服务和 postfix 服务做集成。
  • 最好还能有一个可以有一个常用的别的邮箱如 gmail 等作为 relay sever, 这是因为 私有的邮件服务器发送出去的邮件会被认为是垃圾邮件 。 据说是可以配置 domainTXT 类型的记录可以解决这个问题,但是我没尝试成功。

2 配置的详细过程

2.1 配置SSL证书

2.1.1 生成私有证书

可以手动生成私有证书, 也可以通过acme tools 生成对应的SSL证书。

  • 生成根证书及私钥

    openssl genrsa -out private/cakey.pem 1024 #生成CA根证书私钥
    openssl req -new -x509 -key private/cakey.pem -out cacert.pem #生成CA根证书
  • 生成服务器证书私钥、证书

    openssl genrsa -out private/yourdomain.key 1024
    openssl req -new -key private/server.key -out crl/yourdomain.csr #生成证书请求文件,可提供认证CA签核,或自签名。
    openssl ca -in crl/server.csr -out certs/yourdomain.crt #自签名证书

最后将生成的 keycrt 文件放到 /etc/ssl/ 下对应的 certs , private 目录下面即可。

2.2 配置Postfix

  • 编辑 /etc/postfix/main.cf 文件,配置域名,证书并起用 SSL 以及 sasl 的选项。

    myhostname = xxxxx.com
    mydomain = xxxx.com
    smtpd_use_tls = yes
    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_cert_file = /etc/pki/tls/certs/yourdomain.crt
    smtpd_tls_key_file = /etc/pki/tls/private/yourdomain.key
    smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_security_options = noanonymous
    smtpd_sasl_local_domain = $mydomain
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    

    myhostname , mydomain 填上你真实的域名, 同时,修改真实的 ssl 证书的路径。

  • 编辑 /etc/postfix/generic 文件。 添加一行到文件最后面

    @domainname   xxxxx.gmail.com
    

    其中 domainname 替换为你申请的域名, xxxxx.gmail.com 为你之前准备的可以作为 relay server 的邮箱。 配置到这里,表示使用该账号发送邮件出去,目的是为了避免你发出去的邮件被认为是垃圾邮件。

  • 编辑或创建 /etc/postfix/sasl_passwd 文件。 添加一行到文件最后面

    [smtp.gmail.com]:587    account@gmail.com:password
    

    这里是配置当使用 gmail 的作为 SMTPrelay sever 的时候,使用的账号和密码。 accountpassword 替换为你真实的用户名和密码。

  • 编辑 /etc/postfix/master.cf 文件。 mastercf.png

2.3 配置Dovecot

  • 编辑 /etc/dovecot/dovecot.conf 文件, 确认支持的协议为 imappop3

    protocols = imap pop3
    
  • 编辑 /etc/dovecot/conf.d/10-auth.conf ,确认以下配置:

    disable_plaintext_auth = no
    auth_mechanisms = plain login
    
  • 编辑 /etc/dovecot/conf.d/10-ssl.conf, 确认开启了 ssl 以及使用了正确的证书:

    ssl = yes
    ssl_cert = </etc/pki/tls/certs/yourdomain.crt
    ssl_key = </etc/pki/tls/private/yourdomain.key
    

2.4 生效配置,重启服务

  • 更新 postfix lookup table

    sudo postmap /etc/postfix/sasl_passwd
    sudo postmap /etc/postfix/generic
  • 重启 postfix=, =dovecot 服务

    sudo systemctl restart postfix
    sudo systemctl restart dovecot
  • 开机启动 postfix, dovecot 服务

    sudo systemctl enable postfix
    sudo systemctl enable dovecot

2.5 确认以及配置防火墙

下面是 postfix, dovecot 使用到的端口, 配置 iptables 打开这些端口。

Protocols Usage Plain Text/ encrypted session Encrypted session only
POP3 Incoming mail 110 995
IMAP Incoming mail 143 993
SMTP Outgoing mail 25 465
Submission Outgoing mail 587  

3 测试功能

在测试 smtpimap 协议的时候, 对 encrypted session only 使用的端口默认是需要用 openssl 来访问的。 而非 encrypted 可以直接使用 telnet 来测试。

  • 测试 SMTP 服务 调用 openssl 访问服务器的 465 端口:

    openssl s_client -connect mail.example.com:465

    返回 ssl 协商的结果

    New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
    Server public key is 4096 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-RSA-AES256-GCM-SHA384
        Session-ID: 4D22C02B32E6B83A7380CE7C69A69FEE3985CE7B653EB423CDCA29940
        Session-ID-ctx:
        Master-Key: 9E10F874F9052D5EE47DE164A3DC95A008A3829D6E7CBD071473D9313ADC3FD9DE9DE
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        TLS session ticket lifetime hint: 3600 (seconds)
        TLS session ticket:
        0000 - 07 ad 7b 9e c4 12 81 3f-13 06 ed c9 72 3a 08 e7   ..{....?....r:..
        0010 - 0e f2 72 84 70 18 47 17-94 b2 05 94 1a a7 6a 6c   ..r.p.G.......jl
        0020 - c5 37 04 ee f7 c0 36 0f-29 44 67 a9 cb f6 91 14   .7....6.)Dg.....
        0030 - 72 b6 21 45 fa 82 3b 8e-51 76 5b 4a 2e 6c 26 2a   r.!E..;.Qv[J.l&*
        0040 - 15 0c a3 3d 2c ed de ee-41 04 26 0c 89 93 c3 4f   ...=,...A.&....O
        0050 - e9 84 a0 46 68 73 b7 f4-94 3f 46 a9 af 37 a4 7f   ...Fhs...?F..7..
        0060 - 2f 3c 73 bc 43 8b 75 ac-5f 33 10 60 f6 d4 ca 74   /<s.C.u._3.`...t
        0070 - a6 60 49 8f bc 7e be 73-1e 47 c5 6d 50 21 95 53   .`I..~.s.G.mP!.S
        0080 - 9b 78 82 d6 0d d5 32 20-eb 94 50 bc a6 b1 6f fe   .x....2 ..P...o.
        0090 - 03 ee 80 4d 09 35 47 14-e4 5d aa d2 18 1f c7 ee   ...M.5G..]......
        00a0 - ca 11 a6 c1 3f d3 66 42-df 3b 4d 66 0e 7e 95 89   ....?.fB.;Mf.~..
        00b0 - 62 d0 69 76 3b fd 74 7a-d7 86 d5 6a d0 23 f8 b3   b.iv;.tz...j.#..
    
        Start Time: 1584262970
        Timeout   : 7200 (sec)
        Verify return code: 18 (self signed certificate)
        Extended master secret: no
    ---
    220 mail.example.com ESMTP Postfix
    

    输入 auth login plain 的命令, 后面跟上你的用户名密码的 base64 编码。 其中 account, password 用你真实的账号替换。

    echo -ne "\0account\0password" | base64
    220 machineheart.tech ESMTP Postfix
    AUTH LOGIN PLAIN AGFjY291bnQAcGFzc3dvcmQ=
    501 5.5.4 Syntax: AUTH mechanism
    AUTH LOGIN
    334 VXNlcm5hbWU6
    

    看到类似的返回即表示验证成功。后面即可以使用 smtp 的常用命令类似 mail from:, rcpt to: 去发送邮件了。

  • 测试 IMAP 服务 与 smtp 类似,也是使用 openssl 来测试 993 端口。

    openssl s_client -connect mail.example.com:993
     *tag login account password*
     tag OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES 
     THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED 
     I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE 
     SNIPPET=FUZZY SPECIAL-USE] Logged in
     *tag list "" "*"*
     * LIST (\HasNoChildren \Sent) "." Sent
     * LIST (\HasNoChildren \Drafts) "." Drafts
     * LIST (\HasNoChildren) "." "Deleted Items"
     * LIST (\HasNoChildren) "." INBOX
    tag OK List completed (0.001 + 0.000 secs).
    

Date: 2020-03-15

Author: shawn-win11

Created: 2022-09-24 Sat 14:46

Validate