Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

TLS e HTTPS no Node.js

Atualizado em: 1 de outubro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

HTTPS é o protocolo HTTP transportado por TLS. No Node.js, os módulos node:https e node:tls permitem criar servidores e clientes seguros, configurar certificados, validar identidades e inspecionar conexões criptografadas.

Em muitas arquiteturas, TLS termina no CDN, ingress ou load balancer. Mesmo assim, entender o funcionamento é importante para comunicação interna, mTLS, diagnóstico de certificados e configuração correta de clientes.

Criando um servidor HTTPS

import { createServer } from 'node:https';
import { readFileSync } from 'node:fs';

const server = createServer({
  key: readFileSync('./certs/server-key.pem'),
  cert: readFileSync('./certs/server-cert.pem'),
}, (req, res) => {
  res.writeHead(200, {
    'content-type': 'application/json; charset=utf-8',
  });
  res.end(JSON.stringify({ status: 'secure' }));
});

server.listen(8443);

A chave privada deve ter permissões restritas. Não a inclua no repositório ou imagem pública.

Certificado, chave e cadeia

Os principais arquivos são:

  • chave privada do servidor;
  • certificado do servidor;
  • certificados intermediários;
  • CA raiz confiada pelo cliente.

O servidor precisa apresentar a cadeia intermediária correta. Um navegador pode funcionar por possuir intermediários em cache enquanto outro cliente falha.

Cliente HTTPS

import { get } from 'node:https';

get('https://example.com', (res) => {
  console.log(res.statusCode);
  res.resume();
}).on('error', (error) => {
  console.error(error);
});

Por padrão, o cliente valida a cadeia e o hostname. Não desative essa validação em produção.

CA privada

import { Agent } from 'node:https';
import { readFileSync } from 'node:fs';

const agent = new Agent({
  ca: readFileSync('./certs/internal-ca.pem'),
  keepAlive: true,
});

Adicionar uma CA privada é melhor que usar rejectUnauthorized:false. Distribua a CA por secret manager ou configuração controlada.

NODE_EXTRA_CA_CERTS

O ambiente pode adicionar certificados confiáveis por uma variável de processo:

NODE_EXTRA_CA_CERTS=/etc/certs/internal-ca.pem node dist/server.js

Teste o comportamento na versão do Node.js utilizada e não substitua silenciosamente o armazenamento de confiança sem documentação.

mTLS

Mutual TLS autentica servidor e cliente por certificados.

const server = createServer({
  key: readFileSync('./certs/server-key.pem'),
  cert: readFileSync('./certs/server-cert.pem'),
  ca: readFileSync('./certs/client-ca.pem'),
  requestCert: true,
  rejectUnauthorized: true,
}, (req, res) => {
  const certificate = req.socket.getPeerCertificate();
  res.end(JSON.stringify({ subject: certificate.subject }));
});

Não use somente o Common Name como autorização. Valide SAN, emissor, uso de chave e identidade definida pela PKI.

Cliente mTLS

const agent = new Agent({
  cert: readFileSync('./certs/client-cert.pem'),
  key: readFileSync('./certs/client-key.pem'),
  ca: readFileSync('./certs/server-ca.pem'),
  keepAlive: true,
});

Rotacione certificados e proteja a chave do cliente.

SNI

Server Name Indication permite servir certificados diferentes no mesmo IP. O Node.js pode selecionar um contexto seguro de acordo com o hostname.

import tls from 'node:tls';

const contexts = new Map([
  ['api.example.com', tls.createSecureContext({
    key: readFileSync('./certs/api-key.pem'),
    cert: readFileSync('./certs/api-cert.pem'),
  })],
]);

const server = createServer({
  SNICallback(servername, callback) {
    callback(null, contexts.get(servername));
  },
});

Valide servername e sempre tenha comportamento para host desconhecido.

ALPN

ALPN negocia protocolos como HTTP/1.1 e HTTP/2 durante o handshake.

const socket = tls.connect({
  host: 'example.com',
  port: 443,
  ALPNProtocols: ['h2', 'http/1.1'],
});

socket.on('secureConnect', () => {
  console.log(socket.alpnProtocol);
});

Versões mínimas

Evite protocolos antigos. Configure uma versão mínima compatível com sua política:

const server = createServer({
  key,
  cert,
  minVersion: 'TLSv1.2',
});

A política pode exigir TLS 1.3 ou permitir TLS 1.2 por compatibilidade. Teste clientes reais.

