Debian 10 部署 Roundcube Webmail:Bind9、Postfix、Dovecot、SMTPS、IMAPS 与 HTTPS
1. 服务介绍
Roundcube 是基于浏览器的 Web 邮件客户端,提供登录、收件箱、邮件阅读、撰写、附件、通讯录和文件夹管理功能。完整邮件系统通常由多个服务协同完成:Bind9 提供域名解析,Postfix 负责 SMTP 投递,Dovecot 提供 IMAP 邮件访问,Apache2 提供 HTTPS 网页入口,MariaDB 保存 Roundcube 的配置、会话和用户偏好,CA 或受信任证书保障 TLS 通信。
本文整理一套 Debian 10 实验环境中的私人 Webmail 配置流程,覆盖邮箱域名解析、邮件用户、广播别名、Roundcube 数据库、Apache HTTPS、SMTPS、IMAPS 和浏览器收发测试。Roundcube 只负责网页操作,不负责投递邮件,也不代替 Dovecot 保存邮件正文。
2. 准备运行环境
• 操作系统:Debian 10;其他 Debian 版本需要按软件包、PHP 和配置文件路径调整。
• 权限:root 或具备 sudo 权限的管理员账号。
• 实验域名:将 example.com 替换为自己的邮件域名;准备 mail.example.com 或 webmail.example.com 的 A 记录和 MX 记录。
• 服务角色:可以在一台实验主机部署,也可以拆分 DNS、邮件、数据库和 Web 服务;拆分部署时将 localhost 替换为对应服务器地址。
• 软件源:apt 源可用,服务器能访问软件仓库。
• 证书:准备与访问域名匹配的证书和私钥。实验环境可使用自建 CA,生产环境应使用受信任证书。
• 测试账号:准备两个邮箱账号,例如 mailuser1@example.com 和 mailuser2@example.com;账号密码只在实验环境中保存,不写入文章或脚本。
• 网络端口:DNS 使用 53,HTTP/HTTPS 使用 80/443,SMTP 使用 25/465/587,IMAP 使用 143/993。
• 操作建议:修改配置前备份文件;所有示例中的域名、IP、账号、密码和证书路径都必须替换为实际值。
3. 相关知识
3.1 DNS 与邮件域名
邮件系统至少需要正向解析和 MX 记录。Webmail 域名用于浏览器访问,邮件域名用于收发邮件;两者可以相同,也可以分开。修改区域文件后必须递增 SOA 序列号,否则从服务器或缓存可能继续使用旧数据。
3.2 Postfix、Dovecot 与 Roundcube
Postfix 接收 SMTP 请求并把邮件投递到本地邮箱或远程服务器;Dovecot 通过 IMAP 让客户端读取邮箱;Roundcube 通过 IMAP 读信,通过 SMTP Submission 发信。Roundcube 数据库连接正常,只能说明 Web 客户端自身配置正常,不能证明邮箱认证或 SMTP 投递正常。
3.3 端口和 TLS
• 25/tcp:服务器之间的 SMTP,通常不作为普通客户端提交端口。
• 465/tcp:SMTPS,连接建立后立即进入 TLS。
• 587/tcp:SMTP Submission,通常使用 STARTTLS 和 SMTP AUTH。
• 993/tcp:IMAPS,连接建立后立即进入 TLS。
• 143/tcp:IMAP,可通过 STARTTLS 加密。
Roundcube 的 default_host 应指向 IMAPS 或 IMAP 服务,smtp_server 应指向 SMTPS 或 Submission 服务,协议前缀和端口必须与实际服务一致。
3.4 数据库与邮箱数据
MariaDB 只保存 Roundcube 的设置、联系人、会话和缓存等数据。邮件正文、收件箱和文件夹由 Dovecot 管理。数据库账号应使用独立用户,只授予 Roundcube 数据库权限,不要直接使用数据库 root 账号连接 Web 应用。
3.5 广播别名
广播地址是 Postfix alias 或虚拟别名,不是单独的邮箱目录。收到发往广播地址的邮件后,Postfix 将邮件复制投递给多个目标用户。目标用户列表发生变化时要重新生成 alias 数据库并重新加载 Postfix。
4. 实验步骤
4.1 配置 Bind9 与邮箱域名
安装 DNS 服务和测试工具:
bash
apt update
apt -y install bind9 bind9utils dnsutils
systemctl enable --now bind9
在 /etc/bind/named.conf.local 中添加正向区域。下面使用示例域名和地址,按实际拓扑替换:
bind
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
};
编辑 /etc/bind/db.example.com,至少准备 SOA、NS、A 和 MX 记录:
dns
$TTL 86400
@ IN SOA ns1.example.com. admin.example.com. (
2026091301 ; serial
3600 ; refresh
900 ; retry
604800 ; expire
86400 ) ; minimum
IN NS ns1.example.com.
ns1 IN A 192.0.2.10
mail IN A 192.0.2.10
webmail IN A 192.0.2.10
@ IN MX 10 mail.example.com.
检查配置并重载 Bind9:
bash
named-checkconf
named-checkzone example.com /etc/bind/db.example.com
systemctl reload bind9
验证正向解析、MX 和服务状态:
bash
dig @127.0.0.1 mail.example.com A
dig @127.0.0.1 example.com MX
systemctl --no-pager --full status bind9










