Postfix Relay: Somente envia mensagens de saída para a Internet em determinado critério, retransmite para outro relé se o critério não for atendido

1

Isso soará um pouco confuso e complexo, mas temos uma configuração maligna muito atualmente para e-mail em um dos ambientes dos meus clientes.

Do sistema mais interno para o exterior, temos:

Exchange Server -> Sendmail Server -> McAfee Email Gateway -> OUTSIDE

Isso é um pouco ruim porque os e-mails fora do escritório com destino externo (de alguém dentro do sistema para fora) não funcionam, eles aparentemente são pegos no McAfee Email Gateway e não são retransmitidos para fora.

O que estou tentando fazer é configurar um servidor Postfix como um retransmissor E um servidor SMTP e, dependendo do que está sendo recebido:

  1. Enviar e-mail diretamente (usando SMTP, apenas para respostas de ausência temporária)
  2. Transmitir e-mails para o servidor do Sendmail, pelo restante de suas tarefas de repasse, como normalmente teria acontecido.

Isso pareceria um pouco com o seguinte:

Exchange Server -> Postfix Relay --- Out of Office messages only ---> OUTSIDE
                         |
                   All other mail
                         |
                         ---> Sendmail Server/Relay ---> McAfee Email Gateway ---> OUTSIDE

Estou um pouco atrasado em como configurar o Postfix para a opção de retransmissão seletiva. Existe alguém que possa dar algumas dicas sobre como conseguir isso?

    
por Thomas Ward 01.08.2017 / 19:07

1 resposta

0

Eu criei uma abordagem muito hackeada para isso.

Essencialmente, eu coloco um 'servidor' SMTP customizado escrito em Python rodando entre o servidor Postfix e o servidor Exchange que realmente lida com o roteamento de retransmissão real . Está escrito em Python e é executado como superusuário na porta 25 (devido às restrições de ligação de porta).

Esse script Python então processa a mensagem como normalmente faria, passando por um e-mail do analisador de seqüência de caracteres e lendo a linha de assunto para determinar para onde enviá-la e enviando a mensagem original, inalterada, para o Postfix local Servidor SMTP (a ser enviado diretamente para a saída) ou para outro retransmissor na rede. Até agora, parece estar funcionando.

Este é o código que eu uso para isso no lado do Python:

#!/usr/bin/env python3

# Libraries
import smtplib
import smtpd
import asyncore
import email
import sys
from datetime import datetime

print('Starting custom mail handling server...')

# CONFIGURATION VARIABLES - We are expecting to relay, so... let's relay.
SMTP_RELAY = 'SMTP_RELAY_HOSTNAME_OR_IP'
SMTP_DIRECT = 'localhost'

#############
#############
# SMTP SERVER
#############
#############


# noinspection PyMissingTypeHints,PyBroadException
class AutoReplyHandlerSMTP(smtpd.SMTPServer):

    def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
        print('MESSAGE RECEIVED - [%s]' % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        print('Receiving message from:', peer)
        print('Message addressed from:', mailfrom)
        print('Message addressed to  :', rcpttos)
        print('Message length        :', len(data))
        print(data)

        # Flush the output buffered (handy with the nohup launch)
        sys.stdout.flush()

        # Analyze and extract data headers
        msg = email.message_from_string(data)
        subject = ''
        try:
            subject = msg['Subject']
            subject = subject.lower()
        except:
            print("Subject error:", sys.exc_info()[0])
        print('Message subject       :', msg['Subject'])

        # Determine whether we are directly sending outbound, or if we're relaying to another server.
        if "automatic reply" in subject:
            print("Automatic reply received, sending directly.")
            # Local postfix SMTPd is on tcp/6625.
            conn = smtplib.SMTP(host=SMTP_DIRECT, port=6625, timeout=60)
            conn.sendmail(mailfrom, rcpttos, msg.as_string())
            conn.quit()
        else:
            print("Standard message detected, sending to relay.")
            # Other relay server is on tcp/25 (standard smtp)
            conn = smtplib.SMTP(host=SMTP_RELAY, timeout=60)
            conn.sendmail(mailfrom, rcpttos, msg.as_string())

        # Flush the output buffered (handy with the nohup launch)
        print("\n\n")
        sys.stdout.flush()
        return


# Listen to port 25 ( 0.0.0.0 can be replaced by the ip of your server but that will work with 0.0.0.0 )
server = AutoReplyHandlerSMTP(('0.0.0.0', 25), None)

# Wait for incoming emails
asyncore.loop()

Eu configurei o Postfix para escutar no SMTP em uma porta diferente. Na verdade, isso foi o que acabou sendo feito, em /etc/postfix/master.cf no meu servidor Ubuntu para isso, e é basicamente as duas linhas e como eu configurei o SMTPd no Postfix - note que você pode usar qualquer porta de alta numeração para qualquer outra porta Postfix SMTPd, mas eu escolhi algo fácil:

#smtp      inet  n       -       y       -       -       smtpd
6625      inet  n       -       y       -       -       smtpd

O script Python encaminha os dados para a porta 6625 e o SMTPd do Postfix sendo executado lá; com isso sendo feito, especificamente deixamos o Python determinar qual servidor ou retransmissão SMTP é o "próximo salto". Isso quebra os cabeçalhos padrão "Recebido por", mas supostamente funciona bem com mensagens.

Eu não encontrei nenhum problema com a minha solução, e parece que esteja funcionando. Testes adicionais são necessários, mas essa 'solução' parece resolver o problema de roteamento de como rotear mensagens (saída direta do SMTP, ou através do resto dos relés) sem mexer na configuração do Postfix realmente.

    
por 03.08.2017 / 03:55