21 out 2026 · ferramentas, linux, tls · 5 min
HTTPS no seu localhost com mkcert, sem aviso de certificado
mkcert cria uma autoridade certificadora na sua máquina, instala essa CA no trust store do sistema e do navegador, e assina um certificado para localhost, 127.0.0.1 e ::1. O navegador para de reclamar porque a cadeia fecha na CA em que ele já confia. Medido: com a CA passada em –cacert, o curl retorna HTTP 200 e ssl_verify_result 0 em 0,006 s; sem ela, falha com “unable to get local issuer certificate”.
O que mkcert faz
Certificado autoassinado assina a si mesmo. O navegador não tem motivo para confiar. mkcert separa em duas partes: a autoridade (rootCA.pem e rootCA-key.pem, criados uma vez) e o certificado folha, assinado por essa autoridade. O mkcert -install coloca a autoridade nos trust stores que o sistema e o navegador leem. Depois, qualquer certificado assinado por ela passa sem aviso.
O rootCA-key.pem é o segredo. Quem tiver esse arquivo pode emitir certificado válido para qualquer nome na sua máquina. Não copie para outro host, não commite, não compartilhe.
Instalação no Linux
Baixe o binário da página de releases (v1.4.4 em outubro de 2026). No Debian/Ubuntu, instale libnss3-tools antes, porque o mkcert só escreve no store do Firefox/Chrome se o certutil existir na hora do -install.
sudo apt install libnss3-tools
# baixe mkcert-v*-linux-amd64 da página de releases
chmod +x mkcert
sudo mv mkcert /usr/local/bin/
mkcert -version
Gerar a CA e o certificado
mkcert -install
mkcert -CAROOT
mkcert -cert-file ./localhost.pem -key-file ./localhost-key.pem localhost 127.0.0.1 ::1
O primeiro comando cria a CA e a instala. O segundo mostra onde ela mora (tipicamente ~/.local/share/mkcert). O terceiro gera localhost.pem e localhost-key.pem, válidos para localhost, 127.0.0.1 e ::1, expirando em 21 de janeiro de 2029.
Passe todos os nomes numa chamada só. Um certificado com vários SAN é mais fácil de gerenciar que cinco certificados.
Prova: servidor local com cadeado
Subi um servidor HTTPS na porta 8443 usando localhost.pem e localhost-key.pem. Com a CA em –cacert, o curl retorna HTTP 200 e ssl_verify_result 0 em 0,006 s. Sem a CA, falha com “unable to get local issuer certificate”. O navegador se comporta igual: com a CA instalada, sem aviso; sem ela, aviso.
Usar em Node, nginx e container
Node não lê o store do sistema por padrão. Aponte a CA com a variável de ambiente:
NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" node server.js
No nginx, use os arquivos gerados:
ssl_certificate /etc/nginx/certs/localhost.pem;
ssl_certificate_key /etc/nginx/certs/localhost-key.pem;
Num contêiner que precisa chamar o endpoint local, copie só o rootCA.pem e rode update-ca-certificates. Nunca copie a chave.
Quando não usar
mkcert é ferramenta de desenvolvimento, e a própria documentação é clara sobre isso. Para hostname público, use Let’s Encrypt. Para serviço interno com vários hosts e revogação real, use uma CA interna como step-ca. A linha é simples: mkcert para a máquina de um desenvolvedor; além disso, uma CA que alguém opera.
O artefato: script completo
#!/usr/bin/env bash
set -euo pipefail
if ! command -v mkcert >/dev/null 2>&1; then
echo "mkcert nao encontrado."
echo "Linux: baixe o binario em https://github.com/FiloSottile/mkcert/releases"
echo "Debian/Ubuntu: apt install libnss3-tools antes do mkcert -install"
exit 0
fi
CAROOT="$(mkcert -CAROOT)"
echo "CA em: $CAROOT"
mkcert -install
mkcert -cert-file ./localhost.pem -key-file ./localhost-key.pem \
localhost 127.0.0.1 ::1
echo "certificado: ./localhost.pem"
echo "chave: ./localhost-key.pem"
echo "use os dois no seu servidor local"
Como verificar
mkcert -CAROOT mostra o diretório da CA. openssl x509 -in localhost.pem -noout -subject -issuer -dates mostra emissor igual à CA local e datas válidas. curl --cacert "$(mkcert -CAROOT)/rootCA.pem" https://localhost:8443/ deve retornar HTTP 200 com ssl_verify_result 0.
Se der errado
Aviso de certificado no navegador. Causa: o mkcert -install não encontrou o store do navegador, porque o certutil não estava instalado. Correção: instale libnss3-tools (Debian/Ubuntu) ou nss-tools (RHEL) e rode mkcert -install de novo.
curl: (60) SSL certificate problem. Causa: a CA não foi passada. Correção: --cacert "$(mkcert -CAROOT)/rootCA.pem".
Certificado não cobre o nome. Causa: o nome usado no navegador não está na lista de SAN. Correção: regenere incluindo o nome exato, por exemplo mkcert ... app.localhost "*.localhost".
Porta 8443 em uso. Causa: outro processo. Correção: escolha outra porta no servidor ou mate o processo.
Tabela
| Opção | Confiança no navegador | Quando usar |
|---|---|---|
| Certificado autoassinado | não | nunca em dev local se puder evitar |
| mkcert | sim, na sua máquina | desenvolvimento local |
| Let’s Encrypt | sim, em todo lugar | hostname público |
| step-ca | sim, na rede interna | vários hosts, revogação |
FAQ
mkcert funciona no Windows e macOS? Sim. No Windows usa o store do sistema; no macOS, o Keychain. Firefox usa o próprio store NSS nos três.
Preciso rodar mkcert -install em cada projeto? Não. Uma CA por máquina. Gere quantos certificados quiser a partir dela.
O certificado expira? Sim, em cerca de 3 anos (o certificado medido expira em 21 de janeiro de 2029). Rode o comando de geração de novo.
Posso usar wildcard? Sim: mkcert "*.localhost". Útil para subdomínios locais.
É seguro usar em produção? Não. A CA local não tem revogação e a chave não deve sair da máquina.
Fontes
mkcert no GitHub, conferido em outubro de 2026, versão 1.4.4. O guia de mkcert para HTTPS local detalha trust stores por sistema operacional. Para o outro lado da conexão, o handshake TLS passo a passo. Para certificado público, Let’s Encrypt: 64 dias de certificado na borda.