Node.js Seguro: Hardening do Servidor Linux

9 min de leitura Segurança e Hardening
Node.js Seguro: Hardening do Servidor Linux

Hardening de servidores Linux é uma prática essencial para qualquer profissional que lida com infraestrutura, especialmente quando se trata de hospedar aplicações críticas como Node.js. Ao migrar de um ambiente de desenvolvimento local para uma VPS (Virtual Private Server) em produção, as configurações padrão do sistema operacional não são mais suficientes. Elas priorizam a conveniência e a compatibilidade sobre a segurança, o que deixa portas abertas para vulnerabilidades comuns.

O objetivo deste tutorial é guiar você, sysadmin ou desenvolvedor, através de um checklist prático e robusto para endurecer sua instalação do Linux antes mesmo de instalar o Node.js. Um servidor bem configurado dificulta a vida de atacantes, reduz a superfície de ataque e garante que, caso uma falha ocorra no nível da aplicação, o sistema operacional continue estável e isolado.

1. Preparação do Ambiente e Atualização do Sistema

A primeira regra de ouro é nunca começar com um sistema desatualizado. Vulnerabilidades conhecidas (CVEs) em pacotes base são frequentemente exploradas automaticamente por bots na internet. Antes de qualquer configuração avançada, execute o update completo da sua distribuição Linux.

Para sistemas baseados em Debian e Ubuntu (como a maioria das VPS populares):

sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y

Para sistemas baseados em RHEL, CentOS ou Amazon Linux:

sudo yum update -y
# Ou para DNF:
sudo dnf update -y

Reinicie o servidor após grandes atualizações do kernel para garantir que todas as novas camadas de segurança estejam ativas:

sudo reboot

2. Gestão de Usuários e Acesso SSH Seguro

O acesso root direto é o vetor de ataque mais comum. Hackers utilizam scripts automatizados para tentar credenciais padrão contra a porta 22 (SSH). Para mitigar isso, precisamos criar um usuário não-root com privilégios sudo e desabilitar o login raiz.

Criando um Usuário Administrativo

Crie um novo usuário, por exemplo, admin, e adicione-o ao grupo de sudoers:

sudo adduser admin
sudo usermod -aG sudo admin

Defina uma senha forte para este novo usuário ou, preferencialmente, configure chaves SSH para autenticação sem senha (recomendado para maior segurança).

Configurando o SSHD

Edite o arquivo de configuração do serviço SSH. No Debian/Ubuntu, o caminho é /etc/ssh/sshd_config.

sudo nano /etc/ssh/sshd_config

Realize as seguintes alterações críticas:

  • PermitRootLogin no: Impede que qualquer pessoa tente logar como root. Isso força o atacante a adivinhar um nome de usuário válido antes de tentar uma senha.
  • PasswordAuthentication no: Desabilita login por senha. Force o uso de chaves SSH públicas/privadas. Senhas são vulneráveis a ataques de força bruta e dicionário.
  • Port 22: Considere mudar para uma porta não padrão (ex: Port 2200). Isso não é segurança por obscuridade, mas reduz drasticamente o ruído dos logs e ataques automatizados.

Exemplo de configuração segura no arquivo:

PermitRootLogin no
PasswordAuthentication no
Port 2200
AllowUsers admin

Após salvar as alterações, reinicie o serviço SSH para aplicar as mudanças:

sudo systemctl restart sshd

Atenção: Antes de fechar sua sessão atual, teste a conexão com o novo usuário em uma nova janela de terminal. Se você mudou a porta, lembre-se de especificá-la no comando de conexão:

ssh -p 2200 admin@seu_ip

3. Configuração do Firewall (UFW)

Um firewall é sua primeira linha de defesa perimetral. O UFW (Uncomplicated Firewall) é uma interface amigável para o iptables, disponível nativamente em muitas distribuições Linux.

Primeiro, instale o UFW se ainda não estiver presente:

sudo apt install ufw

Agora, defina as políticas padrão. A lógica é simples: bloquear tudo que não foi explicitamente permitido.

sudo ufw default deny incoming
sudo ufw default allow outgoing

Habilite o acesso SSH. Se você mudou a porta para 2200, como sugerido acima, permita o acesso nela:

sudo ufw allow 2200/tcp

Se sua aplicação Node.js rodará na porta padrão HTTP (80) ou HTTPS (443), abra essas portas agora. Para fins de teste e hardening inicial, podemos deixar o HTTP aberto, mas o ideal em produção é usar um proxy reverso (como Nginx) que gerencia o TLS.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Ative o firewall e verifique o status:

sudo ufw enable
sudo ufw status verbose

O comando enable irá perguntar se deseja continuar, pois pode interferir em conexões SSH ativas. Confirme apenas se você tem certeza de que a regra SSH está correta.

4. Instalação Segura do Node.js e NPM

Agora que o sistema operacional está protegido, focamos na aplicação. Evite instalar o Node.js via apt install nodejs, pois as versões nos repositórios oficiais costumam ser desatualizadas e podem conter vulnerabilidades conhecidas já corrigidas em versões mais recentes.

