18.9. Conexões TCP/IP seguras com SSL #

18.9.1. Configuração básica
18.9.2. Configuração do OpenSSL
18.9.3. Uso de certificados de cliente
18.9.4. Arquivos de SSL usados no servidor
18.9.5. Criação de certificados

O PostgreSQL possui suporte nativo para conexões SSL, encriptando assim as comunicações cliente/servidor para aumentar a segurança. Este suporte requer que o OpenSSL esteja instalado nos sistemas cliente e servidor, e seja escolhida esta opção [111] no momento da construção do PostgreSQL (veja Instalação a partir do código-fonte).

Os termos SSL e TLS são frequentemente usados ​​de forma intercambiável para designar uma conexão segura e encriptada que utiliza o protocolo TLS. Os protocolos SSL são os precursores dos protocolos TLS, e o termo SSL ainda é utilizado para conexões encriptadas, embora os protocolos SSL não tenham mais suporte. O SSL é usado de forma intercambiável com o TLS no PostgreSQL.

18.9.1. Configuração básica #

Havendo suporte ao SSL compilado, o servidor PostgreSQL pode ser iniciado com suporte a conexões encriptadas usando protocolos TLS ativos definindo o parâmetro ssl como on no arquivo postgresql.conf. O servidor escuta as conexões normais e SSL na mesma porta TCP, e negocia com qualquer cliente conectando se deve usar o SSL. Por padrão, isto fica a critério do cliente; veja pg_hba.conf como configurar o servidor para exigir o uso de SSL para algumas ou todas as conexões.

Para iniciar no modo SSL, os arquivos contendo o certificado do servidor e a chave privada devem existir. Por padrão, espera-se que estes arquivos tenham os nomes server.crt e server.key, respectivamente, e que estejam no diretório de dados do servidor, mas outros nomes e locais podem ser especificados usando os parâmetros de configuração ssl_cert_file e ssl_key_file.

Nos sistemas Unix, as permissões para o arquivo server.key devem impedir o acesso para todos e para grupo; isto é feito com o comando chmod 0600 server.key. Como alternativa, o arquivo pode pertencer ao usuário root, e ter acesso de leitura para grupo (ou seja, permissões 0640). Esta configuração destina-se a instalações em que os arquivos de certificados e chaves são gerenciados pelo sistema operacional. O usuário sob o qual o servidor PostgreSQL executa deve, então, se tornar membro do grupo com acesso a estes arquivos de certificados e chaves.

Se o diretório de dados permitir acesso de leitura para grupo, os arquivos de certificado devem ser colocados fora do diretório de dados para atender aos requisitos de segurança descritos acima. Geralmente, é permitido o acesso de leitura para grupo no diretório de dados, para que um usuário sem privilégios possa fazer backup do banco de dados; neste caso, o programa de backup não poderá ler os arquivos de certificado e, provavelmente, ocorrerá um erro.

Se a chave privada estiver protegida por senha, o servidor solicitará a senha e não iniciará até que a senha seja inserida. Por padrão, o uso de senha desativa a capacidade de alterar a configuração do SSL do servidor sem o reiniciar, mas veja ssl_passphrase_command_supports_reload. Além disso, as chaves privadas protegidas por senha não podem ser usadas no Windows.

O primeiro certificado em server.crt deve ser o certificado do servidor, porque deve corresponder à chave privada do servidor. Também podem ser adicionados ao arquivo os certificados de autoridades de certificação intermediárias, evitando a necessidade de registrar os certificados intermediários do cliente, assumindo que o certificado raiz e os certificados intermediários foram criados com extensões v3_ca. (definindo a restrição básica do certificado CA como true [112] [113].) Isto permite a expiração mais fácil de certificados intermediários.

Não é necessário adicionar o certificado raiz ao arquivo server.crt. Em vez disso, os clientes devem ter o certificado raiz da cadeia de certificados do servidor.

18.9.2. Configuração do OpenSSL #

