域名邮箱自托管实战:用 Cypht 搭一个邮件聚合 WebMail

#前言

为什么要自托管邮件?因为你可以把所有邮箱(Gmail、企业邮箱、个人域名邮箱)统一在一个界面里收发,再也不用在多个邮件 App 之间切换。

本文以生产环境真实部署为例:
域名:mail.zsuuu.com
WebMail 程序:Cypht(开源、轻量、支持 IMAP/SMTP)
后端:Postfix Dovecot MariaDB
Web 服务器:nginx php-fpm



#一、方案选型:为什么是 Cypht?

方案 重量级 部署难度 功能
|——|——--|———-|——|
Roundcube 较重 中等 单邮箱,功能全
RainLoop 轻量 简单 单/多邮箱
Cypht 轻量 简单 多邮箱聚合,支持 RSS/Feed
SquirrelMail 重 复杂 非常老旧

Cypht 的核心优势:
支持同时连接多个 IMAP 账号,统一界面管理
支持 RSS/ATOM 订阅(可以当资讯阅读器)
支持 Gmail/Outlook/Yahoo 等一键配置
数据库存储会话和配置,支持 DB Session
支持 2FA(两步验证)



#二、服务器端邮件服务准备

假设你的 VPS 已经装好了 Postfix Dovecot MariaDB,这里列出关键检查项。

##2.1 检查邮件服务端口

bash
ss -tlnp grep -E "587|993|465|25|110|143"


预期输出(均有 LISTEN):


LISTEN  100  0.0.0.0:587   0.0.0.0:*   SMTP 提交
LISTEN  100  0.0.0.0:993   0.0.0.0:*   IMAPS (加密)
LISTEN  100  0.0.0.0:465   0.0.0.0:*   SMTP SMTPS
LISTEN  100  0.0.0.0:25    0.0.0.0:*   SMTP 收发
LISTEN  100  0.0.0.0:110   0.0.0.0:*   POP3
LISTEN  100  0.0.0.0:143   0.0.0.0:*   IMAP


##2.2 创建邮件数据库(MariaDB)

sql
CREATE DATABASE cypht_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'cypht'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT ALL PRIVILEGES ON cypht_db.* TO 'cypht'@'localhost';
FLUSH PRIVILEGES;


##2.3 SSL 证书

确保域名已有 SSL 证书(Let's Encrypt 或其他),Cypht 要求 HTTPS。

bash
如果没有,用 acme.sh 申请
curl https://get.acme.sh sh
~/.acme.sh/acme.sh --issue -d mail.yourdomain.com --standalone




#三、Cypht 安装(Nginx PHP-FPM 方式)

这是本服务器当前运行的部署方式(不依赖 Docker,直接跑在主机上)。

##3.1 下载 Cypht 源码

bash
cd /www/wwwroot
将 mail.zsuuu.com 替换为你的域名
git clone https://github.com/jasonmunro/hm3.git mail.yourdomain.com
cd mail.yourdomain.com


当前稳定版本:v2.6.0,可指定版本:
bash
git checkout 2.6.0


##3.2 安装 PHP 依赖

bash
安装 PHP 及必要扩展(Ubuntu/Debian)
apt install -y php-fpm php-mysql php-mbstring php-xml php-curl php-gd php-zip php-session php-fileinfo php-dom php-sqlite3

PHP 版本要求:PHP 7.4+
php -v


##3.3 配置 PHP-FPM

Cypht 对 PHP 配置有特定要求,创建配置文件:

bash
cat /usr/local/etc/php/conf.d/cypht.ini << 'EOF'
post_max_size 60M
upload_max_filesize 50M
open_basedir /var/lib/hm3/:/usr/local/share/cypht/:/tmp:/usr/local/bin:/tmp/composer_cache:/tmp/composer_home:/etc
session.save_path /var/lib/hm3/sessions
EOF

创建必要目录
mkdir -p /var/lib/hm3/{users,sessions,attachments}
chown -R www-data:www-data /var/lib/hm3


##3.4 配置 Nginx 站点

bash
cat /etc/nginx/sites-available/mail.yourdomain.com.conf << 'EOF'
server {
    listen 80;
    server_name mail.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name mail.yourdomain.com;

    root /www/wwwroot/mail.yourdomain.com/site;
    index index.php;

    SSL 配置(替换为你自己的证书路径)
    ssl_certificate /fullchain.pem;
    ssl_certificate_key /privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 50M;

    access_log /var/log/nginx/mail-access.log;
    error_log /var/log/nginx/mail-error.log;

    location {
        try_files $uri /index.php$is_args$args;
    }

    location \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index index.php;
        fastcgi_pass unix:/run/php/php-fpm.sock;  或 127.0.0.1:9000
    }

    禁止访问敏感目录
    location /\. {
        deny all;
    }
}
EOF

