TL;DR — Resumo Rápido

step-ca transforma qualquer servidor em uma CA privada para TLS interno, mTLS e certificados SSH. Guia completo de instalação, provisioners, ACME e produção.

step-ca é uma autoridade certificadora privada de código aberto da Smallstep que permite executar sua própria PKI para TLS interno, mTLS entre microsserviços e certificados SSH, sem enviar tráfego a uma CA pública. Se você já teve problemas com Let’s Encrypt em domínios privados, avisos de certificados autoassinados ou distribuição de confiança em dezenas de serviços, o step-ca resolve tudo isso com um design moderno orientado à automação. Este guia cobre o ciclo completo: por que você precisa de uma CA privada, arquitetura, instalação, provisioners, ACME para renovação automática, certificados SSH e uma implantação HA em produção.

Por que uma CA Privada?

CAs públicas como Let’s Encrypt exigem validação de domínio pela internet pública. Isso exclui imediatamente:

  • Nomes de host internospostgres.internal, api.corp ou qualquer domínio .local / .corp
  • mTLS para microsserviços — o mTLS exige que cada serviço apresente um certificado de cliente; emitir milhares de certificados de curta duração de uma CA pública é impraticável e caro
  • Redes de confiança zero — cada conexão autenticada por certificado, não por posição na rede
  • Ambientes air-gapped — sem acesso à internet pública
  • Service mesh sem sidecars — TLS nativo entre serviços usando certificados do step-ca evita o overhead de um Istio ou Linkerd completo

step-ca preenche essa lacuna com um servidor compatível com ACME, tempos de vida curtos (24 horas por padrão), daemons de renovação automática e integração de primeira classe com Kubernetes via webhook autocert e step-issuer do cert-manager.

Arquitetura

┌─────────────────────────────────────────────┐
│             servidor step-ca                │
│  ┌──────────┐  ┌─────────────┐              │
│  │  CA Raiz │→ │CA Intermediária             │
│  │(offline) │  │             │              │
│  └──────────┘  └──────┬──────┘              │
│                       │ assina              │
│  ┌────────────────────▼──────────────────┐  │
│  │            Provisioners               │  │
│  │  JWK │ ACME │ OIDC │ AWS │ K8sSA │…  │  │
│  └───────────────────────────────────────┘  │
└─────────────────────────────────────────────┘
         ↑ API HTTPS (porta 9000)
    ┌────┴────┐
    │step CLI │  certbot  Caddy  Traefik  cert-manager
    └─────────┘

A CA raiz assina apenas o certificado da CA intermediária. Em produção, mantenha a chave raiz offline. A CA intermediária é com que o step-ca opera no dia a dia. Os provisioners são os mecanismos de autenticação que controlam a emissão de certificados.

Instalação

Binário (Linux/macOS)

# step CLI
wget https://github.com/smallstep/cli/releases/latest/download/step_linux_amd64.tar.gz
tar xzf step_linux_amd64.tar.gz && sudo mv step /usr/local/bin/

# step-ca servidor
wget https://github.com/smallstep/certificates/releases/latest/download/step-ca_linux_amd64.tar.gz
tar xzf step-ca_linux_amd64.tar.gz && sudo mv step-ca /usr/local/bin/

macOS (Homebrew)

brew install step
brew install step-ca

Docker

docker run -v step:/home/step \
  -p 9000:9000 \
  -e "DOCKER_STEPCA_INIT_NAME=CA Interna" \
  -e "DOCKER_STEPCA_INIT_DNS_NAMES=ca.internal,localhost" \
  -e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
  smallstep/step-ca

Kubernetes (Helm + autocert)

helm repo add smallstep https://smallstep.github.io/helm-charts
helm install step-certificates smallstep/step-certificates \
  --set ca.name="CA Interna" \
  --set ca.dns="step-certificates.default.svc.cluster.local"

Configuração Inicial: step ca init

step ca init \
  --name "CA Corporativa" \
  --dns ca.corp.internal \
  --address :9000 \
  --provisioner admin@corp.internal

Isso cria em $(step path)/:

  • certs/root_ca.crt — certificado de CA raiz (distribuir a todos os clientes)
  • certs/intermediate_ca.crt — certificado intermediário
  • secrets/root_ca_key — chave privada de CA raiz (manter offline)
  • secrets/intermediate_ca_key — chave intermediária (usada pelo servidor)
  • config/ca.json — configuração do servidor

Inicie o servidor:

step-ca $(step path)/config/ca.json

Para produção, crie uma unidade systemd:

[Unit]
Description=Smallstep CA
After=network.target

[Service]
User=step
ExecStart=/usr/local/bin/step-ca /etc/step-ca/config/ca.json
Restart=always
RestartSec=5
Environment=STEPPATH=/etc/step-ca

[Install]
WantedBy=multi-user.target

Provisioners

Provisioners são plugins de autenticação. Adicione mais com:

step ca provisioner add <nome> --type <TIPO>

JWK — Interativo / Baseado em Scripts

O provisioner padrão. Clientes se autenticam com um JSON Web Token:

step ca certificate api.internal api.crt api.key

ACME — Automatizado (Caddy, Nginx, certbot)

