Postfix - amavisd-new sem host local ou servidor de correio de uma nova maneira

Existem muitas instruções sobre como aumentar o servidor de correio em um monte de postfix - amavisd-new - dovecot. E a grande maioria deles se repete quase literalmente, incluindo erros e imprecisões.

Parece chato para mim apertar botões sem pensar, então decidi otimizar a configuração padrão: e se eu construir a interação do postfix e do amavisd-new não através do localhost, mas em um soquete unix?

Como se viu, nem tudo é tão simples, mas eu fiz! Instrução e remendo sob o corte.

Sinceramente, geralmente não gosto de interação por meio de host local na mesma máquina. Se você deseja organizar a troca de dados entre dois aplicativos, é muito mais correto, seguro e com menos recursos fazer isso por meio de um soquete unix no sistema de arquivos. Além disso, dessa forma, você pode organizar a proteção (por meio de direitos no sistema de arquivos), mesmo quando ela estiver ausente no nível do aplicativo ou protocolo.

Portanto, o caminho do correio no grupo discutido se parece com o seguinte:



Acontece que precisamos organizar duas conexões: ao transferir para a filtragem e ao retornar ao MTA. Como o soquete é criado pelo ouvinte, no primeiro caso, ele será amavisdo e, no segundo - postfix.

Vamos começar com o segundo, porque é mais simples e melhor descrito. Para que o postfix crie um soquete de escuta, basta especificar unix, não inet, na segunda coluna de master.cf (coluna de tipo). Nesse caso, a primeira coluna define o caminho e o nome do arquivo do soquete.

Como os processos do postfix funcionam no chroot (isso pode ser desativado para um processo específico, mas não vale a pena), você precisa criar uma pasta dentro do diretório inicial do postfix: / var / spool / postfix. Ele terá os dois soquetes:

mkdir /var/spool/postfix/amavis chown amavis:postfix /var/spool/postfix/amavis chmod 770 /var/spool/postfix/amavis 

Configuração de poço e postfix:

 amavis/postfix-in unix y - y - - smtpd -o smtpd_client_restrictions=$local_clients_only -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions= -o smtpd_milters= 

As opções específicas dependem da sua configuração, esta é a minha opção.

Existem dois problemas:

  1. O caminho será relativo a / var / spool / postfix / private, que está sujeito a permissões muito estritas.
  2. Não tenho certeza se isso é verdade em todas as distribuições, mas no Ubuntu, com certeza. É melhor não tocar nos direitos da pasta (os soquetes de todos os serviços postfix estão lá), é melhor criar apenas um link simbólico.
  3. Além do soquete, o postfix também cria um arquivo pid para o processo, cujo nome é gerado automaticamente pela máscara de $ type. $ Name. Onde type será igual a unix e o nome é retirado da primeira coluna do master.cf. Acontece que unux.amavis / postfix-in, ou seja, arquivo em uma subpasta. Ele próprio não o criará e cairá com um erro.

Então, substituímos muletas:

 cd /var/spool/postfix/private ln -s ../amavis . mkdir /var/spool/postfix/pid/unix.amavis 

Não é muito bom, mas não destrutivo para a estrutura de pastas normal do pacote.

Reiniciamos o postfix e garantimos que o arquivo de soquete apareça na pasta amavis e o arquivo pid em pid / unix.amavis. Infelizmente, os direitos ao soquete são 666, mas os direitos da pasta que você criou anteriormente protegerão o arquivo de olhos desnecessários.

Você pode verificar o trabalho com o comando:

 netcat -U /var/spool/postfix/amavis/postfix-in 220 mail.example.ru ESMTP Postfix 

Bem, eles fizeram isso. Agora amavisd.

Primeiro, configure o caminho de retorno de email através do soquete unix de propriedade do postfix. Isso funciona imediatamente:

 $forward_method = 'smtp:/var/spool/postfix/amavis/postfix-in'; $notify_method = \$forward_method; 