4.2 配置 Postfix 和 Dovecot
安装邮件服务:
bash
apt -y install postfix dovecot-core dovecot-imapd dovecot-pop3d
Postfix 主配置至少确认主机名、邮件域名、投递目录和本地网络:
bash
postconf -e 'myhostname = mail.example.com'
postconf -e 'mydomain = example.com'
postconf -e 'myorigin = $mydomain'
postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain'
postconf -e 'home_mailbox = Maildir/'
postconf -e 'inet_interfaces = all'
postconf -e 'inet_protocols = ipv4'
Dovecot 使用 Maildir 时,确认 /etc/dovecot/conf.d/10-mail.conf 中的邮箱位置:
conf
mail_location = maildir:~/Maildir
确认认证机制和监听协议,生产环境不要启用不加密的明文认证:
conf
# /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes
auth_mechanisms = plain login
# /etc/dovecot/conf.d/10-master.conf
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
创建实验用户和 Maildir:
bash
adduser mailuser1
adduser mailuser2
su - mailuser1 -c 'mkdir -p ~/Maildir/{cur,new,tmp}'
su - mailuser2 -c 'mkdir -p ~/Maildir/{cur,new,tmp}'
配置广播 alias。编辑 /etc/aliases,加入实际目标用户:
text
all: mailuser1, mailuser2
生成 alias 数据库并重载服务:
bash
newaliases
postfix check
systemctl enable --now postfix dovecot
systemctl reload postfix dovecot
验证用户、队列、监听端口和 Dovecot 配置:
bash
getent passwd mailuser1 mailuser2
postconf -n
doveconf -n
postqueue -p
ss -lntp | egrep ':(25|110|143|993)\b'























4.3 创建实验 CA 和服务器证书
实验环境可以用自建 CA 为邮件和 Web 服务签发证书。证书的 CN/SAN 必须包含客户端访问的域名,例如 mail.example.com 和 webmail.example.com。
bash
mkdir -p /root/lab-ca/{private,certs,newcerts}
chmod 700 /root/lab-ca/private
touch /root/lab-ca/index.txt
echo 1000 > /root/lab-ca/serial
openssl genrsa -out /root/lab-ca/private/ca.key 4096
openssl req -x509 -new -nodes -key /root/lab-ca/private/ca.key \
-sha256 -days 3650 -out /root/lab-ca/ca.crt \
-subj '/C=CN/O=Lab/CN=Lab Root CA'
生成服务器私钥、CSR 和证书时,使用包含 SAN 的配置文件:
bash
openssl genrsa -out /etc/ssl/private/mail.example.com.key 2048
openssl req -new -key /etc/ssl/private/mail.example.com.key \
-out /root/mail.example.com.csr \
-subj '/C=CN/O=Lab/CN=mail.example.com'
将 CA 证书导入测试客户端信任库后,再使用浏览器、Outlook 或 openssl s_client 验证 TLS。生产环境不要复用实验私钥,也不要把私钥上传到文章平台。





4.4 配置 MariaDB 数据库
安装并启动 MariaDB:
bash
apt -y install mariadb-server mariadb-client
systemctl enable --now mariadb
mysql_secure_installation
为 Roundcube 创建独立数据库和账号。密码使用现场生成的随机值:
sql
CREATE DATABASE roundcube CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'roundcube'@'localhost' IDENTIFIED BY '<roundcube-db-password>';
GRANT ALL PRIVILEGES ON roundcube.* TO 'roundcube'@'localhost';
FLUSH PRIVILEGES;
验证数据库账号和字符集:
bash
mysql -u roundcube -p -D roundcube -e 'SELECT VERSION(); SHOW TABLES;'


