跳转到主要内容

于 2025年04月22日 摘录自 Postfix MongoDB Howto

Postfix 对 MongoDB 的支持

Postfix 可以将 MongoDB 用作其任何查找操作的数据源:aliases(5)virtual(5)canonical(5)等。这允许您将邮件服务的相关信息存储在具有精细访问控制的复制型 NoSQL 数据库中。由于未将这些信息本地存储在邮件服务器上,管理员可从任何位置进行维护,而用户可控制您认为合适的任何部分。多个邮件服务器可使用相同的信息,无需经历复制到每个服务器的麻烦和延迟。

本文件涵盖的主题:

使用 MongoDB 支持构建 Postfix

这些说明假设您已按照 INSTALL 文档从源代码构建 Postfix。如果您是从供应商提供的源代码包构建 Postfix,可能需要进行一些修改。

Postfix MongoDB 客户端需要 mongo-c-driver 库。该库可从 mongod-c 项目,或从您的操作系统发行版中安装二进制包,通常命名为 mongo-c-drivermongo-c-driver-devellibmongoc-dev。安装 mongo-c-driver 库可能会将 libbson 作为依赖项一并安装。

要为 Postfix 添加 MongoDB 映射支持,请在 CCARGS 环境变量中添加选项 -DHAS_MONGODB 和 -I,指定包含 MongoDB 头文件的目录,并指定 AUXLIBS_MONGODB 包含 libmongoc 和 libbson 库,例如:

% make tidy
% make -f Makefile.init makefiles \
CCARGS="$CCARGS -DHAS_MONGODB -I/usr/include/libmongoc-1.0 \
-I/usr/include/libbson-1.0" \
AUXLIBS_MONGODB="-lmongoc-1.0 -lbson-1.0"

'make tidy' 命令仅在您之前未包含 MongoDB 支持构建 Postfix 时需要执行。

如果 MongoDB 共享库位于运行时链接器无法识别的目录中,请在 "-lbson-1.0" 之后添加 "-Wl,-R,/path/to/directory" 选项。然后只需运行 'make'。

配置 MongoDB 查找

要使用 MongoDB 查找,请在 main.cf 中将 MongoDB 源定义为表查找,例如:

alias_maps = hash:/etc/aliases, proxy:mongodb:/etc/postfix/mongo-aliases.cf

文件 /etc/postfix/mongo-aliases.cf 可以指定多个参数。如需完整说明,请参阅 mongodb_table(5) 手册页。

示例:虚拟别名映射

以下是一个使用 MongoDB 查找 virtual(5) 别名的基本示例。假设在 main.cf 中,您有:

virtual_aligma_maps = hash:/etc/postfix/virtual_aliases, 
proxy:mongodb:/etc/postfix/mongo-virtual-aliases.cf

并在 mongodb:/etc/postfix/mongo-virtual-aliases.cf 中有:

uri = mongodb+srv://user_name:password@some_server
dbname = mail
collection = mailbox
query_filter = {"$or": [{"username":"%s"}, {"alias.address": "%s"}], "active": 1}
result_attribute = username

此示例假设邮箱名称存储在 MongoDB 后端,格式如下:

{
  "username": "[email protected]",
  "alias": [
    {"address": "[email protected]"},
    {"address": "[email protected]"}
  ],
  "active": 1
}

当收到发送到 "[email protected]" 的邮件且该地址未在 /etc/postfix/virtual_aliases 数据库中找到时,Postfix 将搜索监听在 some_server 服务器端口 27017 的 MongoDB 服务器/集群。它将使用提供的凭据连接,并搜索所有用户名与 "[email protected]" 匹配或别名字段包含 "[email protected]" 的条目。它将返回找到的条目中的用户名属性,并构建一个包含其电子邮件地址的列表。

注意事项:

  • 投影(见下文)类似,Postfix MongoDB 客户端会自动从 result_attribute 结果中移除顶级 '_id' 字段。
  • Postfix mongodb 客户端仅解析数据类型为 UTF8、INT32、INT64 和 ARRAY 的结果字段。其他字段将被忽略,并在日志中记录警告。

示例:邮件列表

在邮件列表中,一种实现方式如下:

{
  "name": "[email protected]",
  "active": 1,
  "address": [
    "[email protected]",
    "[email protected]",
    "[email protected]"
  ]
}

使用以下过滤器,将生成一个以逗号分隔的字符串,包含该列表中的所有电子邮件地址。

query_filter = {"name": "%s", "active": 1}
result_attribute = address

注意事项:

  • 投影(见下文)类似,Postfix MongoDB 客户端会自动从 result_attribute 结果中移除顶级 '_id' 字段。
  • Postfix MongoDB 客户端仅解析数据类型为 UTF8、INT32、INT64 和 ARRAY 的结果字段。其他字段将被忽略,并在日志中记录警告。

示例:高级投影

本模块还支持使用更复杂的 MongoDB 投影。在某些场景下,可能需要对从数据库中检索的数据执行拼接等操作。虽然建议保持数据库设计足够简单以避免此类需求,但 Postfix 支持使用 MongoDB 投影来实现目标。

考虑以下示例:

{
  "username": "[email protected]",
  "local_part": "user",
  "domain": "example.com",
  "alias": [
    {"address": "[email protected]"},
    {"address": "[email protected]"}
  ],
  "active": 1
}

virtual_mailbox_maps 可通过以下参数在 mongodb:/etc/postfix/mongo-virtual-mailboxes.cf 文件中创建:

uri = mongodb+srv://user_name:password@some_server
dbname = mail
collection = mailbox
query_filter = {"$or": [{"username":"%s"}, {"alias.address": "%s"}], "active": 1}
projection = { "mail_path": {"$concat": ["$domain", "/", "$local_part"]} }

这将返回从数据库字段构建的 'example.com/user' 路径。

使用投影时需注意以下几点:

  • result_attribute类似,Postfix MongoDB 客户端会自动从投影结果中移除顶级 '_id' 字段。
  • Postfix MongoDB 客户端仅解析数据类型为 UTF8、INT32、INT64 和 ARRAY 的字段。其他字段将被忽略,并在日志中记录警告。建议在使用投影时排除任何不必要的字段。

反馈

如有问题,请发送至 [email protected]。请包含与 Postfix 配置相关的信息:postconf 中的 MongoDB 相关输出、所使用的库文件等。若问题涉及数据库内容,请附上相关数据库条目的部分内容。

致谢

  • Stephan Ferraro(Aionda GmbH)实现了 Postfix MongoDB 客户端的早期版本。
  • Hamid Maadani(Dextrous Technologies, LLC)添加了对投影和 %letter 插值的支持,并添加了文档。
  • Wietse Venema 采用了代码并进行了重构,同时更新了文档。