Haraka 3.3.5 常用 CLI 命令详解

Haraka 3.3.5 命令行工具全集实测:haraka 主命令(-i、-c、-l、-o、-p、-t、--qlist 等)与 haraka_grep 的用法、回显与踩坑实录

Haraka邮件服务器2026/10/21

Haraka 3.3.5 常用 CLI 命令详解

目标:逐条讲清 Haraka 3.3.5 自带的命令行工具——haraka 主命令(版本查询、初始化、插件管理、运行、插件测试模式、出站队列管理)与 haraka_grep 日志检索脚本——给出真实回显、参数表、典型用法与踩坑实录,作为日常运维的速查手册。

一、环境信息

本文全部命令与回显在以下环境实测:

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Node.js:v20.20.2;npm:10.8.2
  • Haraka:3.3.5(npm 全局安装,二进制位于 /usr/bin/haraka,包主体位于 /usr/lib/node_modules/Haraka)
  • 服务目录:/opt/haraka;服务身份:mail01.example.com
  • 运行方式:systemd 托管(haraka.service),25 端口

安装与托管过程见 《Ubuntu 22.04 安装 Haraka 3.3.5 指南》,配置文件逐项含义见 《Haraka 3.3.5 配置参数详解》。

二、工具概览

Haraka 3.3.5 的 npm 包自带两个可执行入口(bin 字段声明):

命令路径用途
haraka/usr/bin/haraka主命令:安装初始化、启动服务、插件管理、测试模式、队列管理
haraka_grep/usr/bin/haraka_grepshell 脚本:在 Haraka 日志文件中按模式检索

三、前置条件

  1. 已安装 Haraka(haraka --version 可执行);
  2. 服务目录已存在(没有则先 haraka -i /opt/haraka);
  3. 系统装有 less(-h 查看插件文档依赖它,缺失会崩溃,见 6.2 节);
  4. haraka_grep 依赖 grep/bzgrep/zgrep 与 /var/log/maillog 式日志文件(Ubuntu 上默认不存在,见 6.4 节)。

四、haraka 主命令

4.1 命令总览与帮助

haraka --help

实测回显(全文):

Haraka.js — A Node.js Email Server project
Usage: haraka [options] [path]
Options:
    -v, --version               Outputs version number
    -h, --help                  Outputs this help message
    -h NAME                     Shows help for NAME
    -c, --configs               Path to your config directory
    -i, --install               Copies the default configs to a specified dir
    -l, --list                  List the plugins bundled with Haraka
    -p, --plugin                Generate a new plugin with the given name
    -f, --force                 Force overwriting of old files
    --qlist                     List the outbound queue
    --qstat                     Get statistics on the outbound queue
    --qunstick                  Unstick (force delivery) for a given domain
    -o, --order                 Show all registered plugins and their run order
    -t PLUGIN                   Plugin test mode
    --------------- PLUGIN TEST MODE OPTIONS (all optional) --------------
    --ip IP                     IP address to use
    --helo HELO                 HELO to use
    --ehlo EHLO                 EHLO to use
    --envfrom FROM              MAIL FROM to use
    --envfrom TO                RCPT TO(s) to use
    --message FILE              Message file to use
    --dump-mime                 Dump the MIME structure and body text
    --dump-stream               Dump the MessageStream to stdout
    --skip-deny                 Continue running hooks after DENY/DENYSOFT
    --set-relay                 Set connection.relaying

💡 注意帮助原文中 --envfrom TO 为官方帮助的笔误(第 15 行与第 16 行重复了 --envfrom),实际作用是 --envto TO——指定 RCPT TO,实测见 4.8 节。

4.2 版本与帮助查询(-v / -h)

haraka --version
haraka -v

实测回显(两个写法等价):

Haraka.js — Version: 3.3.5

4.3 初始化服务目录(-i)

haraka -i /opt/haraka

实测回显(在全新目录执行时):

