Executando verificação de segurança...
5

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 👋

Carregando publicação patrocinada...
2

"(...)para conquistar esse nível de maturidade e competência, não tem atalho(...)"
by Filipe Deschamps

Que responsabilidade colocar um gerador de licenças na nuvem, se não entendi errado.

De qualquer forma, o relato dos desafios enfrentados foi suficiente para mostrar um pouco do que é o dia a dia dessa profissão. Lembrei-me de um vídeo do Filipe Deschamps relatando os desafios de programar um crawler, suas descobertas e o embate com os artifícios inusitados dos servidores lidando com as requisições além da quota.

1

O site é bem simples para falar a verdade. A única responsabilidade crítica é gerar as cobranças para os clientes que querem adquirir uma licença/chave de ativação para o software que é vendido. Uma vez que o pagamento é realizado, a licença/chave de ativação é gerada e o cliente recebe as informações de como realizar a ativação do programa por email.
E realmente, quando essas coisas misteriosas acontecem, e é a primeira vez que você lida com algo do tipo, é necessário manter a calma e continuar sendo um bom profissional. É uma pena que maturidade e competência sejam duas coisas que apenas o tempo e a experiência ajudam a modelar.
Mas muito bem lembrado desse trecho do vídeo do Felipe. Com toda a certeza, vou levar isso para o resto da carreira 😝.

1

jmsl, verdade, essa parte de pagamento é bem crítico, pois envolve valores. Eu não tive ainda a oportunidade de lidar com uma API para confirmação de pagamentos.

Tenho certo apreço pelo assunto referente a licença de ativação de software pois é um fator repleto de novidades no que se refere à criptografia. Nos dias atuais, vários software com alto valor agregado usam um sistema online para ativação. Automaticamente consultam um servidor na nuvem. Proporciona um certo "controle" para o desenvolvedor saber em que país onde o produto está sendo utilizado e uma segurança par ao cliente desativar uma licença no caso de extravio do computador. Outros software adotam uma chave de licença física espetada em uma porta no computador, proporcionando mais liberdade para o proprietário emprestá-la entre diferentes usuários (perdeu, já era!). Aquele modo de licenciamento com chave lógica (usuário:serial e contando com a colaboração do cliente não divulgá-la) parece ser útil somente para aplicações com custo reduzido. O desenvolvedor geralmente disponibiliza um website com login e senha para que o cliente consulte tais informações sempre que precisar evitando a necessidade de contato do software com um servidor na nuvem.

3

Fica tranquilo que, hoje em dia, é bem simples lidar com pagamentos. Seja para gerar cobranças ou enviar dinheiro de uma conta para outra, tudo se tornou bem mais descomplicado com gateways de pagamento como a Stripe, Mercado Pago ou uma PagHiper da vida. Hoje, também se encontram bibliotecas para tudo, então você nunca estará trabalhando com uma implementação do completo zero (o que pode ser um erro se não souber o que está fazendo). É claro que é necessário conhecer bem o gateway de pagamento e a biblioteca com que você vai trabalhar, mas, tirando isso, o resto é apenas lógica e saber estruturar todos os dados que achar relevantes. Se quiser praticar recomendo a Stripe (ela oferece uma documentação ótima para desenvolvedores).

Licenças/chaves de ativação são um assunto bem complicado e relativo. Não existe bala de prata, e cada caso é um caso. De fato, existem várias features que podem ser implementadas nas chaves para ter total rastreio delas, saber onde e quando foram usadas, etc. Mas, neste site, essa implementação é bem simples. Existe sim um sistema para controle, mas nada muito mirabolante – e é aquela coisa, não podemos fazer algo de nível Microsoft com orçamento limitado.