PostgreSQL lê o arquivo de configuração do OpenSSL para todo o sistema. Por padrão, este arquivo se chama openssl.cnf, e está localizado no diretório mostrado pelo comando openssl version -d Este padrão pode ser mudado configurando a variável de ambiente OPENSSL_CONF para o nome do arquivo de configuração desejado.

O OpenSSL oferece suporte a uma ampla variedade de cifras e algoritmos de autenticação, de força variável. Embora possa ser especificada uma lista de cifras no arquivo de configuração do OpenSSL, podem ser especificadas cifras especificamente para uso pelo servidor de banco de dados modificando ssl_ciphers no arquivo postgresql.conf.

Nota

É possível ter autenticação sem sobrecarga de encriptação usando as cifras NULL-SHA ou NULL-MD5. No entanto, um man in the middle pode ler e passar as comunicações entre o cliente e o servidor. Além disso, a sobrecarga de encriptação é mínima comparada com a sobrecarga de autenticação. Por estes motivos, as cifras NULL não são recomendadas.

18.9.3. Uso de certificados de cliente #

Para exigir que o cliente forneça um certificado confiável, devem ser colocados os certificados das autoridades de certificação raiz (CAs) em um arquivo no diretório de dados, definido o parâmetro ssl_ca_file no arquivo postgresql.conf com o novo nome do arquivo, e adicionada a opção de autenticação clientcert=verify-ca ou clientcert=verify-full para a(s) linha(s) hostssl apropriada(s) no arquivo pg_hba.conf. Será solicitado ao cliente o certificado durante a inicialização da conexão SSL. (Veja SSL Support para obter a descrição sobre como configurar certificados no cliente.)

Para uma entrada hostssl com clientcert=verify-ca, o servidor verifica se o certificado do cliente está assinado por uma das autoridades de certificação confiáveis. Se for especificado clientcert=verify-full, o servidor não apenas verifica a cadeia de certificados, mas também verifica se o nome de usuário ou seu mapeamento corresponde ao cn (Nome Comum) do certificado fornecido. Note que a validação da cadeia de certificados é sempre garantida quando o método de autenticação cert é usado (veja Autenticação por certificado).

Os certificados intermediários, que se encadeiam a certificados raiz existentes, também podem aparecer no arquivo ssl_ca_file, se for desejado evitar armazená-los nos clientes (assumindo que os certificados raiz e intermediário foram criados com extensões v3_ca). As entradas da Lista de Certificados Revogados (CRL) também serão verificadas, se o parâmetro ssl_crl_file, ou ssl_crl_dir, estiver definido.

A opção de autenticação clientcert está disponível para todos os métodos de autenticação, mas apenas nas linhas pg_hba.conf especificadas como hostssl. Quando clientcert não está especificado, o servidor verifica o certificado do cliente em seu arquivo CA somente se um certificado do cliente for apresentado e o CA estiver configurado.

Existem duas abordagens para garantir que os usuários forneçam um certificado durante o login.

A primeira abordagem usa o método de autenticação cert para entradas hostssl no arquivo pg_hba.conf, de forma que o próprio certificado seja usado para autenticação enquanto também fornecendo segurança para a conexão SSL. Veja Autenticação por certificado para obter detalhes. (Não é necessário especificar nenhuma opção clientcert explicitamente, ao usar o método de autenticação cert.) Neste caso, o cn (Nome comum) fornecido no certificado é verificado em relação ao nome de usuário, ou a um mapeamento aplicável.

A segunda abordagem combina qualquer método de autenticação para entradas hostssl com a verificação de certificados de cliente configurando a opção de autenticação clientcert para verify-ca, ou verify-full. A primeira opção apenas reforça que o certificado está válido, enquanto a última também garante que o cn (Nome comum) no certificado corresponde ao nome de usuário, ou a um mapeamento aplicável.

18.9.4. Arquivos de SSL usados no servidor #