create: /opt/haraka
create: /opt/haraka/plugins
create: /opt/haraka/docs
create: /opt/haraka/config
create: /opt/haraka/docs/Plugins.md
create: /opt/haraka/config/connection.ini
create: /opt/haraka/config/smtp.ini
create: /opt/haraka/config/log.ini
create: /opt/haraka/config/plugins

要点:-i 只生成骨架不启动服务;目录已存在时在已有文件上执行会保留原文件(不覆盖),配合 -f 可强制覆盖。生成文件清单与作用见《Haraka 3.3.5 配置参数详解》第四节。

4.4 前台启动运行(-c)

haraka -c /opt/haraka

实测回显(前台启动,Ctrl+C 结束;输出节选):

Using iconv-lite only. To support rare encodings: npm install iconv
loglevel: DEBUG
log format: DEFAULT
[WARN] [-] [server] smtp.ini.nodes unset, using 1, see https://github.com/haraka/Haraka/wiki/Performance-Tuning
Starting up Haraka version 3.3.5
[DEBUG] [-] [plugins] Loading
[INFO] [-] [plugins] loading relay
[DEBUG] [-] [plugins] registered hook connect_init to relay.acl priority 0
[ERROR] [-] [relay] appending missing CIDR suffix in: relay_acl_allow

⚠️ 注意两条启动告警的含义:nodes unset 提示未设 cluster worker 数(设 nodes=cpus 消除);appending missing CIDR suffix 提示 relay_acl_allow 里的 127.0.0.1 未带掩码(Haraka 自动按 /32 处理并告警,写成 127.0.0.1/32 消除)。loglevel: DEBUG 回显说明前台启动在读取 log.ini 当前值,示例环境当时 level=debug。

生产环境用 systemd 托管(unit 文件见安装指南 4.5 节),前台方式仅用于首次排障:

systemctl start haraka      # 生产启动
systemctl status haraka     # 状态
journalctl -u haraka -f     # 实时日志(等价前台观察)

4.5 内置插件清单(-l)

haraka -l

实测回显(全文):

*global

plugins/
        block_me
        data.signatures
        delay_deny
        prevent_credential_leaks
        process_title
        profile
        rcpt_to.host_list_base
        rcpt_to.in_host_list
        record_envelope_addresses
        reseed_rng
        status
        tarpit
        tls
        toobusy
        xclient

plugins/auth
        auth_base
        auth_bridge
        auth_proxy
        auth_vpopmaild
        flat_file

plugins/queue
        deliver
        discard
        lmtp
        qmail-queue
        quarantine
        smtp_bridge
        smtp_forward
        smtp_proxy
        test

NPM packages (/usr/lib/node_modules/Haraka)
        access
        aliases
        asn
        attachment
        bounce
        clamd
        dcc
        dkim
        dns-list
        early_talker
        fcrdns
        geoip
        greylist
        headers
        helo.checks
        karma
        known-senders
        limit
        mail_from.is_resolvable
        messagesniffer
        qmail-deliverable
        redis
        relay
        rspamd
        spamassassin
        spf
        uribl

清单分四组:plugins/(内置顶层插件)、plugins/auth/(认证族)、plugins/queue/(队列族)、NPM packages(随包分发的 npm 插件)。名称可原样填入 config/plugins 启用。

4.6 插件执行顺序查看(-o)

haraka -o -c /opt/haraka

实测回显(实验环境启用了 relay、access、tls、mail_from.is_resolvable、rcpt_to.in_host_list、queue/smtp_forward 时,全文):

loglevel: DEBUG
log format: DEFAULT

Hook: connect_init -------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
relay                               acl                                    0  30

Hook: connect ------------------------------------------------------------------
Plugin                              Method                              Prio  T/O
--------------------------------------------------------------------------------
relay                               pass_relaying                          0  30
access                              rdns_access                            0  30
access                              any                                    0  30

Hook: capabilities -------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
tls                                 advertise_starttls                     0  30

