Configurando conexões seguras com SSL no PostgreSQL
Proteja suas conexões com certificados SSL e autenticação robusta.
Por que SSL/TLS é obrigatório em produção
Conectar ao seu banco PostgreSQL sem criptografia é como enviar sua senha por e-mail não criptografado: qualquer um no caminho pode interceptar. SSL/TLS garante que seus dados trafeguem seguros entre aplicação e banco.
Riscos de conexões não criptografadas
- 🔓 Senhas expostas - Credenciais visíveis em plain text
- 🔓 Dados vazados - Queries e resultados interceptáveis
- 🔓 Man-in-the-middle - Atacantes podem alterar dados
- 🔓 Compliance violado - LGPD, PCI-DSS exigem criptografia
- 🔓 Auditoria impossível - Sem garantia de origem
1. Como SSL/TLS funciona no PostgreSQL
Handshake SSL
1. Cliente conecta ao servidor
2. Servidor envia certificado digital
3. Cliente valida certificado (CA chain)
4. Troca de chaves criptográficas
5. Conexão segura estabelecida
6. Dados trafegam criptografados (AES-256)
Modos de SSL no PostgreSQL
| Modo | Descrição | Uso |
|---|---|---|
disable |
Sem SSL | ❌ Nunca em produção |
allow |
SSL se disponível | ⚠️ Inseguro |
prefer |
Prefere SSL | ⚠️ Pode falhar para plain |
require |
SSL obrigatório | ✅ Recomendado |
verify-ca |
Valida CA | ✅ Mais seguro |
verify-full |
Valida CA + hostname | ✅ Máxima segurança |
2. Configurando SSL no servidor PostgreSQL
Gerando certificados SSL
# Gere certificado auto-assinado (desenvolvimento)
openssl req -new -x509 -days 365 -nodes -text \\
-out server.crt \\
-keyout server.key \\
-subj "/CN=postgres.meudominio.com"
# Permissões corretas
chmod 600 server.key
chown postgres:postgres server.key server.crt
# Copie para diretório do PostgreSQL
cp server.crt server.key /var/lib/postgresql/data/
Configuração em postgresql.conf
# Habilite SSL
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt' # Opcional: para client certificates
# Cipher suites modernos (TLS 1.2+)
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
ssl_prefer_server_ciphers = on
ssl_min_protocol_version = 'TLSv1.2'
# Reinicie PostgreSQL
sudo systemctl restart postgresql
Configuração em pg_hba.conf
# Exija SSL para conexões remotas
# TYPE DATABASE USER ADDRESS METHOD
hostssl all all 0.0.0.0/0 md5
hostssl all all ::/0 md5
# Bloqueie conexões não-SSL
hostnossl all all 0.0.0.0/0 reject
# Reload configuração
sudo systemctl reload postgresql
3. Conectando com SSL do cliente
Node.js / JavaScript
// Com pg (node-postgres)
const { Pool } = require('pg');
const pool = new Pool({
host: 'postgres.meudominio.com',
port: 5432,
database: 'meudb',
user: 'usuario',
password: 'senha',
ssl: {
rejectUnauthorized: true, // Valida certificado
ca: fs.readFileSync('./ca-certificate.crt').toString(),
// Para client certificates:
key: fs.readFileSync('./client-key.pem').toString(),
cert: fs.readFileSync('./client-cert.pem').toString(),
}
});
// Connection string alternativa
const connectionString = 'postgresql://user:pass@host:5432/db?sslmode=require';
const pool2 = new Pool({ connectionString });
Python
import psycopg2
# Com psycopg2
conn = psycopg2.connect(
host='postgres.meudominio.com',
port=5432,
database='meudb',
user='usuario',
password='senha',
sslmode='require', # ou 'verify-full'
sslrootcert='/path/to/ca-cert.crt',
sslcert='/path/to/client-cert.pem',
sslkey='/path/to/client-key.pem'
)
Java (JDBC)
String url = "jdbc:postgresql://postgres.meudominio.com:5432/meudb" +
"?ssl=true" +
"&sslmode=verify-full" +
"&sslrootcert=/path/to/ca-cert.crt" +
"&sslcert=/path/to/client-cert.crt" +
"&sslkey=/path/to/client-key.pk8";
Connection conn = DriverManager.getConnection(url, "usuario", "senha");
Go
import (
"database/sql"
"crypto/tls"
"crypto/x509"
_ "github.com/lib/pq"
)
connStr := "host=postgres.meudominio.com port=5432 " +
"user=usuario password=senha dbname=meudb " +
"sslmode=verify-full sslrootcert=/path/to/ca-cert.crt"
db, err := sql.Open("postgres", connStr)
Ruby (Rails)
# database.yml
production:
adapter: postgresql
host: postgres.meudominio.com
database: meudb
username: usuario
password: senha
sslmode: require
sslrootcert: /path/to/ca-cert.crt
psql (CLI)
# Conexão com SSL obrigatório
psql "postgresql://user:pass@host:5432/db?sslmode=require"
# Com variáveis de ambiente
export PGSSLMODE=require
export PGSSLROOTCERT=/path/to/ca-cert.crt
psql -h postgres.meudominio.com -U usuario -d meudb
4. Validando conexões SSL
Verificar SSL ativo
-- No PostgreSQL, verifique conexões SSL
SELECT
pid,
usename,
application_name,
client_addr,
ssl,
ssl_version,
ssl_cipher
FROM pg_stat_ssl
JOIN pg_stat_activity USING (pid)
WHERE ssl = true;
-- Resultado esperado:
-- ssl: true
-- ssl_version: TLSv1.3
-- ssl_cipher: TLS_AES_256_GCM_SHA384
Teste de conexão
#!/bin/bash
# test-ssl-connection.sh
echo "Testando conexão SSL..."
# Deve funcionar
psql "postgresql://user:pass@host:5432/db?sslmode=require" -c "SELECT version();" && \\
echo "✅ SSL funcionando!"
# Deve falhar
psql "postgresql://user:pass@host:5432/db?sslmode=disable" -c "SELECT 1;" 2>&1 | \\
grep -q "rejected" && \\
echo "✅ Conexões não-SSL bloqueadas corretamente!"
5. Client Certificates (mTLS)
Para segurança máxima, use autenticação mútua (cliente também tem certificado):
Gerando certificado do cliente
# 1. CA key e certificado
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
# 2. Client key
openssl genrsa -out client.key 4096
# 3. Client certificate request
openssl req -new -key client.key -out client.csr
# 4. Assine com CA
openssl x509 -req -days 365 -in client.csr \\
-CA ca.crt -CAkey ca.key -CAcreateserial \\
-out client.crt
# 5. Converta para formato correto (se necessário)
openssl pkcs8 -topk8 -inform PEM -outform DER \\
-in client.key -out client.pk8 -nocrypt
Configuração no servidor
# postgresql.conf
ssl_ca_file = 'ca.crt'
# pg_hba.conf - exija client cert
hostssl all all 0.0.0.0/0 cert clientcert=verify-full
6. Troubleshooting SSL
Erro: "SSL is not enabled on the server"
Solução:
1. Verifique postgresql.conf: ssl = on
2. Certificados no lugar correto
3. Permissões: chmod 600 server.key
4. Reinicie PostgreSQL
Erro: "certificate verify failed"
Solução:
1. Use sslmode=require (não verify-full) temporariamente
2. Verifique CA certificate correto
3. Hostname deve bater com CN do certificado
4. Certificado não expirado: openssl x509 -in server.crt -noout -dates
Erro: "no pg_hba.conf entry for host"
Solução:
1. Adicione entrada hostssl no pg_hba.conf
2. Recarregue: SELECT pg_reload_conf();
3. Verifique IP do cliente está permitido
7. SSL/TLS no CloudPG
No CloudPG, SSL/TLS é obrigatório e configurado automaticamente:
- ✅ TLS 1.2+ apenas - Protocolos antigos desabilitados
- ✅ Certificados válidos - Assinados por CA confiável
- ✅ Renovação automática - Certificados sempre atualizados
- ✅ Perfect Forward Secrecy - Ciphers modernos
- ✅ HSTS habilitado - Força HTTPS no dashboard
- ✅ Sem configuração - Funciona out-of-the-box
Como conectar no CloudPG
// Simples assim:
const pool = new Pool({
connectionString: 'postgresql://user:pass@seu-cluster.cloudpg.com.br:5432/db',
ssl: { rejectUnauthorized: true } // Apenas isso!
});
// Ou ainda mais simples:
const connectionString = 'postgresql://user:pass@host:5432/db?sslmode=require';
const pool = new Pool({ connectionString });
Conclusão
SSL/TLS é essencial para qualquer aplicação em produção. Os pontos principais:
- ✅ Sempre use
sslmode=requireno mínimo - ✅ Em produção, prefira
verify-full - ✅ Use certificados de CAs confiáveis
- ✅ Teste conexões regularmente
- ✅ Monitore expiração de certificados
- ✅ Desabilite protocolos antigos (TLS 1.0/1.1)
Com CloudPG, SSL/TLS funciona automaticamente, sem dor de cabeça de configuração ou renovação.
Conexões seguras desde o primeiro minuto
Crie seu banco PostgreSQL com SSL/TLS configurado automaticamente e comece a desenvolver com segurança.