O problema

O problema

O problema

Não consigo descobrir como forçar o Postfix a usar uma conexão TLS com o MySQL. EUpodeconecte-se manualmente do servidor Postfix ao servidor MySQL com TLS como usuário postfix, para que não haja nada quebrado com a autenticação MySQL. O problema é claro: o Postfix não está solicitando TLS para a conexão MySQL.

Versões:

  • SO: CentOS 7
  • Postfix: 2:2.10.1-6.el7 e 2:3.2.4-1.gf.el7
  • MySQL (MariaDB): 5.5.56

Como cheguei aqui

Tenho pesquisado em toda a web, incluindo vários sites StackExchange, por uma resposta a esta pergunta. Eu li longamente a documentação do Postfix e do MySQL, repetidamente. A melhor resposta que encontrei é aquela que rejeito por ser desnecessariamente complicada: "Configure um túnel SSH entre seus servidores Postfix e MySQL e conecte-se a ele."Deve haver uma maneira de instruir o Postfix a usar criptografia TLS (SSL) com o cliente MySQL.

Antes de explorarmos a configuração, deixe-me esclarecer: A configuração do meu servidor de e-mail funciona perfeitamente sem o MySQL TLS. Estou usando TLS para SMTPS e IMAPS com sucesso e isso temnada a ver com minha pergunta. O correio está sendo transportado com segurança dentro e fora da minha rede, exceto que as conexões MySQL entre o Postfix e o servidor MySQL não são criptografadas. Exceto pelo link Postfix-MySQL exposto, não há nenhum problema com minha infraestrutura de correio.

No entanto, devido às mudanças nos requisitos de segurança, devo atualizar minha infraestrutura existente para criptografar todas as conexões MySQL. Configurar o TLS para conexões MySQL foi fácil. Testes manuais mostram que os clientes MySQL podem se conectar com sucesso através de um link criptografado por TLS de todos os hosts permitidos. Portanto, a configuração do MySQL TLS também é sólida e funciona para tudoexceto Postfix.

O que eu tentei

Configuração relevante no servidor Postfix:

/etc/postfix/main.cf

Reduzido a apenas uma das várias conexões para manter o material o mais específico possível.

virtual_alias_maps = proxy:mysql:/etc/postfix/lookup_aliases.cf
proxy_read_maps = $virtual_alias_maps
/etc/postfix/lookup_aliases.cf

Credenciais e nomes de host ofuscados.

hosts = mysql-server.domain.tld
user = postfix
password = *****
dbname = mail
option_file = /etc/my.cnf.d/client.cnf
option_group = client
tls_verify_cert = yes
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
/etc/my.cnf

Este arquivo está intacto. Estou incluindo-o apenas para mostrar que o próximo arquivo de configuração está incluído corretamente na configuração do cliente MySQL.

!includedir /etc/my.cnf.d
/etc/my.cnf.d/client.cnf
[client]
ssl = true

Bem-sucedido - MANUAL - Saída da conexão MySQL TLS do servidor Postfix como usuário postfix

Observe em particular que o TLS é empregado com sucesso:

# hostname -f
mail.domain.tld

# sudo -u postfix mysql -h mysql-server.domain.tld -u postfix -p mail
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 72
Server version: 5.5.56-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [mail]> \s
--------------
mysql  Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:     72
Current database:  mail
Current user:      [email protected]
SSL:           Cipher in use is DHE-RSA-AES256-GCM-SHA384
Current pager:     stdout
Using outfile:     ''
Using delimiter:   ;
Server:            MariaDB
Server version:        5.5.56-MariaDB MariaDB Server
Protocol version:  10
Connection:        mysql-server.domain.tld via TCP/IP
Server characterset:   latin1
Db     characterset:   utf8
Client characterset:   utf8
Conn.  characterset:   utf8
TCP port:      3306
Uptime:            1 hour 27 min 23 sec

Threads: 1  Questions: 271  Slow queries: 0  Opens: 13  Flush tables: 2  Open tables: 39  Queries per second avg: 0.051
--------------