Bem, agora a parte mais difícil é instalar soquetes no amavisd. A solução pode ser encontrada na Internet , mas é proposto o uso de um único soquete especificado pelo parâmetro $ unix_socketname. Eu também queria meu próprio protocolo amavisd-novo (AM.PDP) e recepção de email por soquetes.

O arquivo de configuração padrão contém uma referência à diretiva @listen_sockets, mas não há descrição para isso. Mas está nas notas de lançamento , mesmo com exemplos! É verdade que existe apenas um soquete, mas o que impede você de tentar?

OK, mas como definir o protocolo para o soquete (especificado no banco de políticas)? Em todos os exemplos, eles simplesmente escrevem SOCK. Por analogia com os soquetes inet (você pode especificar a porta do host), sugeri que fosse necessário especificar o caminho completo para o arquivo de soquete. Aqui está o que aconteceu:

 $unix_socketname = undef; $inet_socket_bind = undef; $inet_socket_port = undef; @listen_sockets = ('/var/lib/amavis/amavisd.sock', '/var/spool/postfix/amavis/amavis-in.sock'); $unix_socket_mode = 0660; %interface_policy = ( '/var/lib/amavis/amavisd.sock' => 'AM.PDP-SOCK', '/var/spool/postfix/amavis/amavis-in.sock' => 'LMTP-SOCK' ); $policy_bank{'LMTP-SOCK'} = { protocol => 'LMTP' }; $policy_bank{'AM.PDP-SOCK'} = { protocol => 'AM.PDP', auth_required_release => 0, # don't require secret-id for release }; 

Reiniciando, verificando - de fato, os dois soquetes foram criados! Vitória Na verdade, quando você tenta se conectar ao soquete, nada acontece e um erro é gravado no log de que o protocolo não está definido para ele. Acontece que o banco de apólices não se aplica a eles.

Como assim? Eu tive que ir para o código.

Essa campanha trouxe duas novidades - como sempre, boas e ruins. O bom é que a suposição sobre% interface_policy estava correta:

 # load policy banks according to my socket (destination), # then check for allowed access from the peer (client/source) # sub access_is_allowed($;$$$$) { my($unix_socket_path, $src_addr, $src_port, $dst_addr, $dst_port) = @_; my(@bank_names); if (defined $unix_socket_path) { push(@bank_names, $interface_policy{"SOCK"}); push(@bank_names, $interface_policy{$unix_socket_path}); } elsif (defined $dst_addr && defined $dst_port) { $dst_addr = '['.lc($dst_addr).']' if $dst_addr =~ /:[0-9a-f]*:/i; # IPv6? push(@bank_names, $interface_policy{$dst_port}); push(@bank_names, $interface_policy{"$dst_addr:$dst_port"}); } load_policy_bank($_) for @bank_names; 

O ruim é que $ unix_socket_path entra nessa função vazia. É preenchido da seguinte forma:

 my $is_ux = $sock && $sock->UNIVERSAL::can('NS_proto') && $sock->NS_proto eq 'UNIX'; 

E as duas propriedades estão vazias lá.

Um estudo da documentação sugeriu esta opção:

 my $unix_socket_path = $sock->hostpath(); 

E funcionou! Pronto .patch pode ser dito aqui .

Há o toque final. Como o amavisd cria seu próprio soquete com direitos apenas para si próprio e negamos o acesso ao restante (o que é verdade), precisamos adicionar o postfix ao grupo amavis para que ele possa gravar no soquete:

 gpasswd -a postfix amavis 

Feito.

PS: Enviei o patch e a descrição do problema por Mark Martinec por correio, pois não encontrei nenhuma menção ao rastreador de erros no site . Ainda não recebi uma resposta, mas não conto com ela - o projeto parece abandonado (a última versão há mais de dois anos).

Source: https://habr.com/ru/post/pt415597/


All Articles