A maneira recomendada de manter controle sobre a versão e garantir atualizações seguras é através do nvm (Node Version Manager).

Instalando o NVM

Faça login como seu usuário admin (não use root) e execute o script de instalação oficial:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Para carregar o comando nvm no seu terminal atual, feche e reabra o terminal ou execute:

source ~/.bashrc

Instalando a Versão LTS do Node.js

O NVM permite instalar múltiplas versões. Para produção, sempre utilize a versão LTS (Long Term Support), que recebe correções de segurança por um período prolongado.

nvm install --lts
nvm use --lts
nvm alias default lts/*

Verifique a instalação:

node -v
npm -v

Segurança do NPM

O ecossistema de pacotes do Node.js é vasto, mas também alvo de ataques de "typosquatting" e injeção de código malicioso em dependências. Adote as seguintes práticas:

  • Sempre verifique o nome do pacote antes de instalar.
  • Use npm ci em vez de npm install em ambientes de produção. O ci ignora o package.json e instala estritamente conforme o package-lock.json, garantindo reproduzibilidade e evitando atualizações não intencionais.
  • Execute regularmente npm audit para identificar dependências com vulnerabilidades conhecidas.

5. Isolamento de Processo e Execução

Nunca, em hipótese alguma, execute sua aplicação Node.js como usuário root. Se houver uma falha de segurança na sua aplicação (como um exploit de RCE - Remote Code Execution), o atacante terá controle total do servidor.

A solução é executar a aplicação sob um usuário dedicado e com permissões mínimas.

Criando Usuário Dedicado

sudo adduser --disabled-password --gecos "" nodeapp
# Adicione este usuário ao grupo sudo apenas se ele precisar fazer deploy, mas não execute a app como root

Usando Systemd para Gerenciamento Seguro

O Systemd é o gerenciador de processos do Linux e oferece recursos poderosos de isolamento. Crie um arquivo de serviço para sua aplicação Node.js.

sudo nano /etc/systemd/system/nodeapp.service

Configure o arquivo com as seguintes diretrizes de segurança:

[Unit]
Description=Node.js Application
After=network.target

[Service]
Type=simple
User=nodeapp
Group=nodeapp
WorkingDirectory=/var/www/nodeapp
ExecStart=/home/admin/.nvm/versions/node/v18.16.0/bin/node server.js
Restart=on-failure

# Hardening do Systemd
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/www/nodeapp/logs

[Install]
WantedBy=multi-user.target

Explicação das diretivas de hardening no Systemd:

  • NoNewPrivileges=yes: Impede que o processo ganhe novos privilégios (ex: via setuid).
  • ProtectSystem=strict: Torna todo o sistema de arquivos apenas leitura, exceto diretórios explícitos.
  • PrivateTmp=yes: Dá ao processo seu próprio espaço temporário isolado do resto do sistema.
  • User=nodeapp: Garante que a app rode com permissões limitadas do usuário criado especificamente para ela.

Ative e inicie o serviço:

sudo systemctl daemon-reload
sudo systemctl enable nodeapp
sudo systemctl start nodeapp

6. Monitoramento e Logs

A segurança não termina com a configuração inicial. Você precisa monitorar o que acontece no seu servidor. O fail2ban é uma ferramenta essencial para proteção contra ataques de força bruta no SSH.

Instalando Fail2Ban

sudo apt install fail2ban

Crie um arquivo de configuração local para não sobrescrever as configurações padrão durante atualizações:

sudo nano /etc/fail2ban/jail.local

Adicione a seguinte configuração para proteger sua porta SSH personalizada:

[sshd]
enabled = true
port = 2200
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Reinicie o fail2ban:

sudo systemctl restart fail2ban

Isso bloqueará automaticamente qualquer IP que tentar fazer mais de 3 logins falhos no SSH em um período curto.

7. Atualização Contínua e Backups

O hardening é um processo contínuo, não um evento único.

  • Atualizações Automáticas: Configure atualizações de segurança automáticas para o sistema operacional. No Debian/Ubuntu, use o pacote unattended-upgrades.
  • Backups: Implemente backups regulares do seu código-fonte e configurações. Teste a restauração desses backups periodicamente.
  • Auditoria de Dependências: Integre npm audit no seu pipeline de CI/CD para bloquear deploys que introduzam vulnerabilidades conhecidas.

Lembre-se: a segurança é uma camada. Se o Node.js tiver uma falha, o Systemd isola o dano. Se o SSH for atacado, o Fail2Ban bloqueia o invasor. Se o firewall estiver ativo, portas desnecessárias permanecem fechadas.

Ao seguir estes passos, você transforma sua VPS de um servidor padrão em uma máquina robusta, pronta para hospedar aplicações Node.js com um nível profissional de segurança e estabilidade.

Compartilhar: Link copiado!
Esse tutorial foi útil?

Comentários (0)

Seja o primeiro a comentar.

Deixe seu comentário

Seu comentário será analisado antes de ser publicado.

0/2000