启用站点
ln -s /etc/nginx/sites-available/mail.yourdomain.com.conf /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx


##3.5 配置 Cypht 环境变量

Cypht 使用环境变量或 .env 文件配置,创建:

bash
cat /www/wwwroot/mail.yourdomain.com/.env << 'EOF'
管理员账号(登录 WebUI 用)
AUTH_USERNAME=admin
AUTH_PASSWORD=admin

数据库配置
DB_CONNECTION_TYPE=host
DB_DRIVER=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=cypht_db
DB_USER=cypht
DB_PASS=your_strong_password

会话和配置存储方式:PHP(文件)或 DB(数据库)
SESSION_TYPE=DB
USER_CONFIG_TYPE=DB

附件存储
ATTACHMENT_DIR=/var/lib/hm3/attachments
EOF


##3.6 初始化数据库表

Cypht 会自动创建所需表,但先手动检查一下:

bash
cd /www/wwwroot/mail.yourdomain.com
php scripts/setup_database.php


输出类似以下内容表示成功:

Setting up Cypht database tables...
Tables created successfully.


##3.7 访问安装向导

打开浏览器访问:https://mail.yourdomain.com

首次访问时,系统会提示创建管理员账户,设置强密码即可。



#四、Cypht Docker 部署(备选方案)

如果不想直接在主机上安装,可以用 Docker 运行。

##4.1 docker-compose.yaml

yaml
services:
  db:
    image: mariadb:10
    ports:
      "3306:3306"
    volumes:
      ./data/mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD=root_password
      MYSQL_DATABASE=cypht
      MYSQL_USER=cypht
      MYSQL_PASSWORD=cypht_password
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ucypht", "-pcypht_password"]
      interval: 10s
      timeout: 5s
      retries: 5

  cypht:
    image: cypht/cypht:2.6.0
    depends_on:
      db:
        condition: service_healthy
    ports:
      "80:80"
    environment:
      AUTH_USERNAME=admin
      AUTH_PASSWORD=admin
      DB_CONNECTION_TYPE=host
      DB_DRIVER=mysql
      DB_HOST=db
      DB_NAME=cypht
      DB_USER=cypht
      DB_PASS=cypht_password
      SESSION_TYPE=DB
      USER_CONFIG_TYPE=DB
    volumes:
      ./data/attachments:/var/lib/hm3/attachments
    restart: always


bash
docker compose up -d


访问 http://your-server-ip 即可。



#五、配置邮件账号(以 zsuuu.com 为例)

登录 Cypht 后,按以下步骤添加邮箱账号:

##5.1 添加 IMAP 账号(收件)

1. 点击 Add an E-mail Account
2. 选择邮箱提供商(Gmail Outlook Yahoo)或手动配置
3. 手动配置参数(以 zsuuu.com 域名邮箱为例):

参数 
|——|—--|
Account name zsuuu
IMAP server mail.zsuuu.com
IMAP port 993(IMAPS)或 143(STARTTLS)|
Use TLS 
IMAP username your-username@zsuuu.com
IMAP password 你的邮箱密码

