# kiri-mail-server 部署使用指南 ## 一、安装 ```bash composer require game-worker/kiri-mail-server ``` --- ## 二、创建配置文件 将默认配置复制到你的项目: ```bash cp vendor/game-worker/kiri-mail-server/config/mail.php config/mail.php ``` 编辑 `config/mail.php`: ```php [ 'host' => '0.0.0.0', 'port' => 25, 'hostname' => 'mail.yourdomain.com', // ← 改成你的域名 ], 'imap' => [ 'host' => '0.0.0.0', 'port' => 143, ], 'redis' => [ 'host' => '127.0.0.1', 'port' => 6379, ], 'storage' => [ 'path' => '/data/mail', // ← 邮件存储目录,确保可写 ], 'domains' => [ 'local' => ['yourdomain.com'], // ← 你的域名 ], 'database' => [ 'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => 3306, 'database' => 'mail', 'username' => 'root', 'password' => 'your_mysql_password', // ← 改成你的密码 ], 'auth' => [ 'type' => 'simple', // 快速测试用 simple,生产用 database(见第五节) 'users' => [ // 仅 simple 模式有效 'admin@yourdomain.com' => 'password123', ], 'require_auth_for_send' => true, ], ]; ``` --- ## 三、选择认证模式 ### 模式 A:简单配置认证(测试用) ```php 'auth' => [ 'type' => 'simple', 'users' => [ 'user1@yourdomain.com' => 'mypassword', 'user2@yourdomain.com' => 'anotherpassword', ], ], ``` ### 模式 B:数据库认证(生产用) 在 `config/databases.php` 中添加 mail 连接: ```php // config/databases.php return [ 'connections' => [ // 原有连接... 'db' => [ /* ... */ ], // 新增邮件数据库连接 'mail' => [ 'id' => 'mail', 'cds' => 'mysql:host=127.0.0.1;port=3306;dbname=mail', 'username' => 'root', 'password' => 'yourpassword', 'database' => 'mail', 'tablePrefix' => '', 'driver' => 'mysql', 'charset' => 'utf8mb4', 'pool' => ['min' => 1, 'max' => 10], ], ], ]; ``` 执行 SQL 迁移: ```bash mysql -u root -p mail < vendor/game-worker/kiri-mail-server/migrations/001_init.sql ``` `config/mail.php` 中设置: ```php 'auth' => [ 'type' => 'database', ], ``` --- ## 四、注册进程 编辑 `config/servers.php`: ```php return [ 'process' => [ \Kiri\MailServer\SmtpServerProcess::class, // SMTP 收信 :25 \Kiri\MailServer\ImapServerProcess::class, // IMAP 读信 :143 \Kiri\MailServer\OutboundDeliveryProcess::class, // 外发投递 ], ]; ``` 启动服务: ```bash php kiri.php sw:server start ``` --- ## 五、注册 Webmail 路由 创建 `app/Controller/MailWebController.php`: ```php connect('127.0.0.1', 6379); $storage = new MaildirStorage('/data/mail'); $mailQueue = new MailQueue($redis); $auth = new DatabaseAuth(); $this->api = new MailApiController($auth, $storage, $mailQueue); } #[Get('/webmail')] public function index(): string { return WebmailViews::loginPage(); } #[Post('/webmail/login')] public function login(): string { $email = $this->request->post('email'); $password = $this->request->post('password'); if ($this->api->verifyCredentials($email, $password)) { // 生产环境应使用 Session 或 JWT $url = '/webmail/inbox?email=' . urlencode($email); return $this->response->withHeader('Location', $url)->withStatus(302); } return WebmailViews::loginPage(); } #[Get('/webmail/inbox')] public function inbox(): string { $email = $_GET['email'] ?? ''; $data = $this->api->list($email); return WebmailViews::inboxPage($email, $data['messages'] ?? []); } #[Get('/webmail/read')] public function read(): string { $email = $_GET['email'] ?? ''; $id = $_GET['id'] ?? ''; $data = $this->api->read($email, $id); return WebmailViews::readPage($email, $data); } } ``` --- ## 六、创建管理面板路由 创建 `app/Controller/MailAdminController.php`: ```php connect('127.0.0.1', 6379); $mailQueue = new MailQueue($redis); $this->api = new AdminApiController($mailQueue); } #[Get('/admin')] public function dashboard(): string { $domains = $this->api->listDomains()['domains'] ?? []; $queueStats = $this->api->queueStats(); return WebmailViews::adminDashboard($domains, $queueStats); } #[Get('/admin/users')] public function users(): string { $domainId = (int)($_GET['domain_id'] ?? 0); $users = $this->api->listUsers($domainId)['users'] ?? []; return WebmailViews::adminUsers($users, "Domain #{$domainId}"); } #[Post('/api/admin/domains/create')] public function createDomain(): string { $result = $this->api->createDomain( $this->request->post('domain'), $this->request->post('description', ''), (int)$this->request->post('max_users', 100), (int)$this->request->post('max_quota', 0), ); return json_encode($result); } #[Post('/api/admin/users/create')] public function createUser(): string { $result = $this->api->createUser( $this->request->post('email'), (int)$this->request->post('domain_id'), $this->request->post('password'), ); return json_encode($result); } } ``` --- ## 七、测试验证 ### 测试 SMTP 收信 ```bash # 连接 SMTP 服务器 telnet localhost 25 # 发送测试邮件 EHLO test MAIL FROM: RCPT TO: DATA From: sender@external.com To: admin@yourdomain.com Subject: Test Email Hello, this is a test email. . QUIT ``` ### 发送外部邮件 ```bash # 使用认证 (AUTH PLAIN) telnet localhost 25 EHLO test AUTH PLAIN AG1haWwAMTIzNA== # base64(\0user\0pass) MAIL FROM: RCPT TO: DATA From: admin@yourdomain.com To: friend@gmail.com Subject: Outbound Test Hello from my mail server! . QUIT ``` 检查队列状态: ```bash redis-cli > ZCARD mail:queue:outbound # 待发送数 > ZCARD mail:queue:outbound:dead # 死信数 ``` ### 测试 IMAP 读信 ```bash telnet localhost 143 A001 LOGIN admin@yourdomain.com password123 A002 SELECT INBOX A003 FETCH 1:* (FLAGS BODY[]) A004 LOGOUT ``` ### 测试 Webmail ```bash # 浏览器访问 open http://localhost:9501/webmail ``` --- ## 八、DNS 记录配置(生产环境必须) 在你的 DNS 管理后台添加: | 类型 | 名称 | 值 | 说明 | |------|------|-----|------| | **A** | `mail` | `你的服务器IP` | 邮件服务器主机 | | **MX** | `@` | `mail.yourdomain.com` | 邮件路由,优先级 10 | | **TXT** | `@` | `v=spf1 mx -all` | SPF 记录 | | **TXT** | `mail._domainkey` | `v=DKIM1; k=rsa; p=你的公钥` | DKIM 签名(需先生成密钥) | 生成 DKIM 密钥: ```bash openssl genrsa -out dkim_private.pem 2048 openssl rsa -in dkim_private.pem -pubout -out dkim_public.pem # 将公钥内容放入 DNS TXT 记录: mail._domainkey.yourdomain.com ``` --- ## 九、检查清单 - [ ] `config/mail.php` 中 `hostname` 改为真实域名 - [ ] `domains.local` 添加了真实域名 - [ ] `storage.path` 目录存在且可写 - [ ] Redis 服务已启动 (`redis-cli ping`) - [ ] MySQL 数据库已创建并迁移 - [ ] DNS MX 记录已配置(指向 `mail.yourdomain.com`) - [ ] DNS SPF 记录已配置 - [ ] 防火墙开放端口 25、143、587 - [ ] `config/servers.php` 注册了三个进程