Hook: unrecognized_command -----------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
tls                                 upgrade_connection                     0  30

Hook: disconnect ---------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
tls                                 hook_disconnect                        0  30

Hook: helo ---------------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
access                              any                                    0  30

Hook: ehlo ---------------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
access                              any                                    0  30

Hook: mail ---------------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
access                              mail_from_access                       0  30
access                              any                                    0  30
mail_from.is_resolvable             hook_mail                              0  30
rcpt_to.in_host_list                hook_mail                              0  30

Hook: rcpt ---------------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
access                              rcpt_to_access                         0  30
access                              any                                    0  30
rcpt_to.in_host_list                hook_rcpt                              0  30

Hook: data_post ----------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
access                              data_any                               0  30

Hook: queue --------------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
queue/smtp_forward                  queue_forward                          0  30

Hook: get_mx -------------------------------------------------------------------
Plugin                              Method                              Prio T/O
--------------------------------------------------------------------------------
relay                               force_routing                          0  30
queue/smtp_forward                  get_mx                                 0  30

解读:每个 Hook 段内的行序即执行序(Prio 相同时按 config/plugins 中的声明顺序);T/O 是插件超时(30 秒,来自 plugin_timeout)。修改 config/plugins 后用本命令核对实际生效的钩子链,是调序排障的第一工具。

4.7 插件文档查看(-h NAME)

haraka -h tls

实测回显(输出节选,less 分页展示插件 README):

# tls

This plugin enables the use of TLS (via `STARTTLS`) in Haraka.

For this plugin to work you must have SSL certificates installed correctly.

Haraka has [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) support. When the remote MUA/MTA presents a servername during the TLS handshake and a TLS certificate with that Common Name matches, that certificate will be presented. If no match is found, the default certificate (see Certificate Files) is presented.

## Certificate Files

Defaults settings are shown and can be overridden in `config/tls.ini`.

