SPAM é uma batalha sem fim. Cria-se uma forma de mitigar ou diminuir e são apenas algumas semanas de sossego. Logo eles acham uma forma de burlar as barreiras que criamos. Como faz tempo que não trabalho com mail de larga escala e controlo apenas a da VM do servidor do meu site, eu não tenho nem ideia do tamanho do problema que grandes empresas como Google têm. A quantidade de SPAM que tenho de lidar já é mais que suficiente pra eu me aborrecer.
Eu já implementei SPF pra verificação de origem dos mails, mailassassin, white e black list e o volume continua alto.
Mailassassin era um dos mais promissores, mas consome muita CPU a cada verificação. Além disso, ele é um software muito burro (desculpem ao autores e fãs), pois ele recebe o mail para fazer análise. Porque não fazer logo na conexão alguma verificação e descartar logo? No fim, gastou banda, CPU e memória pra ver algo óbvio. Quando recebo um mail vindo de algo como “helio-a414c-loureiro.eng.br-a414c@121serqueemas.com.br” é bastante claro que é falso e se destina à SPAM. Então, não seria lógico já matar o mail no momento do recebimento?
Pois o projeto OpenBSD resolveu cuidar disso. Eles criaram um daemon que enferniza a vida de spammers. É um verdadeiro saci pererê dos e-mails. O spamd recebe o mail e funciona de uma forma muito lenta, com a conexão bem degradada. Após terminar a tentativa de envio do mail, ele simplesmente fecha a conexão e pede que tente novamente. Se o servidor tentar novamente, muito provavelmente não é uma máquina de SPAM. Como essa tentativa seguida faz parte do protocolo SMTP, servidores legítimos continuaram tentando enquanto spammers vão para outra pobre vítima.
No último hackathon que participei, tentei fazer um port desse daemon pro Linux. Encontrei um port já em andamento chamado obspamd no github, que estava com o build quebrado, e consegui arrumar o que estava com problemas. Minha ideia era fazer um daemon funcional e completo portado para Linux, com autoconf e configure. E foi num dos bug reports que eu estava respondendo que alguém mandou outra mensagem avisando que existia um port já bem funcional do mesmo, o greyd.
Conhecendo o greyd
Fiquei surpreso ao descobrir que até site oficial já tinha, o http://greyd.org, pois eu nunca tinha ouvido falar. Até onde vi, não existem pacotes para ele em Debian ou em Ubuntu. Então, boa parte da instalação foi feita manualmente.
O que eu gostaria de fazer com o obspamd, de criar um sistema de build com autoconfigure, já está pronto no greyd. Além disso, ele já implementa as chamadas de kernel pra adicionar as regras de firewall necessárias pro funcionamento do greyd.
Por quê do firewall? Tanto o original, spamd, quanto o greyd, funcionam ouvindo na porta 8025. Então, todo pacote que não foi classificado, baseado em IP de origem, ao tentar conectar na porta 25, padrão de mail, é redirecionado à porta 8025. O greyd segue com a conexão e marca esse tipo de pacote como provável whitelist (lista branca). Na segunda tentativa de conexão, esse pacote já vai direto pro servidor de mail, que no meu caso é um postfix. Esse controle é feito através do firewall iptables com regras no PREROUTING e ipset do kernel, marcando tipos de pacote com IP de origem. E precisa do módulo conntrack do kernel.
Baixando e compilando o greyd
Como é um programa bem recente, não existem pacotes pra ele – ao menos em Debian/Ubuntu. Então, ele ainda exige a compilação e instalação manual.
Para baixar o greyd diretamente do github:
# git clone https://github.com/mikey-austin/greyd.git
Para compilação, eu escolhi usar sqlite3 como formato de arquivo de whitelist, então precisei incluir os cabeçalhos e bibliotecas referentes.
# apt-get install libsqlite3-dev libnetfilter-log-dev libnetfilter-conntrack-dev \ libpcap0.8 libspf2-dev # cd greyd # autoreconf -vi # ./configure \ --with-sqlite \ --with-netfilter \ --with-spf \ --bindir=/usr/bin \ --sbindir=/usr/sbin \ --sysconfdir=/etc \ --docdir=/usr/share \ --libdir=/usr/lib \ --localstatedir=/var \ GREYD_PIDFILE=/var/run/greyd.pid \ GREYLOGD_PIDFILE=/var/run/greylogd.pid \ DEFAULT_CONFIG=/etc/default/greyd.conf # make
O greyd também precisa que sejam criados 2 usuários: greyd e greydb, que controlam daemon e base de dados da lista. No seu repositório existe um diretório que ajuda a criar pacotes; nele é possível ver os comandos pra realizar essa tarefa manualmente em greyd/packages/debian/postinst:
# adduser --quiet --system --home /var/run/greyd --group \ --uid 601 --gecos "greyd" --shell /bin/false --disabled-login greyd # adduser --quiet --system --home /var/lib/greyd --group --uid 602 --gecos "greydb" --shell /bin/false --disabled-login greydb
Em seguida, é preciso criar o diretório onde a base de dados em squlite3 ou bsddb será escrita.
# mkdir -p /var/greydb # chown -R greydb:greydb /var/greydb
Com a configuração de compilação, as configurações serão armazenadas em /etc/default/greyd.conf. O spamd do OpenBSD, por padrão, roda em um ambiente chroot() para proteção do sistema. Eu não consegui fazer o mesmo com o greyd. As configurações que estou usando no momento são (usando diff para comparar):
# diff -u ./etc/greyd.conf /etc/default/greyd.conf --- ./etc/greyd.conf 2016-07-07 13:47:43.000000000 -0300 +++ /etc/default/greyd.conf 2016-07-08 09:49:28.000000000 -0300 @@ -5,8 +5,8 @@ # # Debugging options and more verbose logs. # -debug = 0 -verbose = 0 +debug = 1 +verbose = 1 daemonize = 1 # @@ -17,7 +17,7 @@ # # Address to listen on. # -bind_address = "127.0.0.1" +bind_address = "200.123.234.321" # # Main greyd port. @@ -32,7 +32,7 @@ # # Enable listening on IPv6 socket. # -enable_ipv6 = 0 +enable_ipv6 = 1 bind_address_ipv6 = "::1" # @@ -60,7 +60,7 @@ # # Chroot enable & location for main daemon. # -chroot = 1 +chroot = 0 chroot_dir = "/var/empty/greyd" # @@ -82,11 +82,13 @@ # Specify the maximum number of connections. # # max_cons = 800 +max_cons = 30 # # Specify the maximum number of blacklisted connections to tarpit. # # max_cons_black = 800 +max_cons_black = 30 # # The firewall configuration. @@ -114,8 +116,8 @@ # section database { #driver = "/usr/lib/greyd/greyd_bdb_sql.so" - #driver = "/usr/lib/greyd/greyd_sqlite.so" - driver = "/usr/lib/greyd/greyd_bdb.so" + driver = "/usr/lib/greyd/greyd_sqlite.so" + #driver = "/usr/lib/greyd/greyd_bdb.so" path = "/var/greyd" db_name = "greyd.db"
Em geral, ele funciona apenas na interface de loopback, mas por usar um Debian mais velho, o Wheezy, precisei ajustar pra ouvir na interface pública, a eth0.
Feito isso, basta iniciar o daemon e o daemon de controle de log:
# /etc/init.d/greylogd start # /etc/init.d/greyd start
Para quem já usa sistemas com systemd:
# systemctl start greylogd # systemctl start greyd
O próprio systemd cuidará de adicionar e habilitar esses serviços.
Mas ainda falta o firewall. São necessárias algumas regras na inicialização:
# ipset create greyd-whitelist hash:ip family inet hashsize 1024 maxelem 65536 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -m set \ --match-set greyd-whitelist src -j LOG --log-prefix "[GREYD WHITED]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -m set \ --match-set greyd-whitelist src -j NFLOG --nflog-group 155 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -m set \ --match-set greyd-whitelist src -j ACCEPT # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j LOG \ --log-prefix "[GREYD 25 DNAT]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j DNAT \ --to-destination 200.123.234.321:8025 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j LOG \ --log-prefix "[GREYD 25 REDIRECTED]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j REDIRECT \ --to-ports 8025 # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25 -j LOG \ --log-prefix "[GREYD FAILED]" # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8025 -j LOG \ --log-prefix "[GREYD 8025 JAILED]" # iptables -t filter -A INPUT -p tcp --dport smtp -j ACCEPT # iptables -t filter -A INPUT -p tcp --dport 8025 -j ACCEPT
Eu adicionei mais logs para poder também acompanhar os pacotes, para ver se estão sendo marcados ou não de acordo.
De início, eu fiquei na dúvida se eu estava recebendo algum e-mail ou não, mas logo percebi que estava funcionando de acordo.
A fila de mails indesejados, que ficavam travados por não ter endereço de retorno, praticamente zeraram. O uso de memória aumento um pouco, assim como o conntrack no kernel. Por enquanto, nada absurdo. E parece estar funcionando bem até agora. Se não respondi algum mail seu, já sabe o motivo 😉
Acabaram os SPAMs? Não! Spam é spam e enquanto houver mail, existirá spammers. É fácil de implementar e barato, mas eles diminuíram. E ao saber que estou gastando a conexão deles fazendo nada já me alegra o suficiente.
Meu próximo passo será gerar um pacote no meu ppa no launchpad: https://launchpad.net/~helioloureiro