Lösung 1:
Natürlich ist dies möglich. Sie müssen nur die Binärdatei CAP_NET_BIND_SERVICE.
angeben
sudo setcap cap_net_bind_service=ep some-binary
Unter Linux wurden die Dinge, die root tun kann, in eine Reihe von Fähigkeiten aufgeteilt. CAP_NET_BIND_SERVICE ist die Fähigkeit, sich an Ports <=1024.
zu bindenEs ist wahrscheinlich sogar möglich, AppArmor, SELinux oder ein anderes Linux-Sicherheitsmodul (LSM) zu verwenden, um dem Programm Zugriff zu gewähren, um diesen einen Port speziell zu binden, aber ich denke, das wäre Zeitverschwendung. Sicherheit basiert nicht mehr so stark auf Portnummern wie in der fernen Vergangenheit.
Hier ist ein Skript für OSX, um die Ports 80 und 443 an nicht privilegierte Ports weiterzuleiten:
echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
" | sudo pfctl -ef -
Lösung 2:
Eine weitere Möglichkeit, Ihren Daemon dazu zu bringen, auf Anfragen von einer niedrigeren Portnummer zu antworten, besteht darin, iptables oder ähnliches zu verwenden, um einen Port mit niedrigerer Nummer auf den Port mit höherer Nummer umzuleiten, auf dem Ihr Daemon lauscht:
sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
Ersetzen Sie 80 durch den offenzulegenden Port und 8080 durch den Listener-Port Ihrer Anwendung.
Lösung 3:
Ich denke, es gibt eine Möglichkeit, aber ich bin mir nicht 100 % sicher, ob das funktionieren würde.
Es ist die Bindung des Ports, der root erfordert, nicht die Anwendung, die ihn verwendet, also funktioniert die folgende Methode möglicherweise, aber Sie müssen zuerst sudo-Zugriff haben.
Zuerst starten Sie Ihren Prozess als Root-Benutzer mit sudo myApp
, sobald der Port gebunden wurde, können Sie den Eigentümer des Prozesses auf einen nicht privilegierten Benutzer umstellen.
Lösung 4:
Ich erinnere mich dunkel an eine Bibliothek namens "authbind", die das tut, was Sie brauchen, indem sie den Systemaufruf bind() (über eine LD_PRELOAD-Bibliothek) umschließt und, wenn ein privilegierter Port angefordert wird, ein setuid-Root-Programm erzeugt, das eine Kopie von erhält Dateideskriptor, überprüft dann, ob die Anwendung tatsächlich an den Port binden darf, führt bind() aus und beendet sich.
Ich bin mir über den Projektstatus nicht sicher, aber die Methode sollte bei Bedarf ziemlich einfach (erneut) implementiert werden können.