在树莓派上安装设置邮件服务器

我们有不少项目需要发送邮件,而且需要有自己的邮件服务器。

下面我们会一步步的教你如何安装和设置一个简单的SMTP邮件服务器,并且安装一个webmail

如何在树莓派上安装设置一个邮件服务器呢?

邮件服务器的安装大概有这么几个步骤:

  1. 安装Postfix来发送邮件;
  2. 设置Postfix来接收邮件;
  3. 增加Dovecot让我们可以用POP/IMAP来管理邮件;
  4. 安装RoundCube让我们可以在web页面上访问我们的邮件;

下面我们会详细介绍每个步骤。

预置条件

要想安装邮件服务器,至少有一台树莓派和和作为中继的SMTP服务器(譬如Gmail)。

如果想学习本教程,至少要满足下面几个条件:

  1. 一台树莓派;
  2. 一个域名(下面所有用到域名的地方都会用domain.com来代替);
  3. 一个静态公网IP地址(至少有一个动态域名服务);

另外两个建议:

  • 建议按照这个教程先安装树莓派的操作系统raspbian (lite版本足够使用);

  • 建议在你经常使用的计算机上使用 SSH 按照本教程复制/粘贴命令和配置;

安全提示

建立自有的安全可用的邮件服务器往往是很困难的。

安装设置过程中可能会很容易就错过某一个设置,会导致你的服务器变成一个开放的 SMTP 中继,或被垃圾邮件填满。

所以,一定要严格遵循本教程,查看系统日志,确保只有你在服务器上执行这些操作。

增加额外的安全措施,像防火墙firewallfail2ban服务就很好。

DNS 配置

IP 地址

在接下来的步骤中,我们将更改域名 DNS 设置,使用我们的 IP 地址作为邮件服务器

如果没有静态公网 IP 地址,则需要使用像花生壳之类的免费动态 DNS 服务(ddns)将域名不断重定向到动态变化的 IP 地址,你必须安装一个工具定期把服务器当前 IP 地址发送给它们,然后它们会将域名重定向到最后一个你发送的 IP 地址上,这样你的域名才会映射到正确的 IP地址上。

如果你没有购买顶级域名的话,可以直接使用这个动态域名提供商的二级域名。

对于一个电子邮件服务器来说,动态域名并不是个很好的选择,因为当你的 IP 地址改变时,会有一个小的停机时间;如果不较真的话,这样也还可以。

Dns 解析配置

现在需要去你的域名注册商网站,增加或改变下面的域名解析记录来匹配你的当前 IP 地址(或者你的动态 DNS 提供商域名) :

  • MX
  • pop.domain.com
  • smtp.domain.com
  • imap.domain.com
  • mail.domain.com

MX这条记录强制在你的树莓派上接收电子邮件。

其他几条记录仅仅是为了让你访问你的邮件而更容易记住的名字。

修改这几条记录,可能要最长要24小时才能生效。

你可以用一些工具(如 Network-Tools.com)来查看这些变更是否生效。

使用Postfix发送邮件

现在让我们来进行主要的事情,并且开始安装 Postfix

Postfix是邮件服务器的基础组件,有了它,才可以发送和接收对应到我们域名的邮件。

这一步,我们会看到如何才能发送邮件。

安装

开始安装 Postfix

1
sudo apt-get install postfix

在安装过程中,我们必须选择如下两个配置项:

  • 邮件配置的一般类型:Internet site
  • 系统邮件名称: domain.com

现在,我们将在生成的配置文件中修改两个地方:

  • vi或者其他编辑器(如: nano)打开配置文件

    1
    sudo vi /etc/postfix/main.cf
  • 禁用 IPv6 管理

    • 把下面的配置项

      1
      inet_protocols = all
    • 替换为:

      1
      inet_protocols = ipv4
  • myhostname配置项的值修改为你的域名

    1
    myhostname= domain.com
  • 如果你使用的是本地局域网,由于大多数互联网提供商都不允许直接发送电子邮件,所以你必须在配置文件中添加一个中继主机(relay host)配置项,并请求服务提供商提供一个中继服务器

    1
    relayhost = smtp.yourprovider.com
  • 保存,退出 (:wq)

  • 重新启动 Postfix

    1
    sudo service postfix restart