MariaDB [mail]> \q
Bye

Configuração relevante no servidor MySQL:

Subsídios MySQL

Observe que o TLS (SSL) é NECESSÁRIO, mas, caso contrário, as permissões são relativamente frouxas até que eu resolva esse problema de conexão TLS:

MariaDB [(none)]> SHOW GRANTS FOR 'postfix'@'10.0.101.%';
+-----------------------------------------------------------------------------------------------------+
| Grants for [email protected].%                                                                       |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'postfix'@'10.0.101.%' IDENTIFIED BY PASSWORD '*SOMEPASSWORDHASH' REQUIRE SSL |
| GRANT SELECT ON `mail`.* TO 'postfix'@'10.0.101.%'                                                  |
+-----------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

Histórico

A conexão Postfix falha quando REQUIRE SSL

Mesmo que o teste manual de linha de comando da conexão TLS do MySQL seja BEM SUCEDIDO aqui, o Postfix ainda não usará o MySQL TLS.

O log geral do MySQL:

180217 14:45:15       16 Connect   [email protected] as anonymous on mail
      16 Connect   Access denied for user 'postfix'@'mail.domain.tld' (using password: YES)

O log do Postfix:

Feb 19 19:22:55 mail postfix/cleanup[11951]: warning: proxy:mysql:/etc/postfix/lookup_aliases.cf lookup error for "[email protected]"
Feb 19 19:22:55 mail postfix/cleanup[11951]: warning: E2CCA2069823: virtual_alias_maps map lookup problem for [email protected] -- message not accepted, try again later
A conexão Postfix é bem-sucedida quando REQUIRE SSL é removido

Este é o Postfix conectando-se com sucesso após alterar a permissão de REQUIRE SSL para REQUIRE NONE. Contudo, a conexão énão criptografado.

180217 15:17:21       26 Connect   [email protected] as anonymous on mail
          26 Query show databases
          26 Query show tables
          26 Field List    admin
          26 Field List    alias
          26 Field List    alias_domain
          26 Field List    config
          26 Field List    domain
          26 Field List    domain_admins
          26 Field List    fetchmail
          26 Field List    log
          26 Field List    mailbox
          26 Field List    quota
          26 Field List    quota2
          26 Field List    vacation
          26 Field List    vacation_notification
          26 Query select @@version_comment limit 1

Conclusão

Tudo que preciso é que o Postfix honre ssl = truesuas conexões de cliente MySQL. Por favor, deixe-me saber se você precisar de mais informações.

Atualizar:

Depois de postar esta pergunta, descobri através de uma leitura mais cuidadosa que versões do Postfix anteriores a 2.11 não suportam a leitura de arquivos de configuração do MySQL. Como tal, é impossível configurar a versão do Postfix fornecida pelo fornecedor (versão 2.10) para usar MySQL TLS. Sinto uma má escolha de palavras na documentação do Postfix, onde a parte superior doa documentação do Postfix para configuração do MySQLlê:

Postfix 3.1 and earlier don't read [client] option group settings unless a non-empty option_file or option_group value are specified. To enable this, specify, for example "option_group = client".

O autor não conseguiu explicar:

These options are ignored for Postfix 2.10 and earlier.  Postfix 2.11 through 3.1 don't read [client] option group settings unless a non-empty option_file or option_group value are specified. To enable this, specify, for example "option_group = client".

Então, atualizei o Postfix no CentOS 7 da versão 2.10 fornecida pelo fornecedor para oGhettoForge Plus fornecidoversão 3.2. Eu instalei o postfix3-mysqlpacote adicional. Eu tinha grandes esperanças, mas elas foram frustradas. Agora, mesmo com o Postfix 3.2,ainda não se conecta ao MySQL através de um link TLS.

Eu tentei ambos option_file = /etc/my.cnf(deve ser o padrão e desnecessário) e option_file = /etc/my.cnf.d/client.cnfsem sucesso.