4.5 安装 Roundcube 并导入数据库结构
安装 Roundcube、Apache、PHP 和 MariaDB 驱动:
bash
apt -y install roundcube roundcube-mysql apache2 php php-mysql php-mbstring php-intl php-xml php-curl php-zip php-imagick libapache2-mod-php
安装时如果由 dbconfig-common 自动创建数据库,确认数据库名、账号和密码与后续配置一致;如果已经手工创建数据库,则选择手动配置。
不同 Debian 软件包版本的初始化 SQL 路径可能不同,先查找实际文件:
bash
find /usr/share/roundcube /usr/share/dbconfig-common/data/roundcube \
-type f \( -name '*.sql' -o -name 'mysql' \) -print
导入数据库结构,以下路径按实际查找结果替换:
bash
mysql -u roundcube -p roundcube < /usr/share/roundcube/SQL/mysql.initial.sql
编辑 /etc/roundcube/debian-db.php 和 /etc/roundcube/config.inc.php,至少配置数据库、IMAPS、SMTPS 和随机密钥:
php
$config['db_dsnw'] = 'mysql://roundcube:<roundcube-db-password>@localhost/roundcube';
$config['default_host'] = 'ssl://mail.example.com:993';
$config['smtp_server'] = 'tls://mail.example.com:587';
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
$config['product_name'] = 'Example Webmail';
$config['des_key'] = '<replace-with-a-random-secret>';
限制配置文件权限:
bash
chown root:www-data /etc/roundcube/debian-db.php /etc/roundcube/config.inc.php
chmod 640 /etc/roundcube/debian-db.php /etc/roundcube/config.inc.php







4.6 配置 Apache HTTPS 和 Roundcube 访问
启用 Roundcube 配置、SSL 和常用模块:
bash
a2enconf roundcube
a2enmod ssl headers rewrite
创建或修改 HTTPS 虚拟主机:
apache
<VirtualHost *:80>
ServerName webmail.example.com
Redirect permanent / https://webmail.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName webmail.example.com
DocumentRoot /var/lib/roundcube
SSLEngine on
SSLCertificateFile /etc/ssl/certs/webmail.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/webmail.example.com.key
<Directory /var/lib/roundcube>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
检查 Apache 配置、证书权限和监听端口:
bash
apachectl configtest
apachectl -S
systemctl enable --now apache2
systemctl reload apache2
ss -lntp | egrep ':(80|443)\b'
客户端访问:
text
https://webmail.example.com/roundcube












4.7 配置 Postfix SMTPS 和 Dovecot IMAPS
4.7.1 Postfix 启用 Submission/SMTPS
在 /etc/postfix/main.cf 中确认 TLS 证书和认证基础参数:
conf
smtpd_tls_cert_file = /etc/ssl/certs/mail.example.com.crt
smtpd_tls_key_file = /etc/ssl/private/mail.example.com.key
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
在 /etc/postfix/master.cf 中启用 Submission 端口,并按实际 Dovecot Socket 路径调整:
conf
submission inet n - y - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
smtps inet n - y - - smtpd
-o smtpd_tls_wrappermode=yes
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
4.7.2 Dovecot 提供 IMAPS 和 SMTP AUTH
在 Dovecot 中配置 TLS:
conf
protocols = imap
listen = *
ssl = required
ssl_cert = </etc/ssl/certs/mail.example.com.crt
ssl_key = </etc/ssl/private/mail.example.com.key
在认证服务中暴露 Postfix 可访问的 UNIX Socket:
conf
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
重启并检查配置:
bash
doveconf -n
postfix check
systemctl restart dovecot postfix
ss -lntp | egrep ':(25|465|587|993)\b'
