A Tabela 18.2 resume os arquivos relevantes para a configuração do SSL no servidor. (Os nomes de arquivo mostrados são os nomes padrão. Os nomes configurados localmente podem ser diferentes.)

Tabela 18.2. Arquivos de SSL usados no servidor

ArquivoConteúdoEfeito
ssl_cert_file ($PGDATA/server.crt)certificado do servidorenviado ao cliente para indicar a identidade do servidor
ssl_key_file ($PGDATA/server.key)chave privada do servidorcomprova que o certificado do servidor foi enviado pelo dono; não indica que o dono do certificado é confiável
ssl_ca_fileautoridades de certificação confiáveisverifica se o certificado do cliente é assinado por uma autoridade de certificação confiável
ssl_crl_filecertificados revogados por autoridades de certificaçãoo certificado do cliente não deve estar nesta lista

O servidor lê estes arquivos quando é ativado, e sempre que a configuração do servidor for recarregada. Nos sistemas Windows, também são relidos sempre que um novo processo servidor é gerado para uma nova conexão de cliente.

Se for detectado um erro nesses arquivos na ativação do servidor, o servidor se recusará a iniciar. Mas se o erro for detectado durante a recarga da configuração, os arquivos serão ignorados, e a configuração SSL antiga continuará sendo usada. Nos sistemas Windows, se for detectado um erro nesses arquivos na ativação do processo servidor, este processo servidor não vai conseguir estabelecer uma conexão SSL. Em todos estes casos, a condição de erro é registrada no log do servidor.

18.9.5. Criação de certificados #

Para criar um certificado autoassinado [114] simples para o servidor, válido por 365 dias, pode ser usado o seguinte comando do OpenSSL, substituindo dbhost.yourdomain.com pelo nome do hospedeiro do servidor:

openssl req -new -x509 -days 365 -nodes -text -out server.crt \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"

E depois executado

chmod og-rwx server.key

porque senão o servidor irá rejeitar o arquivo se suas permissões forem mais liberais do que isto. Para obter mais detalhes sobre como criar a chave privada e o certificado do servidor, consulte a Documentação do OpenSSL.

Embora possa ser usado para teste um certificado autoassinado, deve ser usado na produção um certificado assinado por uma autoridade de certificação(CA) (geralmente uma CA raiz para toda toda a empresa).

Para criar um certificado de servidor cuja identidade possa ser validada pelos clientes, primeiro deve ser criada uma solicitação de assinatura de certificado (CSR), e um arquivo de chave pública/privada [115] [116]:

openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key

Em seguida, a requisição deverá ser assinada com a chave para criar uma autoridade de certificação raiz (usando o local padrão do arquivo de configuração do OpenSSL no Linux):

openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

Por fim, deve ser criado um certificado de servidor assinado pela nova autoridade de certificação raiz:

openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key

openssl x509 -req -in server.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out server.crt

Os arquivos server.crt e server.key devem ser armazenados no servidor, e o arquivo root.crt deve ser armazenado no cliente para que o cliente possa verificar se o certificado folha do servidor foi assinado por seu certificado raiz confiável. O arquivo root.key deve ser armazenado off-line para uso na criação de futuros certificados.

Também é possível criar uma cadeia de confiança incluindo certificados intermediários:

# raiz
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

# intermediário
openssl req -new -nodes -text -out intermediate.csr \
  -keyout intermediate.key -subj "/CN=intermediate.yourdomain.com"
chmod og-rwx intermediate.key
openssl x509 -req -in intermediate.csr -text -days 1825 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out intermediate.crt

# folha
openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
  -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
  -out server.crt

Os arquivos server.crt e intermediate.crt devem ser concatenados em um pacote de arquivos de certificado e armazenados no servidor. O arquivo server.key também deve ser armazenado no servidor. O arquivo root.crt deve ser armazenado no cliente, para que o cliente possa verificar se o certificado folha do servidor foi assinado por uma cadeia de certificados vinculados ao seu certificado raiz confiável. Os arquivos root.key e intermediate.key devem ser armazenados off-line para uso na criação de futuros certificados.