此时,服务器应该能够正常启动,不会出现启动错误。如果出现错误,在继续下面步骤之前解决这些问题。

测试

现在我们将通过从 Raspberry Pi 发送电子邮件进行第一次测试

Telnet

使用telnet工具连接到Postfix进行测试。

  • 安装 telnet工具

    1
    sudo apt-get install telnet
  • 连接到 SMTP 服务器

    1
    telnet localhost 25
  • 输入下面的一系列命令:

    • ehlo
    • mail from: you@domain.com
    • rcpt to: user@mail.com
    • data
    • Subject: test
    • Test
    • .
    • quit
  • 上面的一系列命令将会创建一个电子邮件,并将其发送到 user@mail. com (外部电子邮件地址)。

完整的过程跟踪:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
pi@raspberrypi:~ $ telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 domain.com ESMTP Postfix (Raspbian)
ehlo domain.com
250-domain.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
mail from: me@domain.com
250 2.1.0 Ok
rcpt to: youremail@gmail.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Subject: test
Test
.
250 2.0.0 Ok: queued as 44EAE1FE54
quit
221 2.0.0 Bye

Mailutils(邮件相关工具)

如果您正在寻找一种比较友好的方式来从树莓派上发送电子邮件到 user@mail.com ,可以安装 mailutils 来使用 mail 命令

  • 安装 mailutils

    1
    sudo apt-get install mailutils
  • 使用mail命令发送一封测试邮件

    1
    echo 'Test' | mail -s "Test mail command" you@gmail.com

在这两种情况下,我们都可以在日志文件 /var/log/mail.log中看到发送电子邮件的整个过程。

使用Postfix接收电子邮件

编辑Postfix的配置文件让我们可以接收电子邮件。

配置

我们将使用 Maildir 邮箱格式来完成此操作。
Maildir 是一种存储电子邮件的方法,安全又简单。
其中:每个邮箱都是一个目录,每个电子邮件都是一个单独的文件。

  • 编辑配置文件

    1
    sudo vi /etc/postfix/main.cf
  • 在文件尾部增加下面的配置项

    1
    2
    home_mailbox = Maildir/
    mailbox_command =

    这个配置项会让Postfix为每个系统用户创建Maildir文件夹,用户接收到的电子邮件会存放到对应的文件夹中。

现在,让我们按照以下步骤创建 Maildir 文件夹模板:

  • 安装必须的软件包

    1
    sudo apt-get install dovecot-common dovecot-imapd
  • 在模板目录中创建文件夹

    1
    2
    3
    4
    5
    6
    sudo maildirmake.dovecot /etc/skel/Maildir
    sudo maildirmake.dovecot /etc/skel/Maildir/.Drafts
    sudo maildirmake.dovecot /etc/skel/Maildir/.Sent
    sudo maildirmake.dovecot /etc/skel/Maildir/.Spam
    sudo maildirmake.dovecot /etc/skel/Maildir/.Trash
    sudo maildirmake.dovecot /etc/skel/Maildir/.Templates

这些模板会应用到新创建的用户,但是对于已经存在的老用户,需要手工创建。

例如,必须为pi用户运行下面的命令创建对应的邮件文件夹:

1
2
3
sudo cp -r /etc/skel/Maildir /home/pi/
sudo chown -R pi:pi /home/pi/Maildir
sudo chmod -R 700 /home/pi/Maildir

测试

现在可以像前面一样重复相同类型的测试,把用户 pi 作为接收者就可以了。

1
echo "Test" | mail -s "Test" pi@domain.com

Maildir 文件夹中检查是否邮件已经到达。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pi@raspberrypi:~ $ cat /home/pi/Maildir/new/1535959347.Vb302I3dc1bM266961.raspberrypi
Return-Path: <pi@raspberrypi>
X-Original-To: pi@domain.com
Delivered-To: pi@domain.com
Received: by webinpact.**com** (Postfix, from userid 1000)
id 26B5020423; Mon, 3 Sep 2018 07:22:27 +**0000** (UTC)
Subject: Test
To: <pi@domain.com>
X-Mailer: **mail** (GNU Mailutils 3.1.1)
Message-Id: <20180903072227.26B5020423@domain.com>
Date: Mon, 3 Sep 2018 07:22:27 +**0000** (UTC)
From: pi@raspberrypi

