Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Datenbanken 15.06.2026 · 11 min Lesezeit

PostgreSQL nativ installieren und absichern: PGDG-APT-Repository, systemd und pg_hba.conf (Ubuntu/Debian)

PostgreSQL 18 produktionssicher aufsetzen: das offizielle PGDG-APT-Repository einbinden, systemd korrekt konfigurieren und mit pg_hba.conf, dedizierten Rollen und SSL-Erzwingung echte Produktionssicherheit herstellen – ohne Docker-Layer.

Moderne IT-Grafik zur Anleitung für die native Installation und Absicherung von PostgreSQL auf Ubuntu und Debian mit PGDG-APT-Repository, systemd-Dienst, pg_hba.conf, Terminal, Server und Dashboard.

Wer PostgreSQL auf einem Ubuntu- oder Debian-Server produktiv betreiben will, steht schnell vor der Frage: Distro-Paket oder offizielles Repository? Die Antwort ist eindeutig – das PGDG-APT-Repository von postgresql.org liefert immer die aktuelle stabile Version (Stand Juni 2026: PostgreSQL 18), während Ubuntu LTS teils ein bis zwei Hauptversionen zurückliegt. Diese Anleitung zeigt den vollständigen Weg: Repository einrichten, PostgreSQL 18 installieren, den systemd-Service verstehen und die Datenbank in drei Schichten absichern – Netzwerkbindung, Authentifizierungsregeln und Datenbankprivilegien. Der Fokus liegt auf einer nativen systemd-Installation ohne Docker-Layer, wie sie auf dedizierten Datenbankservern, VPS-Umgebungen oder KMU-internen Systemen typisch ist.