Exemplo 18.1. Exemplo do tradutor

Conexão TCP/IP segura com SSL

Neste exemplo é criado um certificado autoassinado para o servidor PostgreSQL executando no sistema operacional Debian 12, e editado os arquivos postgresql.conf e pg_hba.conf para permitir a conexão encriptada.

$ sudo su - postgres
$ export PGDATA="/var/lib/postgresql/18/main"
$ openssl req -new -x509 -days 365 -noenc -text -out server.crt \
  -keyout server.key -subj "/CN=debian"
$ openssl req -new -noenc -text -out root.csr \
  -keyout root.key -subj "/CN=debian"
$ chmod og-rwx root.key
$ openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt
Certificate request self-signature ok
subject=CN = debian
$ openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=debian"
$ chmod og-rwx server.key
$ openssl x509 -req -in server.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out server.crt
Certificate request self-signature ok
subject=CN = debian
$ ls -lt | head
total 540
-rw-r--r--  1 postgres postgres   3352 jun 25 09:27 server.csr
-rw-------  1 postgres postgres   1704 jun 25 09:27 server.key
-rw-r--r--  1 postgres postgres   4122 jun 25 09:26 root.crt
-rw-r--r--  1 postgres postgres   3352 jun 25 09:23 root.csr
-rw-------  1 postgres postgres   1704 jun 25 09:23 root.key
-rw-r--r--  1 postgres postgres   4122 jun 25 09:20 server.crt
$ cp server.crt $PGDATA
$ cp server.key $PGDATA
$ sudo cp root.crt /etc/ssl/certs/
$ nano /etc/postgresql/18/main/postgresql.conf
# - Connection Settings -
listen_addresses = '*'
# - SSL
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
$ nano /etc/postgresql/18/main/pg_hba.conf
# SSL
hostssl   all       all         0.0.0.0/0       scram-sha-256
hostssl   all       all         ::/0            scram-sha-256
$ sudo systemctl restart postgresql
$ psql -h 192.168.3.5 -U ana
Senha para o usuário ana:
psql (18.4 (Debian 18.4-1.pgdg12+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, ↵
                compression: desativado, ALPN: postgresql)
Digite "help" para obter ajuda.

ana=>




[111] Opção --with-ssl=openssl (N. T.)

[112] Uma Autoridade Certificadora (CA) é uma entidade administrativa central de confiança que pode emitir certificados digitais para usuários e servidores. Certificate Authority — IBM (N. T.)

[113] Podemos pensar no caminho entre as Autoridades de Certificação de Raiz e o Cliente como uma ramificação, já que existem as Autoridades de Certificação de Raiz, que emitem os certificados para as Autoridades de Certificação Intermediárias, se existirem, até ao Cliente (ou utilizador final) que aplica o certificado. Autoridade de certificação — Wikipédia (N. T.)

[114] É possível usar os certificados autoassinados para testar uma configuração de SSL antes de criar e instalar um certificado assinado fornecido por uma autoridade de certificação. Certificados Autoassinados — IBM (N. T.)

[115] Este comando cria e processa principalmente solicitações de certificado (CSRs) no formato PKCS#10. Além disso, pode criar certificados autoassinados para uso como CAs raiz. -text mostra a solicitação de certificado no formato de texto; -nodes esta opção está obsoleta desde o OpenSSL 3.0; deve ser usado -noenc em seu lugar. -subj arg define o nome do assunto para uma nova solicitação ou substitui o nome do assunto ao processar uma solicitação de certificado openssl-req - PKCS#10 certificate request and certificate generating command (N. T.)

[116] openssl é o comando para executar o OpenSSL; req é o utilitário do OpenSSL para gerar uma CSR; -out root.csr especifica onde salvar o arquivo CSR; -keyout root.key especifica onde salvar o arquivo de chave privada. Manually Generate a Certificate Signing Request (CSR) Using OpenSSL (N. T.)