Ich habe lange über eine Lösung gegoogelt, aber keine Antwort gefunden.
Ich arbeite unter Ubuntu Linux und möchte einen Server auf Port 80 ausführen. Aufgrund des Sicherheitsmechanismus von Ubuntu erhalte ich jedoch die folgende Fehlermeldung:
java.net.BindException: Berechtigung verweigert: 80
Ich denke, es sollte einfach genug sein, diesen Sicherheitsmechanismus entweder zu deaktivieren, damit Port 80 für alle Benutzer verfügbar ist, oder dem aktuellen Benutzer die erforderlichen Berechtigungen für den Zugriff auf Port 80 zuzuweisen.
Antworten:
Kurze Antwort: Das kannst du nicht. Ports unter 1024 können nur von root geöffnet werden. Wie im Kommentar erwähnt, können Sie mit CAP_NET_BIND_SERVICE , aber dieser Ansatz, der auf Java Bin angewendet wird, bewirkt , dass jedes Java-Programm mit dieser Einstellung ausgeführt wird. Dies ist unerwünscht, wenn nicht sogar ein Sicherheitsrisiko.
Die lange Antwort: Sie können Verbindungen auf Port 80 auf einen anderen Port umleiten, den Sie als normaler Benutzer öffnen können.
Als root ausführen:
Da Loopback-Geräte (wie localhost) die Prerouting-Regeln nicht verwenden, falls Sie localhost usw. verwenden müssen, fügen Sie auch diese Regel hinzu ( danke @Francesco ):
ANMERKUNG: Die obige Lösung eignet sich nicht für Systeme mit mehreren Benutzern, da jeder Benutzer den Port 8080 (oder einen anderen hohen Port, den Sie verwenden möchten) öffnen und so den Datenverkehr abfangen kann. ( Dank an CesarB ).
BEARBEITEN: gemäß Kommentarfrage - um die obige Regel zu löschen:
Dies wird ungefähr so aussehen:
Die Regel, die Sie interessiert, ist nr. 2, um es zu löschen:
quelle
sudo iptables --list
. Ich weiß, was iptables ist und macht, aber ich habe es vorher noch nie wirklich benutzt.Benutze authbind .
Es funktioniert sogar mit Java, wenn Sie den Nur-IPv4-Stack von Java aktivieren. Ich benutze:
quelle
AUTHBIND=yes
in / etc / default / tomcat6authbind
, um dies tatsächlich zuzulassen. Auf der Manpage: "/ etc / authbind / byport / port wird getestet. Wenn diese Datei gemäß access (2) für den aufrufenden Benutzer zur Ausführung verfügbar ist, wird die Bindung an den Port autorisiert." ZB für Port 80sudo touch /etc/authbind/byport/80 ; sudo chmod 777 /etc/authbind/byport/80
. Bei der Erstinstallation von sindauthbind
im Allgemeinen keine Berechtigungen vorkonfiguriert.Wenn Ihr System dies unterstützt, können Sie möglicherweise Funktionen verwenden. Siehe man Fähigkeiten, die Sie benötigen, wäre CAP_NET_BIND_SERVICE.
Unter neuerem Debian / Ubuntu können Sie Folgendes ausführen:
quelle
Eine andere Lösung besteht darin, Ihre App so einzurichten, dass sie mit Port 80 verbunden werden kann. Führen Sie als Root die folgenden Schritte aus
Bedenken Sie, dass dies potenzielle Sicherheitslücken birgt, wenn es nicht absolut richtig gemacht wird, da Ihre App mit dem Netzwerk kommuniziert und mit vollständigen Root-Berechtigungen ausgeführt wird. Wenn Sie diese Lösung wählen, sollten Sie sich den Quellcode für Apache oder Lighttpd oder ähnliches ansehen, wo sie die Root-Rechte verwenden, um den Port zu öffnen, aber dann sofort diese Rechte aufgeben und ein Benutzer mit niedrigeren Rechten "werden" Ein Hijacker kann nicht Ihren gesamten Computer übernehmen.
Update: Wie in dieser Frage zu sehen ist, haben Linux-Kernel seit 2.6.24 eine neue Funktion, mit der Sie eine ausführbare Datei (aber natürlich kein Skript) als "
CAP_NET_BIND_SERVICE
" fähig markieren können. Wenn Sie das Debian-Paket "libcap2-bin" installieren, können Sie dies tun, indem Sie den Befehl absetzenquelle
Ich benutze einfach Nginx vor. Es kann auch auf localhost ausgeführt werden.
apt-get install nginx
.. oder ..
pkg_add -r nginx
.. oder was auch immer zu Ihrem Betriebssystem passt.
Alles was Sie in der nginx.conf brauchen, wenn Sie auf localhost laufen, ist:
quelle
Lösungsvorschlag von Sunny und CesarB:
funktioniert gut, hat aber einen kleinen Nachteil - es hindert den Benutzer nicht daran, eine direkte Verbindung zu Port 8080 anstelle von 80 herzustellen.
Stellen Sie sich das folgende Szenario vor, wenn dies ein Problem sein kann.
Angenommen, wir haben einen Server, der HTTP-Verbindungen an Port 8080 und HTTPS-Verbindungen an Port 8181 akzeptiert.
Wir verwenden iptables, um die folgenden Weiterleitungen einzurichten:
Angenommen, unser Server leitet Benutzer von einer HTTP-Seite auf eine HTTPS-Seite um. Wenn wir die Antwort nicht sorgfältig umschreiben, wird sie an weitergeleitet
https://host:8181/
. An diesem Punkt sind wir geschraubt:https://host:8181/
URL mit einem Lesezeichen versehen, und wir müssten diese URL beibehalten, um zu vermeiden, dass ihre Lesezeichen beschädigt werden.Ich benutze den folgenden Ansatz:
In Kombination mit der standardmäßigen REJECT-Regel in der INPUT-Kette verhindert dieser Ansatz, dass Benutzer eine direkte Verbindung zu den Ports 8080, 8181 herstellen
quelle
Traditionell kann unter Unix nur root Verbindungen zu niedrigen Ports herstellen (<1024).
Die einfachste Möglichkeit, dies zu umgehen, besteht darin, Ihren Server auf einem hohen Port (z. B. 8080) auszuführen und die Verbindungen von Port 80 nach Port 8080 mithilfe einer einfachen iptables-Regel weiterzuleiten. Beachten Sie, dass Sie dadurch den zusätzlichen Schutz von verlieren niedrige Häfen; Jeder Benutzer auf Ihrem Computer kann eine Bindung zu Port 8080 herstellen.
quelle
Wenn Ihr System dies unterstützt, können Sie möglicherweise Funktionen verwenden. Sehen Sie
man capabilities
, derjenige, den Sie brauchen, wäreCAP_NET_BIND_SERVICE
. Nein, ich habe sie noch nie benutzt und ich weiß nicht, ob sie wirklich funktionieren :-)quelle
Verwenden Sie einen Reverse-Proxy (nginx, apache + mod_proxy) oder einen Caching-Reverse-Proxy (Squid, Varnish) vor Ihren Anwendungsservern!
Mit einem Reverse-Proxy können Sie viele interessante Dinge erreichen, wie:
quelle
Sie können das Redir-Programm verwenden:
quelle
Benutze sudo.
Konfigurieren Sie sudo so, dass der normale Benutzer die entsprechenden Befehle ausführen kann:
Oder
Oder
Oder
(Oder welcher andere Befehl / Skript, den Sie zum Starten / Stoppen eines bestimmten Webservers / einer bestimmten App verwenden)
quelle
Die Antwort von sunny ist korrekt, es können jedoch weitere Probleme auftreten, da die Loopback-Schnittstelle die PREROUTING-Tabelle nicht verwendet.
Die Iptables-Regeln, die hinzugefügt werden müssen, sind zwei:
quelle
Unter Linux haben Sie zwei weitere Möglichkeiten:
Mit beiden Erweiterungen des Linux-Kernels können Zugriffsrechte auf einer sehr detaillierten Ebene erteilt werden. Auf diese Weise können Sie diesem Prozess das Öffnen von Port 80 gewähren, erbt jedoch keine der anderen Root-Rechte.
Soweit ich gehört habe, ist grsecurity viel einfacher zu verwenden, SELinux ist jedoch sicherer.
quelle
Eine Lösung besteht darin, iptables zu verwenden, um PAT für Pakete für Port 80 auszuführen. Sie können dies beispielsweise verwenden, um die Pakete an den lokalen Port 8080 weiterzuleiten. Stellen Sie sicher, dass die ausgehenden Pakete wieder auf Port 80 eingestellt sind.
Nach meiner Erfahrung werden die detaillierten Berechtigungsfunktionen von Linux aus Sicherheitsgründen nicht in Standard-Kernel kompiliert.
quelle
Wenn Sie dies versuchen, damit ein vom Benutzer ausgeführter Befehl Port 80 verwenden kann, sind Ihre einzigen Lösungen die iptables-Tricks oder das Festlegen der ausführbaren Datei setuid-to-root.
So wie Apache dies tut (es wird an Port 80 gebunden, aber nicht als Root ausgeführt), wird als Root ausgeführt, an den Port gebunden und anschließend nach dem Port der Besitzer des Prozesses an den nicht privilegierten Benutzer geändert ist eingerichtet. Wenn die App schreiben Sie können laufen von root, können Sie es Eigentümer an den nicht-priv Benutzers ändern, nachdem die Ports eingerichtet werden. Wenn dies jedoch nur für einen durchschnittlichen Benutzer gilt, der über die Befehlszeile ausgeführt wird, müssen Sie eine der anderen Lösungen verwenden.
quelle
Wenn ich verschiedene Web-Serving-Anwendungen (Python-Skripte, Tomcat-Engines, ...) habe, die ich nicht als Root ausführen möchte, konfiguriere ich normalerweise einen Apache-Webserver vor ihnen. Apache lauscht auf Port 80 und Tomcat lauscht auf 8080.
In Apache: s Konfiguration:
Weitere Informationen finden Sie in der Mod-Proxy-Dokumentation: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
quelle
Ich denke, die beste Lösung ist es, Ihre App zu sgiden und sobald der Port gebunden ist, sollten die Berechtigungen durch einen Wechsel zu einem anderen Benutzer verworfen werden.
quelle
Einige Hostsysteme erlauben die Verwendung des NAT-Moduls nicht. In diesem Fall löst 'iptables' das Problem nicht.
Wie wäre es mit Xinetd?
In meinem Fall (Ubuntu 10.04)
Fügen Sie die Konfiguration ein:
Dann:
http://docs.codehaus.org/display/JETTY/port80 erklärt besser.
quelle
Abgesehen davon können Sie dies mit FreeBSD und Solaris (jemand erinnert sich daran ?) Ohne erweiterte Rechte (dh mit Programmen zum Wechseln zu root) tun (an niedrige Ports binden). Da Sie Linux angegeben haben, sende ich dies nur als Hinweis an andere, die diese Frage möglicherweise finden.
quelle
Nekromanzierung.
Einfach. Mit einem normalen oder alten Kernel ist dies nicht der Fall.
Wie bereits von anderen erwähnt, können iptables einen Port weiterleiten.
Wie auch von anderen erwähnt, kann CAP_NET_BIND_SERVICE auch die Aufgabe übernehmen.
Natürlich schlägt CAP_NET_BIND_SERVICE fehl, wenn Sie Ihr Programm von einem Skript aus starten, es sei denn, Sie setzen die Obergrenze für den Shell-Interpreter, was sinnlos ist. Sie können Ihren Dienst genauso gut als root ausführen ...
z. B. für Java müssen Sie ihn anwenden an die JAVA JVM
Dies bedeutet natürlich, dass jedes Java-Programm System-Ports binden kann.
Dito für Mono / .NET.
Ich bin mir auch ziemlich sicher, dass xinetd nicht die besten Ideen sind.
Aber da beide Methoden Hacks sind, warum nicht einfach das Limit durch Aufheben der Beschränkung aufheben?
Niemand hat gesagt, dass Sie einen normalen Kernel ausführen müssen, also können Sie einfach Ihren eigenen Kernel ausführen.
Sie laden einfach den Quellcode für den neuesten Kernel herunter (oder den gleichen, den Sie aktuell haben). Anschließend gehen Sie zu:
Dort suchen Sie nach dieser Zeile
und ändere es auf
Wenn Sie keine unsichere SSH-Situation haben möchten, ändern Sie diese folgendermaßen: #define PROT_SOCK 24
Im Allgemeinen würde ich die niedrigste Einstellung verwenden, die Sie benötigen, z. B. 79 für http oder 24, wenn Sie SMTP an Port 25 verwenden.
Das ist schon alles.
Kompilieren Sie den Kernel und installieren Sie ihn.
Starten Sie neu.
Fertig - diese dumme Grenze ist GEGANGEN und das funktioniert auch für Skripte.
So kompilieren Sie einen Kernel:
https://help.ubuntu.com/community/Kernel/Compile
Kurz gesagt, verwenden Sie iptables, wenn Sie sicher bleiben möchten, und kompilieren Sie den Kernel, wenn Sie sicher sein möchten, dass diese Einschränkung Sie nie wieder stört.
quelle
sudo setcap cap_net_bind_service=+ep /path-to-java/java
), aber ich bekomme immer,java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
wenn Java Caps gesetzt hat. Siehe auch den ersten Teil von unix.stackexchange.com/a/16670/55508<javahome>/lib/amd64/jli/
vonld.so.conf
und Ausführen vonsudo ldconfig