PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Przegląd parametrów połączenia libpq sslpassword w PostgreSQL 13

PostgreSQL od dawna obsługuje połączenia SSL, a także mechanizmy uwierzytelniania oparte na certyfikatach. Chociaż nic w tym względzie nie wydaje się nowe dla świata PostgreSQL. Jednak małym dokuczliwym problemem związanym z połączeniem klienta (uwierzytelnianie oparte na certyfikatach klienta) był monit „Wprowadź frazę hasła PEM:” dla zaszyfrowanego klucza klienta.

Nowa funkcja w PostgreSQL 13 uzupełnia parametr serwera 'ssl_passphrase_command'. Podczas gdy parametr ssl_passphrase_command umożliwia administratorom serwerów określenie hasła do zaszyfrowanych kluczy serwera używanych do certyfikatów serwera; nowo wprowadzony parametr połączenia „sslpassword” zapewnia nieco podobną kontrolę nad połączeniami klientów.

Spojrzenie na infrastrukturę

Aby przejść przez praktyczne ćwiczenie dotyczące tej analizy funkcji, stworzyłem dość podstawowy system:

  • Dwie maszyny wirtualne
    • pgServer (172.25.130.189) 
    • pgClient  (172.25.130.178)
  • Certyfikaty z podpisem własnym na pgServer
  • PostgreSQL 13 zainstalowany na obu komputerach 
  • gcc do kompilacji przykładowego programu libpq

Konfigurowanie serwera 

Aby przeanalizować tę funkcję, skonfigurujmy najpierw instancję serwera PostgreSQL 13 z odpowiednimi certyfikatami i odpowiednią konfiguracją na maszynie wirtualnej 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

Powyższe polecenia generują samopodpisany certyfikat przy użyciu klucza chronionego hasłem. Uprawnienia do pliku server.key są ograniczone zgodnie z wymaganiami PostgreSQL. Konfigurowanie instancji PostgreSQL do korzystania z tych certyfikatów nie jest teraz niczym magicznym. Najpierw utwórz podstawowy folder DATA za pomocą:

[[email protected]]$ initdb 

i wklej następujące parametry konfiguracyjne w wygenerowanym pliku postgresql.conf:

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'

A także upewnij się, że połączenie SSL z węzła pgClient jest akceptowane i może korzystać z mechanizmu uwierzytelniania certyfikatu, wklejając następujący wiersz w wygenerowanym pliku pg_hba.conf:

hostssl    all     all             172.25.130.178/32       cert clientcert=1

Teraz wystarczy uruchomić serwer z powyższą konfiguracją za pomocą polecenia pg_ctl:

[[email protected]]$ pg_ctl start

Konfigurowanie klienta 

Następnym krokiem byłoby wygenerowanie certyfikatów klienta, które są podpisane przez wyżej wymienione certyfikaty serwera:

[[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:

W powyższym kroku generowany jest zaszyfrowany klucz klienta i CSR dla certyfikatu klienta. Poniższe kroki uzupełniają certyfikat klienta, podpisując go przy użyciu certyfikatu głównego serwera i klucza serwera.

[[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:

Jednym ważnym aspektem do zapamiętania jest nazwa CN w certyfikatach. Potraktuj to jako bardziej identyfikację lub nazwę podmiotu. W powyższym certyfikacie klienta, jeśli CN jest ustawiony na „postgres”, jest przeznaczony dla roli o nazwie postgres. Również podczas konfigurowania certyfikatu serwera użyliśmy CN=pgServer; może to mieć znaczenie, gdy używamy trybu weryfikacji pełnej połączenia SSL.

Czas na skopiowanie certyfikatów na komputer klienta w celu wypróbowania połączenia SSL:

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

Domyślnie w środowiskach Linux/Unix, gdy psql jest używany do tworzenia połączeń SSL, wyszukuje certyfikat/klucze w „${HOME}/.postgresql” bieżącego użytkownika. Wszystkie te pliki można również określić w parametrach połączenia — jednak spowodowałoby to zachmurzenie rzeczy, którą chcemy przetestować.

Na komputerze pgClient zmień uprawnienia postgresql.key, aby upewnić się, że PostgreSQL akceptuje to samo.

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

Testowanie funkcji

Parametr połączenia PSQL 

Właściwie skończyliśmy z konfiguracją środowiska. Spróbujmy nawiązać połączenie SSL:

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

Enter PEM pass phrase:

Cóż! Wszystko zaczęło się tylko od powyższego monitu. Jeśli mamy program wsadowy lub skrypt automatyzacji, monit jest nieco trudny do obsłużenia. Dzięki nowemu dodaniu parametru „sslpassword” w ciągu połączenia można teraz łatwo to określić, jak poniżej:

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

Po tym połączenie powinno się udać, bez żadnego monitu.

Podpięcie Libpq do hasła SSL

Historia toczy się dalej – dodano funkcję przechwytującą „PQsetSSLKeyPassHook_OpenSSL” w interfejsie Libpq. Może to być używane przez aplikacje klienckie, które mogą nie mieć dostępu do hasła klucza i muszą generować/pobierać z zewnętrznego interfejsu przy użyciu złożonej logiki.

void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);

Funkcja oddzwaniania typu PQsslKeyPassHook_OpenSSL_type może zostać zarejestrowana za pomocą tego haka. Oddzwonienie zostanie wywołane przez Libpq, gdy będzie trzeba uzyskać hasło. Sygnatura takiej funkcji zwrotnej powinna wyglądać następująco:

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

Poniżej znajduje się przykładowy program „client_conn.c” - który demonstruje integrację takiego hooka:

#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;

}

Skompiluj i uruchom to samo, aby sprawdzić, czy to naprawdę działa:

[[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

Ostatnie słowo przestrogi

Powyższy blog pokazuje małą, ale użyteczną zmianę w parametrach połączenia Libpq/psql dla uwierzytelniania opartego na certyfikacie w PostgreSQL. Ale słowo ostrzeżenia - w powyższym praktycznym ćwiczeniu używaliśmy certyfikatów z podpisem własnym; może nie pasować zbyt dobrze do Twojej organizacji/środowiska produkcyjnego. Możesz chcieć uzyskać certyfikaty innych firm, aby korzystać z takiej konfiguracji SSL.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL:Wybierz rekordy, w których WSZYSTKIE połączone rekordy spełniają pewien warunek

  2. Czy PostgreSQL może mieć ograniczenie unikalności elementów tablicy?

  3. Zrzut Postgres zawierający tylko części tabel dla migawki dewelopera

  4. Jak zoptymalizować replikację logiczną PostgreSQL

  5. JPA Nazwy tabel pisane wielkimi literami