```ini
key=tls_key.pem

内容即插件的 README.md(含全部配置键说明),Q 键退出。按 haraka -h <插件名> 可查任一已装插件的文档;自定义插件的路径形式(如 haraka -c /opt/haraka -h plugins/my_first_plugin)同样支持。

⚠️ 已知坑:未安装 less 的最小化系统上此命令直接崩溃 Error: spawn less ENOENT,apt-get install -y less 解决(详见安装指南 FAQ Q1)。

4.8 生成新插件脚手架(-p / -f)

正确用法必须同时给 -c 指定服务目录:

haraka -p my_first_plugin -c /opt/haraka

实测产物(生成两个文件):

/opt/haraka/plugins/my_first_plugin.js
/opt/haraka/docs/plugins/my_first_plugin.md

生成的插件模板内容(实测 cat 节选):

// my_first_plugin

// documentation via: haraka -c /opt/haraka -h plugins/my_first_plugin

// Put your plugin code here
// type: `haraka -h Plugins` for documentation on how to create a plugin

错误用法一:不带 -c 直接 haraka -p my_first_plugin,实测报错:

Error: Undefined or erroneous arguments

重复生成:同名文件已存在时(不带 -f)实测报错:

Error: /opt/haraka/plugins/my_first_plugin.js already exists

覆盖重建需加 -f(--force)。

4.9 出站队列管理(--qlist / --qstat / --qunstick)

出站队列文件位于服务目录的 queue/ 子目录,滞留消息(下游临时失败重试中)可用以下命令查看与干预。

列出队列消息:

haraka --qlist -c /opt/haraka

实测回显(队列中有 1 封滞留消息时):

Using iconv-lite only. To support rare encodings: npm install iconv
loaded TLD files: 1=1437 2=7876 3=3795
Q: 1792548278720_1792550369331_5_5170_NnZ1vS_2_317dc6228b57 rcpt:1 from:<sender@gmail.com> domain:stuck.example

队列文件名的重试计数段会随退避递增(第 3 段 _5_ 表示已临时失败 5 次);rcpt:1 收件人数、from: 发件人、domain: 投递域。

统计概要:

haraka --qstat -c /opt/haraka

实测回显:

Using iconv-lite only. To support rare encodings: npm install iconv
{ queue_dir: '/opt/haraka/queue', queue_count: 1 }

对指定域强制重投(解除退避等待):

haraka --qunstick stuck.example -c /opt/haraka

实测回显:

250 Command sent for execution. Check Haraka logs for results.

命令经 config/internalcmd_key 密钥通道下发给运行中的 Haraka,实际投递结果看日志(journalctl 中会立刻出现一次 get_mx/连接尝试)。

⚠️ 注意:三个命令都必须带 -c 指向服务目录(否则找不到队列与 internalcmd_key)。Using iconv-lite only 与 loaded TLD files 是这两类命令的固定开场提示行,非错误;提示缺 iconv 包仅在处理生僻编码邮件时有影响,可 cd /usr/lib/node_modules/Haraka && npm install iconv 补装。

4.10 插件测试模式(-t 及其参数)

-t <插件名> 用于在命令行单插件地加载并模拟 SMTP 会话,避免重启真实服务。参数组见 4.1 帮助输出末段。

典型调用(模拟 EHLO/MAIL/RCPT 环境):

haraka -t headers --ip 8.8.8.8 --ehlo tester.gmail.com --envfrom sender@gmail.com --envto postmaster@example.com --message /tmp/msg.eml --dump-mime -c /opt/haraka

实测回显(3.3.5,输出节选):

loglevel: DEBUG
log format: DEFAULT
[DEBUG] [-] [plugins] Loading
[INFO] [-] [plugins] loading headers
[DEBUG] [-] [plugins] no timeout in headers.timeout
[DEBUG] [-] [plugins] plugin headers timeout is: 30s
[DEBUG] [-] [plugins] registered hook data_post to headers.duplicate_singular priority 0
[DEBUG] [-] [plugins] registered hook data_post to headers.missing_required priority 0
[DEBUG] [-] [plugins] registered hook data_post to headers.invalid_return_path priority 0
...
Using iconv-lite only. To support rare encodings: npm install iconv
[DEBUG] [BF09E4B3-4D73-41CD-BC24-B598D57EC924] [core] setupClient got no IP address for this connection!
loaded TLD files: 1=1437 2=7876 3=3795
loaded Public Suffixes: 10210

实测观察(如实记录):在 3.3.5 环境中,测试模式能完成「加载指定插件 → 注册钩子 → 初始化连接上下文(日志出现模拟连接的 DEBUG 行)」全流程,但在 loaded Public Suffixes 后即正常退出(秒级),mail/rcpt/data_post 钩子的实际判定结果未打印输出(对 mail_from.is_resolvable、rcpt_to.in_host_list、headers 三类插件以 --dump-mime 等参数组合重复实测,现象一致)。因此当前版本 haraka -t 的可靠用途是验证插件能否加载、钩子能否注册;完整钩子行为验证建议用真实 SMTP 会话 + log.ini 临时 debug 级日志(见《Haraka 3.3.5 配置参数详解》FAQ Q2)。

参数说明
-t PLUGIN指定测试的插件名;-t all 表示全插件
--ip IP模拟客户端 IP
--helo / --ehlo模拟 HELO/EHLO 名
--envfrom FROM模拟 MAIL FROM
--envto TO模拟 RCPT TO(帮助文本写作 --envfrom TO 为笔误)
--user模拟客户端 uid
--message FILE用指定文件作为消息内容
--dump-mime输出解析后的 MIME 结构
--dump-stream输出 MessageStream 原始流
--skip-denyDENY/DENYSOFT 后继续跑后续钩子
--set-relay置 connection.relaying=true(模拟中继客户端)

五、haraka_grep 日志检索工具

5.1 定位与用法

haraka_grep 是一个 shell 脚本,用于在 Haraka 的日志文件(含压缩归档)中按模式检索,设计配合 syslog 风格日志(日志写入 /var/log/maillog 时):

haraka_grep <pattern> [目录]

脚本头部实测(grep 到的关键逻辑):

haraka_grep is a shell script that greps log files for a pattern and then prints
the results with the filename, line number, and the pattern highlighted.

其检索目标在脚本内硬编码为 /var/log/maillog(对归档文件使用 bzgrep/zgrep 兜底)。

5.2 实测行为与 Ubuntu 适配

在本环境的 Ubuntu 22.04(日志走 journald,无 /var/log/maillog)下执行:

haraka_grep "Listening" /opt/haraka/config

实测回显(脚本对不存在目标的处理,输出节选):

grep: /var/log/maillog: No such file or directory

结论(生产建议):

日志形态推荐检索方式
systemd 托管(本篇主线)`journalctl -u haraka --no-pager
log.syslog/syslog 插件写入 /var/log/maillog(RedHat 系习惯路径)haraka_grep <pattern> 直接可用
format=json 落文件jq -r <字段> 过滤更高效

