带有多行标题和捕获组的 Postfix header_checks

带有多行标题和捕获组的 Postfix header_checks

我们有一个 header_checks 正则表达式传递给“清理”过程,但如果标题有多行,它就不会将其作为单个标题进行处理。

header_check(将 header 的值传递给 FILTER):

/^X-OurHeader:\s+(.*?)/ FILTER $1

master.cf:

cleanup_service.        unix  n       -       y       -       0       cleanup
  -o header_checks=regexp:/etc/postfix/header_check

失败的多行标题示例:

X-OurHeader: a_special_filter_command:my.sub.domain
 b.mail.whatever.com

变为多行之前的原始完整标题是:

X-OurHeader: a_special_filter_command:my.sub.domainb.mail.whatever.com

传递给 FILTER 的结果是:a_special_filter_command:my.sub.domain 并且缺少第二行中剩余的主机名b.mailwhatever.com

如果我将 header_check 改为这样,它会捕获下一行:

/^X-OurHeader:\s+([\s\S]*)/ FILTER $1

然后,$1 捕获组包含第二行,但捕获的文本中仍然有一个空格(可能还有换行符),因此这不起作用。如下所示:

X-OurHeader: a_special_filter_command:my.sub.domain b.mail.whatever.com

使用第一种方法查看日志,我们会看到

postfix/cleanup[123456]: 27429A1FE8: filter: header X-OurHeader: a_special_filter_command:my.sub.domain? b.mail.whatever.com

是否有人会建议采用其他方法?最终目标是我们用需要发送到 FILTER 的特殊 cmd:hostname 值标记标头,但希望支持将 hdr 值拆分为多行,以便长标头满足“长度应小于 78”标准。

答案1

如果您知道或可以确保只有一定数量的变化,请添加其他表达式来分别捕获这些变化/..:(.*) (.*)$/ -> /..:$1$2/- 如果没有空格,后缀将继续使用下一个表达式,因此通过首先放置复杂的匹配来保持模式简单。


如果没有,但仍在正则表达式能力范围内,可能有一种方法可以链式多重查找。我无法将整个内容拼凑起来,但是如果它在您的发行版上可用并且可以正常工作,则文档应该会有所帮助,从手册header_checksDATABASE_README文件开始。

pipemap:{pcre:/extract/category.pcre,pcre:/map/category/to/filter/command.pcre}

基本思想:首先获取总体方向(例如MYFILTER: $1),然后仅应用必要的编辑以使其成为有效的后缀命令,并仔细确保所有输入都能产生有效的输出(MYFILTER: (valid1|valid2) -> FILTER host:port加上后备行MYFILTER:-> FILTER: default:port


除此之外,通常当你想要做一些对于正则表达式和 header_checks 来说太强大的事情时,你会升级到图灵完备性:

  1. 足够动态的查找。例如,如果您喜欢 SQL,那么您应该能够获得一些可读性/可维护性不会太差的东西。请注意多次查找产生的非预期逻辑结果header_checks = sqlite:/path/to/definition.conf pcre:/remaining/simpler/rules.pcre

  2. 一个 milter/policy 守护进程。它们甚至可能调用外部二进制文件,而根本不重定向消息。根据您当前对下一个 FILTER 的想法的界面,这可能会或多或少方便。


我也相信有办法让后缀正确运输如果需要的话,可以通过 header_checks 的多个实例来检查给定的消息,但我不推荐那种路由,因为它不能很好地与其他(或多或少动态的)路由决策混合。

相关内容