So schützen Sie PostgreSQL vor automatisierten Angriffen

Einführung

Es kann verlockend sein, darüber nachzudenken, dass ein Server erst kürzlich in Betrieb genommen wurde, nur wenig Datenverkehr aufweist oder Hackern nichts Wertvolles bietet, das unbemerkt bleibt. Viele Exploits sind jedoch automatisiert und wurden speziell entwickelt, um nach häufigen Konfigurationsfehlern zu suchen. Diese Programme durchsuchen Netzwerke nach Servern, unabhängig von der Art des Inhalts.

Das Zulassen von Remoteverbindungen ist eine der häufigsten und am einfachsten zu behebenden Situationen, die zum Ausnutzen einer PostgreSQL-Datenbank führen können. Dies geschieht, weil bestimmte Konfigurationen es Programmen wie diesen erleichtern, den Server zu erkennen.

In diesem Lernprogramm wird gezeigt, wie das spezifische Risiko durch das Zulassen von Remoteverbindungen gemindert werden kann. Dies ist zwar ein wichtiger erster Schritt, da Server auf andere Weise kompromittiert werden können. Wir empfehlen jedoch, zusätzliche Maßnahmen zum Schutz Ihrer Daten zu ergreifen, die inAdditional Security Considerationsangegeben sind.

Hintergrund

Stellen Sie sich den Server als Geschäft vor, um das spezifische Risiko zu verstehen, das wir verringern. Wenn der Server überhaupt einen Port abhört, ist dies ein bisschen so, als würde ein Neon-"Open" -Zeichen aktiviert. Es macht den Server selbst im Netzwerk sichtbar, wo er von automatisierten Skripten gefunden werden kann.

Wir können uns jeden Hafen als eine Art und Weise vorstellen, wie man den Laden betritt, wie eine Tür oder ein Fenster. Diese Eingänge können geöffnet, geschlossen, gesperrt oder unterbrochen sein, abhängig vom Status der zuhörenden Software. Wenn Sie jedoch auf einer öffentlichen Benutzeroberfläche zuhören, kann ein Skript, das nach einem Zugriff auf das System sucht, den Versuch starten. Beispielsweise könnte das Skript so konfiguriert sein, dass versucht wird, sich mit einem Standardkennwort anzumelden, falls es nicht geändert wurde. Es wird möglicherweise versucht, bekannte Exploits des Listening-Daemons auszuführen, falls dieser nicht gepatcht wurde. Was auch immer das Skript versucht, wenn es in der Lage ist, eine Schwachstelle zu finden und auszunutzen, befindet sich der Eindringling im Inneren und kann sich dem ernsthaften Problem der Beeinträchtigung des Servers zuwenden.

Wenn wir einen Daemon wiepostgresqlauf lokales Abhören beschränken, ist es so, als ob diese bestimmte Tür nach außen nicht existiert. Zumindest in Bezug auf Postgres gibt es keinen weiteren Schritt. Firewalls und VPNs schützen auf ähnliche Weise. In diesem Lernprogramm konzentrieren wir uns darauf, PostgreSQL als öffentlich zugängliche Tür zu entfernen. Informationen zum Sichern des Dämons selbst oder der Daten während der Übertragung oder Speicherung finden Sie unterAdditional Security Considerations.

Voraussetzungen

In diesem Lernprogramm verwenden wirtwo Ubuntu installations, eine für den Datenbankhost und eine als Client, der eine Remoteverbindung zum Host herstellt. Jeder sollte einensudo-Benutzer haben und die Firewall aktiviert sein. Die AnleitungInitial Server Setup with Ubuntu 16.04 kann Ihnen dabei helfen.

One Ubuntu 16.04 PostgreSQL Database Host:

Wenn Sie PostgreSQL noch nicht installiert haben, können Sie dies mit den folgenden Befehlen tun:

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

One Ubuntu 16.04 Client Machine:
Um das Zulassen von Remoteverbindungen zu demonstrieren und zu testen, verwenden wir den PostgreSQL-Clientpsql. Verwenden Sie zur Installation die folgenden Befehle:

sudo apt-get update
sudo apt-get install postgresql-client

Wenn diese Voraussetzungen erfüllt sind, können Sie mitmachen.

