sshd "auf alle Schnittstellen hören" Verhalten, OSX und Ubuntu

610
Congee

Angesichts einer zusätzlichen Loopback-Schnittstelle im Bereich 127.0.0.X( X> 1) von BoxA (die entweder OSX oder Linux ausführen kann), möchte ich den Port 22 dieser zusätzlichen Loopback-Schnittstelle an einen SSH-Forward-Tunnel (dh einen lokalen Port Forward) binden, auf den verwiesen wird bei BoxB.

Unter OSX funktioniert das gut (seltsam im Nachhinein). [Taking X= 2] Nachdem der Loopback-Alias ​​mit ifconfig lo0 alias 127.0.0.2 upaufgerufen wurde, kann SSH einen Tunnel mit erstellen ssh -NfL 127.0.0.2:22:localhost:22 BoxB. Dann ssh 127.0.0.2meldet mich in einer neuen Shell bei BoxA bei BoxB an.

Auf Ubuntu kann ich den Loopback-Alias ​​auf BoxA aufrufen, aber wenn ich den SSH-Tunnel aufbauen möchte, sshklagt er darüber, dass er nicht in der Lage ist, BoxA zu binden (und daher weiterzuleiten). Der nachfolgende ssh 127.0.0.2(in einer neuen Shell auf BoxA) gibt ein Fingerabdruckwarnung, die, wenn sie umgangen wird, mich wieder in BoxA einloggt. Sinn macht - sshdon BoxA hört auf alle Schnittstellen.

Wenn man sich die sshd_configin betrachtet, sind beide für das Abhören 0.0.0.0(und ::für IPv6) konfiguriert .

lsof für OSX gibt:

launchd 1 root 40u IPv6 0xddfcabed61001f0d 0t0 TCP *:ssh (LISTEN) launchd 1 root 41u IPv4 0xddfcabed6100413d 0t0 TCP *:ssh (LISTEN) launchd 1 root 43u IPv6 0xddfcabed61001f0d 0t0 TCP *:ssh (LISTEN) launchd 1 root 44u IPv4 0xddfcabed6100413d 0t0 TCP *:ssh (LISTEN) 

und für Ubuntu:

sshd 1287 0 3u IPv4 21903340 0t0 TCP *:ssh (LISTEN) 

Beide hören also auf alle Schnittstellen, obwohl ich nicht sicher bin, warum OSX 4 Prozesse verwendet. In jedem Fall gibt Ubuntu das erwartete Verhalten an. Warum verhält sich OSX anders?

Die Folgefrage ist natürlich, wie man Ubuntu in dieser Hinsicht wie OSX benimmt.

Während ich auf den Wunsch sshd_configZustand, Platzhalter und / oder logische Operatoren (zB „hört nicht auf 127.0.0.*, hört auf 127.0.0.1“), wie iptableses nicht der Fall zu sein scheint ...

0
Sie brauchen nicht mit X zu spielen. Verwenden Sie einfach `ssh -NfL 22: localhost: 22 BoxB` und stellen Sie als localhost eine Verbindung zum getunnelten Port her: 22 Alex vor 6 Jahren 0
Es gibt einen channel_setup_fwd_listener_tcpip-Fehler mit "bind: Adresse wird bereits verwendet" für ein gutes Maß (auf Ubuntu). Congee vor 6 Jahren 0
Das heißt, Sie binden bereits etwas an denselben Port. Wenn Sie mehrere Tunnel zu anderen Boxen haben oder ein lokaler Dienst es bereits für einen bestimmten Zweck verwendet hat, verwenden Sie einfach einen anderen lokalen Port, der nicht verwendet wird: `ssh -NfL 20001: localhost: 22 BoxA`,` ssh -NfL 20002: localhost: 22 BoxB`, `ssh -NfL 20003: localhost: 22 BoxC` und so weiter ... Verwenden Sie` netstat -lntp`, um lokale / freie Ports zu finden Alex vor 6 Jahren 0
Ja, sshd auf BoxA verwendet Port 22, der in der Ausgabe "lsof" deutlich sichtbar ist. Die ganze Frage ist, warum OSX das Weiterleiten erlaubt: 22 bei neuen Loopback-Schnittstellen und Ubuntu ... Congee vor 6 Jahren 0

1 Antwort auf die Frage

0
A.B

Das ist reproduzierbar mit socat( 1.7.3.2-2nicht 1.7.3.1-2+deb9u1die ignoriert reuseport ) auf Debian (so ähnlich für Ubuntu):

term1$ socat -d -d TCP4-LISTEN:5555,reuseaddr,fork - 2018/08/03 08:20:43 socat[25084] N listening on AF=2 0.0.0.0:5555  term2$ socat -d -d TCP4-LISTEN:5555,bind=127.0.0.2,reuseaddr,fork - 2018/08/03 08:21:00 socat[25085] E bind(5,, 16): Address already in use 2018/08/03 08:21:00 socat[25085] N exit(1) 

Wenn Sie jetzt reuseport beide hinzufügen :

