Запустите ssh как несуществующий/виртуальный пользователь

Запустите ssh как несуществующий/виртуальный пользователь

Есть ли способ запуститься sshот имени пользователя, которого нет на хосте, инициирующем SSH-соединение?

Допустим, у меня есть удаленный хост с настроенной учетной записью и запущенным sshd. Я могу подключиться к этой машине по ssh с помощью ssh remote-user@remote-host. Если у меня есть ключи настройки, ssh будет использовать их, а если ни один ключ не подойдет, он запросит у меня пароль. Предположим, что включена аутентификация по паролю.

Допустим, у меня есть образ Docker, вызываемый docker-imageс установленным ssh и другим необходимым программным обеспечением. Я могу запустить контейнер и ssh без проблем. Обратите внимание, что пользователь root существует.

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: 

Если я запускаю контейнер, используя пользователя, которого нет в образе, я не смогу подключиться к удаленному хосту с помощью 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

Ошибка исходит отssh.c:

    /* Get user data. */
    pw = getpwuid(getuid());
    if (!pw) {
        logit("No user exists for uid %lu", (u_long)getuid());
        exit(255);
    }

Сообщение об ошибке имеет смысл, поскольку ssh использует файлы sshconfig, keys, knownhosts и т. д. из домашнего каталога пользователя, но я думаю, что можно было бы ожидать, что оно будет работать, если пользователь укажет другие местоположения для этих файлов, как показано ниже.

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

В приведенной выше команде ни один из файлов, необходимых ssh (насколько я могу судить), не находится в домашнем каталоге пользователя. Есть ли способ запустить ssh в этом случае без необходимости монтировать host's /etc/passwdили монтировать поддельный файл passwd или возиться с /etc/passwdфайлом или создавать локального пользователя в образе? Я упускаю какие-либо варианты?

Какая разница, кто является владельцем процесса ssh на клиенте? Есть ли веская причина принудительной проверки локального пользователя или это просто вариант реализации, который приняли разработчики ssh?

решение1

У меня возникла та же проблема: мне нужно было запустить sshDocker-контейнер без записи в /etc/passwd.

Поскольку у меня нет доступа к хосту или прав root внутри самого контейнера, я просто заменил проблемный код...


Предупреждение:Безопасность не является проблемой в моем случае использования, поэтому я полностью согласен на все испортить, пока это работает. Я понятия не имею, вызовет ли это проблемы безопасности в будущем, поэтому, пожалуйста, действуйте на свой страх и риск. Это быстрый и грязный хак, чтобы выполнить работу любой ценой:


Внутри ssh.cя заменил вызов на getpwuid(getuid()):

/* 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;

И в misc.cя изменил 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;
}

Связанный контент