Ciphers

O Node.js e OpenSSL fornecem padrões seguros para versões modernas. Personalizar cifras sem conhecimento pode reduzir segurança ou compatibilidade. Siga política organizacional e scanners confiáveis.

Renegociação

Renegociação TLS possui riscos e limites. Não dependa dela para autenticação tardia. Prefira novas conexões ou protocolos desenhados para a necessidade.

Session resumption

Reutilizar sessões TLS pode reduzir custo de handshake. Keep-alive normalmente oferece ganho maior porque evita o handshake completo. Monitore a taxa de novas conexões antes de otimizar tickets e sessões.

Rotação de certificados

Certificados expiram e precisam ser renovados antes. Estratégias:

  • terminar TLS em proxy que recarrega automaticamente;
  • reiniciar gradualmente instâncias com novos secrets;
  • atualizar contexto seguro em processo;
  • monitorar data de expiração;
  • testar cadeia e hostname após rotação.

Não espere o dia da expiração.

Recarregando contexto

Servidores podem atualizar material criptográfico conforme as APIs disponíveis. Planeje uma atualização atômica: carregue e valide os novos arquivos antes de substituir o contexto.

Certificados em containers

Monte certificados como secrets somente leitura. Evite copiá-los durante build. Confirme permissões, caminho e atualização do volume.

Terminação no proxy

Quando o proxy termina TLS e envia HTTP ao Node.js, proteja a rede interna e configure corretamente headers como X-Forwarded-Proto. Só confie nesses headers de proxies conhecidos.

TLS até o backend

Em ambientes de alto requisito, o proxy pode estabelecer HTTPS ou mTLS até cada backend. Isso protege tráfego interno, mas aumenta custo operacional de certificados e diagnóstico.

Erros comuns de certificado

  • certificado expirado;
  • hostname não presente no SAN;
  • cadeia intermediária incompleta;
  • CA privada ausente;
  • relógio incorreto;
  • certificado para uso inadequado;
  • chave não corresponde ao certificado;
  • permissão de arquivo incorreta.

Inspecionando o certificado remoto

const socket = tls.connect({
  host: 'example.com',
  port: 443,
  servername: 'example.com',
});

socket.on('secureConnect', () => {
  const cert = socket.getPeerCertificate(true);
  console.log({
    subject: cert.subject,
    issuer: cert.issuer,
    validFrom: cert.valid_from,
    validTo: cert.valid_to,
  });
  socket.end();
});

Não registre certificados completos em produção sem necessidade.

Hostname e IP

Conectar por IP enquanto o certificado pertence a um hostname causa falha de validação. Informe servername quando a conexão precisa usar SNI e validar o nome esperado.

Timeout de handshake

Clientes lentos podem manter handshakes abertos. Defina timeout apropriado no servidor e no proxy. Monitore falhas e duração do handshake.

Proteção da chave privada

Use permissões mínimas, secret manager, criptografia em repouso e rotação. Em ambientes mais críticos, considere HSM ou serviço de terminação que evite expor a chave ao processo.

Logs seguros

Registre código do erro, hostname conhecido, emissor e expiração quando necessário. Nunca registre chave privada, conteúdo de secrets ou credenciais de cliente.

Observabilidade

Meça:

  • handshakes por segundo;
  • duração do handshake;
  • falhas de validação;
  • versão TLS negociada;
  • ALPN;
  • certificados próximos da expiração;
  • conexões reutilizadas;
  • erros por dependência.

Testes

Teste certificado válido, expirado, hostname incorreto, CA ausente, mTLS sem cliente, rotação, HTTP/2, proxy e shutdown. Use certificados exclusivos de teste.

Erros comuns

  • usar rejectUnauthorized false;
  • guardar chave no Git;
  • não enviar intermediários;
  • confiar em qualquer X-Forwarded-Proto;
  • não monitorar expiração;
  • customizar cifras sem política;
  • não testar mTLS na rotação;
  • registrar material sensível;
  • não alinhar keep-alive e timeout.

Fluxo recomendado

Prefira terminação gerenciada quando possível. Para TLS no Node.js, valide certificados, use CAs corretas, proteja chaves, configure versões modernas e automatize rotação. Combine com HTTP/2 no Node.js, HTTP Keep-Alive, Graceful Shutdown e Health Checks.

Consulte a documentação oficial de TLS e a documentação oficial de HTTPS no Node.js.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita