Configuração SSL/TLS para Conexões PostgreSQL: Um Guia Completo

Aprenda a proteger conexões PostgreSQL com criptografia SSL/TLS. Este guia abrangente cobre configuração do servidor e cliente, incluindo geração de certificados, modificação de `postgresql.conf` e `pg_hba.conf`, e configuração de clientes para comunicação segura e criptografada. Proteja seus dados sensíveis em trânsito e garanta conformidade com padrões modernos de segurança.

Configuração SSL/TLS para Conexões PostgreSQL: Um Guia Completo

A configuração SSL/TLS do PostgreSQL tem duas tarefas separadas. A primeira é a criptografia, para que alguém na rede não possa ler credenciais ou resultados de consultas em trânsito. A segunda é a identidade, para que o cliente saiba que está falando com o servidor de banco de dados real e não com uma máquina fingindo ser ele. Muitas configurações fazem a primeira parte e acidentalmente pulam a segunda.

Essa distinção importa em implantações reais. sslmode=require criptografa a conexão, mas por si só não verifica completamente o nome do host do servidor. sslmode=verify-full faz isso. Se sua aplicação se conecta através de uma rede pública, uma rede corporativa compartilhada, uma sobreposição Kubernetes que você não controla totalmente, ou qualquer ambiente onde o tráfego possa ser interceptado, verify-full deve ser o objetivo.

Entendendo SSL/TLS no PostgreSQL

SSL/TLS (Secure Sockets Layer/Transport Layer Security) é um protocolo criptográfico projetado para fornecer segurança de comunicação sobre uma rede de computadores. Quando aplicado ao PostgreSQL, ele criptografa os dados trocados entre o servidor de banco de dados e seus clientes. Isso impede que partes não autorizadas interceptem e leiam informações sensíveis como credenciais, dados financeiros ou detalhes pessoais.

Os clientes PostgreSQL suportam vários modos SSL:

  • sslmode=disable: Usa apenas uma conexão simples e não criptografada.
  • sslmode=prefer: Tenta TLS primeiro, depois volta para TCP simples se TLS não estiver disponível. Isso é conveniente, mas pode esconder má configuração.
  • sslmode=require: Exige criptografia TLS, mas não necessariamente verifica o nome do host do servidor.
  • sslmode=verify-ca: Exige TLS e verifica se o certificado encadeia até uma CA confiável.
  • sslmode=verify-full: Exige TLS, verifica a CA e verifica se o nome do host corresponde ao certificado.

No lado do servidor, ssl = on significa apenas que o PostgreSQL é capaz de aceitar conexões TLS. Isso não força todo cliente a usar TLS. A aplicação acontece no pg_hba.conf com regras hostssl e evitando regras host mais amplas que permitem que os mesmos usuários e redes se conectem sem TLS.

Pré-requisitos para Configuração SSL/TLS

Antes de começar a configurar PostgreSQL para SSL/TLS, certifique-se de ter o seguinte:

  1. OpenSSL Instalado: O kit de ferramentas OpenSSL é essencial para gerar e gerenciar certificados SSL. Geralmente está pré-instalado em sistemas Linux e macOS. Para Windows, você pode precisar baixar e instalar separadamente.
  2. Acesso aos Arquivos de Configuração do PostgreSQL: Você precisará de privilégios administrativos para modificar os arquivos postgresql.conf e pg_hba.conf.
  3. Entendimento sobre Autoridades Certificadoras (CAs): Embora você possa criar certificados autoassinados para teste, ambientes de produção devem idealmente usar certificados assinados por uma Autoridade Certificadora (CA) confiável ou uma CA empresarial interna.

Configuração SSL/TLS do Lado do Servidor

A configuração do lado do servidor envolve habilitar SSL, especificar a localização dos certificados e chaves SSL e configurar a autenticação do cliente.

1. Gerando ou Obtendo Certificados e Chaves SSL

