{"id":1684,"date":"2026-09-23T09:46:08","date_gmt":"2026-09-23T12:46:08","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/?p=1684"},"modified":"2026-09-23T09:46:08","modified_gmt":"2026-09-23T12:46:08","slug":"ssl-tls-postfix-dovecot","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/es\/2026\/09\/ssl-tls-postfix-dovecot\/","title":{"rendered":"SSL\/TLS en Postfix y en Dovecot: por qu\u00e9 y c\u00f3mo"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro fechando um grande cadeado dourado no servidor de e-mail, com envelopes trancados passando por um t\u00fanel protegido at\u00e9 outro servidor e o c\u00e3o caramelo ao lado\" src=\"\/wp-content\/uploads\/2026\/09\/tls-postfix-dovecot.webp\" width=\"1486\" height=\"856\" \/><\/p>\n<p>Servidor de e-mail sem TLS entrega duas coisas de gra\u00e7a a quem estiver no caminho: o conte\u00fado das mensagens e a senha de cada usu\u00e1rio, que viaja a cada vez que o celular confere a caixa. E n\u00e3o \u00e9 s\u00f3 privacidade: desde fevereiro de 2024 o Gmail exige conex\u00e3o TLS de <em>todo<\/em> remetente. Abaixo, o SSL\/TLS completo num servidor Postfix + Dovecot \u2014 certificado Let&#8217;s Encrypt, as portas certas, vers\u00f5es m\u00ednimas, autentica\u00e7\u00e3o s\u00f3 com criptografia e a prote\u00e7\u00e3o contra o ataque que remove o STARTTLS. Tudo testado em laborat\u00f3rio no Ubuntu 24.04 e no 26.04, que trazem Dovecots de vers\u00f5es diferentes, com sintaxes diferentes.<\/p>\n<p><!-- more --><\/p>\n<h2>Por que o servidor de e-mail precisa de TLS<\/h2>\n<ul>\n<li><strong>Senhas.<\/strong> IMAP, POP3 e SMTP autenticado mandam usu\u00e1rio e senha no in\u00edcio de cada sess\u00e3o. Sem TLS, qualquer um no Wi-Fi do caf\u00e9, no provedor ou num roteador comprometido l\u00ea em texto puro. Um \u00fanico login capturado d\u00e1 acesso \u00e0 caixa inteira \u2014 e \u00e0 redefini\u00e7\u00e3o de senha de tudo que est\u00e1 ligado \u00e0quele e-mail.<\/li>\n<li><strong>Conte\u00fado.<\/strong> Contrato, boleto, nota fiscal, exame m\u00e9dico: a mensagem inteira passa leg\u00edvel entre o cliente e o servidor e entre servidores.<\/li>\n<li><strong>Entregabilidade.<\/strong> As <a href=\"https:\/\/support.google.com\/a\/answer\/81126\">regras do Gmail<\/a> para qualquer remetente incluem \u201cUse a TLS connection for transmitting email\u201d, ao lado de SPF\/DKIM e DNS reverso \u2014 o mesmo pacote do post sobre <a href=\"\/2026\/09\/dkim-dmarc-postfix-opendkim-opendmarc\/\">DKIM e DMARC no Postfix<\/a>.<\/li>\n<li><strong>Protocolo antigo \u00e9 protocolo quebrado.<\/strong> A <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8996\">RFC 8996<\/a> (mar\u00e7o de 2021) diz que TLS 1.0 e 1.1 \u201cMUST NOT be used\u201d. O m\u00ednimo hoje \u00e9 TLS 1.2, e o TLS 1.3 \u00e9 o que os clientes modernos negociam.<\/li>\n<\/ul>\n<h2>As portas e o tipo de TLS de cada uma<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"Diagrama das portas: o usu\u00e1rio envia pela 465 com TLS impl\u00edcito ou pela 587 com STARTTLS obrigat\u00f3rio, l\u00ea a caixa pela 993 ou 995 com TLS impl\u00edcito; o Postfix troca mensagens com outros servidores pela 25 com STARTTLS oportunista; o Dovecot autentica o SMTP do Postfix por socket local\" src=\"\/wp-content\/uploads\/2026\/09\/tls-postfix-dovecot-portas.webp\" width=\"1200\" height=\"650\" \/><\/p>\n<ul>\n<li><strong>25 (SMTP)<\/strong> \u2014 servidor falando com servidor. Usa <strong>STARTTLS oportunista<\/strong> (<a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc3207\">RFC 3207<\/a>): a conversa come\u00e7a em texto puro e sobe para TLS se os dois lados oferecerem. N\u00e3o d\u00e1 para exigir TLS aqui de todo mundo \u2014 boa parte da internet ainda entrega sem ele \u2014, ent\u00e3o o padr\u00e3o \u00e9 <code>may<\/code>.<\/li>\n<li><strong>465 (submissions)<\/strong> \u2014 o usu\u00e1rio enviando, com <strong>TLS impl\u00edcito<\/strong>: a conex\u00e3o j\u00e1 nasce criptografada, como no HTTPS.<\/li>\n<li><strong>587 (submission)<\/strong> \u2014 o usu\u00e1rio enviando com STARTTLS, mas <strong>obrigat\u00f3rio<\/strong>: o servidor recusa qualquer comando antes do TLS.<\/li>\n<li><strong>993 (IMAPS) e 995 (POP3S)<\/strong> \u2014 leitura da caixa com TLS impl\u00edcito.<\/li>\n<li><strong>143 e 110<\/strong> \u2014 IMAP e POP3 sem TLS impl\u00edcito. N\u00e3o exponha para a internet.<\/li>\n<\/ul>\n<p>A <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8314\">RFC 8314<\/a> (janeiro de 2018) recomenda TLS impl\u00edcito para envio e leitura \u2014 465, 993 e 995 \u2014 e aceita a 587 com STARTTLS durante a transi\u00e7\u00e3o. Na pr\u00e1tica, ofere\u00e7a 465 e 587: clientes antigos e alguns celulares ainda v\u00eam configurados na 587.<\/p>\n<h2>Vers\u00f5es no laborat\u00f3rio<\/h2>\n<table>\n<thead>\n<tr>\n<th>Pacote<\/th>\n<th>Ubuntu 24.04<\/th>\n<th>Ubuntu 26.04<\/th>\n<th>Debian 13<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>postfix<\/td>\n<td>3.8.6<\/td>\n<td>3.10.6<\/td>\n<td>3.10.13<\/td>\n<\/tr>\n<tr>\n<td>dovecot-core<\/td>\n<td><strong>2.3.21<\/strong><\/td>\n<td><strong>2.4.2<\/strong><\/td>\n<td><strong>2.4.1<\/strong><\/td>\n<\/tr>\n<tr>\n<td>certbot<\/td>\n<td>2.9.0<\/td>\n<td>4.0.0<\/td>\n<td>4.0.0<\/td>\n<\/tr>\n<tr>\n<td>openssl<\/td>\n<td>3.0.13<\/td>\n<td>3.5.5<\/td>\n<td>\u2014<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A linha que importa \u00e9 a do Dovecot: o 2.4 mudou os nomes das op\u00e7\u00f5es de TLS e n\u00e3o aceita a configura\u00e7\u00e3o do 2.3 sem ajuste. Vou mostrar as duas.<\/p>\n<h2>O certificado: Let&#8217;s Encrypt no nome do servidor<\/h2>\n<p>O certificado tem de ter o nome que os clientes e os outros servidores usam para chegar at\u00e9 voc\u00ea \u2014 o do registro MX e o que est\u00e1 configurado no Thunderbird e no celular. Neste post, <code>mail.example.com<\/code>. Se voc\u00ea usa apelidos como <code>smtp.<\/code> e <code>imap.<\/code>, inclua todos no mesmo certificado com v\u00e1rios <code>-d<\/code>.<\/p>\n<p>Servidor de e-mail geralmente n\u00e3o tem site; o modo <em>standalone<\/em> do certbot sobe um servidor web tempor\u00e1rio na porta 80 s\u00f3 para a valida\u00e7\u00e3o:<\/p>\n<pre><code class=\"language-bash\">sudo apt install -y certbot\nsudo ufw allow 80\/tcp\nsudo certbot certonly --standalone -d mail.example.com \\\n  --agree-tos -m postmaster@example.com --no-eff-email\n<\/code><\/pre>\n<p>Se j\u00e1 existe um nginx ou Apache na m\u00e1quina, use <code>--webroot -w \/var\/www\/html<\/code> no lugar de <code>--standalone<\/code>. O resultado fica em <code>\/etc\/letsencrypt\/live\/mail.example.com\/<\/code>: <code>fullchain.pem<\/code> (certificado + intermedi\u00e1rios) e <code>privkey.pem<\/code> (a chave). Os diret\u00f3rios <code>live<\/code> e <code>archive<\/code> s\u00e3o leg\u00edveis s\u00f3 pelo root \u2014 e tudo bem: Postfix e Dovecot abrem o certificado como root, antes de largar os privil\u00e9gios. N\u00e3o mude as permiss\u00f5es.<\/p>\n<h3>Renova\u00e7\u00e3o e os prazos que est\u00e3o encurtando<\/h3>\n<p>O pacote instala o <code>certbot.timer<\/code>, que renova sozinho. O que ele n\u00e3o faz \u00e9 avisar o Postfix e o Dovecot: eles continuam servindo o certificado antigo da mem\u00f3ria at\u00e9 recarregarem. Um <em>deploy hook<\/em> resolve \u2014 o certbot roda os scripts desse diret\u00f3rio s\u00f3 quando uma renova\u00e7\u00e3o d\u00e1 certo:<\/p>\n<pre><code class=\"language-bash\">sudo tee \/etc\/letsencrypt\/renewal-hooks\/deploy\/recarrega-email.sh &gt;\/dev\/null &lt;&lt;'EOF'\n#!\/bin\/sh\nsystemctl reload postfix dovecot\nEOF\nsudo chmod 755 \/etc\/letsencrypt\/renewal-hooks\/deploy\/recarrega-email.sh\nsudo certbot renew --dry-run\n<\/code><\/pre>\n<p>No Ubuntu 24.04 (certbot 2.9), os hooks desse diret\u00f3rio s\u00f3 rodam com o subcomando <code>renew<\/code> \u2014 que \u00e9 o que o timer usa, ent\u00e3o a renova\u00e7\u00e3o autom\u00e1tica funciona; na <em>primeira<\/em> emiss\u00e3o, recarregue na m\u00e3o.<\/p>\n<p>Isso deixou de ser detalhe. O Let&#8217;s Encrypt <a href=\"https:\/\/letsencrypt.org\/2025\/12\/02\/from-90-to-45\/\">anunciou<\/a> que o certificado padr\u00e3o de 90 dias cai para <strong>64 dias em 10 de fevereiro de 2027<\/strong> e para <strong>45 dias em 16 de fevereiro de 2028<\/strong>. E o CA\/Browser Forum aprovou em 2025 um teto para todas as CAs: 200 dias desde 15 de mar\u00e7o de 2026, 100 dias a partir de mar\u00e7o de 2027 e <strong>47 dias a partir de mar\u00e7o de 2029<\/strong>. Renova\u00e7\u00e3o manual acabou; renova\u00e7\u00e3o sem reload \u00e9 certificado vencido em produ\u00e7\u00e3o.<\/p>\n<h2>Postfix: TLS no main.cf<\/h2>\n<p>O Debian e o Ubuntu j\u00e1 instalam o Postfix com TLS ligado, mas com o certificado autoassinado <code>ssl-cert-snakeoil<\/code> e sem piso de vers\u00e3o nas portas dos usu\u00e1rios. Troque o certificado e acerte o resto:<\/p>\n<pre><code class=\"language-bash\">sudo postconf -X smtpd_tls_cert_file smtpd_tls_key_file\nsudo postconf -e \\\n  'smtpd_tls_chain_files = \/etc\/letsencrypt\/live\/mail.example.com\/privkey.pem, \/etc\/letsencrypt\/live\/mail.example.com\/fullchain.pem' \\\n  'smtpd_tls_security_level = may' \\\n  'smtpd_tls_auth_only = yes' \\\n  'smtpd_tls_mandatory_protocols = >=TLSv1.2' \\\n  'smtp_tls_security_level = may' \\\n  'smtp_tls_mandatory_protocols = >=TLSv1.2' \\\n  'smtpd_tls_loglevel = 1' \\\n  'smtp_tls_loglevel = 1' \\\n  'smtpd_tls_received_header = yes'\n<\/code><\/pre>\n<ul>\n<li><code>smtpd_tls_chain_files<\/code> (Postfix 3.4+): a chave primeiro, depois a cadeia. Substitui o par <code>smtpd_tls_cert_file<\/code>\/<code>smtpd_tls_key_file<\/code>, por isso o <code>postconf -X<\/code> antes.<\/li>\n<li><code>smtpd_*<\/code> \u00e9 o Postfix <em>recebendo<\/em>; <code>smtp_*<\/code> \u00e9 o Postfix <em>entregando<\/em> para outros servidores. Os dois precisam de configura\u00e7\u00e3o.<\/li>\n<li><code>security_level = may<\/code> na porta 25, nos dois sentidos: TLS quando o outro lado oferece. As portas dos usu\u00e1rios ficam com <code>encrypt<\/code> no <code>master.cf<\/code>, abaixo.<\/li>\n<li><code>smtpd_tls_auth_only = yes<\/code>: o servidor nem anuncia <code>AUTH<\/code> antes do TLS. Senha em texto puro fica imposs\u00edvel, n\u00e3o s\u00f3 desaconselhada.<\/li>\n<li><code>*_mandatory_protocols = &gt;=TLSv1.2<\/code> (sintaxe do Postfix 3.6+): vale onde o TLS \u00e9 <strong>obrigat\u00f3rio<\/strong> \u2014 as portas 465 e 587 dos usu\u00e1rios, abaixo. No laborat\u00f3rio, com essa linha, as duas recusaram TLS 1.1 (<code>Cipher is (NONE)<\/code>) nos dois Ubuntu.<\/li>\n<li><strong>Por que n\u00e3o exigir TLS 1.2 tamb\u00e9m na porta 25?<\/strong> Porque ali o TLS \u00e9 oportunista e, se o handshake falha, o Postfix <a href=\"https:\/\/www.postfix.org\/TLS_README.html\">entrega em texto puro<\/a>. Recusar TLS 1.0 de um servidor antigo n\u00e3o bloqueia a mensagem \u2014 s\u00f3 a faz viajar sem criptografia nenhuma, o que \u00e9 pior. Por isso a porta 25 fica com o padr\u00e3o do Postfix (<code>smtpd_tls_protocols<\/code> e <code>smtp_tls_protocols<\/code> em <code>&gt;=TLSv1<\/code>, sem SSLv2\/SSLv3). No laborat\u00f3rio, o Postfix padr\u00e3o do 24.04 e do 26.04 negociou TLS 1.0 e 1.1 de verdade na 25 \u2014 \u00e9 esperado. Quem quiser TLS forte de verdade entre servidores usa MTA-STS ou DANE, no fim do post.<\/li>\n<li><code>loglevel = 1<\/code> registra uma linha por conex\u00e3o TLS, e <code>received_header<\/code> grava vers\u00e3o e cifra no cabe\u00e7alho <code>Received:<\/code> de cada mensagem \u2014 \u00fatil para provar, depois, que ela chegou criptografada.<\/li>\n<\/ul>\n<h2>Postfix: as portas 465 e 587 no master.cf<\/h2>\n<p>O <code>\/etc\/postfix\/master.cf<\/code> do pacote traz as duas entradas comentadas. Descomente ou acrescente, <strong>usando na 5\u00aa coluna o mesmo valor da linha <code>smtp inet<\/code><\/strong> do seu arquivo (<code>y<\/code> no 24.04, que roda o <code>smtpd<\/code> em chroot; <code>n<\/code> no 26.04):<\/p>\n<pre><code class=\"language-text\">submission inet n       -       y       -       -       smtpd\n  -o syslog_name=postfix\/submission\n  -o smtpd_tls_security_level=encrypt\n  -o smtpd_sasl_auth_enable=yes\n  -o smtpd_client_restrictions=permit_sasl_authenticated,reject\n  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject\nsubmissions inet n      -       y       -       -       smtpd\n  -o syslog_name=postfix\/submissions\n  -o smtpd_tls_wrappermode=yes\n  -o smtpd_tls_security_level=encrypt\n  -o smtpd_sasl_auth_enable=yes\n  -o smtpd_client_restrictions=permit_sasl_authenticated,reject\n  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject\n<\/code><\/pre>\n<p><code>smtpd_tls_security_level=encrypt<\/code> torna o TLS obrigat\u00f3rio \u2014 \u00e9 o que ativa o <code>smtpd_tls_mandatory_protocols<\/code> \u2014 e <code>smtpd_tls_wrappermode=yes<\/code> \u00e9 o TLS impl\u00edcito da 465. Nas duas, s\u00f3 passa quem autenticou. Quem confere a senha \u00e9 o Dovecot, pelo SASL:<\/p>\n<pre><code class=\"language-bash\">sudo postconf -e 'smtpd_sasl_type = dovecot' 'smtpd_sasl_path = private\/auth'\nsudo postfix check &amp;&amp; sudo systemctl restart postfix\n<\/code><\/pre>\n<p>O caminho <code>private\/auth<\/code> \u00e9 relativo a <code>\/var\/spool\/postfix<\/code> e funciona com e sem chroot.<\/p>\n<h2>Dovecot 2.3 (Ubuntu 24.04)<\/h2>\n<p>Crie <code>\/etc\/dovecot\/conf.d\/99-tls.conf<\/code> \u2014 o <code>99<\/code> garante que ele \u00e9 lido por \u00faltimo e prevalece sobre o <code>10-ssl.conf<\/code> do pacote:<\/p>\n<pre><code class=\"language-text\">ssl = required\nssl_cert = &lt;\/etc\/letsencrypt\/live\/mail.example.com\/fullchain.pem\nssl_key = &lt;\/etc\/letsencrypt\/live\/mail.example.com\/privkey.pem\nssl_min_protocol = TLSv1.2\nssl_prefer_server_ciphers = yes\ndisable_plaintext_auth = yes\n<\/code><\/pre>\n<p>No 2.3, o <code>&lt;<\/code> antes do caminho \u00e9 obrigat\u00f3rio: ele diz \u201cleia o conte\u00fado deste arquivo\u201d. Sem ele, o Dovecot tenta usar o pr\u00f3prio caminho como certificado.<\/p>\n<h2>Dovecot 2.4 (Ubuntu 26.04 e Debian 13)<\/h2>\n<p>O mesmo arquivo, com os nomes novos:<\/p>\n<pre><code class=\"language-text\">ssl = required\nssl_server_cert_file = \/etc\/letsencrypt\/live\/mail.example.com\/fullchain.pem\nssl_server_key_file = \/etc\/letsencrypt\/live\/mail.example.com\/privkey.pem\nssl_min_protocol = TLSv1.2\nauth_allow_cleartext = no\n<\/code><\/pre>\n<ul>\n<li><code>ssl_cert<\/code>\/<code>ssl_key<\/code> viraram <code>ssl_server_cert_file<\/code>\/<code>ssl_server_key_file<\/code>, com caminho puro, <strong>sem<\/strong> <code>&lt;<\/code>.<\/li>\n<li><code>disable_plaintext_auth = yes<\/code> virou <code>auth_allow_cleartext = no<\/code> (que j\u00e1 \u00e9 o padr\u00e3o).<\/li>\n<li><code>ssl_prefer_server_ciphers<\/code> virou <code>ssl_server_prefer_ciphers<\/code>, e <code>ssl_dh<\/code> virou <code>ssl_server_dh_file<\/code>.<\/li>\n<li>O <code>dovecot.conf<\/code> precisa come\u00e7ar com <code>dovecot_config_version<\/code> e ter <code>dovecot_storage_version<\/code> \u2014 o pacote j\u00e1 traz. Configura\u00e7\u00e3o copiada de um servidor 2.3 n\u00e3o sobe: veja o <a href=\"https:\/\/doc.dovecot.org\/latest\/installation\/upgrade\/2.3-to-2.4.html\">guia de migra\u00e7\u00e3o 2.3 \u2192 2.4<\/a>.<\/li>\n<\/ul>\n<h3>O socket de autentica\u00e7\u00e3o para o Postfix (2.3 e 2.4)<\/h3>\n<p>Em <code>\/etc\/dovecot\/conf.d\/99-postfix-auth.conf<\/code>, igual nas duas vers\u00f5es:<\/p>\n<pre><code class=\"language-text\">service auth {\n  unix_listener \/var\/spool\/postfix\/private\/auth {\n    mode = 0660\n    user = postfix\n    group = postfix\n  }\n}\n<\/code><\/pre>\n<pre><code class=\"language-bash\">sudo doveconf -n &gt;\/dev\/null &amp;&amp; echo config OK\nsudo systemctl restart dovecot\n<\/code><\/pre>\n<p><code>ssl = required<\/code> com a autentica\u00e7\u00e3o sem texto puro faz o Dovecot recusar login fora do TLS. No laborat\u00f3rio, vindo de outra m\u00e1quina pela porta 143:<\/p>\n<pre><code class=\"language-text\"># Dovecot 2.4\na1 NO [PRIVACYREQUIRED] Cleartext authentication disallowed on non-secure (SSL\/TLS) connections.\n# Dovecot 2.3 (POP3 na 110)\n-ERR [AUTH] Plaintext authentication disallowed on non-secure (SSL\/TLS) connections.\n<\/code><\/pre>\n<p>Aten\u00e7\u00e3o ao testar: o Dovecot considera seguras as conex\u00f5es do pr\u00f3prio <code>127.0.0.1<\/code>. Login sem TLS a partir do servidor funciona \u2014 o teste que vale \u00e9 de outra m\u00e1quina.<\/p>\n<h2>Firewall<\/h2>\n<pre><code class=\"language-bash\">sudo ufw allow 25,465,587,993,995\/tcp\n<\/code><\/pre>\n<p>Deixe 143 e 110 fechadas para fora. Quem usa webmail na mesma m\u00e1quina acessa pelo localhost; os clientes externos v\u00e3o pela 993 e pela 995.<\/p>\n<h2>Testando cada porta<\/h2>\n<p>O <code>openssl s_client<\/code> mostra vers\u00e3o, cifra e se a cadeia do certificado foi verificada:<\/p>\n<pre><code class=\"language-bash\">openssl s_client -brief -starttls smtp -connect mail.example.com:25  &lt;\/dev\/null\nopenssl s_client -brief -connect mail.example.com:465 &lt;\/dev\/null\nopenssl s_client -brief -starttls smtp -connect mail.example.com:587 &lt;\/dev\/null\nopenssl s_client -brief -connect mail.example.com:993 &lt;\/dev\/null\nopenssl s_client -brief -connect mail.example.com:995 &lt;\/dev\/null\n<\/code><\/pre>\n<pre><code class=\"language-text\">Protocol version: TLSv1.3\nCiphersuite: TLS_AES_256_GCM_SHA384\nVerification: OK\n<\/code><\/pre>\n<p>Essa foi a sa\u00edda nas cinco portas, nos dois Ubuntu. Para confirmar que TLS antigo \u00e9 recusado nas portas dos usu\u00e1rios, force a vers\u00e3o \u2014 e olhe a cifra, n\u00e3o a linha de protocolo, que o <code>openssl<\/code> imprime mesmo quando o handshake falha:<\/p>\n<pre><code class=\"language-bash\">openssl s_client -tls1_1 -cipher 'DEFAULT:@SECLEVEL=0' \\\n  -connect mail.example.com:465 &lt;\/dev\/null 2&gt;&amp;1 | grep 'Cipher is'\n# Cipher is (NONE)   \u2190 recusado, como deve ser\n<\/code><\/pre>\n<p>Envio autenticado, verificando o certificado, com o <code>swaks<\/code>:<\/p>\n<pre><code class=\"language-bash\">sudo apt install -y swaks\nswaks --server mail.example.com:465 --tlsc --tls-verify \\\n  --auth PLAIN --auth-user ana --from ana@example.com --to voce@gmail.com\n<\/code><\/pre>\n<pre><code class=\"language-text\">=== TLS started with cipher TLSv1.3:TLS_AES_256_GCM_SHA384:256\n&lt;~  235 2.7.0 Authentication successful\n&lt;~  250 2.0.0 Ok: queued as 4D83AB47D87\n<\/code><\/pre>\n<p>Troque <code>:465 --tlsc<\/code> por <code>:587 --tls<\/code> para testar a outra porta. Na 587, sem STARTTLS, o Postfix responde <code>530 5.7.0 Must issue a STARTTLS command first<\/code> a qualquer comando \u2014 e o <code>EHLO<\/code> nem lista <code>AUTH<\/code>.<\/p>\n<p>Para o lado servidor-servidor, o Postfix traz o <code>posttls-finger<\/code>, que se conecta como o Postfix se conectaria a um MX e diz o n\u00edvel de confian\u00e7a obtido:<\/p>\n<pre><code class=\"language-bash\">posttls-finger -c -P \/etc\/ssl\/certs \"[mail.example.com]:25\"\n<\/code><\/pre>\n<p>O resultado termina em <code>Verified TLS connection established<\/code> quando o nome bate com o certificado e a cadeia \u00e9 v\u00e1lida. <code>Untrusted<\/code> indica cadeia desconhecida ou nome diferente \u2014 no laborat\u00f3rio, apareceu ao conectar pelo IP em vez do nome. Para uma an\u00e1lise completa de cifras e vulnerabilidades, o <a href=\"https:\/\/github.com\/testssl\/testssl.sh\">testssl.sh<\/a> (GPLv2) aceita <code>--starttls smtp<\/code>; e o <a href=\"https:\/\/internet.nl\/\">internet.nl<\/a> testa STARTTLS, DANE e DNSSEC do seu dom\u00ednio pela internet.<\/p>\n<h2>O ataque que remove o STARTTLS<\/h2>\n<p>O ponto fraco da porta 25 \u00e9 o pr\u00f3prio \u201coportunista\u201d. O STARTTLS \u00e9 anunciado em texto puro; quem estiver no meio pode apagar a linha <code>250-STARTTLS<\/code> da resposta, e o remetente, configurado com <code>may<\/code>, entrega em texto puro achando que o outro lado n\u00e3o suporta TLS. Nas portas 587 e 993 isso n\u00e3o acontece, porque o TLS \u00e9 obrigat\u00f3rio e a conex\u00e3o simplesmente cai.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"Diagrama comparando dois cen\u00e1rios: sem prote\u00e7\u00e3o, um intermedi\u00e1rio apaga o STARTTLS da resposta e a mensagem segue em texto puro; com MTA-STS ou DANE, o remetente j\u00e1 sabe que o destino exige TLS, recusa a conex\u00e3o rebaixada e mant\u00e9m a mensagem na fila\" src=\"\/wp-content\/uploads\/2026\/09\/tls-postfix-dovecot-starttls-downgrade.webp\" width=\"1200\" height=\"700\" \/><\/p>\n<p>Duas solu\u00e7\u00f5es, que protegem as mensagens que <em>chegam<\/em> no seu dom\u00ednio:<\/p>\n<ul>\n<li><strong>MTA-STS<\/strong> (<a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8461\">RFC 8461<\/a>): voc\u00ea publica, por HTTPS, uma pol\u00edtica dizendo \u201cmeus MX exigem TLS com certificado v\u00e1lido\u201d. Os remetentes que implementam o padr\u00e3o passam a recusar entregar sem isso.<\/li>\n<li><strong>DANE<\/strong> (<a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc7672\">RFC 7672<\/a>): o certificado do MX \u00e9 fixado num registro TLSA assinado com DNSSEC. Exige DNSSEC no dom\u00ednio.<\/li>\n<\/ul>\n<p>O MTA-STS \u00e9 o mais simples de come\u00e7ar. Dois registros e um arquivo:<\/p>\n<pre><code class=\"language-text\">_mta-sts.example.com.   IN TXT  \"v=STSv1; id=20260923T120000;\"\n_smtp._tls.example.com. IN TXT  \"v=TLSRPTv1; rua=mailto:tls-reports@example.com\"\n<\/code><\/pre>\n<p>E em <code>https:\/\/mta-sts.example.com\/.well-known\/mta-sts.txt<\/code>, servido com um certificado v\u00e1lido:<\/p>\n<pre><code class=\"language-text\">version: STSv1\nmode: testing\nmx: mail.example.com\nmax_age: 604800\n<\/code><\/pre>\n<p>Comece com <code>mode: testing<\/code>: os remetentes entregam normalmente, mas mandam relat\u00f3rios de falha ao endere\u00e7o do registro <code>_smtp._tls<\/code> (TLS-RPT, <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8460\">RFC 8460<\/a>). Sem surpresas por algumas semanas, mude para <code>mode: enforce<\/code> e troque o <code>id<\/code> do registro TXT \u2014 \u00e9 a mudan\u00e7a do <code>id<\/code> que avisa os remetentes para buscarem a pol\u00edtica de novo. Cada MX do dom\u00ednio precisa estar numa linha <code>mx:<\/code>.<\/p>\n<p>Para proteger as mensagens que <em>saem<\/em>, o Postfix sabe usar DANE do lado de quem envia: <code>smtp_dns_support_level = dnssec<\/code> e <code>smtp_tls_security_level = dane<\/code>. Destinos com registro TLSA passam a exigir TLS verificado; os sem registro continuam no <code>may<\/code>. Isso depende de um resolver local que valide DNSSEC (unbound, por exemplo) \u2014 sem ele, n\u00e3o ative.<\/p>\n<h2>O que costuma quebrar<\/h2>\n<ul>\n<li><strong>Cliente reclama de certificado inv\u00e1lido<\/strong> \u2014 ele est\u00e1 configurado com um nome que n\u00e3o est\u00e1 no certificado (<code>imap.example.com<\/code>, o IP, o nome antigo do servidor). Emita com todos os nomes usados ou padronize os clientes.<\/li>\n<li><strong>Funciona no Thunderbird e falha em outro servidor<\/strong> \u2014 usou <code>cert.pem<\/code> em vez de <code>fullchain.pem<\/code> e faltou o intermedi\u00e1rio. Navegadores e alguns clientes completam a cadeia sozinhos; servidores de e-mail n\u00e3o.<\/li>\n<li><strong>Certificado venceu, mas a renova\u00e7\u00e3o rodou<\/strong> \u2014 faltou o deploy hook e o servi\u00e7o seguiu com o certificado antigo em mem\u00f3ria. <code>openssl s_client ... | openssl x509 -noout -enddate<\/code> mostra o que est\u00e1 sendo servido de fato.<\/li>\n<li><strong>Dovecot n\u00e3o sobe depois de atualizar para o 26.04<\/strong> \u2014 configura\u00e7\u00e3o 2.3 no 2.4. <code>doveconf -n<\/code> aponta a linha.<\/li>\n<li><strong><code>certbot --standalone<\/code> falha<\/strong> \u2014 a porta 80 est\u00e1 ocupada por um servidor web ou fechada no firewall. Use <code>--webroot<\/code>.<\/li>\n<li><strong>Clientes antigos param de conectar<\/strong> ap\u00f3s exigir TLS 1.2 \u2014 sistemas e clientes de e-mail muito antigos, sem suporte a TLS 1.2. \u00c9 o pre\u00e7o certo; TLS 1.0 \u00e9 proibido pela RFC 8996.<\/li>\n<li><strong>Nada sai pela porta 25<\/strong> \u2014 muitos provedores de nuvem bloqueiam a 25 de sa\u00edda por padr\u00e3o. N\u00e3o \u00e9 TLS: \u00e9 pedido de libera\u00e7\u00e3o no painel do provedor.<\/li>\n<\/ul>\n<h2>Resumo<\/h2>\n<p>Certificado v\u00e1lido no nome do MX, renova\u00e7\u00e3o com reload, TLS 1.2 como piso em tudo que leva senha (465, 587, 993, 995), a porta 25 oportunista como deve ser, senha s\u00f3 dentro do TLS, 465\/587\/993\/995 abertas e 143\/110 fechadas. Com isso o servidor est\u00e1 em dia; com MTA-STS, ele tamb\u00e9m passa a proteger o que chega. Os pr\u00f3ximos passos da mesma pilha: <a href=\"\/2026\/09\/dkim-dmarc-postfix-opendkim-opendmarc\/\">DKIM e DMARC no Postfix<\/a>, o painel <a href=\"\/2026\/09\/go-postfixadmin\/\">go-postfixadmin<\/a> para as caixas virtuais e a hist\u00f3ria das pe\u00e7as em <a href=\"\/2026\/09\/a-historia-do-postfix\/\">A hist\u00f3ria do Postfix<\/a> e <a href=\"\/2026\/09\/a-historia-do-dovecot\/\">A hist\u00f3ria do Dovecot<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Certificado Let\u2019s Encrypt, puertos 465\/587\/993\/995, TLS 1.2 donde hay contrase\u00f1a, Dovecot 2.3 y 2.4, pruebas y MTA-STS contra el ataque que elimina el STARTTLS.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,78,2,120,3],"tags":[477,241,79,476,478,233,479,474,475],"class_list":["post-1684","post","type-post","status-publish","format-standard","hentry","category-debian","category-email","category-linux","category-servidores","category-ubuntu","tag-certbot","tag-dovecot","tag-email","tag-letsencrypt","tag-mta-sts","tag-postfix","tag-seguranca","tag-ssl","tag-tls"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/1684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/comments?post=1684"}],"version-history":[{"count":1,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/1684\/revisions"}],"predecessor-version":[{"id":1689,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/1684\/revisions\/1689"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/media?parent=1684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/categories?post=1684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/tags?post=1684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}