iRedMail 1.7.4 快速入门(域名、邮箱与收发信实测)
基于 iRedMail 1.7.4 实测快速入门:用 iRedAdmin 创建邮件域名与邮箱用户(含密码策略真实拦截与解决)、Roundcube Webmail 登录、SMTP 25/587 与 IMAP 143 三通道域内收发信全链路验证及 mail.log 投递链路解读。
iRedMail 1.7.4 快速入门(域名、邮箱与收发信实测)
目标:在一台装好 iRedMail 1.7.4 的服务器上完成首次实战操作——用 iRedAdmin 管理后台创建邮箱用户、用 Roundcube 登录收发、用 SMTP(25 收信 / 587 提交)与 IMAP(143/993)命令行实测域内收发信全链路,并逐行解读投递日志。所有步骤与回显均为真实环境实测(Ubuntu 22.04 + iRedMail 1.7.4,演示域 example.com)。
一、环境信息
- 操作系统:Ubuntu 22.04,iRedMail 1.7.4(MariaDB 后端,承接《iRedMail 1.7.4 Ubuntu 22.04 安装指南》同一台实测主机)
- 组件:Postfix(SMTP)、Dovecot(IMAP/POP3 + LDA 投递)、Amavisd(调 SpamAssassin 打分 + ClamAV 查毒,10024 过滤 / 10025 回注)、iRedAPD 策略服务
- 域名与主机:演示域 example.com,服务器 FQDN mail.example.com
- 账号:域管理员 postmaster@example.com,本文实测创建测试用户 zhangsan@example.com;vmail / vmailadmin 为数据库专用账号(非邮箱)
- Web 入口:Roundcube https://mail.example.com/mail/、iRedAdmin https://mail.example.com/iredadmin/(Roundcube 插件 managesieve / password / zipdownload)
- 端口:25(SMTP 收信)、587(提交,AUTH + STARTTLS)、143/993(IMAP)、110/995(POP3)
二、前置状态与账号盘点
安装完成后的基线状态:一台主机 FQDN 为 mail.example.com,首个邮件域 example.com 已随向导创建,默认已有两个可用账号(安装摘要与 /root/iRedMail-1.7.4/iRedMail.tips 实录):
| 账号 | 用途 | 密码(本文演示值) |
|---|---|---|
| postmaster@example.com | 域管理员 + 首个邮箱用户 | q1w2e3r4 |
| vmail / vmailadmin | 数据库只读 / 读写账号(非邮箱) | 安装时随机生成,见 iRedMail.tips |
验证数据库中的既有账号(真实回显):
$ mysql -u root -pq1w2e3r4 -N -e "SELECT username, active, domain FROM vmail.mailbox WHERE domain='example.com';"
postmaster@example.com 1 example.com
vmail 库核心表速查(后端选型对比详见安装篇技术拓展:MariaDB 表结构 / OpenLDAP 目录树 / PostgreSQL 表结构三者实体一致):
$ mysql -u root -pq1w2e3r4 -N -e "SHOW TABLES;" vmail
admin
alias
alias_moderators
domain
domain_admins
forwardings
mailbox
mailbox_sharing
quota2
recipient_bcc
sender_bcc
shared_folder
三、用 iRedAdmin 创建邮箱用户(实测)
3.1 登录 iRedAdmin
浏览器访问 https://mail.example.com/iredadmin/(curl 实测登录过程):
$ cj=/tmp/iredadmin.cookies
$ curl -sk -c $cj -d "username=postmaster@example.com&password=q1w2e3r4" https://mail.example.com/iredadmin/login -o /dev/null -w '%{http_code} redirect=%{redirect_url}\n'
303 redirect=https://mail.example.com/iredadmin/dashboard?checknew
$ curl -sk -b $cj https://mail.example.com/iredadmin/dashboard -o /tmp/dash.html -w '%{http_code}\n'
200
$ grep -oE 'Logged in as[^<]*' /tmp/dash.html | head -1
Logged in as postmaster@example.com
Dashboard 页面上的核心入口(实测 dashboard HTML 中提取的链接):
$ grep -oE 'href="/iredadmin/(create|domains)[^"]*"' /tmp/dash.html | sort -u
/iredadmin/create/admin
/iredadmin/create/domain
/iredadmin/create/user
/iredadmin/domains
3.2 创建表单字段盘点
先 GET 表单页,拿字段名与 CSRF token(iRedAdmin 要求 form_add_user + csrf_token):
$ curl -skL -b $cj "https://mail.example.com/iredadmin/create/user" -o /tmp/form.html -w '%{http_code} final=%{url_effective}\n'
200 final=https://mail.example.com/iredadmin/create/user/example.com
$ grep -oE 'name="[a-zA-Z_.]+"' /tmp/form.html | sort -u
name="cn"
name="confirmpw"
name="csrf_token"
name="domainName"
name="form_add_user"
name="mailQuota"
name="newpw"
name="preferredLanguage"
name="submit_add_user"
name="username"
3.3 真实踩坑:密码策略拦截弱密码
直接用与向导相同的弱密码 q1w2e3r4 提交创建用户 zhangsan(完整实测):
$ tok=$(grep -oE 'csrf_token" value="[^"]+' /tmp/form.html | head -1 | sed 's/.*value="//')
$ curl -sk -b $cj -D - -o /tmp/adduser.html \
-d "csrf_token=$tok&domainName=example.com&username=zhangsan&newpw=q1w2e3r4&confirmpw=q1w2e3r4&cn=ZhangSan&preferredLanguage=en_US&form_add_user=add_user" \
"https://mail.example.com/iredadmin/create/user/example.com" 2>&1 | grep -iE '^HTTP|^location'
HTTP/2 303
location: https://mail.example.com/iredadmin/create/user/example.com?msg=PW_NO_UPPERCASE%2CPW_NO_SPECIAL_CHAR
msg=PW_NO_UPPERCASE,PW_NO_SPECIAL_CHAR:密码必须含大写字母与特殊字符。这是 iRedAdmin 的默认密码强度策略(策略项从数据库 iredadmin 库 settings 读取,源码 /opt/www/iredadmin/libs/iredpwd.py 校验项实录:PW_SHORTER_THAN_MIN_LENGTH / PW_NO_LETTER / PW_NO_UPPERCASE / PW_NO_DIGIT_NUMBER / PW_NO_SPECIAL_CHAR)。
⚠️ FAQ:向导安装时设置的 postmaster 密码不受此策略限制(向导内直写数据库),但通过 iRedAdmin 界面新建用户/管理员必须满足策略。可登录 iRedAdmin → Admin Profile(右上角账号 → 设置)→ Password Policy 调整 min_passwd_length / 是否要求大写、数字、特殊字符。
改用满足策略的密码 Q1w2e3r4! 重新提交(真实回显):
$ curl -sk -b $cj -D - -o /tmp/adduser.html \
-d "csrf_token=$tok&domainName=example.com&username=zhangsan&newpw=Q1w2e3r4%21&confirmpw=Q1w2e3r4%21&cn=ZhangSan&preferredLanguage=en_US&form_add_user=add_user" \
"https://mail.example.com/iredadmin/create/user/example.com" 2>&1 | grep -iE '^location'
location: https://mail.example.com/iredadmin/profile/user/general/zhangsan@example.com?msg=CREATED
3.4 验证用户落库与邮箱目录
数据库(真实回显):
$ mysql -u root -pq1w2e3r4 -N -e "SELECT username, active, domain FROM vmail.mailbox WHERE domain='example.com';"
postmaster@example.com 1 example.com
zhangsan@example.com 1 example.com
邮箱目录按用户名首字母三层散列(z/h/a)创建(真实回显):
$ ls /var/vmail/vmail1/example.com/
p z
$ find /var/vmail/vmail1/example.com/z -maxdepth 4 -type d | head -4
/var/vmail/vmail1/example.com/z/h/a/zhangsan-2026.10.17.03.11.01
/var/vmail/vmail1/example.com/z/h/a/zhangsan-2026.10.17.03.11.01/Maildir
doveadm 视角验证用户存在(密码为 Q1w2e3r4!):
$ doveadm auth test zhangsan@example.com 'Q1w2e3r4!'
passdb: zhangsan@example.com auth succeeded
追加域名与批量用户:创建新域名走 iRedAdmin → Create Domain(同表单风格);批量建用户可用官方 SQL 脚本 /root/iRedMail-1.7.4/tools/create_mail_user_SQL.sh(生成 INSERT 语句后导入 vmail 库),本文实测走 iRedAdmin 单用户路径,批量场景见进阶篇。
四、Roundcube Webmail 登录(实测)
Webmail 入口 https://mail.example.com/mail/(注意是 /mail/ 子路径,根路径 302 跳转,实测):
$ curl -sk -o /dev/null -w '%{http_code} redirect=%{redirect_url}\n' https://mail.example.com/mail/
200 redirect=
$ curl -sk https://mail.example.com/ | head -1
<html><head><meta HTTP-EQUIV="REFRESH" content="0; url=/mail/"></head></html>
用新用户 zhangsan 登录(Roundcube 表单字段实测:_token / _user / _pass / _action / _task):
$ rj=/tmp/rc.cookies
$ curl -sk -c $rj https://mail.example.com/mail/ -o /tmp/rc1.html
$ tok=$(grep -oE '_token" value="[^"]+' /tmp/rc1.html | sed 's/.*value="//' | head -1)
$ curl -sk -b $rj -c $rj --data-urlencode "_token=$tok" --data-urlencode "_user=zhangsan@example.com" --data-urlencode "_pass=Q1w2e3r4!" -d "_action=login&_task=login" https://mail.example.com/mail/ -o /dev/null -w '%{http_code} redirect=%{redirect_url}\n'
302 redirect=https://mail.example.com/mail/?_task=mail
$ curl -sk -b $rj "https://mail.example.com/mail/?_task=mail" -o /tmp/rc2.html -w '%{http_code}\n'
200
$ grep -oE '<title>[^<]+' /tmp/rc2.html
<title>Roundcube Webmail :: Inbox
⚠️ 排障实录:curl 复刻 Roundcube 登录时,密码字段名是
_pass不是_password(实测传 _password 返回 401 登录页);且必须带上登录页下发的 _token 与会话 Cookie,缺一不可。
Roundcube 内置插件(实测 /opt/www/roundcubemail/config/config.inc.php):
$config['plugins'] = array('managesieve', 'password', 'zipdownload');
解读:managesieve 提供网页端过滤器(写入 Dovecot sieve),password 允许用户在 Webmail 里自助改密,zipdownload 支持整箱打包下载。
五、域内收发信实测(三通道)
💡 技术拓展:邮件传输链路组件一览(本文实测拓扑)——发件方 MUA → Postfix(25 提交/587 外发提交,587 需 AUTH)→ Amavisd 内容过滤(127.0.0.1:10024,调 SpamAssassin 打分 + ClamAV 查毒)→ 回注 Postfix(127.0.0.1:10025)→ Dovecot LDA 投递到 /var/vmail 邮箱目录 → 收件方 MUA 经 IMAP/POP3(143/993/110/995)读取。iRedAPD 作为 Postfix 策略服务在 SMTP 会话中拦截(灰名单/黑白名单/限速)。下文实测验证的就是这条链路。
5.1 SMTP 25 端口域内投递
用 postmaster 给 zhangsan 发一封(Python smtplib 实测):
$ python3 - <<'EOF'
import smtplib
from email.mime.text import MIMEText
msg = MIMEText('Hello Zhang San, this is a local delivery test.', 'plain', 'utf-8')
msg['Subject'] = 'Local delivery test 01'
msg['From'] = 'postmaster@example.com'
msg['To'] = 'zhangsan@example.com'
s = smtplib.SMTP('127.0.0.1', 25, timeout=30)
s.sendmail(msg['From'], [msg['To']], msg.as_string())
s.quit()
print('SMTP accepted, server reply ok')
EOF
SMTP accepted, server reply ok
等待数秒后确认投递(Maildir 出现新邮件,真实文件名回显):
$ find /var/vmail/vmail1/example.com/z -path '*Maildir/new*' -type f
/var/vmail/vmail1/example.com/z/h/a/zhangsan-2026.10.17.03.11.01/Maildir/new/1792206676.M780867P6296.mail.example.com,S=1794,W=1829
5.2 投递日志逐行解读
/var/log/mail.log 中这封邮件的完整链路(实测日志原文节选):
Oct 17 03:11:16 mail amavis[1788]: (01788-01) Passed CLEAN {RelayedInternal}, MYNETS LOCAL [127.0.0.1]:57746 ESMTP/ESMTP <postmaster@example.com> -> <zhangsan@example.com>, (), Queue-ID: 4j66Jz48gDz3BJfP, Message-ID: <4j66Jz48gDz3BJfP@mail.example.com>, mail_id: TnTyRQyWyDne, b: 8u6qeGpJQ, Hits: -1, size: 536, queued_as: 4j66K058Pjz3BK66, Subject: "Local delivery test 01", From: <postmaster@example.com>, helo=mail.example.com, Tests: [ALL_TRUSTED=-1], autolearn=ham autolearn_force=no, autolearnscore=0, dkim_new=dkim:example.com, 1106 ms
Oct 17 03:11:16 mail postfix/amavis/smtp[6290]: 4j66Jz48gDz3BJfP: to=<zhangsan@example.com>, relay=127.0.0.1[127.0.0.1]:10024, delay=1.2, delays=0.03/0.03/0/1.1, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 4j66K058Pjz3BK66)
Oct 17 03:11:16 mail postfix/pipe[6295]: 4j66K058Pjz3BK66: to=<zhangsan@example.com>, relay=dovecot, delay=0.08, delays=0/0.01/0/0.07, dsn=2.0.0, status=sent (delivered via dovecot service)
逐行解读:
- amavis 行:Passed CLEAN {RelayedInternal} 表示内容过滤通过(Hits: -1 为 SpamAssassin 打分,负分即非垃圾,ALL_TRUSTED 白名单加分);dkim_new=dkim:example.com 表示发信已被 DKIM 签名(签名密钥 /var/lib/dkim/example.com.pem);queued_as 给出过滤后回注 Postfix 的新队列号。
- postfix/amavis/smtp 行:Queue-ID 4j66Jz48gDz3BJfP 经 127.0.0.1:10024 送入 Amavisd,回注 10025 后获得新队列号 4j66K058Pjz3BK66,status=sent(相对内容过滤这一跳)。
- postfix/pipe 行:最终投递 relay=dovecot,status=sent (delivered via dovecot service)—— Dovecot LDA 落盘 Maildir,这也是为什么邮箱目录属主是 vmail 用户。
排障口诀:收不到信按 Queue-ID 顺着 mail.log 三行查(postfix 收入 → amavis 过滤 → dovecot 投递),哪一行缺了就查哪一环;队列堆积用 postqueue -p(本机实测输出 Mail queue is empty)。
5.3 IMAP 143 STARTTLS 收信
用 zhangsan 登录 IMAP 读刚才那封(真实回显):
$ python3 - <<'EOF'
import imaplib, ssl
ctx = ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
m = imaplib.IMAP4('127.0.0.1', 143); m.starttls(ctx)
m.login('zhangsan@example.com','Q1w2e3r4!')
print('IMAP login OK')
typ, data = m.select('INBOX'); print('INBOX messages:', data[0].decode())
typ, d = m.search(None, 'SUBJECT', '"Local delivery test 01"'); print('search hits:', d[0].decode())
n = d[0].split()[0]
typ, md = m.fetch(n, '(BODY.PEEK[TEXT])')
print('body preview:', md[0][1].decode('utf-8','replace').strip()[:80])
m.logout()
EOF
IMAP login OK
INBOX messages: 1
search hits: 1
body preview: SGVsbG8gWmhhbmcgU2FuLCB0aGlzIGlzIGEgbG9jYWwgZGVsaXZlcnkgdGVzdC4=
解读:INBOX messages: 1 与 4.1 投递吻合;body preview 是 base64 编码的正文(IMAP fetch TEXT 默认编码返回),解码即 "Hello Zhang San, this is a local delivery test."。993 端口走隐式 TLS 时把 IMAP4 换成 IMAP4_SSL 即可,账号口令相同。
⚠️ 排障实录:上例 ctx 检查关掉了证书校验——本机是 iRedMail 自签证书(/etc/ssl/certs/iRedMail.crt),Python/客户端默认校验会报 self-signed certificate。生产换正式证书后无需跳过校验。
5.4 SMTP 587 提交端口(带认证外发口)
587 是给用户客户端提交邮件用的(必须 AUTH LOGIN + STARTTLS)。实测用 zhangsan 经 587 向 postmaster 发信:
$ python3 - <<'EOF'
import smtplib, ssl
from email.mime.text import MIMEText
ctx = ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
msg = MIMEText('via submission port 587', 'plain', 'utf-8')
msg['Subject'] = 'Submission test 02'
msg['From'] = 'zhangsan@example.com'
msg['To'] = 'postmaster@example.com'
s = smtplib.SMTP('127.0.0.1', 587, timeout=30)
s.ehlo(); s.starttls(context=ctx); s.ehlo()
s.login('zhangsan@example.com','Q1w2e3r4!')
s.sendmail(msg['From'], [msg['To']], msg.as_string()); s.quit()
print('587 submission OK')
EOF
587 submission OK
验证 postmaster 收到(doveadm 实测,输出为邮箱 GUID 与邮件序号):
$ doveadm search -u postmaster@example.com mailbox INBOX SUBJECT 'Submission test 02'
b0b7110498e7d26a4e19000060880638 4
⚠️ 注意 587 的 iRedMail 约束:reject_sender_login_mismatch(iRedAPD 插件,实测 /opt/iredapd/settings.py 中 plugins 列表含 reject_sender_login_mismatch)——MAIL FROM 地址必须与登录账号一致,否则被拒。客户端配置:服务器 mail.example.com,端口 587,STARTTLS,认证密码即邮箱密码。
六、iRedAdmin 其他常用操作入口
iRedAdmin 是唯一免费的官方管理后台(开源版管理面板对比:iRedAdmin 开源版免费支持域名/用户/别名全管理;Mailcow 内置面板功能类似但随容器分发;Modoboa 面板模块化但需额外装)。常用入口(实测 dashboard 导航):
| 操作 | 路径 | 说明 |
|---|---|---|
| 创建邮箱用户 | Create User(/iredadmin/create/user) | 表单字段见 3.2 节 |
| 创建域名 | Create Domain(/iredadmin/create/domain) | 新增邮件域 |
| 域列表/配额 | /iredadmin/domains | 查看/编辑域配额 |
| 用户详情 | /iredadmin/profile/user/general/<邮箱> | 改密/配额/别名 |
七、常见问题沉淀
Q1:iRedAdmin 建用户报 PW_NO_UPPERCASE / PW_NO_SPECIAL_CHAR? 默认密码策略要求含大写与特殊字符(3.3 节实录)。用满足策略的密码,或登录 iRedAdmin → Admin Profile → Password Policy 调整。
Q2:Roundcube 登录 401? curl 复刻时字段名用 _pass 而非 _password,并带齐 _token 与 Cookie(第四节实录)。
Q3:发信后收件人收不到? 按 5.2 节口诀查 mail.log 三段链路;本机投递正常但队列有堆积时看 postqueue -p;若命中 iRedAPD 灰名单,首次发信会有 450 临时拒绝,几分钟后重试即过(灰名单插件名 greylisting,见 /opt/iredapd/settings.py plugins 列表)。
Q4:客户端收发报证书错误? 自签证书所致。测试环境可临时关闭校验;生产配置 Let's Encrypt 证书(见《iRedMail 1.7.4 进阶实战与运维》)。