Existem duas maneiras principais de obter certificados SSL para seu servidor PostgreSQL:

  • Certificados Autoassinados (para teste/desenvolvimento): São criados usando OpenSSL e não são confiáveis por padrão por clientes externos. São úteis para configuração inicial e testes internos.
  • Certificados de uma Autoridade Certificadora (CA) (para produção): Obtenha certificados de uma CA pública confiável (ex.: Let's Encrypt, DigiCert) ou de uma CA empresarial interna. Isso garante que os clientes possam verificar a identidade do servidor.

Criando Certificados Autoassinados usando OpenSSL:

Esta é uma abordagem comum para ambientes de desenvolvimento e internos. Execute os seguintes comandos em seu servidor PostgreSQL ou em uma máquina com OpenSSL:

  1. Crie um diretório para certificados: É uma boa prática manter os certificados organizados.

    sudo mkdir -p /etc/postgresql/ssl
    sudo chown postgres:postgres /etc/postgresql/ssl
    cd /etc/postgresql/ssl
    
  2. Gere a Chave Privada do Servidor: Esta chave deve ser mantida em segredo.

    sudo openssl genrsa -out server.key 2048
    
  3. Crie uma Solicitação de Assinatura de Certificado (CSR) do Servidor: Isso contém informações sobre seu servidor.

    sudo openssl req -new -key server.key -out server.csr
    

    Use o nome do host ao qual seus clientes se conectarão, como db01.internal.example.com. Clientes modernos normalmente verificam o Subject Alternative Name (SAN), então inclua nomes DNS na solicitação de certificado quando seu processo de CA suportar.

  4. Assine o Certificado com Sua Própria CA (para uso interno):

    • Crie uma chave privada e certificado de CA raiz (se você não tiver um):
      # Gere a chave privada da CA
      sudo openssl genrsa -des3 -out root.key 2048
      # Crie o certificado da CA (válido por 3650 dias)
      sudo openssl req -new -x509 -days 3650 -key root.key -out root.crt
      
    • Assine a CSR do servidor com a CA: Isso cria o certificado de servidor confiável.
      sudo openssl x509 -req -days 365 -in server.csr -CA root.crt -CAkey root.key -set_serial 01 -out server.crt
      
  5. Defina Permissões: Certifique-se de que o usuário PostgreSQL possa ler esses arquivos.

    sudo chown postgres:postgres server.key server.crt root.crt
    sudo chmod 600 server.key
    sudo chmod 644 server.crt root.crt
    

Usando Certificados de uma CA Pública/Empresarial:

Se você obtiver certificados de uma CA, normalmente receberá:

  • server.crt: O certificado público do seu servidor.
  • server.key: A chave privada do seu servidor.
  • root.crt (ou similar): O certificado raiz da CA (e potencialmente certificados intermediários).

Coloque esses arquivos em um diretório seguro (ex.: /etc/postgresql/ssl/) e certifique-se de que o usuário PostgreSQL tenha permissões de leitura.

2. Configurando postgresql.conf

Edite seu arquivo postgresql.conf (geralmente localizado no diretório de dados do PostgreSQL) para habilitar SSL e especificar os arquivos de certificado.

#------------------------------------------------------------------------------
# SSL
#------------------------------------------------------------------------------

ssl = on

# Estes estão todos no formato PEM e são ignorados se a chave/certificado do servidor
# não estiverem configurados. Por padrão, os arquivos são esperados no diretório de
# dados do servidor. Alternativamente, podem ser especificados como caminhos completos.
ssl_cert_file = '/etc/postgresql/ssl/server.crt'     # (altere o nome do arquivo se necessário)
ssl_key_file = '/etc/postgresql/ssl/server.key'      # (altere o nome do arquivo se necessário)
ssl_ca_file = '/etc/postgresql/ssl/root.crt'         # (opcional, para verificação de certificado do cliente)

# Opcional: especifique a lista de cifras se necessário
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'

# Opcional: habilite a verificação de certificado do cliente
#ssl_ca_file deve ser definido para um arquivo contendo o(s) certificado(s) CA para confiar
#ssl_crl_file = ''
#ssl_crl_dir = ''
  • ssl = on: Habilita o suporte SSL no servidor.
  • ssl_cert_file: Caminho para o certificado público do servidor.
  • ssl_key_file: Caminho para a chave privada do servidor.
  • ssl_ca_file: Caminho para certificados CA que o PostgreSQL deve confiar ao verificar certificados de cliente. Os clientes usam seu próprio arquivo CA, como sslrootcert, para verificar o servidor.

3. Configurando pg_hba.conf para Aplicação SSL

O arquivo pg_hba.conf controla a autenticação do cliente. Você precisa modificar as entradas para aplicar conexões SSL.

Por padrão, as entradas no pg_hba.conf se parecem com isso:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
# Conexões locais IPv4:
host    all             all             127.0.0.1/32            scram-sha-256
# Conexões locais IPv6:
host    all             all             ::1/128                 scram-sha-256

Para aplicar SSL, altere as entradas host para hostssl:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
# Conexões locais IPv4:
hostssl all             all             127.0.0.1/32            scram-sha-256
# Conexões locais IPv6:
hostssl all             all             ::1/128                 scram-sha-256

# Exemplo para acesso de rede externa - requer SSL
hostssl all             app_user        10.20.0.0/16            scram-sha-256
hostssl all             app_user        2001:db8:20::/48        scram-sha-256
  • hostssl: Este tipo de registro exige conexões SSL. Qualquer tentativa de conexão sem SSL será rejeitada.
  • hostnossl: Este tipo de registro proíbe explicitamente conexões SSL.
  • host: Permite conexões SSL e não SSL. Se uma regra host correspondente existir antes ou no lugar da sua regra hostssl, os clientes ainda podem se conectar sem TLS.

Evite publicar acesso 0.0.0.0/0 a menos que haja um motivo forte e outros controles estejam em vigor. A maioria dos bancos de dados de produção deve aceitar conexões apenas de sub-redes de aplicativos, hosts bastiões, poolers de conexão ou intervalos de rede privados.

4. Reiniciando o Servidor PostgreSQL

Após modificar postgresql.conf e pg_hba.conf, você deve reiniciar o serviço PostgreSQL para que as alterações entrem em vigor.

# Para sistemas usando systemd (a maioria das distribuições Linux modernas)
sudo systemctl restart postgresql

# Para sistemas usando init.d
sudo service postgresql restart

Configuração SSL/TLS do Lado do Cliente

Os clientes também precisam ser configurados para se conectar de forma segura. Isso envolve especificar parâmetros de conexão, potencialmente fornecer certificados de cliente e verificar o certificado do servidor.

1. Parâmetros da String de Conexão

Ao conectar via psql ou qualquer biblioteca cliente PostgreSQL, você pode especificar parâmetros SSL na string de conexão ou como opções individuais.

Conexão SSL Básica (Apenas Autenticação do Servidor):

psql "sslmode=require host=seu_host_servidor dbname=seu_banco user=seu_usuario"
  • sslmode: Controla o comportamento SSL do cliente.
    • disable: Permite apenas conexões não SSL.
    • allow: Permite não SSL, mas prefere SSL se o servidor suportar.
    • prefer (padrão): Prefere SSL, mas permite não SSL se SSL falhar.
    • require: Permite apenas conexões SSL. Se o servidor não suportar SSL, a conexão falha.
    • verify-ca: Permite apenas conexões SSL e verifica se o certificado do servidor é assinado por uma CA confiável. O parâmetro sslrootcert deve ser definido.
    • verify-full: Permite apenas conexões SSL, verifica o certificado do servidor contra uma CA confiável e verifica se o nome do host do servidor corresponde ao nome comum (CN) ou nome alternativo do assunto (SAN) do certificado.

Verificando o Certificado do Servidor (verify-ca ou verify-full):

Para segurança aprimorada, os clientes devem verificar a identidade do servidor. Isso requer que o cliente confie na CA que assinou o certificado do servidor.

  1. Obtenha o Certificado CA: Pegue o arquivo root.crt (ou o certificado CA apropriado) que foi usado para assinar o certificado do servidor.
  2. Especifique sslrootcert: Informe ao cliente onde encontrar este certificado CA.
psql "sslmode=verify-full host=seu_host_servidor dbname=seu_banco user=seu_usuario sslrootcert=/caminho/para/seu/root.crt"

Esta é a string de conexão que você deve testar a partir do mesmo host ou contêiner que executa a aplicação. Uma falha comum é que psql funciona de um laptop de administrador porque o arquivo CA existe lá, enquanto o contêiner da aplicação falha porque o pacote CA nunca foi montado.

2. Certificados de Cliente (Autenticação Mútua)

Para um nível ainda maior de segurança, você pode implementar autenticação mútua, onde o servidor também verifica a identidade do cliente usando certificados de cliente.

Gerando Certificados de Cliente:

Semelhante aos certificados de servidor, você precisará de uma chave privada de cliente e um certificado de cliente assinado por uma CA confiável pelo servidor (geralmente a mesma CA do certificado do servidor).

  1. Gere a Chave Privada do Cliente:

    openssl genrsa -des3 -out client.key 2048
    
  2. Crie a CSR do Cliente:

    openssl req -new -key client.key -out client.csr
    

    Forneça detalhes, garantindo que o Nome Comum seja único para o cliente.

  3. Assine a CSR do Cliente com a CA:

    sudo openssl x509 -req -days 365 -in client.csr -CA root.crt -CAkey root.key -set_serial <serial_unico> -out client.crt
    
  4. Defina Permissões:

    chmod 600 client.key
    chmod 644 client.crt
    

Configurando pg_hba.conf para Autenticação de Certificado de Cliente:

No servidor, você precisa configurar pg_hba.conf para aceitar autenticação de certificado de cliente. Isso geralmente usa o método de autenticação cert.

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# Exige SSL e autenticação de certificado de cliente para usuário/banco específico
hostssl all             seu_usuario     seu_ip_cliente/32       cert map=seu_mapa_cert

Você também pode precisar definir um arquivo de mapa de certificado (opção cert_map) se quiser mapear detalhes específicos do certificado do cliente (como Subject ou SubjectAltName) para usuários PostgreSQL. Consulte a documentação oficial do PostgreSQL para configuração detalhada de autenticação cert e mapeamento de certificados.

Configurando o Cliente para Usar Certificados:

Atualize a string de conexão do cliente para incluir caminhos para seu certificado e chave:

psql "sslmode=verify-full host=seu_host_servidor dbname=seu_banco user=seu_usuario \
sslrootcert=/caminho/para/seu/root.crt sslcert=/caminho/para/seu/client.crt sslkey=/caminho/para/seu/client.key"

Melhores Práticas e Dicas

  • Use sslmode=verify-full: Procure usar verify-full no lado do cliente para reduzir o risco de ataque man-in-the-middle.
  • Proteja Chaves Privadas: Certifique-se de que as chaves privadas (arquivos .key) tenham permissões de arquivo restritas (ex.: chmod 600) e sejam legíveis apenas pelo usuário PostgreSQL no servidor e pelo usuário conectado no cliente.
  • Renove Certificados Regularmente: Certificados têm datas de expiração. Implemente um processo para renová-los antes que expirem para evitar interrupções de conexão.
  • Gerenciamento Centralizado de Certificados: Para implantações maiores, considere usar um sistema de gerenciamento de certificados ou automatizar a emissão e renovação de certificados.
  • Monitore Logs: Verifique os logs do PostgreSQL para quaisquer erros relacionados a SSL durante a inicialização ou tentativas de conexão.
  • Documentação: Consulte a documentação oficial do PostgreSQL para os parâmetros mais atualizados e opções de configuração avançada específicas para sua versão do PostgreSQL.

Lista de Verificação Rápida

Após reiniciar o PostgreSQL, verifique se o servidor está ouvindo com TLS habilitado:

SHOW ssl;
SHOW ssl_cert_file;
SHOW ssl_key_file;

Em seguida, teste a partir de um host cliente:

psql "host=seu_host_servidor dbname=seu_banco user=seu_usuario sslmode=verify-full sslrootcert=/caminho/para/root.crt"

Dentro da sessão, confirme que a conexão está criptografada:

SELECT ssl, version, cipher
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();

Se ssl for falso, suas regras pg_hba.conf não estão aplicando o que você pensa. Se verify-full falhar mas require funcionar, provavelmente o certificado está faltando o nome do host correto, o cliente não confia na CA, ou a aplicação está se conectando por endereço IP enquanto o certificado foi emitido para um nome DNS.

Uma boa configuração TLS do PostgreSQL não é apenas ssl = on. É uma cadeia: um certificado com os nomes corretos, chaves privadas com permissões restritas, regras hostssl que realmente aplicam TLS e clientes que verificam o servidor em vez de apenas criptografar o soquete.