Monit, automatische Portöffnung, Sicherheit?

ServerSide

New Member
Hallo.

Ich habe gerade in meiner VM an meinen Server-Administrations-Skills gearbeitet (und das an einem Freitag Abend!) und mir sind ein paar Sachen aufgefallen, wo ich mal bei Euch Profis nachfragen wollte.

1. Ich habe Monit installiert und dann per IP:2812 von meinem Hostsystem darauf zugegriffen. Das hat mich gewundert, da ich den Port gar nicht freigegeben habe.
Also per "netstat -plnt" geschaut was Alles so offen ist und dort stand u.a. folgendes:
tcp 0 0 0.0.0.0:2812 0.0.0.0:* LISTEN 3363/monit

Dann habe ich per /etc/monit/monitrc den Port auf 2813 geändert und es wurde auch laut netstat so übernommen. Sprich Programme können einfach so auf die Firewall zugreifen und Ihre eigenen Ports auf/zu machen bzw. ändern.
Ist das denn wirklich in Ordnung so? Hört sich für mich irgendwie etwas seltsam an? Führt monit dann einfach ein iptables script aus, oder wie genau funktioniert das?

2. Netstat gibt auch aus dass mein postgresql Server folgendes macht:
tcp 0 0 127.0.0.1:5432 0.0.0.0 LISTEN 5697/postgres

Das heisst doch dass der Postgre Server am Port 5432 lauscht?
Das finde ich auch problematisch. Ich greife per Django über gunicorn/nginx darauf zu. Wäre es sicherheitstechnisch nicht besser den Postgre Port zuzumachen und Alles über Sockets zu machen? Oder bin ich da zu paranoid?

Oder bedeutet "Local address 127.0.0.1:5432" dass ich nur direkt vom Server (VM) aus drauf zugreifen kann?
Demnach müsste dann das "local address 0.0.0.0:2813" von Monit bedeuten, dass man von "überall" drauf zugreifen kann. Denn ich kann ja von meinem Hostsystem auch direkt drauf zugreifen indem ich mit meinem Hostsystem-Browser einfach IP-Gast:2813 besuche.

Ist das so richtig oder hab ich jetzt Alles komplett vertauscht?

Vielen Dank schonmal!
 
Last edited by a moderator:

ThomasChr

New Member
Imho hast du das mit dem lokal und global horchen richtig verstanden.
Programme öffnen aber nix in der Firewall, einen Port dürfen sie trotz Firewall öffnen. Nur käme an dem Port eben nix an wenns die Firewall verwirft!

Zum Thema Ports habe ich hier mal gebloggt. Bislang hat sich da niemand beschwert dass ich Unsinn erzählt habe also gehe ich mal davon aus dass die dortigen Aussagen stimmen.
Über Firewall hab ich leider noch nix fertiges zum bloggen...

Hoffe das hilft,
Thomas
 

storvi

New Member
Hallo,

Wie Thomas schon richtig gesagt hat, kann eigentlich jedes Programm Ports öffenen, wie es lustig ist. Wenn das Programm Ports < 1024 öffnen möchte (Well known Ports), dann benötigt es in dem Moment root-Rechte.

In netstat (oder neuer "ss") siehst du auf welchem Socket (also IP:port) das Programm gebunden ist. In deinen Fällen lauscht Monit auf alllen verfügbaren Adressen (0.0.0.0 steht für alle Interfaces und alle IPs), während PostgreSQL per default lediglich auf localhost lauscht.

Die Firewall ist "davor", dass heißt du kannst dir das so vorstellen (vereinfacht), dass ein Paket übers Kabel (OSI Layer 1/2) auf die Firewall trifft und dort im Regelwerk geschaut wird, ob Quell- bzw. Ziel-IP (OSI Layer 3) und Quell- und Ziel-Port (OSI Layer 4) passieren dürfen. Wenn das der Fall ist, wird das Paket dann weiter an die Anwendung gereicht - wenn nicht wird es verworfen (wirklich stark vereinfacht).

PostgreSQL hat noch zusätzlich zum Parameter "listen_addresses" die Datei "pg_hba.conf", die als zusätzliche Filterung dient. Dort kannst du genau festlegen, welcher Benutzer auf welche Datenbank über welche IP und welche AUthentisierungsmethode auf die Datenbank zugreifen kann. Daher kontrolliere diese Einstellung und sichere sie bei Bedarf ab.

Gruß
Markus
 

PHP-Friends

Blog Benutzer
Bitte beachten: Auch ein Binden an 127.0.0.1 ist je nach System nicht der heilige Gral. Sobald da irgendwer außer dir Skripte ausführen kann (z.B. normales Webhosting), können die auch zugreifen, sofern nicht z.B. per iptables mit der Owner Match Extension blockiert. Ganz grundsätzlich vertrete ich allerdings die Ansicht, dass auch das kein Freifahrtsschein für fehlende Authentifizierung auf Anwedungsebene sein darf :)
 

ServerSide

New Member
Besteht denn ein Sicherheitstechnischer Unterschied dazwischen ob man Postgre über einen Port oder einen Socket anspricht?

Ich hatte eigentlich (instinktiv) vor den 127.0.0.1:5432 zu schliessen und Postgre stattdessen per Socket ansprechen zu lassen. Ist dies auch wirklich sinnvoll?

Und was meintest Du mit "dass auch das kein Freifahrtsschein für fehlende Authentifizierung auf Anwedungsebene sein darf"? Du meinst speziell für DB-Server?
 

storvi

