Postfix header_checks com cabeçalhos multilinhas e grupo de captura

Postfix header_checks com cabeçalhos multilinhas e grupo de captura

Temos um regexp header_checks passado para o processo de "limpeza", mas ele não está processando o cabeçalho como um único cabeçalho se estiver em várias linhas.

header_check (passa o valor do cabeçalho para FILTER):

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

mestre.cf:

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

Exemplo de cabeçalho multilinha onde falha:

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

O cabeçalho completo original antes de ser multilinhado é:

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

O resultado passado para FILTER é então: a_special_filter_command:my.sub.domain e falta o nome de host restante da segunda linha b.mailwhatever.com.

Se eu alterar o header_check para isso, ele capturará a próxima linha:

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

O grupo de captura $1 contém então a segunda linha, mas ainda há um espaço (e presumivelmente uma nova linha) no texto capturado, então isso não funciona. É assim:

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

Olhando nos logs com a primeira abordagem, vemos

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

Existe uma abordagem alternativa para isso que alguém possa sugerir? O objetivo final é marcar um cabeçalho com valores cmd:hostname especiais que precisam ser enviados para o FILTER, mas queremos suportar que o valor hdr seja dividido em várias linhas para que um cabeçalho longo atenda ao "comprimento DEVE ser < Padrão de 78".

Responder1

Se você sabe ou pode garantir que há apenas um certo número de variações, adicione expressões adicionais para capturá-las separadamente /..:(.*) (.*)$/ -> /..:$1$2/- o postfix continuará com a próxima expressão se não houver espaço, então mantenha os padrões simples colocando a correspondência complexa primeiro.


Se não, mas ainda estiver dentro do poder das expressões regulares, pode haver uma maneira deencadear múltiplas pesquisas. Do início da minha cabeça, não consigo juntar as peças completas, mas se estiver disponível na sua distribuição e funcionar, a documentação deve ser útil, comece com o header_checksmanual e o DATABASE_READMEarquivo.

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

Ideia básica: obtenha primeiro sua orientação geral (por exemplo MYFILTER: $1, ) e só então aplique as edições necessárias para torná-lo um comando postfix válido, garantindo cuidadosamente que todas as entradas levem a uma saída válida ( MYFILTER: (valid1|valid2) -> FILTER host:portmais uma linha de fallback MYFILTER:-> FILTER: default:port)


Caso contrário, geralmente quando você deseja fazer coisas muito poderosas para expressões regulares e header_checks, você escala para a integridade de Turing:

  1. Uma pesquisa suficientemente dinâmica. por exemplo, se você gosta de SQL, isso deve render algo não muito menos legível/manutenível. Cuidado com resultados lógicos não intencionais de múltiplas pesquisasheader_checks = sqlite:/path/to/definition.conf pcre:/remaining/simpler/rules.pcre

  2. Um daemon milter/política. Eles podem até chamar binários externos sem redirecionar a mensagem. Dependendo da interface da sua ideia atual do próximo FILTRO da fila, isso pode ser mais ou menos conveniente.


Eu também acredito que existem maneiras de fazer o postfix funcionar corretamentetransporteuma determinada mensagem por meio de várias instâncias de header_checks, se necessário, mas eu não recomendaria essa rota, ela não combina muito bem com outras decisões de roteamento (mais ou menos dinâmicas).

informação relacionada