4.8 让 Roundcube 使用 SMTPS 和 IMAPS
确认 /etc/roundcube/config.inc.php 中的地址与服务端口一致:
php
$config['default_host'] = 'ssl://mail.example.com:993';
$config['smtp_server'] = 'tls://mail.example.com:587';
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
如果服务端只启用 SMTPS 465,则按实际实现改为:
php
$config['smtp_server'] = 'ssl://mail.example.com:465';
修改后检查 PHP 语法和 Apache 状态:
bash
php -l /etc/roundcube/config.inc.php
apachectl configtest
systemctl reload apache2
不要同时把 IMAPS 地址写成 SMTP 地址,也不要把 ssl://、tls:// 和端口混用。Roundcube 能打开但登录失败时,先看 Dovecot 认证日志;登录成功但发送失败时,先看 Postfix Submission/SMTPS 日志。









5. 验证结果
5.1 DNS 验证
bash
named-checkconf
named-checkzone example.com /etc/bind/db.example.com
dig @127.0.0.1 example.com MX
dig @127.0.0.1 mail.example.com A
预期结果:区域检查返回 OK;MX 指向邮件主机;邮件主机和 Webmail 主机解析到预期地址。
5.2 邮件服务验证
bash
postfix check
doveconf -n
systemctl is-active postfix dovecot
ss -lntp | egrep ':(25|465|587|143|993)\b'
postqueue -p
预期结果:服务状态为 active;SMTP、Submission/SMTPS 和 IMAPS 端口由对应服务监听;队列无异常积压。
5.3 TLS 验证
bash
openssl s_client -connect mail.example.com:993 -servername mail.example.com -crlf
openssl s_client -connect mail.example.com:465 -servername mail.example.com -crlf
openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com -crlf
curl -kI https://webmail.example.com/roundcube/
检查证书域名、证书链、TLS 握手和 HTTP 状态。生产环境应使用受信任证书,不应长期依赖 curl -k。
5.4 Roundcube 和数据库验证
bash
mysql -u roundcube -p -D roundcube -e 'SHOW TABLES;'
php -m | egrep 'curl|dom|mbstring|mysqli|pdo_mysql|xml|zip'
find /var/log/roundcube -type f -maxdepth 1 -print -exec tail -n 40 {} \; 2>/dev/null
tail -n 80 /var/log/apache2/error.log
tail -n 80 /var/log/mail.log
预期结果:Roundcube 数据表存在;PHP 扩展齐全;Apache、Roundcube、Postfix 和 Dovecot 日志没有持续报错。
5.5 浏览器收发验证
-
浏览器打开
https://webmail.example.com/roundcube。 -
使用
mailuser1@example.com登录,向mailuser2@example.com发送测试邮件。 -
使用
mailuser2@example.com登录,确认邮件进入收件箱并回复。 -
向广播地址发送邮件,确认所有目标用户都能在自己的收件箱看到邮件。
-
发送带附件邮件,验证上传、下载和文件夹刷新。
-
在浏览器开发者工具或服务器日志中确认连接使用 HTTPS、IMAPS 和 SMTPS/Submission。
6. 常见问题
6.1 DNS 解析正确但邮件无法投递
检查 MX、A、反向解析、Postfix mydestination 和本地防火墙。修改区域文件后递增 SOA 序列号并重新加载 Bind9。
6.2 Roundcube 页面 403、404 或 500
检查 Apache Alias、DocumentRoot、<Directory> 权限、PHP 扩展和 Apache 错误日志:
bash
apachectl -S
namei -l /var/lib/roundcube
journalctl -u apache2 -n 80 --no-pager
6.3 页面能打开但登录失败
检查 default_host、993 端口、证书 SAN、Dovecot mail_location、认证机制和 Dovecot 日志。Roundcube 数据库连接成功不代表 Dovecot 账号认证成功。
6.4 能登录但不能发信
检查 smtp_server 协议、465/587 端口、SMTP AUTH、TLS 和 Postfix Submission 配置;确认 %u、%p 被当前邮箱账号和密码替换。
6.5 广播地址没有投递到所有用户
检查 /etc/aliases、newaliases 结果、目标用户名和 Postfix 日志。修改 alias 后必须重新生成数据库并 reload Postfix。
6.6 TLS 证书告警或握手失败
确认访问域名与证书 SAN 一致,证书链完整,私钥权限正确,Apache/Postfix/Dovecot 加载同一套匹配证书。修改证书后重新执行配置检查并重启或 reload 对应服务。
6.7 队列积压
bash
postqueue -p
mailq
journalctl -u postfix -n 100 --no-pager
根据日志区分 DNS、TLS、认证、远端拒收和网络阻断,不要直接反复重试造成重复投递。