Voraussetzungen

  1. Ubuntu 22.04 LTS (Jammy) oder 24.04 LTS (Noble) bzw. Debian 12 (Bookworm) – aktuell unterstützte Versionen
  2. Root- oder sudo-Zugang auf dem Zielserver
  3. Internetzugang für den Download vom PGDG-APT-Repository (apt.postgresql.org)
  4. Dokumentation der Anwendungs-IP-Bereiche, die später in pg_hba.conf eingetragen werden
  5. Optional für SSL: ein TLS-Zertifikat und Private Key (selbst signiert mit openssl oder via Let's Encrypt)

Schritt 1: PGDG-APT-Repository einrichten

Das Paket postgresql-common enthält ein offizielles Installationsskript, das Repository-Schlüssel, APT-Quelle und PGDG-Signierschlüssel (ID: ACCC4CF8) vollautomatisch einrichtet. Das ist der empfohlene Weg – er vermeidet Tippfehler beim manuellen GPG-Import und funktioniert auf Ubuntu sowie Debian identisch:

sudo apt update
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh

Das Skript erkennt deine Distribution automatisch (z. B. noble-pgdg für Ubuntu 24.04) und legt eine passende Datei unter /etc/apt/sources.list.d/pgdg.sources an. Für alle, die den Vorgang lieber transparent nachvollziehen wollen, hier der manuelle Weg als Alternative:

sudo apt install -y curl ca-certificates
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
  --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc

Anschließend die APT-Source-Datei für Ubuntu 24.04 (Noble) anlegen:

# /etc/apt/sources.list.d/pgdg.sources
Types: deb deb-src
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: noble-pgdg
Architectures: amd64
Components: main
Signed-By: /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc

Dann PostgreSQL 18 installieren:

sudo apt update
sudo apt install -y postgresql-18

Verifizieren: Nach der Installation sollte der Dienst bereits laufen. Das prüfst du mit:

pg_lsclusters

Erwartete Ausgabe: eine Zeile mit Version 18, Cluster main, Port 5432, Status online.

Schritt 2: systemd-Service verstehen und verwalten

Auf Debian und Ubuntu heißt der systemd-Unit postgresql@18-main – die Benennung folgt dem Schema postgresql@VERSION-CLUSTER. Das vertraut klingende Tool pg_ctlcluster ist dabei nur ein Wrapper, der Root-Aufrufe an systemctl weiterleitet. Direkt mit systemctl zu arbeiten ist transparenter und passt besser in automatisierte Abläufe:

# Status prüfen:
sudo systemctl status postgresql@18-main

# Autostart beim Booten aktivieren (ist nach Installation meist schon aktiv):
sudo systemctl enable postgresql@18-main

# Starten / Stoppen:
sudo systemctl start  postgresql@18-main
sudo systemctl stop   postgresql@18-main

# Neustart (nötig nach listen_addresses-Änderung):
sudo systemctl restart postgresql@18-main

# Reload (reicht für pg_hba.conf-Änderungen):
sudo systemctl reload postgresql@18-main

Der wichtige Unterschied: reload schickt dem laufenden Prozess ein SIGHUP-Signal und liest pg_hba.conf sowie einige andere Parameter neu ein – ohne bestehende Verbindungen zu unterbrechen. Für listen_addresses-Änderungen ist dagegen immer ein vollständiger restart nötig.

Verifizieren: sudo systemctl status postgresql@18-main zeigt active (running) und den Pfad zum PGDATA-Verzeichnis.

Schritt 3: Netzwerkbindung konfigurieren (postgresql.conf)

Die Datei /etc/postgresql/18/main/postgresql.conf steuert, auf welchen Interfaces PostgreSQL lauscht. Der sichere Standard ist localhost – nur lokale Verbindungen sind möglich. Für einen dedizierten Datenbankserver, auf den Anwendungsserver aus dem internen Netz zugreifen, muss die interne IP explizit freigegeben werden:

# /etc/postgresql/18/main/postgresql.conf

# Nur localhost (Standard, sicherste Option für lokale Anwendungen):
listen_addresses = 'localhost'

# Nur eine bestimmte interne IP erlauben (empfohlen für Produktionsserver):
listen_addresses = '127.0.0.1,10.0.0.5'

# Alle Interfaces (nur wenn eine Netzwerk-Firewall davor sitzt):
listen_addresses = '*'

port = 5432

Ein häufiger Fallstrick: listen_addresses = '*' bedeutet noch keine offene Verbindung für alle – pg_hba.conf entscheidet darüber, wer sich tatsächlich verbinden darf. Trotzdem gilt: die kleinste notwendige Bindung wählen. Nach jeder Änderung an listen_addresses ist ein vollständiger Neustart nötig:

sudo systemctl restart postgresql@18-main

Verifizieren: ss -tlnp | grep 5432 zeigt, auf welchen Adressen PostgreSQL tatsächlich lauscht.

Schritt 4: pg_hba.conf – Authentifizierungsregeln

Die Datei /etc/postgresql/18/main/pg_hba.conf ist das Herzstück der PostgreSQL-Zugangskontrolle. Sie folgt einem einfachen, aber wichtigen Prinzip: die erste passende Zeile gewinnt. Restriktivere Regeln müssen deshalb immer vor offeneren stehen. Hier eine produktionssichere Grundkonfiguration:

# /etc/postgresql/18/main/pg_hba.conf
# Reihenfolge beachten: erste passende Zeile gewinnt!

# Lokaler postgres-Admin via Peer-Auth (OS-Level, kein Passwort nötig):
local   all             postgres                                peer

# Lokale Unix-Socket-Verbindungen mit scram-sha-256:
local   all             all                                     scram-sha-256

# Loopback TCP (IPv4 und IPv6):
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256

# Bestimmte Anwendungsrolle aus dem internen Netz:
host    myapp_db        app_user        10.0.0.0/24             scram-sha-256

# SSL-erzwungene Verbindungen aus externem Netz (hostssl = nur mit SSL):
hostssl all             all             0.0.0.0/0               scram-sha-256

# Alles andere explizit ablehnen:
host    all             all             0.0.0.0/0               reject

Beachte den Unterschied zwischen host und hostssl: host erlaubt TCP-Verbindungen mit und ohne SSL, hostssl erzwingt SSL und lehnt unverschlüsselte Verbindungen automatisch ab. Für interne Netze mit vertrauenswürdiger Infrastruktur ist host akzeptabel; für externe Zugriffe immer hostssl verwenden.

Die Authentifizierungsmethoden im Überblick:

MethodeSicherheitPasswort übertragenEmpfehlung
trustKeineNeinNur lokale Dev-Umgebungen
peerOS-LevelNeinLokaler Unix-Socket-Admin
scram-sha-256HochGehasht (Challenge)Produktion – empfohlen
md5NiedrigMD5-gehashtVeraltet, nicht verwenden
passwordKeineKlartextNie verwenden
certSehr hochNein (Zertifikat)Hochsicherheits-Umgebungen
rejectAbsolutExplizites Sperren

Nach dem Speichern die Konfiguration zunächst auf Syntaxfehler prüfen, dann erst laden:

# Syntaxfehler prüfen (als postgres-User):
sudo -u postgres psql -c "SELECT * FROM pg_hba_file_rules WHERE error IS NOT NULL;"

# Konfiguration ohne Neustart einlesen:
sudo systemctl reload postgresql@18-main

Die Systemview pg_hba_file_rules ist ein unterschätztes Werkzeug: Sie zeigt alle geparsten Regeln inklusive Fehlermeldungen, bevor du einen Reload durchführst.

Verbindungstypen auf einen Blick:

TypProtokollSSLTypischer Einsatz
localUnix-Domain-SocketNicht möglichAdmin-Zugriff vom gleichen Host
hostTCP/IPOptionalAnwendungen im internen Netz
hostsslTCP/IPErzwungenExterne Verbindungen, Produktion
hostnosslTCP/IPVerbotenLegacy-Clients ohne SSL

Schritt 5: SSL aktivieren

SSL schützt Verbindungsdaten vor Mitlesen – unverzichtbar, sobald PostgreSQL über ein Netzwerk erreichbar ist. Die Aktivierung erfordert zwei Stellen: postgresql.conf und den SSL-Schlüsseldateien die richtigen Berechtigungen setzen.

# /etc/postgresql/18/main/postgresql.conf
ssl = on
ssl_min_protocol_version = 'TLSv1.2'
# ssl_cert_file und ssl_key_file zeigen standardmäßig auf
# server.crt / server.key im PGDATA-Verzeichnis

Der private Schlüssel muss zwingend mit 0600 geschützt sein – andernfalls verweigert PostgreSQL den Start:

sudo chmod 0600 /etc/ssl/private/postgresql.key
sudo chown postgres:postgres /etc/ssl/private/postgresql.key

Damit SSL auch wirklich erzwungen wird (und nicht nur optional verfügbar ist), müssen in pg_hba.conf alle relevanten Einträge von host auf hostssl umgestellt werden – wie in Schritt 4 gezeigt. Ein ssl = on in postgresql.conf allein reicht nicht; ohne hostssl-Regeln sind unverschlüsselte Verbindungen weiterhin möglich.

sudo systemctl restart postgresql@18-main

Verifizieren: Nach dem Neustart zeigt sudo -u postgres psql -c "SHOW ssl;" den Wert on. Mit sudo -u postgres psql -c "SELECT ssl, version FROM pg_stat_ssl LIMIT 5;" lässt sich prüfen, ob aktive Verbindungen SSL nutzen.

Schritt 6: Rollen, Datenbank und Schema anlegen

Das Prinzip der minimalen Rechte gilt für Datenbankrollen genauso wie für Systembenutzer. Der postgres-Superuser dient ausschließlich der Administration – Anwendungen erhalten eigene Rollen mit exakt den Rechten, die sie benötigen.

Ab PostgreSQL 15 hat das public-Schema standardmäßig kein CREATE-Recht mehr für alle Nutzer. Wer von PostgreSQL 14 upgradet, muss dieses Recht manuell entziehen. Die folgende Einrichtung gilt für eine frische PG-18-Installation und schafft von Anfang an saubere Schema-Isolation:

sudo -u postgres psql <<'SQL'
-- Anwendungsrolle ohne Superuser-Rechte:
CREATE ROLE app_user
  LOGIN
  PASSWORD 'sicheres_passwort_hier_ersetzen'
  CONNECTION LIMIT 20
  NOCREATEDB
  NOSUPERUSER;

-- Datenbank anlegen:
CREATE DATABASE myapp_db OWNER app_user;

-- Schema-Isolation einrichten:
\c myapp_db
CREATE SCHEMA app AUTHORIZATION app_user;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL   ON SCHEMA public FROM PUBLIC;
GRANT USAGE  ON SCHEMA app TO app_user;
GRANT CREATE ON SCHEMA app TO app_user;

-- search_path für die Rolle setzen (bevorzugt app-Schema):
ALTER ROLE app_user SET search_path TO app, public;
SQL

Warum CONNECTION LIMIT 20? Diese Einschränkung schützt vor unbeabsichtigter Ressourcenerschöpfung, etwa durch einen Verbindungsleck in der Anwendung. Der Standardwert -1 (unbegrenzt) ist für Produktionsrollen ungeeignet.

Das Passwort des postgres-Admins solltest du ebenfalls setzen, selbst wenn Peer-Auth lokale Anmeldungen ohne Passwort ermöglicht – für den Fall einer zukünftigen TCP-Konfiguration:

sudo -u postgres psql -c "\password postgres"

Verifizieren: Mit sudo -u postgres psql -c "\du" siehst du alle Rollen und ihre Attribute. app_user sollte keine Superuser-Flags zeigen.

Schritt 7: Firewall mit ufw absichern

Eine korrekt konfigurierte pg_hba.conf ist kein Ersatz für eine Host-Firewall. Beide Ebenen ergänzen sich: listen_addresses und pg_hba.conf kontrollieren, wer sich verbinden darf; ufw verhindert, dass TCP-Verbindungen auf Port 5432 überhaupt den PostgreSQL-Prozess erreichen.

# PostgreSQL-Port nur aus dem internen Netz erlauben:
sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp

# Alle anderen Verbindungen auf Port 5432 ablehnen:
sudo ufw deny 5432

# Status prüfen:
sudo ufw status verbose

Die Reihenfolge der ufw-Regeln entspricht dem gleichen Prinzip wie pg_hba.conf: spezifischere Regeln (Allow für internes Netz) müssen vor allgemeinen stehen (Deny für alle). Da ufw Regeln nach Einfügereihenfolge auswertet, zuerst die Allow-Regel, dann die Deny-Regel hinzufügen.

Verifizieren: Von einem Rechner außerhalb des erlaubten IP-Bereichs: nc -zv <server-ip> 5432 sollte mit „Connection refused" oder Timeout scheitern. Aus dem erlaubten Netz sollte der Verbindungsversuch ankommen (ggf. mit Authentifizierungsfehler, was korrekt ist).

Troubleshooting / Typische Fehler

PostgreSQL startet nicht nach SSL-Aktivierung

Der häufigste Grund: der Private Key hat zu offene Berechtigungen. PostgreSQL verweigert den Start, wenn server.key (oder der konfigurierte Schlüsselpfad) für andere Benutzer lesbar ist. Prüfen und korrigieren:

ls -la /etc/postgresql/18/main/server.key
# Muss -rw------- (0600) mit Owner postgres:postgres sein
sudo chmod 0600 /etc/postgresql/18/main/server.key
sudo chown postgres:postgres /etc/postgresql/18/main/server.key
sudo systemctl start postgresql@18-main

pg_hba.conf-Änderungen ohne Wirkung

Änderungen an pg_hba.conf werden erst nach einem Reload wirksam. Viele vergessen diesen Schritt:

sudo systemctl reload postgresql@18-main
# Alternativ aus psql:
sudo -u postgres psql -c "SELECT pg_reload_conf();"

listen_addresses-Änderung hat keine Wirkung trotz reload

listen_addresses gehört zu den Parametern, die einen vollständigen Neustart erfordern – reload reicht hier nicht. Ein sudo systemctl restart postgresql@18-main ist nötig. Der Hinweis findet sich auch in der postgresql.conf selbst (Kommentar # (change requires restart)).

Verbindung schlägt mit „FATAL: password authentication failed" fehl

Mögliche Ursachen: (1) Der Client verwendet noch md5, aber pg_hba.conf verlangt scram-sha-256 – Client-Library aktualisieren. (2) Das Passwort wurde mit md5-Hashing gespeichert, bevor auf scram-sha-256 umgestellt wurde – Passwort neu setzen mit \password rollenname in psql.

Syntaxfehler in pg_hba.conf finden

sudo -u postgres psql -c \
  "SELECT line_number, type, address, error FROM pg_hba_file_rules WHERE error IS NOT NULL;"

Distro-Paket statt PGDG installiert

Wenn psql --version eine ältere Version als 18 zeigt, ist wahrscheinlich das Ubuntu-eigene Paket installiert. Das lässt sich prüfen mit apt-cache policy postgresql – der Candidate sollte von apt.postgresql.org kommen, nicht von archive.ubuntu.com.

Häufige Fragen

Was bringt das PGDG-Repository gegenüber dem Ubuntu-Paket?

Das PGDG-Repository von postgresql.org liefert immer die aktuelle stabile Version – Stand Juni 2026 ist das PostgreSQL 18. Ubuntu LTS liegt typischerweise ein bis zwei Hauptversionen zurück (Ubuntu 22.04 enthält PG 14, Ubuntu 24.04 PG 16). Darüber hinaus sind Minor-Updates zeitnah verfügbar, und mehrere PostgreSQL-Versionen können parallel installiert sein. pg_lsclusters zeigt alle aktiven Cluster auf einen Blick.

Wie lese ich pg_hba.conf neu ein, ohne PostgreSQL zu stoppen?

Mit sudo systemctl reload postgresql@18-main oder innerhalb einer psql-Session mit SELECT pg_reload_conf();. Wichtig: Das funktioniert nur für Parameter wie pg_hba.conf-Regeln, log_level und ähnliches. Für listen_addresses ist ein vollständiger Neustart unumgänglich.

Kann ich PostgreSQL 17 und 18 gleichzeitig betreiben?

Ja. Das PGDG-Repository unterstützt parallele Installationen. postgresql-17 und postgresql-18 bekommen automatisch unterschiedliche Ports zugewiesen. pg_lsclusters zeigt alle Cluster mit Version, Port und Status.

Was hat sich am public-Schema ab PostgreSQL 15 geändert?

Ab PG 15 hat die spezielle Rolle PUBLIC kein CREATE-Recht mehr auf dem public-Schema – das ist der sichere Standard und entspricht dem, was vorher manuell gesetzt werden musste. Bei einem Upgrade von PG 14 erhält der bestehende Cluster diese Änderung nicht automatisch: REVOKE CREATE ON SCHEMA public FROM PUBLIC; muss manuell nachgezogen werden. Ohne diesen Schritt können alle Datenbankbenutzer Objekte im public-Schema anlegen – ein reales Risiko für Privilege-Escalation über Funktionssubstitution.

Wie erzwinge ich ausschließlich SSL-Verbindungen?

Zwei Stellen müssen übereinstimmen: ssl = on in postgresql.conf aktiviert SSL grundsätzlich. Alle TCP-Einträge in pg_hba.conf müssen von host auf hostssl umgestellt werden. Dann werden Nicht-SSL-Verbindungen automatisch abgelehnt, auch wenn der Client sie versucht.

Was ist der Unterschied zwischen GRANT USAGE und GRANT CREATE auf einem Schema?

GRANT USAGE ON SCHEMA app erlaubt dem Benutzer, Objekte im Schema zu referenzieren (also zu lesen und abzufragen). GRANT CREATE ON SCHEMA app erlaubt zusätzlich das Anlegen neuer Tabellen, Funktionen und anderer Objekte. Für eine reine Lese-Anwendungsrolle reicht USAGE; Schreib-Rollen brauchen beide.

Fazit

Eine produktionssichere PostgreSQL-Installation ist kein einmaliger Schritt, sondern eine Kombination aus mehreren aufeinander abgestimmten Maßnahmen. Das PGDG-APT-Repository stellt sicher, dass du immer auf aktuellem Stand bist – ohne auf Distro-Backports warten zu müssen. Die Absicherung in drei Schichten (Netzwerkbindung, Authentifizierungsregeln, Datenbankprivilegien) gibt dir fein abgestimmte Kontrolle: listen_addresses begrenzt, wer überhaupt TCP-Pakete senden kann; pg_hba.conf entscheidet, wer sich verbinden darf und wie; dedizierte Rollen mit minimalen Rechten begrenzen den Schaden im Fall eines kompromittierten Anwendungskontos. Ergänzt durch eine ufw-Firewall und SSL-Erzwingung entsteht ein Sicherheitsmodell mit echter Tiefe – praxistauglich für KMU-Server, VPS-Instanzen und interne Infrastruktur gleichermaßen. Wer den nächsten Schritt gehen will, findet in der PostgreSQL-Performance-Tuning-Anleitung sowie der Backup-Automatisierung sinnvolle Ergänzungen.

Weiterführende Anleitungen und Quellen

  1. PostgreSQL pg_dump und pg_restore: Anleitung für Backup und Migration per Kommandozeile
  2. MySQL & PostgreSQL Backup automatisieren mit cron: mysqldump, pg_dump, Rotation und rclone-Cloud-Sync
  3. PostgreSQL-Performance-Tuning für Einsteiger
  4. PostgreSQL Streaming Replication nativ einrichten (ohne Docker)
  5. VPS absichern und härten: Anleitung mit UFW, SSH-Keys und Fail2Ban
  6. PostgreSQL: Linux Downloads (Ubuntu) – offizielle PGDG-Repository-Anleitung
  7. PostgreSQL Docs: The pg_hba.conf File (Kap. 20.1)
  8. PostgreSQL Docs: Role Attributes (Kap. 21.2)
  9. PostgreSQL Docs: SSL Support (Kap. 19.9)