Test

在新的文件夹中应该只有一个邮件,使用tab自动完成功能可以找到它,可以看到返回路径地址(Return-Path)是不正确的,需要修改主机名来解决这个问题。

1
sudo hostname domain.com

我们终归是达到了这一步的目标:收到了发送到我们域名的电子邮件。

保护邮件服务器

正如在本文开头所说,可以设置一些选项来保证 web 服务器的最低安全性。

  • 编辑配置文件

    1
    sudo vi /etc/postfix/main.cf
  • 在文件末尾增加这些配置

    1
    2
    3
    4
    5
    6
    7
    smtpd_helo_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname,
    reject_unknown_helo_hostname,
    check_helo_access hash:/etc/postfix/helo_access

    此配置 SMTP 限制在本地局域网使用,并且在邮件中隐藏你的域名。

  • 创建 helo_access 文件

    1
    sudo vi /etc/postfix/helo_access

    可以把我们想阻止(block)的域名放到这个文件中。

  • 把下面的内容拷贝到helo_access文件中

    1
    2
    3
    4
    X.X.X.X   REJECT
    domain.com REJECT
    smtp.domain.com REJECT
    mail.domain.com REJECT

    用你的公网 IP 地址替换 X.X.X.X

  • 重新启动 postfix daemon

    1
    sudo service postfix restart

安装配置 Dovecot 支持 POPIMAP

现在,我们有了一个功能齐全、安全的邮件服务器。

那么继续下一部分:通过 SASL 身份验证让 POPIMAP 客户机可以访问这个邮件服务器。

你可能已经注意到了,我们已经在前面的步骤中安装了 Devocot 来创建 Maildir 文件夹,剩下唯一要做的事情就是完成配置即可。