六、注意事项

  1. -c 是万能前缀:-o/-p/--qlist/--qstat/--qunstick/-t 都要求(或强烈建议)同时指定 -c /opt/haraka,否则命令找不到配置/队列/密钥或直接报参数错误;
  2. -h 依赖 less:最小化系统先装 less;
  3. 前台启动必须 -c:haraka /opt/haraka 位置参数写法报 Error: Undefined or erroneous arguments;
  4. 队列命令的密钥前提:--qunstick 依赖 config/internalcmd_key(haraka -i 生成),该文件丢失会使在线队列干预失效;
  5. 保持命令与版本同步:Haraka 补丁版本节奏快(月度级),升级后用 haraka --version 与 haraka -o -c 复核插件注册行为是否变化(如 -t 的输出行为在版本间曾有变化);
  6. 输出清洗:journalctl 回显里的时间戳/UUID 属每次会话不同的动态值,做自动化比对时按字段截取而非全行匹配。

七、常见问题(FAQ)

Q1:haraka 命令找不到(command not found)。

原因:npm 全局 bin 目录不在 PATH。先定位:which haraka;npm 全局安装的 bin 在 /usr/bin(root 安装)或 npm prefix/bin 目录。可用 npm ls -g --depth=0 确认包已装,npm config get prefix 查看全局前缀。

Q2:--qlist 显示的文件在 queue/ 目录找不到?

qlist 读取的是队列文件名列表,而工作进程在临时失败重试时会把队列文件改名(文件名中重试计数递增),两次查看之间文件名可能已变化,属正常现象;以 qlist 最新输出为准。

Q3:-o 输出 loglevel: DEBUG 但 log.ini 是 info?

-o 启动时也会读 log.ini,回显即当前值;若不一致先确认没有其他 haraka 进程/配置目录(-c 指错路径)。

Q4:如何让自建插件进入 -o 输出?

插件文件放 /opt/haraka/plugins/ 后,必须在 config/plugins 中登记才会注册钩子;只写文件不登记时 -l/-o 都不会出现,haraka -p 生成的模板也要手动加进 config/plugins。

八、参考链接

  1. Haraka 主命令源码(bin/haraka,参数定义):https://github.com/haraka/Haraka/blob/master/bin/haraka (查询日期 2026-10-21)
  2. haraka_grep 脚本源码:https://github.com/haraka/Haraka/blob/master/bin/haraka_grep (查询日期 2026-10-21)
  3. 插件注册表 Plugins.md:https://github.com/haraka/Haraka/blob/master/Plugins.md (查询日期 2026-10-21)
  4. 站内系列:《Ubuntu 22.04 安装 Haraka 3.3.5 指南》、《Haraka 3.3.5 配置参数详解》、《Haraka 3.3.5 介绍与选型指南》