Grundlegendes zur Standardkonfiguration

Wenn PostgreSQL aus den Ubuntu-Paketen installiert wird, ist es standardmäßig darauf beschränkt, localhost zu überwachen. Diese Standardeinstellung kann durch Überschreiben vonlisten_addresses in der Dateipostgresql.conf geändert werden. Die Standardeinstellung verhindert jedoch, dass der Server automatisch eine öffentliche Schnittstelle überwacht.

Darüber hinaus erlaubt die Dateipg_hba.confnur Verbindungen von Unix / Linux-Domänensockets und der lokalen Loopback-Adresse für den Server, sodass keine Verbindungen von externen Hosts akzeptiert werden:

ersetzen

# Put your actual configuration here
# ----------------------------------
#
# If you want to allow non-local connections, you need to add more
# "host" records.  In that case you will also need to make PostgreSQL
# listen on a non-local interface via the listen_addresses
# configuration parameter, or via the -i or -h command line switches.

# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

Diese Standardeinstellungen erfüllen das Ziel, eine öffentliche Schnittstelle nicht abzuhören. Wenn wir sie intakt lassen und unsere Firewall aufrechterhalten, sind wir fertig! Wir können direkt zuAdditional Security Considerations gehen, um zu erfahren, wie Daten während der Übertragung gesichert werden.

Wenn Sie eine Verbindung von einem Remote-Host aus herstellen müssen, werden wir im nächsten Abschnitt erläutern, wie Sie die Standardeinstellungen außer Kraft setzen und welche Schritte Sie zum Schutz des Servers ergreifen können.

Remote-Verbindungen konfigurieren

Für ein Produktionssetup und bevor wir mit vertraulichen Daten arbeiten, wird PostgreSQL-Datenverkehr idealerweise während der Übertragung mit SSL verschlüsselt, hinter einer externen Firewall geschützt oder durch ein virtuelles privates Netzwerk (VPN) geschützt. Um dies zu erreichen, können wir den etwas weniger komplizierten Schritt unternehmen, eine Firewall auf unserem Datenbankserver zu aktivieren und den Zugriff auf die Hosts zu beschränken, die sie benötigen.

