PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Uma visão geral dos parâmetros de conexão do PostgreSQL 13 libpq sslpassword

O PostgreSQL há muito tempo suporta conexões SSL e também mecanismos de autenticação baseados em certificados. Embora nada nesse sentido pareça ser novo para o mundo PostgreSQL. No entanto, um pequeno problema irritante para a conexão do cliente (autenticação baseada em certificados do cliente) era um prompt "Digite a frase secreta do PEM:" para a chave do cliente criptografada.

Um novo recurso no PostgreSQL 13 complementa o parâmetro de servidor 'ssl_passphrase_command'. Enquanto o parâmetro ssl_passphrase_command permite que os administradores do servidor especifiquem uma senha para chaves de servidor criptografadas usadas para certificados de servidor; o parâmetro de conexão recém-introduzido 'sslpassword' fornece um controle semelhante para conexões de clientes.

Um olhar sobre a infraestrutura 

Para fazer um exercício prático para esta análise de recursos, estabeleci um sistema bastante básico:

  • Duas máquinas virtuais
    • pgServer ( 172.25.130.189 ) 
    • pgClient  ( 172.25.130.178 )
  • Certificados autoassinados no pgServer
  • PostgreSQL 13 instalado em ambas as máquinas 
  • gcc para compilar um programa libpq de amostra

Configurando o servidor 

Para analisar o recurso, vamos primeiro configurar uma instância do servidor PostgreSQL 13 com os certificados relevantes e a respectiva configuração na máquina virtual pgServer.

[[email protected]]$ echo ${HOME}

/var/lib/pgsql/

[[email protected]]$ mkdir ~/server_certs/ 

[[email protected]]$ openssl genrsa -des3 -passout pass:secretserverpass -out ~/server_certs/server.key

[[email protected]]$ openssl req -new -key ~/server_certs/server.key -days 365 -out ~/server_certs/server.crt -x509 -subj "/C=AU/ST=NSW/L=DY/O=MyOrg/OU=Dev/CN=pgServer"

Enter pass phrase for /var/lib/pgsql/server_certs/server.key:

[[email protected]]$ chmod 0600 /var/lib/pgsql/server_certs/server.key

[[email protected]]$ cp ~/server_certs/server.crt ~/server_certs/root.crt

Os comandos acima estão gerando um certificado autoassinado usando uma chave que é protegida por uma senha. As permissões do server.key são restritas conforme exigido pelo PostgreSQL. Configurar a instância do PostgreSQL para usar esses certificados não é mágica agora. Primeiro crie uma pasta DATA base usando:

[[email protected]]$ initdb 

e cole os seguintes parâmetros de configuração no postgresql.conf gerado:

ssl=on

ssl_cert_file='/var/lib/pgsql/server_certs/server.crt'

ssl_key_file='/var/lib/pgsql/server_certs/server.key'

ssl_ca_file='/var/lib/pgsql/server_certs/root.crt'

ssl_passphrase_command = 'echo secretserverpass'

listen_addresses = '172.25.130.189'

E também certifique-se de que uma conexão SSL do nó pgClient seja aceita e possa usar o mecanismo de autenticação de certificado colando a seguinte linha no pg_hba.conf gerado:

hostssl    all     all             172.25.130.178/32       cert clientcert=1

Tudo o que é necessário agora é iniciar o servidor com a configuração acima usando o comando pg_ctl:

[[email protected]]$ pg_ctl start

Configurando o cliente 

O próximo passo seria gerar certificados de cliente que são assinados pelos certificados de servidor acima mencionados:

[[email protected]]$ mkdir ~/client_certs/

[[email protected]]$ openssl genrsa -des3 -passout pass:secretclientpass -out ~/client_certs/postgresql.key

[[email protected]]$ openssl req -new -key ~/client_certs/postgresql.key -out ~/client_certs/postgresql.csr -subj "/C=AU/ST=NSW/L=DY/O=MyOrg/OU=Dev/CN=postgres"

Enter pass phrase for ~/client_certs/postgresql.key:

Na etapa acima, uma chave de cliente criptografada e um CSR para o certificado de cliente são gerados. As etapas a seguir completam um certificado de cliente assinando-o usando o certificado raiz do servidor e a chave do servidor.

[[email protected]]$ openssl x509 -req -in ~/client_certs/postgresql.csr -CA ~/server_certs/root.crt -CAkey ~/server_certs/server.key -out ~/client_certs/postgresql.crt -CAcreateserial

Signature ok

subject=/C=AU/ST=NSW/L=DY/O=MyOrg/OU=Dev/CN=postgres