Eu até tentei forçar o Postfix a considerar o TLS adicionando tls_verify_cert = yes. Isso também não teve efeito. Observe que o nome do certificado corresponde, portanto, esta verificação será aprovada se for realmente tentada.

Responder1

Sinopse

Para estabelecer uma conexão MySQL TLS do Postfix, você precisa:

  1. Postfix versão 2.11 ou mais recente. CentOS 7 fornece apenasPostfix versão 2.10. Você deve adquirir uma atualização para Postfix de meios não CentOS. Eu optei por usar os pacotes postfix3e postfix3-mysqldeGhettoForge Plusporque parecebem recomendado pela comunidade CentOS.
  2. Definirdentro de seus mysql_tablearquivos de configuraçãoqualquer:
    1. Pelo menos uma tls_ciphersconfiguração permitida;
    2. Um certificado TLS do lado do cliente e sua chave privada correspondente,assinado por uma autoridade de certificação que é comum ao servidor MySQL e ao seu cliente Postfix; ou
    3. ambos.
  3. Não confie na configuração deles em seus arquivos /etc/my.cnf ou /etc/my.cnf.d/*! O código Postfix MySQL não lê esses arquivos para determinar se deve estabelecer uma conexão MySQL TLS; eles são analisados ​​tarde demais. OapenasUma maneira de instigar o Postfix a abrir uma conexão TLS MySQL é especificar as configurações TLS em seus mysql_tablearquivos de configuração. Período.

Como cheguei aqui

Finalmente recorri à leitura do código-fonte do Postfix 3.2. As linhas 653-658 de src/global/dict_mysql.c foram especialmente informativas.

Solução final

Se você quiser emular o comportamento do ssl = true, basta adicionar uma linha semelhante à seguinte aos seus mysql_tablearquivos de configuração:

tls_ciphers = TLSv1.2

Nossa configuração requer que apenas o TLS 1.2 seja usado - e já foi aplicado há muito tempo na configuração de nossos servidores MySQL, então não me ocorreu automaticamente aplicá-lo também nos clientes - mas você está livre para adicionar outros cifras se sua organização tolerar cifras mais antigas.

Observe que estamos perfeitamente satisfeitos em não usar certificados do lado do cliente. Usamos outros meios para proteger e monitorar ativamente nossas conexões de banco de dados; simplesmente não queremos complexidade adicional.

Solução alternativa

Se você preferir impor que apenas clientes conhecidos e confiáveis ​​se conectem aos seus servidores MySQL - e você não pode fazê-lo através de outros mecanismos de aplicação de políticas, como firewalls rígidos, complexidade estrita de senha, periodicidade de rotação de senha, auditoria de conexão e outros - então você pode também use certificados do lado do cliente por meio destas configurações adicionais em seus mysql_tablearquivos de configuração:

tls_key_file = /path/to/private.key
tls_cert_file = /path/to/public.certificate
tls_CAfile = /path/to/common.CA.certificate # OR tls_CApath = /path/to/CA-and-intermediate-chain-certificates/

Novamente, configurando-os em /etc/my.cnf ou /etc/my.cnf.d/*não vai ajudar. Esses arquivos não são analisados ​​atédepoiso tipo de conexão (TLS ou não-TLS) temjá foi decidido.

Se você optar por usar certificados do lado do cliente,aplicá-los no servidor! Vocênãoprecisa de certificados do lado do cliente quando tudo o que você deseja é criptografar o tráfego MySQL; em vez disso, basta usar a tls_ciphersalternativa acima. Adicionar certificados do lado do cliente permite que o MySQL verifique se um cliente conectado já é conhecido e confiável, massomente se você disser ao MySQL como fazer isso! Não vai adivinhar e confiar apenas na presença de uma CA comum entre cliente e servidor é apenas uma implementação parcial desta ferramenta poderosa. Se você estiver interessado neste modelo de segurança do MySQL, encontrei pelo menos umGuia prático que fornece bons exemplos de como empregar a validação de certificado de cliente.

informação relacionada