4. 点击 Add,等待连接测试成功

##5.2 添加 SMTP 账号(发件)

1. 进入 SMTP Servers → Add an SMTP Server
2. 配置参数:

参数 
|——|—--|
SMTP account name zsuuu
SMTP server mail.zsuuu.com
SMTP port 587(STARTTLS)或 465(SSL)|
Use TLS 
SMTP username your-username@zsuuu.com
SMTP password 你的邮箱密码

##5.3 通用邮箱参数参考

邮箱类型 IMAP SMTP SSL/TLS
|———-|——|——|———|
Gmail imap.gmail.com:993 smtp.gmail.com:587 SSL/STARTTLS
Outlook outlook.office365.com:993 smtp.office365.com:587 STARTTLS
QQ 邮箱 imap.qq.com:993 smtp.qq.com:587 SSL
企业域名邮箱 mail.yourdomain.com:993 mail.yourdomain.com:587 STARTTLS



#六、生产环境安全加固

##6.1 强制 HTTPS

确保 nginx 配置了 301 重定向(参考 3.4 节),并添加 HSTS:

nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;


##6.2 限制 PHP-FPM 连接

nginx
location \.php$ {
    限制只允许本地连接
    fastcgi_pass unix:/run/php/php-fpm.sock;
    
    fastcgi_pass 127.0.0.1:9000;
}


##6.3 防止目录遍历

nginx
location {
    try_files $uri /index.php$is_args$args;
    禁止访问 开头的文件
    location /\. deny all; }
}


##6.4 定期更新 Cypht

bash
cd /www/wwwroot/mail.yourdomain.com
git fetch origin
git checkout 2.6.0  或最新稳定版
重新运行数据库迁移(如有)
php scripts/setup_database.php




#七、故障排查

##7.1 附件上传失败

检查目录权限:
bash
chown -R www-data:www-data /var/lib/hm3/attachments
chmod 755 /var/lib/hm3/attachments


确认 PHP 的 open_basedir 配置包含了 /var/lib/hm3/。

##7.2 IMAP 连接失败

确认目标邮箱开启了 IMAP 服务(Gmail 需要开启"低安全性应用"或使用应用密码)
确认防火墙开放了 993(IMAPS)和 587(SMTP)端口
测试连接:
  bash
  测试 IMAP
  openssl s_client -connect mail.yourdomain.com:993 -quiet
  
  测试 SMTP
  openssl s_client -connect mail.yourdomain.com:587 -starttls smtp -quiet
  

##7.3 数据库连接失败

检查 .env 中的数据库账号密码是否正确
确认 MariaDB 允许本地连接
查看错误日志:
  bash
  tail -f /var/log/nginx/mail-error.log
  



#八、效果预览

部署完成后,访问你的 mail.yourdomain.com:

统一收件箱:所有邮箱账号的邮件聚合在一个界面
RSS 订阅:在同一个界面里看邮件 订阅源
多账号管理:支持 Gmail/Outlook/企业邮箱/任何 IMAP 邮箱
轻量快速:比 Roundcube 快很多,纯 PHP 实现



#九、相关端口汇总

服务 端口 用途
|——|——|——|
HTTP 80 页面访问
HTTPS 443 加密页面访问
IMAP 143 邮件接收(STARTTLS)|
IMAPS 993 邮件接收(SSL)|
SMTP 25/587 邮件发送(STARTTLS)|
SMTPS 465 邮件发送(SSL)|
POP3 110/995 邮件接收(旧协议)|
MariaDB 3306 Cypht 数据库



#结语

通过 Cypht Postfix Dovecot,你有了一套完整的自托管邮件聚合平台。所有邮件在一个界面管理,支持多账号、多协议,甚至可以订阅 RSS——比任何一个商业邮件客户端都轻量。

核心价值:数据在自己服务器上,不被第三方平台绑定。