配置

  • 打开 Dovecot 配置文件

    1
    sudo vi /etc/dovecot/dovecot.conf
  • 删掉 IPV6 配置项

    • 查找如下行

      1
      \#listen = *, ::
    • 用下面的内容替换

      1
      listen = *
  • 打开 Dovecot mail 配置文件

    1
    sudo vi /etc/dovecot/conf.d/10-mail.conf
  • 编辑 Maildir 文件夹配置项

    • 找到如下行

      1
      mail_location = mbox:~/mail:INBOX=/var/mail/%u
    • 用下面的内容替换

      1
      mail_location = maildir:~/Maildir
  • 打开 Dovecot master 配置文件

    1
    sudo vi /etc/dovecot/conf.d/10-master.conf
  • Dovecot 开始监听 SASL 认证

    • 注释 default service auth 段落中的所有行(在每行之前添加 #)

    • 在文件末尾添加如下内容

      1
      2
      3
      4
      5
      6
      7
      service auth {
      unix_listener /var/spool/postfix/private/auth {
      mode = 0660
      user = postfix
      group = postfix
      }
      }
  • 打开 Dovecot auth 配置文件

    1
    sudo vi /etc/dovecot/conf.d/10-auth.conf
  • 允许纯文本验证

    • 去掉下面这行的注释,并且修改配置项的值为 no

      1
      \#disable_plaintext_auth = yes
    • 修改配置项值为 no

      1
      disable_plaintext_auth = no
  • 同样编辑下面这行

    1
    auth_mechanisms = plain login
  • 编辑 Postfix 配置文件

    1
    sudo vi /etc/postfix/main.cf
  • 配置 Postfix 使用 SASL (添加如下行)

    1
    2
    3
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
  • 重新启动 DovecotPostfix

    1
    2
    sudo service postfix restart
    sudo service dovecot restart

测试

为了测试 SASL 认证能否正常工作,我们将创建一个测试用户,并尝试用它连接到邮件服务器。

创建用户

创建一个登录名为 test 的用户,密码随意。

1
adduser test

获取编码后的密码

我们需要用 base64对明文密码进行编码,可以这样获取:

1
printf '\0%s\0%s' '[LOGIN]' '[PASSWORD]' | openssl base64

例如:(test/password,编码后的结果是:AHRlc3QAcGFzc3dvcmQ=

登录

现在,我们可以用 telnet 指定这个字符串进行标识尝试建立连接。
唯一的变化是改用 AUTH PLAIN 命令来登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
pi@raspberrypi:~ $ telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 domain.com ESMTP Postfix (Raspbian)
ehlo domain.com
250-domain.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN AHRlc3QAcGFzc3dvcmQ=
235 2.7.0 Authentication successful
mail from: me@domain.com
250 2.1.0 Ok
rcpt to: youremail@gmail.com
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Subject: test
Test
.
250 2.0.0 Ok: queued as 44EAE1FE54
quit
221 2.0.0 Bye

使能 IMAPS

Dovecot 允许我们连接 IMAP (telnet localhost 143),但是我们应该先为 IMAP 启用 TLSTLS的端口是 $993$

  • 编辑 Dovecot master 配置文件

    1
    sudo vi /etc/dovecot/conf.d/10-master.conf
  • 配置在端口 $993$ 上进行监听

    配置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    service imap-login {
    inet_listener imap {
    port = 143
    }
    inet_listener imaps {
    port = 993
    ssl = yes
    }
    }
  • 然后,编辑 SSL 配置文件

    1
    sudo vi /etc/dovecot/conf.d/10-ssl.conf
  • 修改第一行,使 SSL 生效

    1
    ssl = yes
  • 去掉 certificate 路径配置的注释

    1
    2
    ssl_cert = </etc/dovecot/dovecot.pem
    ssl_key = </etc/dovecot/private/dovecot.pem
  • 还得去掉 ssl_protocols 选项的注释,拒绝 SSLv3

    1
    ssl_protocols = !SSLv3
  • 最后,重启 Dovecot 服务

    1
    sudo service dovecot restart

Dovecot 开始监听 $993$ 端口,不过现在如果连接 $993$ 端口还是会报错:

1
imap-login: Fatal: Couldn't parse private ssl_key: error:0906D06C:PEM routines:PE

我们需要生成 SSL 证书:

1
2
cd /etc/dovecot
sudo openssl req -new -x509 -nodes -config /usr/share/dovecot/dovecot-openssl.cnf -out dovecot.pem -keyout private/dovecot.pem -days 365

现在,用下面的命令试试连接 IMAPS 服务并登录,确认 IMAPS 服务是否正常运行:

1
openssl s_client -connect localhost:993

登录语法:a login [LOGIN] [PASSWORD]

整个过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
a login pi password
a 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 SPECIAL-USE] Logged in
b select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 3 EXISTS
* 0 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1536038369] UIDs valid
* OK [UIDNEXT 4] Predicted next UID
b OK [READ-WRITE] Select completed (0.000 + 0.000 secs).
b logout
* BYE Logging out
b OK Logout completed (0.000 + 0.000 secs).
closed

现在可以从局域网中的任意客户机连接到 IMAP 服务,如果你想在外部网络访问你的服务,需要在路由器或者防火墙上开放所需的端口。

设置 Roundcube ,增加 webmail 访问方式

大部分工作已经完成,我们将进一步推进,在 Raspberry Pi 上向邮件服务器添加一个 webmail 服务器,Roundcube是一个现代化的免费开源 webmail软件。

和其他 webmail 相比,Roundcube 的最大优势在于它可以直接从 Debianrasbian官方 软件仓库中获取。

如果 Raspbian 操作系统刚安装好,还需要在操作系统上装上 MySQL/MariaDB数据库软件。

MySQL 数据库服务器

Roundcube 的数据库是存放在 MySQL上的,所以如果没有就先安装 MySQL

1
sudo apt-get install mariadb-server

