
Gibt es eine Möglichkeit, ssh
als Benutzer zu arbeiten, der auf dem Host, der die SSH-Verbindung initiiert, nicht existiert?
Angenommen, ich habe einen Remote-Host mit einem eingerichteten Konto und sshd läuft. Ich kann mich per SSH mit diesem Rechner verbinden ssh remote-user@remote-host
. Wenn ich Schlüssel eingerichtet habe, wird SSH diese verwenden. Wenn keine Schlüssel funktionieren, werde ich nach dem Passwort gefragt. Angenommen, die Passwortauthentifizierung ist aktiviert.
Angenommen, ich habe ein Docker-Image docker-image
mit SSH und anderer erforderlicher Software installiert. Ich kann den Container und SSH problemlos starten. Beachten Sie, dass der Root-Benutzer vorhanden ist.
hostname$ docker run -it --rm docker-image bash
container-id$ whoami
root
container-id$ ssh remote-user@remote-host
remote-user@remote-host's password:
Wenn ich einen Container mit einem Benutzer starte, der im Image nicht vorhanden ist, kann ich keine SSH-Verbindung zum Remote-Host herstellen.
hostname$ docker run -it --rm -u 1234:100 docker-image bash
container-id$ whoami
whoami: cannot find name for user ID 1234
container-id$ ssh remote-user@remote-host
No user exists for uid 1234
container-id$ echo $?
255
Der Fehler kommt vonssh.c:
/* Get user data. */
pw = getpwuid(getuid());
if (!pw) {
logit("No user exists for uid %lu", (u_long)getuid());
exit(255);
}
Die Fehlermeldung ist nachvollziehbar, da SSH die Dateien „sshconfig“, „Keys“, „Knownhosts“ usw. aus dem Home-Verzeichnis des Benutzers verwendet, aber ich denke, man würde erwarten, dass es funktioniert, wenn der Benutzer unterschiedliche Speicherorte für diese Dateien angibt, wie unten gezeigt.
ssh -vvv -i /dev/null -F /dev/null \
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
-o PubkeyAuthentication=no -o PreferredAuthentications=password \
-o PasswordAuthentication=yes
remote-user@remote-host
Im obigen Befehl befinden sich (soweit ich das beurteilen kann) keine der Dateien, die SSH benötigt, im Home-Verzeichnis des Benutzers. Gibt es in diesem Fall eine Möglichkeit, SSH auszuführen, ohne Hosts /etc/passwd
oder eine gefälschte Passwd-Datei mounten oder mit Dateien herumspielen /etc/passwd
oder einen lokalen Benutzer im Image erstellen zu müssen? Übersehe ich irgendwelche Optionen?
Welche Rolle spielt es, wer der Eigentümer des SSH-Prozesses auf dem Client ist? Gibt es einen guten Grund, die lokale Benutzerprüfung zu erzwingen, oder ist dies nur eine Implementierungsoption, die SSH-Entwickler gewählt haben?
Antwort1
Ich hatte also gerade das gleiche Problem: Ich musste es ssh
aus einem Docker-Container heraus ausführen, ohne einen Eintrag in /etc/passwd
.
Da ich weder Zugriff auf den Host noch Root-Zugriff im Container selbst habe, habe ich einfach den fehlerhaften Code ersetzt …
Warnung:Sicherheit ist in meinem Anwendungsfall kein Thema, daher ist es für mich völlig in Ordnung, Dinge durcheinander zu bringen, solange es funktioniert. Ich habe keine Ahnung, ob dies später zu Sicherheitsproblemen führen wird, also gehen Sie bitte auf eigenes Risiko vor. Dies ist ein schneller und einfacher Hack, um die Arbeit um jeden Preis zu erledigen:
Darin ssh.c
habe ich den Aufruf getpwuid(getuid())
durch Folgendes ersetzt:
/* Get user data without using getpwuid
* to run ssh inside a docker container
* without a valid passwd entry for the current user
*/
struct passwd fake_user_data = {
.pw_name = "ssh",
.pw_passwd = "",
.pw_uid = getuid(),
.pw_gid = getgid(),
.pw_gecos = "",
.pw_dir = getenv("HOME"),
.pw_shell = getenv("SHELL")
};
/* pw = getpwuid(getuid()); */
pw = &fake_user_data;
Und misc.c
ich habe Folgendes geändert tilde_expand_filename
:
path = strchr(filename, '/');
struct passwd fake_user_data = {
.pw_dir = getenv("HOME")
};
if (path != NULL && path > filename) { /* ~user/path */
...
} else if ((pw = getpwuid(uid)) == NULL) {
/* bypass missing passwd entry...
fatal("tilde_expand_filename: No such uid %ld", (long)uid); */
pw = &fake_user_data;
}