[[Schritt 1 - Hinzufügen eines Benutzers und einer Datenbank] == Schritt 1 - Hinzufügen eines Benutzers und einer Datenbank

Zunächst fügen wir einen Benutzer und eine Datenbank hinzu, mit denen wir unsere Arbeit testen können. Zu diesem Zweck verwenden wir den PostgreSQL-Clientpsql, um eine Verbindung als Administrator $ (t1) s herzustellen. Durch Übergeben der Option-iansudo wird die Anmeldeshell des Postgres-Benutzers ausgeführt, wodurch sichergestellt wird, dass Optionen aus.profileoder anderen anmeldespezifischen Ressourcen geladen werden. -u Spezies der Postgres-Benutzer:

sudo -i -u postgres psql

Als Nächstes erstellen wir einen Benutzer mit einem Passwort. Stellen Sie sicher, dass Sie anstelle des unten hervorgehobenen Beispiels ein sicheres Kennwort verwenden:

CREATE USER sammy WITH PASSWORD 'password';

Wenn der Benutzer erfolgreich erstellt wurde, sollten wir die folgende Ausgabe erhalten:

OutputCREATE ROLE

[.note] #Note: Seit PostgreSQL 8.1 sind ROLES und USERS synonym. Konventionell wird eine Rolle mit einem Kennwort immer noch als USER bezeichnet, während eine Rolle ohne Kennwort als ROLE bezeichnet wird. Daher wird manchmal ROLE in der Ausgabe angezeigt, wenn wir möglicherweise USER erwarten.
#

Als Nächstes erstellen wir eine Datenbank und gewähren unserem neuen Benutzer vollständigen Zugriff. Es wird empfohlen, Benutzern nur den Zugriff zu gewähren, den sie benötigen, und nur die Ressourcen, über die sie verfügen sollten. Je nach Anwendungsfall kann es daher angezeigt sein, den Zugriff eines Benutzers noch weiter einzuschränken. Weitere Informationen zu Berechtigungen finden Sie in der AnleitungHow To Use Roles and Manage Grant Permissions in PostgreSQL on a VPS.

CREATE DATABASE sammydb OWNER sammy;

Wenn die Datenbank erfolgreich erstellt wurde, sollten wir eine Bestätigung erhalten:

OutputCREATE DATABASE

Nachdem wir einen Benutzer und eine Datenbank erstellt haben, verlassen wir den Monitor

\q

Nach dem Drücken der EINGABETASTE befinden wir uns an der Eingabeaufforderung und können fortfahren.

[[Schritt-2 - Konfigurieren von UFW]] == Schritt 2 - Konfigurieren von UFW

In der Voraussetzung vonInitial Server Setup with Ubuntu 16.04haben wir UFW aktiviert und nur SSH-Verbindungen zugelassen. Bevor wir mit der Konfiguration beginnen, überprüfen wir den UFW-Status:

sudo ufw status

[.Hinweis]##

Note: Wenn die Ausgabe anzeigt, dass die Firewallinactive ist, können wir sie aktivieren mit:

sudo ufw enable

Sobald es aktiviert ist und der Statusbefehl erneut ausgeführt wird, zeigtsudo ufw status die aktuellen Regeln an. Stellen Sie bei Bedarf sicher, dass SSH zugelassen ist.

sudo ufw allow OpenSSH

Sofern wir keine Änderungen an den Voraussetzungen vorgenommen haben, sollte die Ausgabe zeigen, dass nur OpenSSH zulässig ist:

OutputStatus: active

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

Nachdem wir den Firewall-Status überprüft haben, erlauben wir den Zugriff auf den PostgreSQL-Port und beschränken ihn auf den Host oder die Hosts, die wir zulassen möchten.

Mit dem folgenden Befehl wird die Regel für den PostgreSQL-Standardport (5432) hinzugefügt. Wenn Sie diesen Port geändert haben, müssen Sie ihn im folgenden Befehl aktualisieren. Stellen Sie sicher, dass Sie die IP-Adresse des Servers verwendet haben, auf den zugegriffen werden muss. Führen Sie diesen Befehl gegebenenfalls erneut aus, um jede Client-IP-Adresse hinzuzufügen, die Zugriff benötigt:

sudo ufw allow from client_ip_address to any port 5432

Um die Regel noch einmal zu überprüfen, können wirufw status erneut ausführen:

sudo ufw status
OutputTo                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
5432                       ALLOW       client_ip_address
OpenSSH (v6)               ALLOW       Anywhere (v6)

[.note] #Note: Wenn Sie UFW noch nicht kennen, erfahren Sie mehr in der AnleitungUFW Essentials: Common Firewall Rules and Commands.
#

Mit dieser Firewall-Regel konfigurieren wir PostgreSQL jetzt so, dass es seine öffentliche IP-Adresse überwacht. Dies erfordert eine Kombination aus zwei Einstellungen, einen Eintrag für den Verbindungshost inpg_hba.conf und die Konfiguration der Listenadressen inpostgresql.conf.

[[Schritt 3 - Konfigurieren der zulässigen Hosts]] == Schritt 3 - Konfigurieren der zulässigen Hosts

Wir beginnen mit dem Hinzufügen des Hosteintrags inpg_hba.conf. Wenn Sie eine andere Version von PostgreSQL installiert haben, müssen Sie diese im folgenden Pfad ersetzen:

sudo nano /etc/postgresql/9.5/main/pg_hba.conf

Wir platzieren die Zeilen vonhostunter dem Kommentarblock, in dem beschrieben wird, wie nicht lokale Verbindungen zugelassen werden. Wir werden auch eine Zeile mit der öffentlichen Adresse des Datenbankservers einfügen, damit wir schnell testen können, ob unsere Firewall richtig konfiguriert ist. Stellen Sie sicher, dass Sie im folgenden Beispiel den Hostnamen oder die IP-Adresse vonyour Computern ersetzen.

Auszug aus pg_hba.conf

# If you want to allow non-local connections, you need to add more
# "host" records.  In that case you will also need to make PostgreSQL
# listen on a non-local interface via the listen_addresses
# configuration parameter, or via the -i or -h command line switches.
host  sammydb  sammy   client_ip_address/32   md5

Bevor wir unsere Änderungen speichern, konzentrieren wir uns auf die einzelnen Werte in dieser Zeile, falls Sie einige der Optionen ändern möchten:

  • host Der erste Parameter,host, legt fest, dass eine TCP / IP-Verbindung verwendet wird.

  • database `sammydb`Die zweite Spalte gibt an, zu welchen Datenbanken der Host eine Verbindung herstellen kann. Sie können mehrere Datenbanken hinzufügen, indem Sie die Namen durch Kommas trennen.

  • usersammy gibt den Benutzer an, der die Verbindung herstellen darf. Wie bei der Datenbankspalte können mehrere Benutzer durch Kommas getrennt angegeben werden.

  • address Die Adresse gibt die Adresse oder Adressen des Client-Computers an und kann einen Hostnamen, einen IP-Adressbereich oder anderespecial key words enthalten. Im obigen Beispiel haben wir nur die einzelne IP-Adresse unseres Kunden zugelassen.

  • auth-method Schließlich gibt die Auth-Methodemd5 an, dassdouble-MD5-hashed password zur Authentifizierung bereitgestellt werden. Sie müssen lediglich das Kennwort eingeben, das für den Benutzer erstellt wurde, der die Verbindung herstellt.

Eine ausführlichere Beschreibung dieser und zusätzlicher Einstellungen finden Sie in der PostgreSQL-Dokumentation vonThe pg_hba.conf File.

Speichern und beenden Sie die Datei, sobald Sie fertig sind.

[[Schritt-4 - Konfigurieren der Abhöradresse]] == Schritt 4 - Konfigurieren der Abhöradresse

Als Nächstes legen wir die Abhöradresse in der Dateipostgresql.conffest:

sudo nano /etc/postgresql/9.5/main/postgresql.conf

Suchen Sie die Zeilelisten_addressesund definieren Sie darunter Ihre Abhöradressen. Ersetzen Sie dabei unbedingt den Hostnamen oder die IP-Adresse Ihres Datenbankhosts. Möglicherweise möchten Sie überprüfen, ob Sie die öffentliche IP-Adresse des Datenbankservers und nicht den verbindenden Client verwenden:

postgresql.conf

#listen_addresses = 'localhost'         # what IP address(es) to listen on;
listen_addresses = 'localhost,server_ip_address'

Wenn Sie fertig sind, speichern und schließen Sie die Datei.

[[Schritt-5 -—- Neustart-postgresql]] == Schritt 5 - Neustart von PostgreSQL

Unsere Konfigurationsänderungen werden erst nach einem Neustart des PostgreSQL-Daemons wirksam. Deshalb tun wir dies, bevor wir Folgendes testen:

sudo systemctl restart postgresql

Dasystemctl kein Feedback gibt, überprüfen wir den Status, um sicherzustellen, dass der Dämon erfolgreich neu gestartet wurde:

sudo systemctl status postgresql

Wenn die Ausgabe "Aktiv: Aktiv" enthält und mit der folgenden Meldung endet, wird der PostgreSQL-Dämon ausgeführt.

Output...
Jan 10 23:02:20 PostgreSQL systemd[1]: Started PostgreSQL RDBMS.

Nachdem wir den Daemon neu gestartet haben, können wir ihn testen.

[[Schritt 6 - Testen]] == Schritt 6 - Testen

Lassen Sie uns abschließend testen, ob wir von unserem Client-Computer aus eine Verbindung herstellen können. Dazu verwenden wirpsql mit-U, um den Benutzer anzugeben,-h, um die IP-Adresse des Clients anzugeben, und-d, um die Datenbank anzugeben, da wir ' Wir haben unsere Sicherheit verschärft, sodasssammy nur eine Verbindung zu einer einzelnen Datenbank herstellen können.

psql -U sammy -h postgres_host_ip -d sammydb

Wenn alles richtig konfiguriert ist, sollten Sie die folgende Eingabeaufforderung erhalten:

OutputPassword for user sammy:

Geben Sie das Kennwort ein, das Sie zuvor festgelegt haben, als Sie den Benutzersammy im PostgreSQL-Monitor hinzugefügt haben.

Wenn Sie die folgende Eingabeaufforderung erhalten, ist Ihre Verbindung erfolgreich hergestellt:

[secondary_label]
sammydb=>

Dies bestätigt, dass wir die Firewall passieren und eine Verbindung zur Datenbank herstellen können. Wir verlassen jetzt:

\q

Da wir unsere Konfiguration bestätigt haben, werden wir mit dem Aufräumen fertig.

[[Schritt-7 - Entfernen der Testdatenbank und des Benutzers] == Schritt 7 - Entfernen der Testdatenbank und des Benutzers

Zurück auf dem Host, nachdem wir die Verbindung getestet haben, können wir die folgenden Befehle verwenden, um die Datenbank und den Benutzer ebenfalls zu löschen.

sudo -i -u postgres psql

So löschen Sie die Datenbank:

DROP DATABASE sammydb;

Die Aktion wird durch folgende Ausgabe bestätigt:

OutputDROP DATABASE

So löschen Sie den Benutzer:

DROP USER sammy;

Der Erfolg wird bestätigt durch:

OutputDROP ROLE

Zum Abschluss der Bereinigung entfernen wir den Hosteintrag für die Datenbanksammydbaus der Dateipg_hba.conf, da wir ihn nicht mehr benötigen:

sudo nano /etc/postgresql/9.5/main/pg_hba.conf

Zu entfernende Linie auspg_hba.conf

host  sammydb  sammy   client_ip_address/32   md5

Damit die Änderung wirksam wird, speichern und beenden wir den Datenbankserver und starten ihn neu:

sudo systemctl restart postgresl

Um sicherzustellen, dass der Neustart erfolgreich war, überprüfen wir den Status:

sudo systemctl status postgres

Wenn "Aktiv: Aktiv" angezeigt wird, ist der Neustart erfolgreich.

An diesem Punkt können wir mit der Konfiguration der Anwendung oder des Dienstes auf dem Client fortfahren, der eine Remoteverbindung herstellen muss.

Zusätzliche Sicherheitsaspekte

Dieses Lernprogramm soll die Risiken verringern, die durch das Zulassen ungesicherter Remoteverbindungen zu PostgreSQL entstehen. Dies ist eine häufige Situation, in der PostgreSQL versehentlich ausgenutzt wird. Wenn Sie den Zugriff auf den Überwachungsport auf bestimmte Hosts beschränken, werden andere wichtige Sicherheitsaspekte wie die Verschlüsselung Ihrer Daten während der Übertragung nicht berücksichtigt.

Bevor Sie mit realen Daten arbeiten, empfehlen wir, die folgenden Ressourcen zu überprüfen und die entsprechenden Schritte für Ihren Anwendungsfall auszuführen.

  • Security within PostgreSQL: GRANT-Anweisungen bestimmen, welche Benutzer auf eine bestimmte Datenbank zugreifen dürfen, während Rollen die Berechtigungen dieser Benutzer festlegen. In Kombination bieten sie eine Trennung zwischen mehreren Datenbanken in einer einzigen Installation.

  • Setting up SSL with PostgreSQL: Durch Konfigurieren von SSL werden Daten während der Übertragung verschlüsselt. Dies schützt die Daten beim Senden.

  • Securing PostgreSQL TCP/IP Connections with SSH Tunnels: SSH-Tunnel sind nützlich, wenn Sie eine Verbindung zu Clients herstellen, die nicht SSL-fähig sind. In fast jeder anderen Situation ist es vorzuziehen, SSL mit Postgres einzurichten.

Fazit

In diesem Lernprogramm haben wir wichtige Schritte unternommen, um zu verhindern, dass für unsere PostgreSQL-Installation Werbung gemacht wird, indem die Firewall des Servers so konfiguriert wurde, dass nur Verbindungen von Hosts zugelassen werden, die Zugriff benötigen, und PostgreSQL so konfiguriert wurde, dass nur Verbindungen von diesen Hosts akzeptiert werden. Dies verringert das Risiko bestimmter Arten von Angriffen. Dies ist nur der erste Schritt zur Datensicherung. Wir empfehlen, die oben beschriebenen zusätzlichen Sicherheitsmaßnahmen zu überprüfen und umzusetzen.