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 wiepostgresql
auf 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.conf
nur 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-i
ansudo
wird die Anmeldeshell des Postgres-Benutzers ausgeführt, wodurch sichergestellt wird, dass Optionen aus.profile
oder 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 vonhost
unter 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.
-
user
sammy
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-Methode
md5
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.conf
fest:
sudo nano /etc/postgresql/9.5/main/postgresql.conf
Suchen Sie die Zeilelisten_addresses
und 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 Datenbanksammydb
aus 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.