Ist es möglich, einen Kernel-Parameter zu optimieren, damit ein Userland-Programm an die Ports 80 und 443 gebunden werden kann?
Der Grund, den ich frage, ist, dass ich es für dumm halte, einem privilegierten Prozess zu erlauben, einen Socket zu öffnen und zuzuhören. Alles, was einen Socket öffnet und lauscht, ist mit einem hohen Risiko verbunden, und Anwendungen mit hohem Risiko sollten nicht als Root ausgeführt werden.
Ich versuche lieber herauszufinden, welcher nicht privilegierte Prozess Port 80 überwacht, als Malware zu entfernen, die mit Root-Rechten versehen ist.
Antworten:
Ich bin nicht sicher, worauf sich die anderen Antworten und Kommentare hier beziehen. Dies ist ziemlich einfach möglich. Es gibt zwei Optionen, die den Zugriff auf Ports mit niedriger Nummer ermöglichen, ohne dass der Prozess auf root angehoben werden muss:
Option 1: Verwenden Sie diese Option,
CAP_NET_BIND_SERVICE
um einem Prozess Portzugriff mit niedriger Nummer zu gewähren:Mit diesem
setcap
Befehl können Sie dauerhaften Zugriff auf eine bestimmte Binärdatei gewähren, um sie an Ports mit niedriger Nummer zu binden :Weitere Einzelheiten zum e / i / p-Teil finden Sie unter
cap_from_text
.Anschließend
/path/to/binary
können Sie Verbindungen zu Ports mit niedriger Nummer herstellen. Beachten Sie, dass Siesetcap
die Binärdatei selbst anstelle eines Symlinks verwenden müssen.Option 2: Verwenden Sie diese Option
authbind
, um einen einmaligen Zugriff mit genauerer Benutzer- / Gruppen- / Portkontrolle zu gewähren:Genau dafür gibt es das
authbind
( Manpage- ) Tool.Installieren Sie
authbind
mit Ihrem bevorzugten Paket-Manager.Konfigurieren Sie es, um Zugriff auf die relevanten Ports zu gewähren, z. B. um 80 und 443 von allen Benutzern und Gruppen zuzulassen:
Führen Sie nun Ihren Befehl über aus
authbind
(optional mit Angabe--deep
oder anderen Argumenten, siehe Manpage):Z.B
Beides hat Vor- und Nachteile. Option 1 gewährt der Binärdatei Vertrauen, bietet jedoch keine Kontrolle über den Zugriff pro Port. Option 2 gewährt dem Benutzer / der Gruppe Vertrauen und bietet Kontrolle über den Zugriff pro Port, aber AFAIK unterstützt nur IPv4.
quelle
rwx
Erlaubnis?-p
Würden Sie den Befehl zum Zurücksetzen des Vorgangs in Option 1 erneut mit intead of ausführen+eip
?setcap
Erlaubnis für die versionsspezifische ausführbare Ruby-Datei geben , z. B./usr/bin/ruby1.9.1
chmod
zubyport
speichern. Ich habe gesehen, wie Berechtigungen von500
bis erteilt wurden744
. Ich würde mich an die restriktivste halten, die für Sie funktioniert.Dale Hagglund ist genau richtig. Also werde ich nur dasselbe sagen, aber auf andere Weise, mit einigen Einzelheiten und Beispielen. ☺
Das Richtige in der Unix- und Linux-Welt ist:
Sie haben die falsche Vorstellung, wo das hohe Risiko liegt. Das hohe Risiko besteht darin , aus dem Netzwerk zu lesen und auf das zu reagieren, was gelesen wird, und nicht darin, einen Socket zu öffnen, ihn an einen Port zu binden und anzurufen
listen()
. Es ist der Teil eines Dienstes, der die eigentliche Kommunikation durchführt, der das hohe Risiko darstellt. Die Teile, die sich öffnen,bind()
undlisten()
(bis zu einem gewissen Grad) der Teil , der sich öffnet,accepts()
sind nicht das hohe Risiko und können unter der Ägide des Super-Benutzers ausgeführt werden. Sie verwenden und verarbeiten keineaccept()
Daten (mit Ausnahme der Quell-IP-Adressen in diesem Fall), die der Kontrolle nicht vertrauenswürdiger Fremder über das Netzwerk unterliegen.Dafür gibt es viele Möglichkeiten.
inetd
Wie Dale Hagglund sagt, macht das der alte "Netzwerk-Superserver"
inetd
. Das Konto, unter dem der Serviceprozess ausgeführt wird, ist eine der Spalten ininetd.conf
. Es trennt den Listening-Teil und den Drop-Privileg-Teil nicht in zwei separate Programme, die klein und leicht zu überwachen sind, sondern trennt den Hauptdienstcode in ein separates Programm, dasexec()
in einem Dienstprozess erstellt wird, der mit einem offenen Dateideskriptor erstellt wird für die Steckdose.Die Schwierigkeit der Prüfung ist nicht so problematisch, da nur das eine Programm geprüft werden muss.
inetd
Das Hauptproblem ist nicht die Überwachung, sondern, dass es im Vergleich zu neueren Tools keine einfache, fein abgestimmte Laufzeitdienststeuerung bietet.UCSPI-TCP und Daemontools
Daniel J. Bernsteins UCSPI-TCP- und daemontools- Pakete wurden dafür zusammen entwickelt. Alternativ kann Bruce Guenters weitgehend gleichwertiges daemontools-encore- Toolset verwendet werden.
Das Programm zum Öffnen des Socket-Dateideskriptors und zum Binden an den privilegierten lokalen Port wird
tcpserver
über UCSPI-TCP ausgeführt. Es macht sowohl dielisten()
als auch dieaccept()
.tcpserver
Anschließend wird entweder ein Dienstprogramm erstellt, das die Root-Berechtigungen selbst löscht (da das bereitgestellte Protokoll darin besteht, als Superuser zu beginnen und sich dann "anzumelden", wie dies beispielsweise bei einem FTP- oder einem SSH-Dämon der Fall ist) odersetuidgid
a in sich geschlossenes kleines und leicht zu überprüfendes Programm, das nur Berechtigungen verwirft und dann das eigentliche Dienstprogramm lädt (von dem also kein Teil jemals mit Superuser-Berechtigungen ausgeführt wird, wie dies beispielsweise der Fall istqmail-smtpd
).Ein Service-
run
Skript wäre also zum Beispiel (dieses für dummyidentd zur Bereitstellung eines Null-IDENT-Dienstes):Leckereien
Mein nosh-Paket wurde dafür entwickelt. Es hat einen kleinen
setuidgid
Nutzen, genau wie die anderen. Einsystemd
kleiner Unterschied besteht darin, dass es sowohl mit "LISTEN_FDS" -Diensten als auch mit UCSPI-TCP-Diensten verwendet werden kann. Daher wird das herkömmlichetcpserver
Programm durch zwei separate Programme ersetzt:tcp-socket-listen
undtcp-socket-accept
.Auch hier spawnen und laden sich die Mehrzweck-Dienstprogramme gegenseitig. Eine interessante Besonderheit des Designs ist, dass man Superuser-Privilegien nach,
listen()
aber schon vor, fallen lassen kannaccept()
. Hier ist einrun
Skriptqmail-smtpd
, das genau das tut:Die Programme , die unter der Schirmherrschaft der Superuser sind die kleinen Service-agnostisch Kettenlade Tools
fdmove
,clearenv
,envdir
,softlimit
,tcp-socket-listen
, undsetuidgid
. Ab dem Startpunktsh
ist der Socket geöffnet und an densmtp
Port gebunden , und der Prozess verfügt nicht mehr über Superuser-Berechtigungen.s6, s6-networking und execline
Die s6- und s6-Netzwerkpakete von Laurent Bercot wurden dazu in Verbindung entwickelt. Die Befehle sind strukturell denen von
daemontools
und UCSPI-TCP sehr ähnlich .run
Skripte wären ähnlich, mit Ausnahme der Substitution vons6-tcpserver
fortcpserver
unds6-setuidgid
forsetuidgid
. Man kann sich jedoch auch dafür entscheiden, gleichzeitig das Execline- Toolset von M. Bercot zu verwenden .Hier ist ein Beispiel eines FTP-Dienstes, der geringfügig von Wayne Marshalls Original geändert wurde und Execline, S6, S6-Networking und das FTP-Server-Programm von publicfile verwendet :
ipsvd
Gerrit Papes ipsvd ist ein weiteres Toolset, das mit ucspi-tcp und s6-networking vergleichbar ist. Die Tools sind
chpst
undtcpsvd
dieses Mal, aber sie tun dasselbe, und der Code mit hohem Risiko, der das Lesen, Verarbeiten und Schreiben von Dingen übernimmt, die von nicht vertrauenswürdigen Clients über das Netzwerk gesendet werden, befindet sich immer noch in einem separaten Programm.Hier ist das Beispiel von M. Pape, wie man
fnord
einrun
Skript ausführt:systemd
systemd
Das neue Dienstüberwachungs- und Init-System, das in einigen Linux-Distributionen zu finden ist, soll das tun, was esinetd
kann . Es werden jedoch keine kleinen eigenständigen Programme verwendet. Man musssystemd
leider in vollem Umfang prüfen .Mit
systemd
erstellt man Konfigurationsdateien, um einen Socket zu definieren, dersystemd
lauscht, und einen Dienst, dersystemd
startet. Die Service "Unit" -Datei enthält Einstellungen, mit denen Sie den Serviceprozess in hohem Maße steuern können, einschließlich des Benutzers, unter dem er ausgeführt wird.Wenn dieser Benutzer als Nicht-Superuser festgelegt ist,
systemd
erledigt er die gesamte Arbeit, indem er den Socket öffnet, an einen Port bindetlisten()
undaccept()
in Prozess 1 den Superuser und den zugehörigen Dienstprozess aufruft (und, falls erforderlich, aufruft ) Spawns werden ohne Superuser-Rechte ausgeführt.quelle
Ich habe einen etwas anderen Ansatz. Ich wollte Port 80 für einen node.js-Server verwenden. Ich konnte es nicht tun, da Node.js für einen Nicht-Sudo-Benutzer installiert wurde. Ich habe versucht, Symlinks zu verwenden, aber es hat bei mir nicht funktioniert.
Dann habe ich erfahren, dass ich Verbindungen von einem Port zu einem anderen Port weiterleiten kann. Also habe ich den Server auf Port 3000 gestartet und eine Portweiterleitung von Port 80 auf Port 3000 eingerichtet.
Dieser Link enthält die tatsächlichen Befehle, die dazu verwendet werden können. Hier sind die Befehle -
Ich habe den zweiten Befehl verwendet und es hat bei mir funktioniert. Ich denke, dies ist ein Mittelweg, um es dem Benutzerprozess nicht zu erlauben, direkt auf die unteren Ports zuzugreifen, sondern ihnen den Zugriff über die Portweiterleitung zu ermöglichen.
quelle
Ihre Instinkte sind völlig richtig: Es ist eine schlechte Idee, ein großes komplexes Programm als Root ausführen zu lassen, da ihre Komplexität es schwierig macht, ihnen zu vertrauen.
Es ist jedoch auch eine schlechte Idee, regulären Benutzern das Binden an privilegierte Ports zu ermöglichen, da solche Ports normalerweise wichtige Systemdienste darstellen.
Der Standardansatz zur Lösung dieses offensichtlichen Widerspruchs ist die Privilegientrennung . Die Grundidee besteht darin, Ihr Programm in zwei (oder mehr) Teile zu unterteilen, von denen jeder einen genau definierten Teil der Gesamtanwendung darstellt und die über einfache, begrenzte Schnittstellen kommunizieren.
In dem von Ihnen angegebenen Beispiel möchten Sie Ihr Programm in zwei Teile unterteilen. Einer, der als root ausgeführt wird und den privilegierten Socket öffnet und bindet und ihn dann irgendwie an den anderen Teil weitergibt, der als regulärer Benutzer ausgeführt wird.
Diese zwei Hauptwege, um diese Trennung zu erreichen.
Ein einzelnes Programm, das als root gestartet wird. Das allererste, was es tut, ist, die notwendige Steckdose so einfach und begrenzt wie möglich zu gestalten. Anschließend werden Berechtigungen gelöscht, das heißt, es wird in einen regulären Benutzermodus-Prozess konvertiert und alle anderen Aufgaben werden ausgeführt. Das korrekte Löschen von Berechtigungen ist schwierig. Nehmen Sie sich daher bitte die Zeit, um den richtigen Weg zu finden.
Ein Programmpaar, das über ein Socket-Paar kommuniziert, das von einem übergeordneten Prozess erstellt wurde. Ein nicht privilegiertes Treiberprogramm empfängt anfängliche Argumente und führt möglicherweise eine grundlegende Argumentvalidierung durch. Es erstellt über socketpair () ein Paar verbundener Sockets und führt dann zwei andere Programme aus, die die eigentliche Arbeit erledigen und über das Socket-Paar kommunizieren. Einer dieser Vorgänge ist privilegiert und erstellt den Server-Socket sowie alle anderen privilegierten Vorgänge. Der andere Vorgang erledigt die komplexere und daher weniger vertrauenswürdige Anwendungsausführung.
[1] http://en.m.wikipedia.org/wiki/Privilege_separation
quelle
Einfachste Lösung: Entfernen Sie alle privilegierten Ports unter Linux
Funktioniert auf Ubuntu / Debian:
(Funktioniert gut für VirtualBox mit Nicht-Root-Account)
Achten Sie jetzt auf die Sicherheit, da alle Benutzer alle Ports binden können!
quelle