Ejecute ssh como un usuario virtual/inexistente

Ejecute ssh como un usuario virtual/inexistente

¿Existe alguna forma de ejecutarlo sshcomo 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-imagecon 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/passwdo montar un archivo de contraseña falso o alterar el /etc/passwdarchivo 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 sshdesde 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.creemplacé 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.cmodifiqué 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;
}

información relacionada