Getting CA Private Key

Enter pass phrase for /var/lib/pgsql/server_certs/server.key:

Um aspecto importante a ser lembrado é o nome do CN nos certificados. Considere-o mais como uma identificação ou nome da entidade. No certificado de cliente acima, se o CN estiver definido como 'postgres', ele é destinado a uma função chamada postgres. Além disso, ao configurar o certificado do servidor, usamos CN=pgServer; pode ser importante quando usamos um modo de verificação completa da conexão SSL.

Hora de copiar os certificados para a máquina cliente para experimentar a conexão SSL:

[[email protected]]$ scp -r client_certs/* [email protected]:~/.postgresql

Por padrão em ambientes Linux/Unix, quando o psql é usado para fazer conexões SSL, ele procura certificados/chaves em ‘${HOME}/.postgresql’ do usuário atual. Todos esses arquivos também podem ser especificados nos parâmetros de conexão - No entanto, isso teria obscurecido o que queremos testar.

Na máquina pgClient, altere a permissão do postgresql.key para garantir que o PostgreSQL aceite o mesmo.

[[email protected]]$ chmod 0600 ~/.postgresql/postgresql.key

Testando o recurso 

Parâmetro de conexão PSQL 

Estamos praticamente prontos com a configuração do ambiente. Vamos tentar fazer uma conexão SSL:

[[email protected]]$ psql "host=172.25.130.189 port=5432 user=postgres dbname=postgres sslmode=prefer"

Enter PEM pass phrase:

Bem! Tudo começou apenas com o prompt acima. Se tivermos um programa em lote ou um script de automação, o prompt será um pouco complicado de manusear. Com a nova adição do parâmetro 'sslpassword' na string de conexão, agora é fácil especificá-lo conforme abaixo:

[[email protected]]$ psql "host=172.25.130.189 port=5432 user=postgres dbname=postgres sslmode=prefer sslpassword=secretclientpass"

A conexão deve ser bem-sucedida depois disso, sem nenhum prompt.

Libpq Hook para senha SSL

A história continua - há adição de uma função de gancho 'PQsetSSLKeyPassHook_OpenSSL' na interface Libpq. Isso pode ser usado por aplicativos cliente que podem não ter acesso à senha da chave e precisam gerar/buscar de uma interface externa usando alguma lógica complexa.

void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);

Uma função de retorno de chamada do tipo PQsslKeyPassHook_OpenSSL_type pode ser registrada usando este gancho. O retorno de chamada será invocado pelo Libpq quando precisar obter uma senha. A assinatura de tal função de retorno de chamada deve ser:

int my_callback_function(char *buf, int size, PGconn *conn);

Abaixo está um exemplo de programa 'client_conn.c' - que demonstra a integração de tal gancho:

#include <stdlib.h>

#include <string.h>

#include "libpq-fe.h"

void do_exit(PGconn *conn) {

    PQfinish(conn);

    exit(1);

}

/**

 * For PQsetSSLKeyPassHook_OpenSSL to provide password for SSL Key

 **/

int ssl_password_provider(char *buf, int size, PGconn *conn)

{    

    const char * default_key_password = "secretclientpass";

    strcpy(buf, default_key_password);

    return strlen(default_key_password);

}

/**

 * Sample program to make a connection and check server version

 */

int main() 

{

    PQsetSSLKeyPassHook_OpenSSL( ssl_password_provider );

    PGconn *conn = PQconnectdb("host=172.25.130.189 port=5413 user=postgres dbname=postgres sslmode=prefer");

    if (PQstatus(conn) == CONNECTION_BAD) 

    {

        fprintf(stderr, "Connection to DB failed: %s\n", PQerrorMessage(conn));

        do_exit(conn);

    }

    printf("Server version: %d\n", PQserverVersion(conn));

    PQfinish(conn);

    return 0;

}

Compile e execute o mesmo para verificar se realmente funciona:

[[email protected]]$ gcc -DUSE_OPENSSL  -I/usr/pgsql-13/include/ -lpq -L/usr/pgsql-13/lib/ client_conn.c -o client_conn

[[email protected]]$ client_conn

[[email protected]]$ ./client_conn

Server version: 130000

Uma palavra final de cautela


O blog acima mostra uma pequena mas útil mudança nos parâmetros de conexão Libpq/psql para autenticação baseada em certificado no PostgreSQL. Mas, uma palavra de cautela - no exercício prático acima, usamos certificados autoassinados; pode não se encaixar muito bem em sua organização/ambiente de produção. Você pode tentar obter alguns certificados de terceiros para usar essa configuração de SSL.