
¿Existe alguna forma de ejecutarlo ssh
como usuario que no existe en el host que inicia la conexión ssh?
Digamos que tengo un host remoto con una cuenta configurada y sshd en ejecución. Puedo ingresar a esa máquina usando ssh remote-user@remote-host
. Si tengo claves de configuración, ssh las usará y si ninguna clave funciona, me solicitará la contraseña. Supongamos que la autenticación de contraseña está habilitada.
Digamos que tengo una imagen de Docker llamada docker-image
con ssh y otro software requerido instalado. Puedo iniciar el contenedor y ssh sin problemas. Tenga en cuenta que el usuario root existe.
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:
Si inicio un contenedor usando un usuario que no existe en la imagen, no puedo conectarme al host remoto usando ssh.
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
El error viene dessh.c:
/* Get user data. */
pw = getpwuid(getuid());
if (!pw) {
logit("No user exists for uid %lu", (u_long)getuid());
exit(255);
}
El mensaje de error tiene sentido porque ssh usa archivos sshconfig, claves, hosts conocidos, etc. del directorio de inicio del usuario, pero creo que uno esperaría que funcione cuando el usuario especifica diferentes ubicaciones para esos archivos, como se muestra a continuación.
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
En el comando anterior, ninguno de los archivos que ssh necesita (hasta donde yo sé) está en el directorio de inicio del usuario. ¿Hay alguna manera de ejecutar ssh en este caso sin tener que montar el host /etc/passwd
o montar un archivo de contraseña falso o alterar el /etc/passwd
archivo o crear un usuario local en la imagen? ¿Estoy pasando por alto alguna opción?
¿Qué importa quién es el propietario del proceso ssh en el cliente? ¿Existe una buena razón para forzar la verificación del usuario local o es solo una opción de implementación que tomaron los desarrolladores de ssh?
Respuesta1
Entonces tuve el mismo problema: necesitaba ejecutar ssh
desde dentro de un contenedor acoplable sin una entrada en /etc/passwd
.
Como no tengo acceso al host ni a la raíz dentro del contenedor, simplemente seguí adelante y reemplacé el código ofensivo...
Advertencia:La seguridad no es una preocupación en mi caso de uso, por lo que estoy totalmente de acuerdo con estropear las cosas siempre que funcione. No tengo idea si esto causará problemas de seguridad en el futuro, así que continúe bajo su propio riesgo. Este es un truco rápido y sucio para hacer el trabajo a toda costa:
En el interior ssh.c
reemplacé la llamada getpwuid(getuid())
con:
/* 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;
Y en misc.c
modifiqué 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;
}