New Member
Du kannst ruhig über TCP statt den Socket gehen. Sicherheitstechnisch ändert sich da nicht viel - Wenn ein Benutzer Zugriff auf das Socket hat, kann er auf die DB zugreifen, wenn er lokal ist kann er dies auch...

PostgreSQL filtert selbst nochmal über die Datei pg_hba.conf.
Da ist bei vielen Distributionen die Defaulteinstellung zu "lasch".

Lies dir die Dokumentation durch und konfiguriere es so restriktiv wie möglich.

Gruß
Markus
 

Orebor

He who dances with pointers
Der Zugriff über den Unix Domain Socket sollte schneller sein, da so der Teile des TCP Stacks des Kernels umgangen werden.
 

d4f

Müder Benutzer
Du kannst ruhig über TCP statt den Socket gehen. Sicherheitstechnisch ändert sich da nicht viel - Wenn ein Benutzer Zugriff auf das Socket hat, kann er auf die DB zugreifen, wenn er lokal ist kann er dies auch...
Das ist so nicht wahr. Im _Standardfall_ wird es so gehandhabt allerdings kann man bei Sockets, da es Dateien sind, die UNIX-Rechteverteilung verwenden und über Zugriffsrechte sowie Gruppenzugehörigkeit sehr präzise Zugriffsrechte geben.
 

storvi

New Member
Das ist so nicht wahr. Im _Standardfall_ wird es so gehandhabt allerdings kann man bei Sockets, da es Dateien sind, die UNIX-Rechteverteilung verwenden und über Zugriffsrechte sowie Gruppenzugehörigkeit sehr präzise Zugriffsrechte geben.
Also stimmt doch die Aussage: Wenn der Benutzer Zugriff auf das Socket hat, dann kann ein Zugriff (abhängig von weiterer Filterung) darüber erfolgen.

Mittels Benutzer- und Gruppenberechtigungen kann man diesen Zugriff auf OS-Ebene weiter einschränken. Auf Applikations-Ebene (also hier DB) kann über die pg_hba.conf sowohl für den Socket- als auch den TCP-Zugriff granular entschieden werden, welcher Zugriff erlaubt ist.

Gruß
Markus
 

elias5000

Site Reliability Engineer
UNIX-Rechteverteilung verwenden und über Zugriffsrechte sowie Gruppenzugehörigkeit sehr präzise Zugriffsrechte geben.
Meiner Meing nach sollte man nicht die PG-eigene Authentifizierung damit ersetzen. DB-Zugriff sollte immer über authentifizierte Clients erfolgen. Insofern hätte man dann zwei Layer an Zugriffsbeschränkung und das ist ein Layer zuviel. Es sollte immer klar sein, wo der Zugriff gewährt/verweigert wird. Mehr als ein Auth-Layer macht es im Zweifelsfall nur schwerer zu debuggen, wenn etwas nicht funktioniert.

Edit: Falls das nicht klar genug formuliert war: Ich halte die Einschränkung der Zugriffsrechte für den PG-Socket für unnötig, wenn nicht sogar schlecht. IMHO sollte man auch immer das "Principle of least effort" beachten und nicht mehr in die Implementierung legen als nötig. Wenn man mehr als das nötige macht, sollte man begründen können, wieso und diese Begründung sollte auch einem Hinterfragen stand halten. Anderenfalls ist es nur unnötiger Cargo-Kult.
 
Last edited by a moderator:

storvi

New Member
Ich sehe Socket-Berechtigungen auch eher also "Firewall"-Ersatz bei TCP-Verbindungen.

So kannst du schon ein mehrstufigen Ansatz wählen - gerade auch weil PostgreSQL per Default bei den Sockets die Berechtigung 777 setzt.

Falls gewünscht (und die pg_hba.conf den persönlichem Sicherheitsgefühl nicht ausreicht) kann dies aber mittels Konfigurationsparametern (unter anderem unix_socket_permissions) ausgetrieben werden.

Gruß
Markus
 

PHP-Friends

Blog Benutzer
Und was meintest Du mit "dass auch das kein Freifahrtsschein für fehlende Authentifizierung auf Anwedungsebene sein darf"? Du meinst speziell für DB-Server?
Jein; ich meine letztendlich das, was elias5000 recht anschaulich beschrieben hat: Man sollte sich auf keinen "Workaround" - in welcher Form auch immer - verlassen, um den Zugriff eines (lokalen) Benutzers auf eine Anwendung zu verhindern, sondern immer in der Anwendung selbst eine Authentifizierung durchführen.
 

ServerSide

New Member
Ich habe mich ein wenig zur Sache Port vs Socket belesen und auch wenns nicht direkt um den Sicherheitsaspekt geht, hier doch zwei ganz interessante Links:

1. Redis Benchmark Port vs Socket: http://redis.io/topics/benchmarks
(Achtung: log Skala)
2. PostgreSQL Geschwindigkeit ~30% schneller über Sockets: http://zaiste.net/2015/05/postgresql_unix_socket_vs_tcpip_loopback/
(Für Details dem Link zum Originalartikel folgen)

Das ganze wird bei meinem bescheidenen Projekt zwar nicht viel Unterschied machen, aber schaden tut es auch nicht. Und ich wollte Postgre ohnehin über Sockets laufen lassen.
 

storvi

New Member
Es kommt auch darauf an, ob die Anwendung überhaupt eine Verbindung über Sockets ermöglicht. Manche Anwendungen können nur über TCP/IP Verbindungen zur DB aufbauen.

TCP/IP wird interessant, wenn du DB-Server und Anwendungsserver trennst. Wenn du mit Sockets klar kommst, dann spricht nichts gegen eine Nutzung.

Gruß
Markus
 

Top