按照下面的步骤,设置 MySQL Server root 用户密码,并且创建一个 Roundcube

  • root 用户连接 MySQL Server

    1
    sudo mysql -uroot
  • 设置 root 用户的密码

    1
    2
    3
    use mysql;
    UPDATE user SET password=PASSWORD('YourPassword'), plugin='' WHERE User='root' AND Host = 'localhost';
    FLUSH PRIVILEGES;

    别忘了用你的真正密码替换上面命令中的 YourPassword

  • Roundcube 创建一个数据库用户

    1
    CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'password';

    用你的真正密码替换上面命令中的password

  • 创建 Roundcube 数据库

    1
    CREATE DATABASE roundcubemail;
  • 赋予 Roundcube用户访问 Roundcube 数据库的所有权限

    1
    GRANT ALL PRIVILEGES ON roundcubemail.* to 'roundcube'@'localhost';
  • 退出 mysql 控制台

    1
    2
    FLUSH PRIVILEGES;
    quit

数据库配置好了,继续下一步。

Roundcube

执行下面的命令,安装 RoundCube

1
sudo apt-get install roundcube roundcube-plugins

其他所有依赖项(主要是 ApachePHPMySQL 客户端)也会自动安装。

同样,安装向导会询问有关 MySQL 服务器的问题:

  • Imap Server: ssl://imap.domain.com:993
  • Default language: 设置为中文
  • Configure database with dbconfig-common: yes
  • MySQL application password for Roundcube: Roundcube 数据库用户密码
  • Database administrator password: MySQL 数据库服务器的 root 密码

现在编辑 Roundcubeapache 配置来启用 web 应用程序,

1
sudo vi /etc/apache2/conf-enabled/roundcube.conf

去掉第一行的注释,

1
Alias /roundcube /var/lib/roundcube

然后用浏览器打开 urlhttp://[RASPBERRY-IP]/roundcube

roundcube login interface

如果出错,用下面的命令重新进入安装向导:

1
sudo dpkg-reconfigure roundcube-core

现在可以用前面步骤中创建的凭据或帐户 pi 登录,到这里 webmail 就可以正式使用了。

记住:可以在 RoundCube 上添加其他插件来扩展功能

日志和配置文件汇总

如上,我们看到了如何在 Raspberry Pi 上设置一个完整的邮件服务器。

如果还有错误,或者想进一步了解,下面是所有相关文件的存放路径,可供查看和参考。

Postfix

本教程使用 Postfix 来发送和接收电子邮件,这是邮件服务器的核心。

配置文件

  • /etc/postfix/main.cf : Postfix 主配置文件
  • /etc/postfix/master.cf : Postfix 过程配置文件

日志文件

  • /var/log/mail.log : 所有的过程和出错信息都记录在这个文件中

Dovecot

Dovecot 用来管理带有 SASL 安全层的 IMAP 连接。

配置文件

  • /etc/dovecot/dovecot.conf : Dovecot 主配置文件
  • /etc/dovecot/conf.d/ : 这个子文件夹包含几个文件,每个文件包含配置的一部分,很容易找到所需选项

日志文件

  • /var/log/syslog : Dovecot 没有自己的专有日志文件,所有日志都在 syslog

Apache

Apache 用来承载 Roundcube 业务。
除非 RoundCube 根本无法访问,否则不需要改动 Apache 的任何地方。

配置文件

  • /etc/apache2/apache2.conf : apache2 主配置文件
  • /etc/apache2/conf-enabled/ : Apache 承载的具体服务配置 (如 Roundcube.conf)
  • /etc/apache2/sites-enabled/ : 所有 Apache 站点的配置

日志文件

  • /var/log/apache/error.log : Apache 的错误日志文件

Roundcube

Roundcube 是邮件服务器的 webmail,提供 web 方式读取和发送邮件的能力。

配置文件

  • /etc/roundcube/config.inc.php : Roundcube 主配置文件

日志文件

  • /var/log/roundcube/errors : Roundcube 的错误日志文件

结束语

到这里,我们的教程就正式结束了。
我们讲述了如何设置一个完整的邮件服务器,包括:

  • Postfix 提供了邮件的发送和接收,即:邮件传输能力
  • Dovecot 提供了安全认证
  • Roundcube 提供了以 web 方式访问电子邮件的能力

你可能已经注意到,这个安装设置的过程并不简单,有很多配置项,需要耗费很多的精力。

我认为在大多数情况下,Postfix 的第一部分会让你感兴趣,完成这一部分后,就可以发送来自不同项目的电子邮件了,后续其他步骤不是必须的。

无论如何,你只要安装知道怎么做的内容就够了。