Wie aktiviere ich SSL für PostgreSQL-Verbindungen?

Standardmäßig sind alle PostgreSQL-Verbindungen unsicher, was zu Sicherheitsproblemen führen kann, wenn sie in Produktionsumgebungen mit hohem Datenverkehr eingesetzt werden. Die SSL-Verschlüsselung stellt sicher, dass die übertragenen Daten nicht von jemandem in der Mitte der Verbindung abgefangen werden.

In diesem Lernprogramm lernst du, wie du SSL/TLS für PostgreSQL-Verbindungen aktivierst.

Voraussetzungen

  • Ein Linux-Server. Für unser Tutorial verwenden wir einen Ubuntu 22.04 Server.
  • Ein sudo-Benutzer ohne Root-Rechte.
  • Ein vollständig qualifizierter Domainname (FQDN) wie postgresql.example.com.
  • Stelle sicher, dass alles auf dem neuesten Stand ist.
    $ sudo apt update
    $ sudo apt upgrade
    
  • Ein paar Pakete, die dein System braucht.
    $ sudo apt install curl nano software-properties-common apt-transport-https ca-certificates lsb-release ubuntu-keyring -y
    

    Einige dieser Pakete sind vielleicht schon auf deinem System installiert.

Schritt 1 – Firewall konfigurieren

Bevor du die Pakete installierst, musst du als erstes die Firewall so konfigurieren, dass sie die Ports für HTTP, HTTPS und PostgreSQL öffnet.

Überprüfe den Status der Firewall.

$ sudo ufw status

Du solltest etwas wie das Folgende sehen.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Öffne die HTTP-, HTTPS- und PostgreSQL-Ports in der Firewall.

$ sudo ufw allow 5432
$ sudo ufw allow http
$ sudo ufw allow https

Überprüfe den Status zur Bestätigung erneut.

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
5432                       ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
80/tcp (v6)                ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)
5432 (v6)                  ALLOW       Anywhere (v6)             

Schritt 2 – Installiere PostgreSQL 14

Ubuntu 22.04 wird standardmäßig mit PostgreSQL 14 ausgeliefert. Zur Installation gibst du den folgenden Befehl ein.

$ sudo apt install postgresql postgresql-contrib

Das Paket postgresql-contrib enthält einige zusätzliche Hilfsprogramme.

Du kannst auch das offizielle APT-Repository von PostgreSQL für die Installation verwenden. Führe den folgenden Befehl aus, um den PostgreSQL GPG-Schlüssel hinzuzufügen.

$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-key.gpg >/dev/null

Füge das APT-Repository zu deiner Quellenliste hinzu.

$ sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/postgresql-key.gpg arch=amd64] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

Aktualisiere das System-Repository.

$ sudo apt update

Jetzt kannst du PostgreSQL mit dem oben genannten Befehl installieren.

Überprüfe den Status des PostgreSQL-Dienstes.

$ sudo systemctl status postgresql
? postgresql.service - PostgreSQL RDBMS
     Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
     Active: active (exited) since Mon 2022-12-12 00:01:06 UTC; 19s ago
   Main PID: 3497 (code=exited, status=0/SUCCESS)
        CPU: 1ms

Dec 12 00:01:06 postgresql systemd[1]: Starting PostgreSQL RDBMS...
Dec 12 00:01:06 postgresql systemd[1]: Finished PostgreSQL RDBMS.

Du kannst sehen, dass der Dienst aktiviert ist und standardmäßig läuft.

Lege das Passwort für das Konto postgres fest.

$ sudo -i -u postgres psql -c "ALTER USER postgres PASSWORD '<new_password>';"

Schritt 3 – SSL installieren

Um ein SSL-Zertifikat mit Let’s Encrypt zu installieren, müssen wir das Tool Certbot herunterladen. Dazu verwenden wir den Snapd-Paketinstaller. Ubuntu 22.04 wird mit Snap vorinstalliert.

