Como parar um servidor que está enviando spam
Última atualização:
O primeiro sinal raramente é o próprio spam. É um e-mail do provedor sobre abuso, um cliente cujas faturas caem no lixo eletrônico, devoluções de mensagens que você nunca enviou, ou uma fila de e-mail com dez mil mensagens. A essa altura o endereço do servidor geralmente já está numa blocklist, e todo e-mail legítimo que sai dele sofre junto.
O spam sai de um servidor de três jeitos: uma caixa de e-mail cuja senha foi adivinhada ou roubada, um script PHP (um plugin invadido ou um formulário de contato abusado) que chama mail(), ou um programa que fala SMTP direto com outros servidores. Os passos abaixo descobrem qual é o caso, param o envio, limpam a fila, fecham a brecha e tiram o endereço das listas. Os comandos são para Postfix e Exim no Debian, no Ubuntu e na família RHEL; spammer@example.com, QUEUE_ID e 203.0.113.10 representam o que você encontrar.
Verifique se o servidor está enviando spam
Comece pela fila de e-mail. Um servidor saudável tem poucas mensagens esperando, muitas vezes nenhuma. Milhares de mensagens, ou um remetente dono da maioria delas, é spam. O segundo comando lista os remetentes com mais mensagens na fila.
sudo postqueue -p | tail -n 1
sudo postqueue -p | awk '/^[0-9A-Za-z]/ {print $7}' | sort | uniq -c | sort -rn | headO Exim, como no cPanel e no exim4 do Debian (o comando exim também existe lá), conta a fila com exim -bpc. As linhas seguintes listam os principais remetentes e os principais domínios de destino:
sudo exim -bpc
sudo exim -bp | awk '/^ *[0-9]+[mhd] / {print $4}' | sort | uniq -c | sort -rn | head
sudo exim -bp | exiqsumm | sort -rn | headUm remetente <> ou MAILER-DAEMON é uma devolução (bounce). Uma fila cheia de devoluções quer dizer que o servidor aceitou ou enviou e-mail para endereços que não existem: típico de spam enviado daqui, ou de backscatter de um formulário que manda uma cópia para qualquer endereço digitado nele.
Qual conta está enviando
Spam enviado por uma caixa de e-mail aparece como um usuário autenticado com muito mais mensagens do que os outros. O Postfix registra isso como sasl_username, nos arquivos de log ou, sem rsyslog, no journal:
sudo sh -c "zgrep -h -o 'sasl_username=[^ ,]*' /var/log/mail.log* /var/log/maillog* 2>/dev/null" \
| sort | uniq -c | sort -rn | head
sudo journalctl --since "24 hours ago" -t postfix/smtpd | grep -o 'sasl_username=[^ ,]*' \
| sort | uniq -c | sort -rn | headO Exim registra o login como A= em cada mensagem que aceita, e a pasta do script como cwd= para e-mail enviado localmente (o cPanel registra isso por padrão). Um cwd= dentro de um site, como /home/user/public_html/wp-content/…, aponta para o script:
sudo grep -h ' <= ' /var/log/exim_mainlog /var/log/exim4/mainlog 2>/dev/null \
| grep -o ' A=[^ ]*' | sort | uniq -c | sort -rn | head
sudo grep -h -o 'cwd=[^ ]*' /var/log/exim_mainlog /var/log/exim4/mainlog 2>/dev/null \
| sort | uniq -c | sort -rn | headQual script PHP está enviando
O e-mail enviado pelo mail() do PHP passa pelo sendmail local e não faz login, então não tem usuário. Leia os cabeçalhos de uma mensagem da fila: com mail.add_x_header ativado, o PHP adiciona X-PHP-Originating-Script, o ID de usuário e o nome do arquivo do script.
sudo postcat -hq QUEUE_ID | grep -iE '^(From|To|Subject|X-PHP-Originating-Script):'
sudo exim -Mvh QUEUE_ID | grep -iE '(From|To|Subject|X-PHP-Originating-Script):'Se o cabeçalho não estiver lá, ative-o e faça o PHP registrar cada chamada de mail() com o caminho completo e a linha do script. Encontre o php.ini que o seu servidor web usa (o PHP-FPM tem o seu próprio no Debian e no Ubuntu):
php --ini | grep 'Loaded Configuration'
ls /etc/php/*/fpm/php.ini /etc/php.ini 2>/dev/nullmail.add_x_header = On
mail.log = syslogReinicie o PHP-FPM ou o servidor web (sudo systemctl restart php8.3-fpm, php-fpm ou httpd, conforme o sistema), espere alguns minutos e leia o log:
sudo journalctl --since "1 hour ago" | grep 'mail() on' | tail -n 20
sudo grep -h 'mail() on' /var/log/syslog /var/log/messages 2>/dev/null | tail -n 20Programas que falam SMTP diretamente
Algumas ferramentas de spam pulam o servidor de e-mail e se conectam elas mesmas à porta 25 dos servidores dos destinatários, então não deixam nada na fila. Veja as conexões SMTP de saída e os programas donos delas. O seu servidor de e-mail (master/smtp no Postfix, exim) é normal; php, perl, python ou um nome aleatório não é.
sudo ss -tnp state established '( dport = :25 or dport = :465 or dport = :587 )'
sudo ss -tnp state established '( dport = :25 )' | grep -o 'users:(("[^"]*"' | sort | uniq -c | sort -rnPare o spam agora
Pare primeiro a origem, depois a fila. Para uma caixa de e-mail, troque a senha no seu painel ou sistema de e-mail e encerre as sessões dela. Para um script, guarde uma cópia como evidência e deixe o arquivo ilegível, para que o servidor web não consiga mais executá-lo:
sudo mkdir -p /root/evidence
sudo cp -p /path/to/script.php /root/evidence/
sudo chmod 000 /path/to/script.phpPara um processo que fala SMTP diretamente, pegue o PID na saída do ss acima, veja de onde ele vem e pare-o como no guia do minerador de criptomoedas: é malware, e tem persistência própria.
Enquanto você limpa, impeça a fila de sair. No Postfix, defer_transports segura tudo o que é entrega remota e continua aceitando e-mail novo, então nada se perde:
sudo postconf -e 'defer_transports = smtp'
sudo postfix reloadQuando a fila estiver limpa (próximo passo), libere-a:
sudo postconf -e 'defer_transports ='
sudo postfix reload
sudo postqueue -fNo Exim, congele as mensagens do remetente que você encontrou. Mensagens congeladas ficam na fila e não são entregues:
sudo exiqgrep -i -f 'spammer@example\.com' | xargs -r sudo exim -MfAtenção: Enquanto a entrega remota está pausada, o e-mail legítimo também espera. Não deixe pausado por mais de algumas horas: depois do tempo de vida da fila (5 dias por padrão no Postfix), as mensagens em espera são devolvidas.
Limpe a fila de e-mail
Apague o spam por remetente, junto com as devoluções, para que as mensagens legítimas da fila fiquem. Rode o passo 1 de novo antes, para ter certeza do endereço do remetente.
sudo postqueue -p | awk '/^[0-9A-Za-z]/ && $7 == "spammer@example.com" {sub(/[*!]$/, "", $1); print $1}' \
| sudo postsuper -d -
sudo postqueue -p | awk '/^[0-9A-Za-z]/ && $7 == "MAILER-DAEMON" {sub(/[*!]$/, "", $1); print $1}' \
| sudo postsuper -d -No Exim, a primeira linha apaga as mensagens do remetente, e a segunda as congeladas, que depois de um spam são quase todas devoluções:
sudo exiqgrep -i -f 'spammer@example\.com' | xargs -r sudo exim -Mrm
sudo exiqgrep -z -i | xargs -r sudo exim -MrmAtenção: postsuper -d ALL e apagar a fila inteira do Exim também apagam mensagens legítimas, e mensagens apagadas não podem ser recuperadas. Apague por remetente, a menos que a fila não tenha mais nada.
Conte a fila de novo. Se ela voltar a crescer, a origem ainda está ativa: volte ao passo 1.
Descubra como o spam saiu
Trocar uma senha ou apagar um script encerra esta rodada. A próxima começa se você não souber como tudo começou.
Uma caixa de e-mail comprometida
Uma caixa usada por um spammer faz login de muitos endereços, muitas vezes de muitos países, às vezes milhares num dia. Conte os endereços que a usaram:
sudo sh -c "zgrep -h 'user@example.com' /var/log/mail.log* /var/log/maillog* /var/log/exim_mainlog* /var/log/exim4/mainlog* 2>/dev/null" \
| grep -oE '\[[0-9]{1,3}(\.[0-9]{1,3}){3}\]' | sort | uniq -c | sort -rn | head -20A senha foi adivinhada (procure muitos logins com falha nessa caixa antes do primeiro bem-sucedido) ou roubada do computador do usuário ou de outro site. Escolha uma senha nova e longa, e verifique todas as outras caixas com senha fraca.
Um script PHP
Um script que envia o que uma requisição pedir é ou um malware enviado por uma brecha, ou um formulário legítimo sem proteção. Procure mailers e arquivos PHP alterados recentemente nos sites:
sudo grep -rlE 'mail\s*\(\s*\$_(POST|GET|REQUEST)|LeafMailer|eval\s*\(\s*base64_decode' \
--include='*.php' /var/www /home 2>/dev/null | head -50
sudo find /var/www /home -name '*.php' -type f -mtime -7 2>/dev/null | head -50Depois veja quem chamou o script, e com que frequência. Um formulário de contato enviado milhares de vezes por poucos endereços está sendo abusado; um arquivo que ninguém deveria conhecer, chamado por muitos endereços, é um backdoor.
sudo sh -c "grep -hI 'POST /path/to/script.php' /var/log/nginx/*access*.log /var/log/apache2/*access*.log /var/log/httpd/*access_log 2>/dev/null" \
| awk '{print $1}' | sort | uniq -c | sort -rn | head- Um script malicioso: remova-o, depois descubra como ele foi enviado (um plugin ou tema desatualizado, uma senha de admin fraca, um formulário de upload) e feche essa porta. O guia do minerador de criptomoedas mostra como procurar o resto do que um invasor deixa.
- Um formulário abusado: adicione um CAPTCHA ou um campo oculto que os bots preenchem, nunca deixe o visitante escolher o destinatário e não mande cópia para o endereço digitado no formulário.
Um open relay
Mais raro hoje, mas confira: um servidor de e-mail que entrega mensagens de qualquer um para qualquer um. No Postfix, mynetworks deve listar só o próprio servidor e as suas redes, e as restrições de relay devem terminar com reject_unauth_destination:
postconf mynetworks smtpd_relay_restrictions smtpd_recipient_restrictionsEvite que aconteça de novo
SPF, DKIM e DMARC
Esses três registros DNS dizem aos outros servidores de e-mail quais servidores podem enviar pelo seu domínio e se uma mensagem vem mesmo de você. Eles não impedem que uma caixa invadida envie spam pelo seu servidor, mas impedem que outros falsifiquem o seu domínio, e os grandes provedores hoje esperam esses registros antes de entregar o seu e-mail. Um exemplo para um domínio cujo e-mail sai de 203.0.113.10:
example.com. TXT "v=spf1 mx ip4:203.0.113.10 -all"
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"O DKIM precisa de uma chave no servidor de e-mail (OpenDKIM no Postfix, embutido no Exim; painéis como cPanel e Plesk fazem isso por você) e da parte pública dela no DNS. Confira o que está publicado:
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT default._domainkey.example.comNota: O dig está no pacote dnsutils no Debian e no Ubuntu (bind9-dnsutils nas versões mais novas) e no bind-utils na família RHEL. O seletor DKIM, aqui default, depende da sua configuração.
Limites de envio
Um limite transforma uma conta comprometida de cem mil mensagens em algumas centenas. O Postfix limita as mensagens por endereço de cliente; o e-mail que o PHP envia pelo sendmail não passa por esse limite, e limites por usuário precisam de um serviço de política como o postfwd.
sudo postconf -e 'smtpd_client_message_rate_limit = 100' 'anvil_rate_time_unit = 3600s'
sudo postfix reloadO Exim pode limitar cada usuário autenticado na sua ACL de RCPT. No cPanel, use **Max hourly emails per domain** nas Tweak Settings do WHM.
# In the RCPT ACL (acl_check_rcpt), before the accept for authenticated users
deny authenticated = *
ratelimit = 200 / 1h / strict / per_rcpt / $authenticated_id
message = Sending rate limit exceededSó o servidor de e-mail pode usar a porta 25
Num servidor web, nada além do servidor de e-mail precisa se conectar à porta 25 de outros servidores. Esta regra do nftables recusa as conexões de saída para a porta 25 de qualquer outro usuário, o que barra scripts e malware que falam SMTP diretamente. Troque postfix pelo usuário do seu servidor de e-mail: Debian-exim para o Exim no Debian e no Ubuntu, exim na família RHEL, mailnull no cPanel.
sudo nft add table inet smtpguard
sudo nft 'add chain inet smtpguard out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet smtpguard out tcp dport 25 meta skuid != { root, postfix } rejectAtenção: Acerte o nome do usuário: com o nome errado, o servidor para de entregar qualquer e-mail. Aplicações que enviam por um servidor SMTP externo na porta 25 também param; de qualquer forma elas deveriam usar a 587 com login. A tabela some depois de um reboot: quando estiver funcionando, coloque-a na configuração do seu firewall. No cPanel, **SMTP Restrictions** no WHM faz o mesmo.
Muitos provedores de nuvem bloqueiam a porta 25 de saída por padrão e a liberam sob pedido. Se você não envia e-mail nenhum a partir do servidor, deixe bloqueada e envie por um serviço de relay na 587.
E o reforço de sempre
- Mantenha o WordPress, os plugins e os temas atualizados, e remova os que você não usa.
- Proteja os logins de e-mail contra força bruta como o SSH: veja Como parar ataques de força bruta no SSH.
- Mantenha
mail.add_x_headeremail.logativados, para que da próxima vez o script seja identificado em segundos.
Tire o servidor das blocklists
Peça a remoção só depois que o spam parou e a causa foi fechada: um servidor que volta para a lista logo depois de sair é tratado com mais rigor na segunda vez. Consulte as principais listas por DNS, com o endereço público do servidor em IP:
IP=203.0.113.10
REV=$(echo "$IP" | awk -F. '{print $4"."$3"."$2"."$1}')
for bl in zen.spamhaus.org bl.spamcop.net; do echo "$bl: $(dig +short "$REV.$bl" A)"; done
dig +short -x "$IP"Resposta vazia quer dizer fora da lista; um endereço como 127.0.0.2 quer dizer listado. O Spamhaus recusa consultas feitas por resolvedores públicos e responde 127.255.255.254 a elas: nesse caso use o site dele. A última linha mostra o DNS reverso (PTR) do endereço, que deve ser um nome de host que resolve de volta para ele.
- Spamhaus: consulte o endereço em check.spamhaus.org, que explica cada listagem e como pedir a remoção.
- SpamCop: as listagens expiram sozinhas quando as denúncias param (spamcop.net).
- Microsoft (Outlook, Hotmail): peça a remoção em sender.office.com.
- Gmail: não há formulário de remoção; o Postmaster Tools mostra a reputação do seu domínio enquanto ela se recupera.
Nota: Procedimentos em novembro de 2026, tirados das páginas das próprias listas. A recuperação leva dias, não horas: a reputação nos grandes provedores só melhora enquanto você continua enviando e-mail limpo.
O que o InfraFence faz contra spam saindo do seu servidor
O InfraFence atua mais nas causas do que no e-mail em si:
- Força bruta no e-mail: o agente lê os logs do Postfix, Exim, Dovecot e Roundcube (ou o journal do systemd) e bane um endereço depois de 5 logins com falha ou tentativas de relay em 5 minutos, em SMTP, submission, IMAP, POP3 e webmail. Cada evento informa a caixa de e-mail que foi tentada. Veja SSH e força bruta.
- Scripts de envio: o scanner de malware tem assinaturas para scripts PHP que enviam o que uma requisição pedir (
mail()alimentado direto do$_POST, LeafMailer), web shells e backdoors, regras YARA, e sinaliza arquivos PHP criados em pastas de upload. Com as varreduras automáticas ativadas, arquivos PHP novos em pastas de upload são varridos em até 30 segundos. Veja Malware. - Ameaças de saída: conexões do servidor para endereços das listas Spamhaus DROP e Emerging Threats são reportadas como críticas. Veja Ameaças de saída e DNS.
O que ele não faz: o InfraFence não lê a fila de e-mail, não conta nem limita o e-mail de saída, não bloqueia a porta 25 e não verifica se o seu endereço está numa blocklist. Uma caixa usada com a senha correta parece um login normal para ele. A fila, os limites e a remoção das listas deste guia continuam com você.
Perguntas
- O servidor não tem servidor de e-mail. Como ele pode enviar spam?
- O
mail()do PHP usa osendmailque quase toda distribuição instala, e um malware pode se conectar sozinho à porta 25 de outros servidores. Confira as conexões de saída no passo 1 e a regra que reserva a porta 25 para o servidor de e-mail. - SPF, DKIM e DMARC vão parar o spam?
- Não. Eles comprovam quais servidores podem enviar pelo seu domínio, e o spam enviado por uma caixa invadida no seu servidor passa por eles. Eles protegem o seu domínio contra falsificação e ajudam o seu e-mail legítimo a ser entregue.
- Quanto tempo leva para sair de uma blocklist?
- Depende da lista. As listagens do SpamCop expiram sozinhas quando as denúncias param; o Spamhaus e a Microsoft atendem um pedido de remoção depois que o problema foi resolvido. A reputação no Gmail e no Outlook se recupera ao longo de dias de envio limpo.
Teste grátis em 1 servidor
O Starter é gratuito para um servidor, com proteção completa e bloqueio automático. Sem cartão de crédito.
Instale o agente como root, com o seu token no lugar de <TOKEN>:
curl -fsSL https://github.com/infrafence/infrafence-agent/releases/latest/download/install.sh | sudo bash -s -- --token <TOKEN>O token é criado no painel, em Servidores › Adicionar servidor.
