Wie kann man Reverse-SSH-Tunelling-Ports einschränken?

9

Wir haben einen öffentlichen Server, der SSH-Verbindungen von mehreren Clients hinter Firewalls akzeptiert.

Jeder dieser Clients erstellt einen Reverse-SSH-Tunnel, indem er den ssh -RBefehl von seinen Webservern an Port 80 zu unserem öffentlichen Server verwendet.

Der Zielport (auf der Clientseite) des Reverse-SSH-Tunnels ist 80, und der Quellport (auf der Seite des öffentlichen Servers) hängt vom Benutzer ab. Wir planen, für jeden Benutzer eine Karte mit Portadressen zu erstellen.

Zum Beispiel würde Client A seinen Webserver an Port 80 zu unserem Port 8000 tunneln. Client B von 80 bis 8001; Client C von 80 bis 8002.

Client A: ssh -R 8000:internal.webserver:80 clienta@publicserver

Client B: ssh -R 8001:internal.webserver:80 clientb@publicserver

Client C: ssh -R 8002:internal.webserver:80 clientc@publicserver

Grundsätzlich versuchen wir, jeden Benutzer an einen Port zu binden und ihm nicht zu erlauben , zu anderen Ports zu tunneln.

Wenn wir die Forward-Tunneling-Funktion von SSH mit verwenden ssh -L, können wir mithilfe der permitopen=host:portKonfiguration zulassen, welcher Port getunnelt wird . Es gibt jedoch kein Äquivalent für den umgekehrten SSH-Tunnel.

Gibt es eine Möglichkeit, Reverse-Tunneling-Ports pro Benutzer einzuschränken?

Utku Zihnioglu
quelle
1
Nur durch systemweite Richtlinien wie SELinux oder IPTABLES.
Andrew Smith

Antworten:

6

Da Sie " Nicht zulassen" fett gedruckt haben, möchten Sie vermutlich eine Art Laufzeit-Zurückweisung auf der SSH-Clientseite, die die Portbindung verhindert. Also habe ich den Quellcode für Sie ausgegraben:

serverloop.c:

/* check permissions */
if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
    || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)
#endif
    ) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");
} else {
        /* Start listening on the port */
        success = channel_setup_remote_fwd_listener(
            listen_address, listen_port,
            &allocated_listen_port, options.gateway_ports);
}

Wie Sie sehen, gibt es leider nicht viele Bedingungen, die eine Portweiterleitung außer den Standardbedingungen verhindern.

Ich wollte den gleichen Vorschlag für die Verwendung mod_ownerin iptablesmir empfehlen , aber Jeff hat mich geschlagen.

Ihre sauberste Lösung würde nur darin bestehen, diese Datei zu ändern (Sie können beispielsweise pw->pw_uiddie UID des Benutzers abrufen und diese dem richtigen Port zuordnen) und Ihren SSH-Server neu zu kompilieren. Dies hängt jedoch davon ab, wie gut Sie damit vertraut sind .

Jay
quelle
Das ist sehr gut. Ich kann tatsächlich die gleiche Syntax von der Option -L (Tunneling) kopieren und zum Laufen bringen. Danke.
Utku Zihnioglu
3

Mein Vorschlag ist die Verwendung von SELinux. Sie müssen Benutzerprofile konfigurieren, mit denen die Ports geöffnet werden können. Der sshdProzess teilt die Berechtigungen des Benutzers auf, bevor ein Port zum Weiterleiten geöffnet wird, sodass alle auf die Prozesse des Benutzers angewendeten Funktionen erzwungen werden sshd. Beachten Sie, dass Sie sich auf alle Benutzerprozesse beschränken müssen, da dies einmal netcatzum Weiterleiten eines anderen Ports verwendet werden kann. Ich werde später versuchen, die richtige Syntax für Sie zu finden (oder jeder andere Benutzer kann sie gerne für mich bearbeiten).

Alternativ können Sie versuchen, zu verwenden iptables.

iptables -m owner --add-owner $user -p tcp --sport 8000 -j ACCEPT
iptables -m owner --add-owner $user -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT

Dies hindert sie jedoch nicht daran, den Port zu öffnen und einen anderen Benutzer zu verweigern.

Jeff Ferland
quelle
Danke für die tolle Antwort. Ich werde die Konfiguration der SELinux / Benutzerprofile ausprobieren. Es klingt wie die Lösung für meine Frage.
Utku Zihnioglu