Stelle sicher, dass deine Version von Snapd auf dem neuesten Stand ist.

$ sudo snap install core 
$ sudo snap refresh core

Installiere Certbot.

$ sudo snap install --classic certbot

Stelle mit folgendem Befehl sicher, dass der Certbot-Befehl ausgeführt wird, indem du einen symbolischen Link auf das Verzeichnis /usr/bin erstellst.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Erstelle ein SSL-Zertifikat.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d postgresql.example.com

Mit dem obigen Befehl wird ein Zertifikat in das Verzeichnis /etc/letsencrypt/live/postgresql.example.com auf deinem Server heruntergeladen.

Erstelle ein Diffie-Hellman-Gruppenzertifikat.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Schritt 4 – Konfiguriere die Certbot-Erneuerung für PostgreSQL

PostgreSQL hat keine Berechtigung, auf die Zertifikate aus dem Let’s Encrypt-Ordner zuzugreifen, daher können wir ihm nicht sagen, dass er die Zertifikate aus dem Ordner direkt verwenden soll. Die Alternative ist, die Zertifikate in das PostgreSQL-Verzeichnis zu kopieren, aber das funktioniert nur vorübergehend, da sie dann ablaufen und du sie erneut manuell kopieren musst.

Die beste Methode ist die Verwendung eines Erneuerungs-Hooks, der bei jeder Erneuerung automatisch ausgeführt wird und die Kopiervorgänge durchführt.

Schaue im PostgreSQL-Datenverzeichnis nach.

$ sudo -i -u postgres psql -U postgres -c 'SHOW data_directory'

Erstelle die Datei renewal hook und öffne sie zur Bearbeitung.

$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/postgresql.sh

Füge den folgenden Code in die Datei ein.

#!/bin/bash
umask 0177
DOMAIN=postgresql.example.com
DATA_DIR=/var/lib/postgresql/15/main
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem $DATA_DIR/server.crt
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem $DATA_DIR/server.key
chown postgres:postgres $DATA_DIR/server.crt $DATA_DIR/server.key
# only for SELinux - CentOS, Red Hat
# chcon -t postgresql_db_t $DATA_DIR/server.crt $DATA_DIR/server.key

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Mache die Datei ausführbar.

$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/postgresql.sh

Schritt 5 – PostgreSQL konfigurieren

Finde den Pfad für die PostgreSQL-Konfigurationsdatei.

$ sudo -i -u postgres psql -U postgres -c 'SHOW config_file'

Öffne die Datei zur Bearbeitung.

$ sudo nano /etc/postgresql/15/main/postgresql.conf

Suche den Abschnitt Verbindungseinstellungen, entkommentiere die Variable listen_address und ändere ihren Wert in *. Stelle sicher, dass die Datei wie folgt aussieht.

listen_address = '*'		# what IP address(es) to listen on;

Suche den Abschnitt SSL und bearbeite die Datei so, dass sie die folgenden Werte enthält.

ssl = on  
ssl_cert_file = 'server.crt'  
ssl_key_file = 'server.key'  
ssl_prefer_server_ciphers = on
ssl_dh_params_file = '/etc/ssl/certs/dhparam.pem'

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Schritt 6 – PostgreSQL-Verbindung konfigurieren

Öffne die Datei /etc/postgresql/15/main/pg_hba.conf zum Bearbeiten.

$ sudo nano /etc/postgresql/15/main/pg_hba.conf

Füge die folgende Zeile hinzu, um SSL für PostgreSQL zu aktivieren.

hostssl all  all  0.0.0.0/0  scram-sha-256

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Schritt 7 – Zertifikat erneuern

Führe den folgenden Befehl aus, um eine erzwungene Erneuerung durchzuführen. Dadurch wird das Deployment-Skript ausgelöst, das die Zertifikate an den richtigen Ort kopiert, damit PostgreSQL sie verwenden kann.

$ sudo certbot renew --force-renewal

