Nginx com SSL e Let's Encrypt

    HTTPS é obrigatório em produção — protege a comunicação, é exigido por browsers modernos e afeta o SEO. Let's Encrypt fornece certificados SSL gratuitos e automáticos. Certbot configura o Nginx e agenda a renovação sem intervenção manual.

    Instalar Certbot e obter certificado

    Instalar Certbot e emitir certificado SSL para o domínio:

    bash
    # Instalar Certbot com plugin do Nginx
    sudo apt install -y certbot python3-certbot-nginx
    
    # Garantir que o DNS do domínio aponta para o IP da VPS antes de prosseguir
    # Verificar: dig api.seudominio.com.br
    
    # Obter certificado (Certbot edita o nginx.conf automaticamente):
    sudo certbot --nginx -d seudominio.com.br -d www.seudominio.com.br
    
    # Ou sem edição automática (modo certonly):
    sudo certbot certonly --nginx -d seudominio.com.br
    
    # Para múltiplos domínios em um único certificado:
    sudo certbot --nginx \
      -d seudominio.com.br \
      -d www.seudominio.com.br \
      -d api.seudominio.com.br
    
    # Listar certificados emitidos:
    sudo certbot certificates
    
    # Testar renovação (não altera nada):
    sudo certbot renew --dry-run
    Dica
    Let's Encrypt exige que o domínio aponte para o IP da VPS e que a porta 80 esteja acessível publicamente para validar o desafio HTTP. Certifique-se de que o firewall permite HTTP (porta 80) antes de emitir o certificado.

    Configuração SSL com nota A+ no SSL Labs

    Configuração completa com TLS 1.2/1.3, HSTS e ciphers modernos:

    nginx
    # /etc/nginx/conf.d/ssl-params.conf — parâmetros SSL reutilizáveis
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;      # TLS 1.3 ignora isso; TLS 1.2: cliente escolhe
    
    # Ciphers seguros para TLS 1.2 (TLS 1.3 usa ciphers próprios)
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    
    # OCSP Stapling — melhora performance de handshake
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    # Session cache — reutilizar sessões TLS (melhora performance)
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    
    # Diffie-Hellman group — gerar com:
    # openssl dhparam -out /etc/nginx/dhparam.pem 2048
    ssl_dhparam /etc/nginx/dhparam.pem;
    
    # /etc/nginx/conf.d/minha-api.conf
    server {
        listen 443 ssl http2;
        server_name seudominio.com.br;
    
        ssl_certificate     /etc/letsencrypt/live/seudominio.com.br/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seudominio.com.br/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/seudominio.com.br/chain.pem;
    
        include /etc/nginx/conf.d/ssl-params.conf;
    
        # HSTS: forçar HTTPS por 1 ano
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header Host $host;
        }
    }

    Renovação automática com systemd timer

    Certbot instala automaticamente um timer para renovar certificados:

    bash
    # Verificar o timer instalado pelo Certbot:
    sudo systemctl status certbot.timer
    sudo systemctl list-timers certbot*
    
    # O timer roda duas vezes ao dia e renova certificados
    # que expiram em menos de 30 dias
    
    # Verificar logs de renovação:
    sudo journalctl -u certbot.service --no-pager | tail -30
    
    # Se o timer não existir, criar manualmente via cron:
    # sudo crontab -e
    0 3 * * * certbot renew --quiet --nginx && nginx -s reload
    
    # Hook para recarregar Nginx após renovação:
    # /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
    #!/bin/bash
    nginx -s reload
    
    sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
    
    # Testar que o hook funciona:
    sudo certbot renew --dry-run

    Wildcard certificate com DNS challenge

    Para *.seudominio.com.br, use DNS challenge em vez de HTTP challenge:

    bash
    # Wildcard requer DNS challenge (verificação via registro TXT no DNS)
    # Suporta automação apenas se seu provedor DNS tem plugin para Certbot
    
    # Para Cloudflare (plugin oficial):
    sudo pip install certbot-dns-cloudflare
    
    # Criar arquivo com API token do Cloudflare:
    sudo mkdir -p /etc/letsencrypt/cloudflare
    cat > /etc/letsencrypt/cloudflare/credentials.ini << 'EOF'
    dns_cloudflare_api_token = SEU_TOKEN_DA_CLOUDFLARE
    EOF
    sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
    
    # Emitir certificado wildcard:
    sudo certbot certonly \
      --dns-cloudflare \
      --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
      -d "seudominio.com.br" \
      -d "*.seudominio.com.br"
    
    # Renovação automática funciona com o mesmo plugin:
    sudo certbot renew --dry-run

    Verificar e monitorar expiração de certificados

    Monitore a expiração dos certificados para evitar interrupções:

    bash
    # Verificar validade de todos os certificados:
    sudo certbot certificates
    
    # Verificar data de expiração diretamente:
    echo | openssl s_client -servername seudominio.com.br \
      -connect seudominio.com.br:443 2>/dev/null \
      | openssl x509 -noout -dates
    
    # Script para alertar quando certificado expira em menos de 20 dias:
    #!/bin/bash
    DOMAIN="seudominio.com.br"
    EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null \
      | openssl x509 -noout -enddate | cut -d= -f2)
    EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
    NOW_EPOCH=$(date +%s)
    DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
    
    if [ "$DAYS_LEFT" -lt 20 ]; then
      curl -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
        -d "chat_id=$CHAT_ID&text=⚠️ Certificado SSL de $DOMAIN expira em $DAYS_LEFT dias!"
    fi

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes