Como o suporte da hospedagem salvou meu dia
Uma bela tarde, voltando do trabalho, ativo o 4G no celular e encontro mensagens do meu cliente. E claro, todas são reclamações sobre algo que não está funcionando. A tarde acaba de piorar.
AVISO: Abaixo, você encontrará o relato de algumas horas do meu trabalho. Por favor, não se faça de desenvolvedor perfeito dizendo que tomei decisões erradas. Todos nós cometemos erros, e eu expus os meus claramente aqui. Meu objetivo é mostrar algumas armadilhas nas quais caí, e quem sabe ajudar alguém a evitá-las.
O site
Meu cliente tem um site que vende licenças de um software proprietário, faz uma requisição para uma API do software para emitir uma licença de uso e faz o envio de todas as informações para o email da compra. Esse é o caminho bonito e o resultado esperado.
É claro que tudo funciona, e como funciona. Um projeto robusto, feito em Laravel, tudo polido, bonito, mas é claro que meu cliente quer migrar o site de hospedagem – e sim, acredite, Laravel em hospedagem compartilhada... Nada contra, mas né...
A migração "automática"
Não irei citar nomes de hospedagens, mas ela oferece um serviço de migração automática de sites. Basta colocar literalmente as informações de acesso do seu painel (cPanel ou qualquer outro) e o link para acessar o painel. É claro que pode sim existir certa automação para isso, mas sabemos que não existe mágica. Provavelmente alguém do time técnico da hospedagem vai acessar o painel e fazer o que precisa ser feito para migrar.
Dito e feito, meu cliente — provavelmente em um momento de insanidade — optou por uma "migração automática" para economizar dinheiro.
"Mágicamente", em algumas horas, tudo estava online, domínio apontado e blá blá blá. Mas será que realmente tudo estava certo? Se você tem o conhecimento técnico necessário para trabalhar com TI, já deve saber que algo assim é inaceitável. Alguém, provavelmente aleatório, realizando a migração de um projeto entre hospedagens sem o conhecimento real do projeto.
Utilizei palavras duras acima, não sei se atingi a ferida de alguém, mas me digam onde errei.
Negligência
É claro que não fiquei feliz com a decisão do meu cliente, e pelo valor que cobrei, não consigo entender como isso foi maior que o risco da "migração automática".
Não demorou para ele me mandar uma mensagem dizendo que os pagamentos não estavam sendo aprovados.
Provavelmente o gateway X entrou em manutenção, ou quem sabe uma rota dele mudou.
Olhando o arquivo de logs à procura de erros, não encontrei nada fora do normal, com exceção de erros de timeout da própria API do gateway de pagamentos. Eu literalmente vi "timeout" acompanhado da mensagem de tratamento de erro ao lidar com o webhook, e logo falei para o meu cliente:
- Olha, tivemos várias tentativas de comunicação com o gateway de pagamento X, porém ele não deu resposta e, por isso, não tivemos a confirmação do pagamento no site. Apenas aguarde, que em 2 horas vamos receber uma nova notificação e tudo deve funcionar. Provavelmente foi só uma instabilidade do gateway.
Eu poderia ter aumentado o timeout? Poderia. Poderia ter monitorado de fato as requisições que estavam entrando na aplicação? Poderia. Poderia ter feito uma compra fake só para testar? Poderia. Mas eu fiz alguma dessas coisas? Não. Motivo? Não me pergunte 🤦.
O pior pecado que um desenvolvedor pode cometer é a preguiça, ainda mais em horário de trabalho, mas naquele momento eu estava convencido da minha conclusão, e ficou por isso.
Após dar esse "veredito" ao meu cliente, acessei a página do site e me deparei com um captcha... Aquilo não era da aplicação... Mas me lembrei dele falando: "A hospedagem X tem um sistema anti-bot, blá blá blá", e logo assumi que esse era o tal "sistema anti-bot". Aí tive um pensamento rápido: "E se esse captcha estiver barrando a notificação do gateway?", mas logo conclui: "Não faz sentido, eu vi que houve tráfego na rota da notificação".
Se você tiver experiência, já deve saber como isso acaba.
O passado condena
Como já era tarde da noite, e também como é um software de um nicho pequeno, nada foi observado até os próximos dias, e adivinhem, os pagamentos não foram aprovados 😭.
E volta o cão arrependido (eu, no caso), não com uma arma apontada para minha cabeça – como poderia ser em um projeto mais sério (explico isso no final). Vamos lá, é hora de debugar e monitorar.
E, é claro, que dentro de uma hospedagem compartilhada o que resta é colocar triggers para log em vários pontos do processamento das notificações de pagamento.
Então, vamos gerar um cupom com 99% de desconto aqui, vamos comprar a licença e... Nada acontece, o pagamento não é aprovado, mas temos LOGS! Os logs vão nos dar as respostas... Eeh... Não 😩.
Temos, sim, algo acessando a rota da notificação, mas no corpo da requisição encontramos apenas:
{
"id": "~hash aleatório~"
}
O que é isso e de onde vem? Olhei a documentação do gateway de pagamento e, não, não houve mudanças no funcionamento dela. Literalmente, isso quebrou minhas pernas... Ou minhas mãos, já que são elas que escrevem o código – perdão pela piada ruim.
O fato é que as informações não estão chegando corretamente no endpoint do webhook, e por isso a validação da requisição a descarta por não seguir o padrão esperado, resultando em nenhum pagamento aprovado.
Neste ponto, só conseguia pensar naquele captcha, e agora vamos procurar de que buraco ele está vindo e por que ele existe ali, já que os outros sites do meu cliente na mesma hospedagem não estão sofrendo com isso. Depois de muito pesquisar, cheguei à conclusão de que aquele captcha não poderia vir de outro lugar além da própria hospedagem 🫠. Agora, vamos entender de onde vem e como desativar essa coisa.
A hospedagem fornece um recurso de CDN para os sites, e uma das opções na CDN é ativar o modo "estou sob ataque". Quando isso fica ativo, ele literalmente coloca um captcha para todo mundo que tenta acessar o site antes de liberar o acesso.
Não que isso não seja eficaz, mas que solução ruim, convenhamos. E também, por que colocar isso na seção de CDN? A seção de segurança fica só com o SSL por estética???
Pelas minhas pesquisas, a história bate. Aquela página é dessa proteção da CDN. Mas agora o detalhe: o plano do meu cliente na hospedagem não permite o uso da CDN. O que está acontecendo??
Pesquisas e mais pesquisas, e nada. Nenhuma alma na internet parece ter passado pelo que passei. Mas, confiando na minha suspeita, entrei em contato com o suporte da hospedagem X, e acreditem, que suporte rápido, mas algo parecia errado...
Os olhos não veem e o coração não sente
O suporte me respondia extremamente rápido, mas pensei que era aquele sistema de mensagens pré-prontas para os casos comuns. Passei minutos debatendo com o suporte sobre o meu caso.
* Os diálogos abaixo não são os mesmos que troquei com o suporte, mas o sentido das frases é o mesmo:
"Verifique se seu domínio não está em uma proxy como a Cloudflare e com a proteção de captcha ativa." — Definitivamente não. O domínio nem na Cloudflare estava, devido ao meu cliente confiar na proteção anti-bot/DDoS da hospedagem.
"Verifique as regras do firewall do seu servidor." — Com acesso SSH sem permissões elevadas não posso nem dar um htop (hospedagem compartilhada).
"Limpe o cache do navegador e verifique se nenhuma extensão do navegador está causando isso." — Limpar o cache, ok... Mas extensão do navegador? Que raios de extensão vai me adicionar um captcha para entrar nas páginas?? 🤨
"Verifique se algum plugin não está adicionando esse captcha." — Plugin no Laravel? Sério? PLUGIN?? Laravel != WordPress.
A cada resposta que eu dava, o suporte parecia voltar um passo atrás e começar o loop novamente. Foi aí que caiu a ficha: perguntei se ele era um bot, e pensa numa cara de decepção 🤦.
Passei quase 20 minutos conversando com uma I.A. que não era capaz de entender que não conseguiria resolver meu problema para, assim, chamar um humano. Pedi para a I.A. chamar um humano, e assim ela fez — amém, meu Deus, pelo menos isso.
É incrível como, em 1 minuto com um humano, constatou-se que, SIM, aquele captcha era da mesma proteção da CDN da hospedagem. Foi só o suporte desativar e, magicamente, tudo voltou a funcionar. Os pagamentos foram aprovados.
A hospedagem colocou o captcha para barrar um ataque DDoS (um indício de ataque, como o suporte disse). Admito que isso é bem nobre e mostra a competência deles, mas ainda é meio complicado, pois é algo que claramente pode gerar efeitos colaterais, como já vimos aqui. Também foi dito que todo o tráfego deveria passar por uma proxy como a Cloudflare para evitar que esse tipo de ataque chegue à hospedagem. Caso contrário, o captcha pode voltar.
Não acabou
Lembra da "migração automática"? Uma das coisas que não fizeram nessa migração foi reagendar o cronjob para rodar o scheduler do Laravel, e, devido a isso, as licenças não são emitidas e os emails não são enviados aos clientes. Sim, isso do scheduler com cronjob é uma baita gambiarra, ainda mais rodando a fila do Laravel no scheduler... Mas o que eu posso fazer? É hospedagem compartilhada, o supervisor não está disponível.
E, graças a Deus, não me lembro o que fui alterar no .env da aplicação, e lá dei de cara com o debug da aplicação LIGADO. Sabe o que é a aplicação dar erro de conexão com algum serviço e aparecer o erro detalhado, com até mesmo credenciais do serviço (ex. dados para conexão com um banco de dados ou talvez até a API key e token de um gateway de pagamento)? Esse era o risco com aquele true no debug. Provavelmente, o suporte se esqueceu desse detalhe ao realizar a migração. Devem ter ativado para ver os erros durante o deploy e esqueceram de desativar.
Imagina se um aleatório tivesse a sorte de se deparar com um erro desses e soubesse o que fazer com tais informações? Depende, realmente depende. Às vezes, nada se fosse com o banco de dados, já que o firewall só permite a conexão com a lista de IPs liberados ou ainda apenas por localhost (da máquina da hospedagem). Seja como for, ainda é muito arriscado simplesmente deixar essa opção ativada.
Final feliz?
Tudo está funcionando e a todo vapor novamente, e depois de alguns esporros no meu cliente, vamos ver se ele cria juízo e aprende algo.
Mas é isso, pessoas. Esse é o meu relato que aconteceu há alguns dias, e espero ler a opinião de vocês sobre o caso. Desejo um bom dia/tarde/noite e até a próxima 👋