step ca provisioner add acme --type ACME

Exemplo com certbot:

certbot certonly \
  --server https://ca.internal:9000/acme/acme/directory \
  --standalone \
  -d api.internal \
  --agree-tos -m admin@corp.internal

Caddy no Caddyfile:

api.internal {
  tls {
    ca https://ca.internal:9000/acme/acme/directory
  }
  reverse_proxy localhost:8080
}

OIDC — Baseado em SSO

step ca provisioner add google --type OIDC \
  --client-id <GOOGLE_CLIENT_ID> \
  --client-secret <SECRET> \
  --configuration-endpoint https://accounts.google.com/.well-known/openid-configuration

Identidade de Instância na Nuvem (AWS / GCP / Azure)

step ca provisioner add aws --type AWS --aws-account 123456789012
step ca provisioner add gcp --type GCP --gcp-project meu-projeto
step ca provisioner add azure --type Azure --azure-tenant <TENANT_ID>

Contas de Serviço do Kubernetes (K8sSA)

step ca provisioner add k8s --type K8sSA \
  --public-key /var/run/secrets/kubernetes.io/serviceaccount/public-key.pub

Emissão de Certificados

# ECDSA P-256 (padrão) com SANs
step ca certificate api.internal api.crt api.key \
  --san api.corp --san 10.0.1.50

# Ed25519
step ca certificate api.internal api.crt api.key --kty OKP --crv Ed25519

# RSA 4096 (compatibilidade legada)
step ca certificate api.internal api.crt api.key --kty RSA --size 4096

# Certificado de curta duração (1 hora)
step ca certificate api.internal api.crt api.key --not-after 1h

Certificados SSH

# Certificado de usuário SSH
step ssh certificate usuario@corp.internal id_ecdsa --provisioner google

# Certificado de host SSH
step ssh certificate --host api.internal ssh_host_ecdsa_key --provisioner aws

Configure o sshd:

TrustedUserCAKeys /etc/ssh/step_user_ca.pub
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
HostKey /etc/ssh/ssh_host_ecdsa_key

Renovação e Revogação

Renovação Automática (—daemon)

step ca renew --daemon api.crt api.key

Em um serviço systemd:

ExecStartPost=/usr/local/bin/step ca renew --daemon \
  /etc/tls/servico.crt /etc/tls/servico.key \
  --exec "systemctl reload meu-servico"

Revogação

step ca revoke --serial 1234567890abcdef

Backends de Banco de Dados e Alta Disponibilidade

BackendPadrãoHACaso de uso
BadgerSimNãoInstância única, dev/equipes pequenas
PostgreSQLNãoSimProdução multi-réplica
MySQLNãoSimProdução multi-réplica
"db": {
  "type": "postgresql",
  "dataSource": "postgresql://stepca:password@pg.internal:5432/stepca?sslmode=require"
}

Comparação: Opções de CA Privada

FerramentaServidor ACMECerts SSHProvisionersHAFacilidadeLicença
step-caSim (integrado)Sim8 tiposSim (BD ext.)AltaApache 2
CFSSLNãoNãoNenhumSimMédiaBSD
Vault PKIVia pluginVia Vault SSHVia Vault authSim (Raft)BaixaBSL
EJBCASimNãoMuitosSimMuito baixaLGPL / EE
Let’s EncryptSim (público)NãoApenas ACMEN/AMuito altaN/A
mkcertNãoNãoNenhumNãoMuito altaMIT

Armadilhas e Casos Especiais

Desvio de relógio — o step-ca rejeita CSRs se o relógio do cliente diferir mais de alguns minutos. Certifique-se de que NTP esteja em execução em todos os nós.

Proteção da chave CA raiz — após step ca init, mova root_ca_key para offline. A chave intermediária é tudo que o step-ca precisa para operar.

ACME e SANs de IP — os desafios ACME HTTP-01 e DNS-01 funcionam para nomes de domínio. Para SANs de endereço IP, use o step CLI diretamente.

Transparência de certificados — ao contrário das CAs públicas, o step-ca não envia certificados para registros CT. Isso é desejável para infraestrutura interna.

Gestão de senhas de provisioner — armazene as senhas em um gerenciador de segredos. Nunca as codifique em scripts.

Resumo

  • step-ca executa uma PKI privada completa: CA raiz, CA intermediária e API REST para emissão de certificados
  • Use certificados de curta duração (padrão 24h) e renovação com --daemon em vez de CRL/OCSP
  • O provisioner ACME torna o step-ca uma CA interna compatível com Caddy, Nginx, Traefik e certbot
  • Provisioners de nuvem (AWS, GCP, Azure) permitem bootstrap de identidade de workload sem segredos compartilhados
  • K8sSA e integração com cert-manager automatizam TLS por pod no Kubernetes sem sidecars
  • Certificados SSH do step-ca eliminam o gerenciamento individual de known_hosts por servidor
  • Para HA, mude o backend para PostgreSQL e execute múltiplas réplicas atrás de um balanceador de carga
  • Mantenha a chave CA raiz offline; rotacione a chave intermediária independentemente se comprometida

Artigos Relacionados