ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Mailu 匿名邮件服务(Anonmail)完全指南:随机别名生成、SimpleLogin 兼容 API 与 Bitwarden 集成

Mailu 匿名邮件服务(Anonmail)完全指南:随机别名生成、SimpleLogin 兼容 API 与 Bitwarden 集成 后端通信【免费下载链接】MailuInsular email distribution - mail server as Docker images项目地址https://gitcode.com/gh_mirrors/ma/Mailu点击查看免费下载导读Mailu 内置的 Anonymous Email ServiceAnonmail匿名邮件服务是一种为保护真实邮箱地址而设计的随机别名生成机制系统会为每个域名动态生成形如github.bananaexample.com的随机别名并将收到的邮件转发到你的真实邮箱同时支持管理员在 Web 界面手工创建、用户通过 SimpleLogin 兼容 API 自助创建以及 Bitwarden 密码管理器在生成用户名时自动申请别名。读完本文你将掌握 Anonmail 的域级开关与访问授权机制、POST /api/alias/random/new接口的完整调用方式含认证头、参数与响应字段、别名命名规则与冲突规避策略以及 Bitwarden Forwarded email alias 的配置步骤和常见故障排查方法。一、Anonmail 是什么从文档到源码的完整认识依据官方文档 docs/anonmail.rstMailu 的 Anonymous Email Service 具备以下核心能力通过管理界面Admin UI或 API 生成随机别名支持基于主机名的别名前缀例如github.alphaexample.com方便识别该别名用于哪个网站提供每域per-domain访问控制域名管理员可以精确决定谁能使用哪个域生成别名。在源码层面Anonmail 不是独立的新组件而是对 Mailu 既有的Alias模型的扩展。在 models.py 中Alias类新增了三个与匿名别名相关的字段hostname记录生成该别名时提交的网站主机名可空用于别名前缀识别owner_email别名所有者邮箱标注这个别名是谁创建的标准别名该字段为空disabled是否禁用与所有者是否启用相互独立见下文禁用语义。同时Domain 模型 新增anonmail_enabled布尔字段默认False用于在域名维度上启用/关闭 Anonmail 服务。数据模型、表单与 REST 模式schemas中的对应字段可见于 forms.py 与 schemas.py。二、管理端配置开启域名并授予访问权限2.1 域名级开关Domain configuration官方文档指出Enable Anonymous Email Service in the domain settings. Each domain has an individual toggle.具体操作路径在管理界面的域Domain管理中新建域名时勾选Enable Global Anonymous Email Service表单字段见 create.html已存在的域名可在域详情页查看 Anonmail 状态details.html并在域名列表中看到启用标记list.html。该开关的作用范围是整个域一旦开启域内任何用户都可以通过 Web 界面使用该域生成匿名别名。但注意域的anonmail_enabled只是面向所有用户开放的快捷通道真正的粒度控制由下一节的域访问授权完成。2.2 按用户授权Domain access文档原文Individual domain access can be granted in the domain access function by a domain manager or global admin.Mailu 提供了一个专门的DomainAccess数据模型models.py它是domain_name → user_email的授权表用于精确控制某个用户可以使用某个域生成匿名别名。授权只能由**域名管理员domain manager或全局管理员global admin**执行对应的管理界面路由在 managers.pyGET/POST /domain/access/list/domain_name查看/列出该域已授权的用户POST /domain/access/create/domain_name通过表单或 JSON字段user为某个用户授予该域的 Anonmail 访问权重复授权会返回 409POST /domain/access/delete/domain_name/access_id撤销授权。值得注意的权限判定逻辑在 models.py 的has_domain_access()中满足以下任一条件即视为拥有某域访问权用户是全局管理员global_admin——隐式拥有所有域用户是该域的管理员出现在domain.managers中用户存在于该域的DomainAccess授权表中。2.3 用户视角个人匿名别名管理匿名别名本质上仍然是标准 Mailu 别名只是多了所有者与元数据。用户登录管理界面后在Anonymous Aliases页面anonaliases.html可以看到自己创建的别名及其元数据Alias、Domain、Destination、Note、Hostname、Created、Status等列列表上方提供 Generate alias 按钮仅当拥有至少一个可访问域时显示。对应后端路由aliases.pyGET /anonalias/list列出当前用户owner_email拥有的匿名别名GET/POST /anonalias/create创建页面表单会动态填充用户可访问的域列表判定逻辑与 API 一致见 aliases.pyPOST /anonalias/delete/alias_email删除别名带确认POST /anonalias/enable/alias_email/POST /anonalias/disable/alias_email启用/禁用别名均带确认。文档中说明别名可以直接从界面禁用或删除这三条路由即对应实现。禁用操作不会删除别名记录而是把disabled置为True邮件投递随即停止启用后恢复投递。截图参考文档中的 AnonymousAlias.png 展示了匿名别名管理列表的界面形态其中包含上述各元数据列。三、API 使用SimpleLogin 兼容的随机别名接口3.1 认证方式Authentication文档要求先在管理界面Authentication tokens认证令牌下为当前用户创建应用令牌然后以user-email:auth-token的格式放入Authentication请求头。后端验证逻辑位于 common.py 的user_token_authorization装饰器它按照与内部 nginx 认证一致的过程校验读取Authentication请求头若无该头且当前没有已登录会话直接返回401按:分割出user_email与token自动urllib.parse.unquote解码用user_email查询用户用户不存在返回403调用utils.check_credentials_for_api()utils.py验证令牌API 场景只接受应用令牌不接受用户登录密码令牌校验通过后还会检查令牌的 IP 白名单限制token.ip若令牌绑定了 IP 而当前来源不匹配则拒绝。调用前需满足的三个要求文档原文持有有效的应用令牌32 位十六进制小写字符串见 utils.py 的is_app_token()判定目标域已启用 Anonmailanonmail_enabled True拥有目标域的所有权域管理员/全局管理员或已被显式授权DomainAccess。此外user_token_authorization在认证前后都会调用限流器limiter.py请求来源 IP 若触发AUTH_RATELIMIT_IP阈值默认5/hour见 configuration.py会直接返回429 Too Many Requests认证失败也会对来源 IP 计数限流从而抑制暴力尝试。3.2 端点与参数端点POST /api/alias/random/new该接口在 simplelogin.py 中实现属于非版本化的 SimpleLogin 兼容端点。之所以不带版本前缀是因为注册逻辑api/init.py只有在配置了API_TOKEN非空时才会注册该 Blueprint且注册路径就是{WEB_API}默认/api——Bitwarden 等第三方客户端无法指定版本号因此必须保持与 SimpleLogin 完全一致的路径结构。请求头请求头值Authenticationuser-email:auth-tokenContent-Typeapplication/json参数hostnamequery string可选网站主机名用于生成别名前缀例如www.github.comnoteJSON body可选别名描述/备注destinationJSON body可选转发目标地址可以是字符串或数组。示例文档原文TOKENuser-email:your-auth-token curl -X POST https://admin.example.com/api/alias/random/new?hostnamewww.github.com \ -H Authentication: ${TOKEN} \ -H Content-Type: application/json \ -d {note:GitHub signup}3.3 服务端行为从请求到落库的完整链路依据 simplelogin.py一次成功请求的内部流程如下确定可访问域集合遍历所有域名收集满足has_domain_access(d.name, user)或该域已启用 Anonmail 且属于用户所在域条件的域若集合为空返回403 You do not have access to any domains for creating aliases随机选择域用secrets.choice()从可访问域中随机挑选一个作为别名域名默认备注若提供了hostname但未提供note自动生成Website: {hostname}作为备注生成唯一 localpart在ANONMAIL_MAX_RETRIES默认 10配置见 configuration.py次尝试内调用utils.generate_anonymous_alias_localpart()utils.py并做三层冲突检查models.Alias.resolve()排除 SQL 通配符wildcard别名可能匹配的情况Alias.query.filter_by(email...)排除与已有别名含已禁用别名的精确冲突User.query.filter_by(email...)排除与已有用户的精确冲突 若重试耗尽仍无唯一候选返回409 Unable to find a unique alias after several retries写入数据库创建Alias记录destination固定为当前用户邮箱g.user.email并记录owner_email、hostname未提供时为空字符串与commentnote返回 SimpleLogin 兼容响应HTTP 状态码201。3.4 别名命名规则hostname 前缀generate_anonymous_alias_localpart()的命名逻辑分两种模式带 hostname先用get_tld()解析出主机名的注册域名主体去掉www.、子域名与路径再拼接一个随机英文单词5~10 个字母形如groupon.banana、github.tiger若 TLD 解析失败或单词生成失败则回退为纯随机 token不带 hostname直接返回secrets.token_urlsafe(12)生成的 URL 安全随机 token。测试用例 test_api.py 明确验证了前缀提取行为输入 hostname期望前缀www.groupon.comgrouponhttps://www.amazon.com/some/pathamazonshop.example.orgexamplesubdomain.test.co.uktestsingle.comsingle3.5 响应格式接口成功返回201的 JSON 字段与含义见 simplelogin.py 与 test_api.py字段类型说明emailstring创建的别名完整邮箱如github.bananaexample.comenabledboolean别名是否启用not disablednotestring别名备注无则空字符串creation_datestring创建日期格式%Y-%m-%d %H:%M:%Screation_timestampinteger创建时间戳nb_forwardinteger转发邮件数当前恒为 0未统计nb_blockinteger拦截邮件数当前恒为 0未统计nb_replyinteger回复数当前恒为 0未统计3.6 相关辅助端点在 v1/alias.py 中与匿名别名相关的还有一组带版本前缀/api/v1的辅助接口均使用api_token_authorization全局API_TOKEN认证GET /api/v1/alias/me列出当前用户创建的所有匿名别名按owner_email过滤PATCH /api/v1/alias/me/alias修改匿名别名可更新comment、destination、wildcard、hostname、disabled目标地址必须存在于 Mailu 用户中DELETE /api/v1/alias/me/alias删除自己拥有的匿名别名GET /api/v1/alias/domains/available返回所有可用域名列表。四、Bitwarden 集成密码管理器的自动别名生成4.1 配置步骤文档原文描述了 Bitwarden 的接入方式在 Bitwarden 的**用户名生成器Username Generator**中选择Forwarded email alias作为来源然后填写三项配置Email domain希望别名落在哪个域名对应 Mailu 的anonmail_enabled域名你的 TOKEN即user-email:auth-tokenMailu 管理界面域名即admin.example.com这类入口地址Bitwarden 会向该主机发起/api/alias/random/new请求。4.2 兼容性原理Bitwarden 的 Forwarded email alias 功能遵循 SimpleLogin 的 API 规范而 Mailu 的兼容端点正是为此设计端点路径完全一致POST /api/alias/random/newsimplelogin.py认证头使用Authentication: user-email:token与 SimpleLogin 格式一致响应字段email、enabled、note等与 SimpleLogin 的响应模型对齐。在 api/init.py 的注册逻辑中兼容端点特意注册为非版本化路径注释明确写道Register SimpleLogin-compatible endpoint (non-versioned for Bitwarden)——因为 Bitwarden 只会调用固定路径无法感知版本号。测试 test_api.py 中的test_authentication_header_compatibility也专门验证了Authentication头Bitwarden 格式在 Mailu 端点上的可用性。截图参考文档中的 BitwardenUsernameGenerator.png 展示了 Bitwarden 用户名生成器中Forwarded email alias的配置界面。五、别名行为与投递语义文档的 Behavior 一节明确了两条关键规则源码均能印证规则 1匿名别名 标准 Mailu 别名。通过 Anonmail 创建的别名在数据库中就是一条普通Alias记录入站邮件按标准别名解析流程转发到配置的目标地址。Alias.resolve()models.py同时处理了大小写匹配与通配符wildcard匹配两种场景因此匿名别名与非匿名别名在投递路径上完全一致。规则 2目标地址必须属于令牌所有者。API 创建的别名destination被固定为[g.user.email]simplelogin.py不允许任意转发地址即使是 v1 的PATCH /alias/me/alias更新目标地址也要求目标必须是 Mailu 中真实存在的用户v1/alias.py。这有效防止匿名别名被滥用于向任意第三方地址转发。禁用语义disabled字段与所有者状态相互独立。Alias.resolve()的判定条件是别名未禁用且所有者若有处于启用状态models.py单独禁用别名会停止投递而不影响所有者单独禁用所有者会暂停其名下所有匿名别名的投递但不会改动各别名的disabled标志重新启用所有者后投递自动恢复。UI 层的启用/禁用路由aliases.py即是对该字段的读写。六、故障排查Troubleshooting依据文档并对照源码逻辑可按下表定位常见问题现象排查方向源码依据403 / 401 错误检查令牌是否有效是否为 32 位十六进制应用令牌、令牌是否绑定 IP 白名单、目标域 Anonmail 是否开启、用户是否拥有域访问授权认证失败也会触发 IP 限流默认 5/hourcommon.py、utils.py、limiter.py404 错误确认域已启用 Anonmail 且目标别名确实存在查询/删除/更新不存在的别名会返回 404v1/alias.py无法创建别名检查域 Anonmail 状态与域访问授权无可访问域时接口返回 403重试 10 次仍无法生成唯一 localpart 时返回 409simplelogin.py邮件未投递确认别名处于启用状态disabled为假且所有者账号启用确认目标地址是 Mailu 中真实存在的用户邮箱models.py另外补充两个与本文档无直接冲突但值得注意的边界情况请求来源 IP 触发限流会返回429区别于认证失败服务端必须在配置中设置API_TOKEN否则整个/api下的 v1 与 SimpleLogin 兼容端点都不会注册api/init.py所有 API 调用将得到 500 错误提示。七、测试与验证仓库在 tests/anonmail/ 目录下提供了一整套针对匿名别名的测试可用于验证行为与回归test_api.py覆盖创建成功、域未启用时的授权例外、权限拒绝403、hostname 前缀提取、word 模式github.{word}、无 hostname 随机 token、Authentication 头兼容性等场景test_alias_detail.py验证收件人分隔符recipient delimiter下显式别名与 catchall 的优先级test_2695_case_duplicate.py 与 test_2695_lowercase_migration.py验证 localpart 大小写归一化及大小写冲突迁移test_4078_forward_destination_localpart.py验证转发目标 localpart 的字符合法性校验。其中 test_api.py 的test_create_random_alias_success演示了最小可用调用序列创建启用 Anonmail 的域 → 为用户授予 DomainAccess → 携带Authentication: email:32位token调用接口 → 断言返回 201 且别名落库含owner_email与hostname。结语Mailu 的 Anonymous Email Service 是一套兼顾隐私保护与运维可控的匿名别名方案域名管理员通过anonmail_enabled开关与DomainAccess授权完成粒度控制普通用户既可在管理界面手工生成/禁用/删除别名也能借助 SimpleLogin 兼容的POST /api/alias/random/new接口实现程序化创建更可与 Bitwarden 的 Forwarded email alias 用户名生成器无缝对接。理解其数据模型Alias.hostname/owner_email/disabled与Domain.anonmail_enabled、DomainAccess、认证链路Authentication头 应用令牌 IP 限流与命名规则hostname 前缀 随机单词/token即可在生产环境中安全、可追溯地部署这套匿名邮件能力。赞分享后端通信【免费下载链接】MailuInsular email distribution - mail server as Docker images项目地址https://gitcode.com/gh_mirrors/ma/Mailu点击查看免费下载相关推荐dashy匿名邮箱AnonAddy集成dashy匿名邮箱AnonAddy集成 还在为每个网站注册不同的邮箱而烦恼担心个人信息泄露AnonAddy匿名邮箱服务与Dashy的完美集成让你在个人仪前端后端认证鉴权为什么e5-small-openmind是语义相似性任务的终极选择实测对比10种主流模型为什么e5 small openmind是语义相似性任务的终极选择实测对比10种主流模型 在自然语言处理领域 语义相似性任务 是衡量文本之间语义关联程度的核CAS 匿名 Principal ID 释放Transient 与 Persistent 匿名用户名生成实战指南CAS 匿名 Principal ID 释放Transient 与 Persistent 匿名用户名生成实战指南 本指南聚焦 Apereo CAS 中匿名后端认证鉴权单点登录上一篇ChainList组件设计可复用组件架构下一篇从静态到动态Nuclei变量系统实现模板参数化的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表