Wie kann ich mithilfe von Setcap eine Remote-Portweiterleitung auf Port 80 zu meinem lokalen Host einrichten?

Wie kann ich mithilfe von Setcap eine Remote-Portweiterleitung auf Port 80 zu meinem lokalen Host einrichten?

Ich möchte Verbindungen kurzzeitig zur Entwicklung akzeptieren, wenn ich per NAT verbunden bin, und versuche daher Folgendes:

$ ssh [email protected] -R 80:localhost:80

Das schlägt fehl, da ich versuche, einen Port zu binden, der zu niedrig ist:

Warning: remote port forwarding failed for listen port 80

Ich habe also herausgefunden, was ich tun kann, setcap 'cap_net_bind_service=+ep' /my/applicationum es zu ermöglichen, auf Ports unter 1024 zu lauschen. Ich habe also Folgendes in meiner Suders-Crontab:

@reboot setcap 'cap_net_bind_service=+ep' /usr/sbin/sshd

Aber ich kann mich immer noch nicht an Port 80 binden. Was mache ich falsch? Ich werde stattdessen einfach nginx als Proxy für 8080 oder iptables oder so etwas verwenden, aber ich frage mich immer noch, warum das, was ich versucht habe, nicht funktioniert hat.

Antwort1

Wie in @dwurf's erklärtakzeptierte Antwort, sshwird für den Benutzer nur an Ports unter 1024 gebunden root.

Dies ist ein großartiger Anwendungsfall, socatwenn Sie dies nicht sind root.

Führen Sie zunächst eine Remote-Weiterleitung an den Port 8080(oder einen anderen zulässigen Port) des Remote-Computers durch:

ssh [email protected] -R 8080:localhost:80

Ordnen Sie dann auf dem Remotecomputer den Port 80den folgenden Port zu 8080:

sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

Anmerkungen:

Wie von Dirk Hoffman vorgeschlagen, können diese beiden Befehle in einer einzigen Zeile kombiniert werden:

ssh -t [email protected] -R 8080:localhost:80 sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

(Dies -tist erforderlich, falls Sie zur Eingabe Ihres sudoPassworts ein interaktives Terminal benötigen.)

Antwort2

OpenSSH wird die Verbindung zu privilegierten Ports grundsätzlich ablehnen, es sei denn, die Benutzer-ID des angemeldeten Benutzers ist 0 (root). Die relevanten Codezeilen sind:

if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0) ||
    (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");

Quelle:http://www.openssh.com/cgi-bin/cvsweb/src/usr.bin/ssh/serverloop.c?annotate=1.162Zeilen 1092-1098

Wenn Sie neugierig sind, pwist vom Typ struct passwd *und unter Linux ist definiert in/usr/include/pwd.h

Antwort3

Ich habe ein ähnliches Problem, daher bin ich zu der Lösung gekommen, indem ich DNATder OUTPUTTabellenkette eine Regel hinzufüge nat:

iptables -t nat -A OUTPUT -d 127.0.0.0/8 -p tcp --dport 80 \
-j DNAT --to-destination :8080

Diese Regel ersetzt den Zielport 80 für alle lokal generierten TCP-Pakete effektiv durch 8080.

Wenn Sie auch die Weiterleitung eingehender Verbindungen zulassen möchten, fügen Sie der PREROUTING natKette eine zusätzliche Regel hinzu:

iptables -t nat -A PREROUTING -d 10.0.0.200 -p tcp --dport 80 \
-j REDIRECT --to-port 8080

wobei 10.0.0.200die IP-Adresse der Schnittstelle ist, die eingehende Verbindungen an Ihren Webdienst weiterleiten soll

Antwort4

Ausarbeitung des Lösungsvorschlags vonBen Maresüber,

unten ist ein Einzeiler, der:

öffnet zwei Remote-Port-Weiterleitungen:
1. Remote-Port 8888 zum lokalen Port 80
2. Remote-Port 8443 zum lokalen Port 443

Auf dem Remote-Rechner verbindet Socat alles, was
1. auf Port 80 ankommt, um zu Port 8888 gestreamt zu werden,
   der dann zu Port 80 des lokalen Hosts getunnelt
wird. 2. auf Port 443 ankommt, um zu Port 8443 gestreamt zu werden,
   der dann zu Port 443 des lokalen Hosts getunnelt wird.

ssh -t -i ~/.ssh/id_rsa \
    -R 0.0.0.0:8888:0.0.0.0:80 \
    -R 0.0.0.0:8443:0.0.0.0:443 \
    remoteUser@remoteMachine \
    -- "(sudo socat TCP-LISTEN:80,fork TCP:localhost:8888) & \
        sudo socat TCP-LISTEN:443,fork TCP:localhost:8443"

Wenn Sie also den Befehl ausführen, müssen Sie Ihr Root-Passwort des Remote-Rechners eingeben (um die Ports 80/443 auflisten zu können) und dann (solange der Tunnel hergestellt ist) wird alles, was auf Port 80 oder 443 des Remote-Hosts ankommt, zu den Ports 80 bzw. 443 Ihres lokalen Rechners getunnelt...

erinnern!!

Um an alle Netzwerkschnittstellen (0.0.0.0) binden zu können, müssen Sie Ihre Remote-Rechner bearbeiten /etc/ssh/sshd_configund festlegen GatewayPorts clientspecifiedoderGatewayPorts yes

Sie können dies auf dem Remotecomputer überprüfen, netstat -tlpn | grep -E '8888|8443'worauf Folgendes angezeigt werden sollte:

tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      -

und nicht

tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8443          0.0.0.0:*               LISTEN      -

verwandte Informationen