Überprüfe, ob die Zertifikate in das PostgreSQL-Datenverzeichnis kopiert wurden.

$ sudo ls /var/lib/postgresql/15/main/

Du wirst die folgende Ausgabe sehen, die dir die Zertifikate anzeigt.

base          pg_dynshmem   pg_notify    pg_snapshots  pg_subtrans  PG_VERSION  postgresql.auto.conf  server.crt
global        pg_logical    pg_replslot  pg_stat       pg_tblspc    pg_wal      postmaster.opts       server.key
pg_commit_ts  pg_multixact  pg_serial    pg_stat_tmp   pg_twophase  pg_xact     postmaster.pid

Starte PostgreSQL neu, um die Änderungen zu übernehmen.

$ sudo systemctl restart postgresql

Schritt 8 – Teste die Verbindung

Verbinde dich mit der Datenbank von einem anderen Rechner aus, auf dem der PostgreSQL-Client installiert ist.

$ psql -d "dbname=postgres sslmode=require" -h postgresql.example.com -U postgres

Du solltest die folgende PostgreSQL-Eingabeaufforderung sehen. Da wir einen Client mit PostgreSQL 14 verwenden, siehst du eine Warnung über inkompatible Versionen.

Password for user postgres:
psql (14.5 (Ubuntu 14.5-0ubuntu0.22.04.1), server 15.1 (Ubuntu 15.1-1.pgdg22.04+1))
WARNING: psql major version 14, server major version 15.
         Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=#

Dies bestätigt eine erfolgreiche SSL-Verbindung.

Beende die Shell.

postgres=# \q

Wenn deine App einen Verbindungsstring verwendet, benutze ihn im folgenden Format für eine SSL-Verbindung.

postgres://user:password@postgresql.example.com:5432/database_name?sslmode=require

Du kannst den SSL-Modus auf verify-full oder verify-ca ändern, wenn du das Root-Zertifikat für Let’s encrypt im Verzeichnis /var/lib/postgresql/.postgresql auf der Client-Seite zur Verfügung hast.

Erstelle das Verzeichnis /var/lib/postgresql/.postgresql.

$ sudo mkdir -p /var/lib/postgresql/.postgresql

Das Wurzelzertifikat für Let’s Encrypt ist ISRG Root X1, das sich auf dem Server im Verzeichnis /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt befindet.

Kopiere das Root-Zertifikat in das Verzeichnis /var/lib/postgresql/.postgresql.

$ sudo cp /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt /var/lib/postgresql/.postgresql/root.crt

Teste die Verbindung im Modus verify-full oder verify-ca und du solltest eine erfolgreiche Verbindung sehen.

Schritt 9 – Überprüfe die Clients

Melde dich in der PostgreSQL-Shell auf dem Server an.

$ sudo -i -u postgres psql

Führe den folgenden SQL-Befehl aus, um die verbundenen Clients zu überprüfen.

SELECT ssl.pid, usename, datname, ssl, ssl.version, ssl.cipher, ssl.bits, client_addr
FROM pg_catalog.pg_stat_ssl ssl, pg_catalog.pg_stat_activity activity
WHERE ssl.pid = activity.pid;

Du solltest eine ähnliche Ausgabe sehen.

 pid  | usename  | datname  | ssl | version |         cipher         | bits |  client_addr
------+----------+----------+-----+---------+------------------------+------+----------------
 5126 | postgres | postgres | t   | TLSv1.3 | TLS_AES_256_GCM_SHA384 |  256 | 122.161.84.220
 5154 | postgres | postgres | f   |         |                        |      |
(2 rows)

Dies bestätigt die Verbindung der Clients auf der Serverseite.

Fazit

Damit ist der Lehrgang zur Aktivierung von SSL für PostgreSQL-Verbindungen abgeschlossen. Wenn du noch Fragen hast, schreibe sie in die Kommentare unten.

Das könnte dich auch interessieren …