
后端网络/通信【免费下载链接】HarakaA fast, highly extensible, and event driven SMTP server项目地址https://gitcode.com/gh_mirrors/ha/Haraka点击查看免费下载导读queue/smtp_bridge是 Haraka 邮件服务器中的一个队列插件它的核心职责是把入站连接inbound connection上已经认证成功的用户名与密码原样转发给另一台 SMTP 服务器并将整封邮件投递到该服务器从而在不依赖配置文件存储凭据的前提下实现“认证即转发”。本文将以 docs/plugins/queue/smtp_bridge.md 为骨架结合插件源码、配套认证插件与测试用例完整讲解它的工作模型、配置方法、实现原理以及与smtp_proxy、smtp_forward的差异读完后你将能够独立部署一套基于“客户端 AUTH 凭证桥接”的转发链路。插件定位认证转发而非固定凭据转发根据官方文档queue/smtp_bridge负责向另一台 SMTP 服务器投递邮件deliver to another SMTP server桥接来自初始连接initial connection的认证细节与邮件正文数据它被设计为与认证插件auth/auth_bridge配套使用“This plugin is meant to be used with the pluginauth/auth_bridge”两者共享同一份配置文件config/smtp_bridge.ini它与queue/smtp_proxy、queue/smtp_forward的本质区别在于后两者从配置文件读取auth_user/auth_pass等静态凭据来向远端服务器认证而smtp_bridge完全不读取配置文件中的 AUTH 细节它只是“简单地使用原始连接的 AUTH 细节original AUTH details把邮件正文投递到远端 SMTP 服务器”也就是说这台 Haraka 在此场景下扮演的是一个**“信任上游客户端认证结果”的中继角色**客户端用什么账号密码在 Haraka 上完成了 AUTHHaraka 就用同一组账号密码去远端服务器完成认证并投递。与之配套的 auth/auth_bridge 插件则负责认证侧的工作将客户端的用户名/密码桥接到远端 SMTP 服务器再把远端返回的认证结果代理回给客户端。它不需要用户采用userdomain.com格式也不检查域名是否存在于配置中这正是它与auth/auth_proxy的差异因此非常适合与smtp_bridge组成一条整条链路都复用同一组客户端凭据的转发通道。配置说明config/smtp_bridge.iniqueue/smtp_bridge的配置存放在config/smtp_bridge.ini采用 INI 风格格式仓库中给出的默认示例文件config/smtp_bridge.ini内容如下hostlocalhost #port #auth_type #priority10各配置项的含义如下配置项默认值说明host无唯一必填项你要进行认证并投递authenticating and posting的目标主机例如smtp.host.tld、192.0.2.25:587或[2001:db8::1]:587。参考 auth/auth_bridge 中的说明host 支持haraka-net-utils的 Endpoint 格式IPv6 地址若想附带端口必须加方括号如[2001:db8::1]:587port空此时 Haraka 使用25目标服务器端口。仅当host中未包含端口时生效若host中已写明端口如192.0.2.25:587则以 host 内嵌端口为准auth_type空此时 Haraka 会尝试自动挑选合适的认证方法指定向远端服务器发送的 SMTP AUTH 类型priority10用于hook_get_mx返回的 MX 优先级注意host是唯一必需的设置“This is the only setting required”其余三项按需启用即可。配置解析由 plugins/queue/smtp_bridge.js 中的load_flat_ini完成它通过this.config.get(smtp_bridge.ini, ...)加载并注册了重载回调因此修改配置文件后 Haraka 会热重载SIGHUP / 配置重载机制无需重启进程。工作流程两个 Hook 完成“复制凭据 覆盖 MX”queue/smtp_bridge只注册了两个 Hook所有逻辑都非常精简plugins/queue/smtp_bridge.js1.hook_data_post把连接级凭据复制进事务exports.hook_data_post (next, connection) { const txn connection?.transaction if (!txn) return next() // Copy auth notes to transaction notes so theyre available in hmail.todo.notes txn.notes.auth_user connection.notes.auth_user txn.notes.auth_passwd connection.notes.auth_passwd return next() }这一步发生在邮件正文接收完成之后它把保存在连接对象connection.notes上的认证用户名与密码复制到事务txn.notes。注释中明确写明了意图复制到 transaction notes 是为了让它们最终出现在出站邮件条目hmail.todo.notes中供出站投递阶段使用。如果当前没有事务如连接在 DATA 阶段前被丢弃则直接放行。2.hook_get_mx覆盖 MX 解析把投递目标指到配置的主机exports.hook_get_mx function (next, hmail) { let priority 10 if (this.cfg.main.priority) { priority this.cfg.main.priority } let authType null if (this.cfg.main.auth_type) { authType this.cfg.main.auth_type } let port null if (this.cfg.main.port) { port this.cfg.main.port } return next(OK, { priority, exchange: this.cfg.main.host, port, auth_type: authType, auth_user: hmail.todo.notes.auth_user, auth_pass: hmail.todo.notes.auth_passwd, }) }该方法在 Haraka 出站投递查询 MX 时被调用并直接以OK返回一个 MX 对象从而完全跳过 DNS MX 查询返回对象中的exchange固定为配置文件中的hostauth_user/auth_pass取自hmail.todo.notes——这正是hook_data_post预先复制进去的那组客户端凭据实现了“原始连接的 AUTH 细节随邮件一起走到投递阶段”priority、port、auth_type分别对应配置项未配置时返回10/null/null源码中的默认值清晰可见。配合 outbound/hmail.js 中get_mx_respond的处理逻辑可以确认当get_mx钩子返回OK与 MX 对象时出站系统会直接使用该对象建立连接并尝试投递而不再执行 DNS MX 解析。出站认证的底层实现从“自动选型”到“AUTH 命令”当queue/smtp_bridge通过hook_get_mx把认证凭据带入 MX 对象后出站投递的实际认证动作发生在 outbound/hmail.js 的auth_and_mail_phase()函数中这里可以印证文档所述“auth_type 留空时 Haraka 会自动挑选合适的方法”只有当mx.auth_user与mx.auth_pass都存在时才发起 AUTH否则直接进入MAIL阶段若远端服务器未在 EHLO 能力中通告AUTH会记录 warning 并不认证直接投递若未显式配置auth_typeHaraka 的自动选型优先级为CRAM-MD5 PLAIN LOGIN源码注释说明 CRAM-MD5 最安全优先、PLAIN 往返次数少次之、LOGIN 兜底选定的类型与远端通告的能力不匹配时同样降级为“不认证直接投递”认证成功进入MAIL阶段AUTH LOGIN/AUTH CRAM-MD5属于多轮交互出站代码会基于远端返回的挑战串VXNlcm5hbWU6即 base64 的 “Username:”、UGFzc3dvcmQ6即 “Password:”依次回填 base64 的用户名与密码详见process_ehlo_data与line事件处理中的case auth分支。也就是说即便配置中不写auth_type只要远端支持上述任一种标准 SASL 机制桥接认证也能自动完成当然你也可以通过auth_type显式锁定某一种。认证侧配套auth/auth_bridge如何桥接客户端 AUTH要理解整条链路还需要看认证侧。客户端在 Haraka 上完成 SMTP AUTH 时认证插件会把结果写入connection.notes.auth_user与connection.notes.auth_passwdplugins/auth/auth_base.js 中认证成功后执行connection.notes.auth_user safe_user、connection.notes.auth_passwd credentials[1]也可以通过plugin.blankout_password true禁止密码写入。queue/smtp_bridge的hook_data_post正是从这里取数。而 plugins/auth/auth_bridge.js 实现了check_plain_passwdexports.check_plain_passwd function (connection, user, passwd, cb) { const { host, port } this.cfg.main let ep try { ep net_utils.Endpoint.parse(host, port || 25) } catch (err) { connection.logerror(this, invalid host: ${err.message}) return cb(false) } this.try_auth_proxy(connection, ${ep}, user, passwd, cb) }它读取的是同一份smtp_bridge.inithis.config.get(smtp_bridge.ini, ...)因此host与port在认证侧与投递侧保持一致port缺省时按 25 处理host 非法时记录错误并拒绝认证核心动作是调用继承自auth/auth_proxy的try_auth_proxy向目标主机发起一次 SMTP 会话若远端通告STARTTLS则先升级 TLS机会式加密本地 key/cert 仅在配置了互认证时才附带然后优先用AUTH PLAIN、其次AUTH LOGIN提交客户端传来的原始user/passwd把远端结果作为 Haraka 端认证的最终结果返回。由此形成完整闭环客户端 → (AUTH 桥接到远端) → 认证通过 → 邮件正文收完后 → 凭据复制进事务 → 出站时覆盖 MX 指向同一主机 → 用同一组凭据认证并投递。测试验证行为已被测试用例锁定仓库中的单元测试 test/plugins/queue/smtp_bridge.js 完整覆盖了上述行为可作为实现事实的佐证hook_data_post组无事务时直接next()有事务时把connection.notes.auth_user/auth_passwd复制到transaction.notes连接上未设置认证值时复制undefinedhook_get_mx组默认priority10且exchange为配置的 host配置priority20时返回 20配置auth_type: PLAIN时透传配置port: 587时透传auth_user/auth_pass从hmail.todo.notes透传未配置port/auth_type时返回null。这些断言与文档中的默认值描述port默认空、auth_type默认空、priority默认 10逐条对应说明文档所述行为有测试兜底。与queue/smtp_proxy、queue/smtp_forward的对比文档特别强调了三者的区别。结合 docs/plugins/queue/smtp_proxy.md 与 docs/plugins/queue/smtp_forward.md 及对应源码可归纳如下维度queue/smtp_bridgequeue/smtp_proxyqueue/smtp_forwardAUTH 凭据来源原始客户端的 AUTH 细节经hook_data_post复制进事务 notes配置文件中的auth_user/auth_pass配置文件中的auth_user/auth_pass支持按域路由建立上游连接的时机出站投递阶段覆盖get_mx绕过 DNSMAIL FROM 时即建立连接见 smtp_proxy.js可即时获得远端收件人过滤等 SMTP 阶段过滤能力队列queue时才建立连接见 smtp_forward.js适合搭配内容过滤减少连接数但收件人校验被推迟到队列阶段典型用途复用客户端凭证的认证转发链路前向到具备成熟外发能力的邮件服务器前向到具备成熟外发能力的邮件服务器简单来说smtp_proxy/smtp_forward解决的是“固定凭据/固定路由”的前向转发而smtp_bridge解决的是“把客户端已经认证过的身份原样桥接给下一跳”两者适用场景不同可按需组合或互斥使用。启用与部署步骤在 Haraka 中启用该插件与配套认证插件的步骤如下在 config/plugins 中启用两个插件确认包含auth/auth_bridge与queue/smtp_bridge可参考现有插件列表文件中的注释格式启用队列插件的同时应禁用或协调其他queue类插件避免多个队列插件冲突编辑 config/smtp_bridge.ini至少设置host指向目标 SMTP 服务器唯一必填项按需开启port、auth_type、priority配置 TLS若远端服务器支持STARTTLS机会式加密会在认证代理与出站投递阶段自动启用前提是 Haraka 的 tls.ini 已正确配置证书与密钥重载配置修改smtp_bridge.ini后由 Haraka 的配置重载机制SIGHUP自动生效两个插件共享同一份配置与重载回调验证运行测试套件如npm test下的 test/plugins/queue/smtp_bridge.js可确认插件行为实际部署时可通过观察 Haraka 日志中的 AUTH 与投递记录确认客户端凭据被原样用于远端认证。小结queue/smtp_bridge是一个设计极简但语义清晰的桥接型队列插件它不接触任何静态凭据而是通过hook_data_post把客户端认证身份带入事务、通过hook_get_mx把投递目标固定到配置主机与auth/auth_bridge协同完成“客户端 AUTH 凭证即转发凭据”的完整闭环。相比smtp_proxy/smtp_forward的静态凭据转发这种模式更适合那些希望用户用同一组账号在 Haraka 与后端邮件系统之间无缝认证的场景也是理解 Haraka 认证体系与出站投递体系如何协作的一个极佳切入点。赞分享后端网络/通信【免费下载链接】HarakaA fast, highly extensible, and event driven SMTP server项目地址https://gitcode.com/gh_mirrors/ha/Haraka点击查看免费下载相关推荐Haraka queue/smtp_forward 插件SMTP 服务器间转发与多域路由实战指南Haraka queue/smtp_forward 插件SMTP 服务器间转发与多域路由实战指南 导读 queue/smtp_forward 是 Haraka后端网络/通信Haraka auth/auth_proxy 插件按域名代理 AUTH 认证到远程 SMTP 服务器的实战指南Haraka auth/auth_proxy 插件按域名代理 AUTH 认证到远程 SMTP 服务器的实战指南 导读 auth/auth_proxy 是 Ha后端网络/通信Haraka prevent_credential_leaks 插件详解拦截 SMTP 认证用户的凭据泄露Haraka prevent_credential_leaks 插件详解拦截 SMTP 认证用户的凭据泄露 导读 prevent_credential_lea后端网络/通信上一篇Escrcpy安卓设备镜像控制工具使用指南与疑难解答下一篇使用react-snap优化React应用加载性能的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考