term1$ socat -d -d TCP4-LISTEN:5555,reuseaddr,reuseport,fork - 2018/08/03 08:21:28 socat[25086] N listening on AF=2 0.0.0.0:5555  term2$ socat -d -d TCP4-LISTEN:5555,bind=127.0.0.2,reuseaddr,reuseport,fork - 2018/08/03 08:21:56 socat[25092] N listening on AF=2 127.0.0.2:5555   otherterm$ netstat -tnlp 2>/dev/null|grep :5555  tcp 0 0 127.0.0.2:5555 0.0.0.0:* LISTEN 25092/socat  tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN 25086/socat  

Wenn Sie zum socatHerstellen einer Verbindung ein anderes oder ein netcat-Gerät verwenden, wird socatabhängig von der IP-Adresse angezeigt, dass die Verbindung korrekt ist .

Der Verhaltensunterschied hängt also ganz sicher davon ab, wie bindund setsockoptunter MacOS und Ubuntu für ssh aufgerufen werden (vielleicht hat launchd auch eine Rolle?). Mit stracewird dies im Arbeitsfall hinzugefügt socat:

 setsockopt(5, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0 

UPDATE :
Ich werde mich zwar mit dem Buchstaben der OP-Frage befassen: Damit es funktioniert, denke ich auch, dass die Frage nicht über das umfassendere Ziel aussagt, und dieses Ziel könnte mit einer völlig anderen Lösung erreicht werden.

Um zu ändern sshdund das sshVerhalten beim Binden eines Sockets zu ändern, ist es möglich, einen dlsym()Wrapper zu verwenden, der das bind(3)Funktionsverhalten vor dem eigentlichen bind(2)Syscall ändert .

kompilieren Sie die folgende Datei reuseport-wrapper.cmit:

gcc -shared -fPIC -o reuseport-wrapper.so reuseport-wrapper.c -ldl

#define _GNU_SOURCE #include <dlfcn.h>  #include <sys/socket.h> #include <stddef.h> /* NULL */  int bind(int socket, const struct sockaddr *address, socklen_t address_len) { static const int optval=1; static int (*orig_bind)(int, const struct sockaddr *,socklen_t)=NULL;  if (orig_bind == NULL && (orig_bind=dlsym(RTLD_NEXT,"bind")) == NULL) return -1; if (address != NULL && (address->sa_family == AF_INET || address->sa_family == AF_INET6)) { if (setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof optval) != 0) { return -1; } } return orig_bind(socket, address, address_len); } 

Dadurch wird immer ein Wrapper bind(3)gesetzt, SO_REUSEPORTbevor ein inetoder ein inet6Socket gebunden wird.

Platziere es irgendwo (zB als /usr/local/lib/reuseport-wrapper.soaber es ist wirklich egal, da es explizit geladen wird wie ein Plugin).

Bearbeiten /etc/default/sshund hinzufügen:

LD_PRELOAD=/usr/local/lib/reuseport-wrapper.so 

Starten Sie den SSH-Server neu (zB service ssh restart)

Führen Sie ein beliebiges anderes Tool (einschließlich ssh) als root (siehe unten, warum) mit LD_PRELOAD=/usr/local/lib/reuseport-wrapper.soexported aus. Zum Beispiel:

$ sudo su - [...] # LD_PRELOAD=/usr/local/lib/reuseport-wrapper.so ssh -NfL 127.0.0.2:22:localhost:22 userB@BoxB 

Dieser Befehl muss aus zwei Gründen als root gestartet werden: Port 22 erfordert, dass root an ihn bindet, und selbst mit einigen zusätzlichen Funktionen gibt es eine zusätzliche Einschränkung, die in beschrieben wird socket(7):

SO_REUSEPORT (seit Linux 3.9)
Lässt zu, dass mehrere AF_INET- oder AF_INET6-Sockets an eine identische Socketadresse gebunden werden. Diese Option muss für jeden Sockel (einschließlich des ersten Sockels) festgelegt werden, bevor bind (2) am Sockel aufgerufen wird. Um das Port-Hijacking zu verhindern, müssen alle an dieselbe Adresse gebundenen Prozesse dieselbe effektive UID haben . Diese Option kann sowohl für TCP- als auch für UDP-Sockets verwendet werden.

Sobald dies erledigt ist:

# netstat -tnlp |grep -w 22 tcp 0 0 127.0.0.2:22 0.0.0.0:* LISTEN 157/ssh  tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 143/sshd  tcp6 0 0 :::22 :::* LISTEN 143/sshd  

Und der Tunnel wird wie erwartet funktionieren.

Gute Information, danke. Ich bin mir nicht sicher, ob ich es als Antwort an sich akzeptiere, da es das Problem nicht löst (vorausgesetzt, dass es überhaupt fixierbar ist), sondern nützliche Informationen liefert ... Congee vor 6 Jahren 0
Es wurde eine "funktionierende" Lösung hinzugefügt, um etwas anderes hervorzuheben. Möglicherweise versteckt sich die Frage [ein XY-Problem] (https://meta.stackexchange.com/questions/66377/what-is-the-xy- problem). A.B vor 6 Jahren 0
@Congee also hast du mein Update versucht? Damit funktioniert es wie in der Frage, nicht wahr? Ich habe geantwortet, warum es einen Unterschied gibt und wie Ubuntu funktioniert. A.B vor 6 Jahren 0