iRedMail 1.7.4 快速入门(域名、邮箱与收发信实测)

基于 iRedMail 1.7.4 实测快速入门:用 iRedAdmin 创建邮件域名与邮箱用户(含密码策略真实拦截与解决)、Roundcube Webmail 登录、SMTP 25/587 与 IMAP 143 三通道域内收发信全链路验证及 mail.log 投递链路解读。

iRedMailiRedMailUbuntuUbuntu 22.04PostfixDovecot邮件服务器2026/10/17

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)。

一、环境信息

二、前置状态与账号盘点

安装完成后的基线状态:一台主机 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)

逐行解读:

  1. amavis 行:Passed CLEAN {RelayedInternal} 表示内容过滤通过(Hits: -1 为 SpamAssassin 打分,负分即非垃圾,ALL_TRUSTED 白名单加分);dkim_new=dkim:example.com 表示发信已被 DKIM 签名(签名密钥 /var/lib/dkim/example.com.pem);queued_as 给出过滤后回注 Postfix 的新队列号。
  2. postfix/amavis/smtp 行:Queue-ID 4j66Jz48gDz3BJfP 经 127.0.0.1:10024 送入 Amavisd,回注 10025 后获得新队列号 4j66K058Pjz3BK66,status=sent(相对内容过滤这一跳)。
  3. 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 进阶实战与运维》)。

八、参考链接