以不存在/虛擬使用者身分執行 ssh

以不存在/虛擬使用者身分執行 ssh

有沒有辦法ssh以啟動 ssh 連線的主機上不存在的使用者身分執行?

假設我有一個遠端主機,設定了帳戶並運行 sshd。我可以使用 ssh 進入該機器ssh remote-user@remote-host。如果我有設定密鑰,ssh 將使用它,如果沒有密鑰起作用,它會提示我輸入密碼。假設啟用了密碼身份驗證。

假設我有一個名為docker-imagessh 的 Docker 映像,並安裝了其他所需的軟體。我可以毫無問題地啟動容器和 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,而無需安裝主機/etc/passwd或安裝偽造的 passwd 檔案或弄亂/etc/passwd檔案或在映像中建立本機使用者?我是否忽略了任何選擇?

客戶端上 ssh 進程的擁有者是誰有什麼關係呢?強製本地用戶檢查是否有充分的理由,或者這只是 ssh 開發人員採用的實作選項?

答案1

所以我遇到了同樣的問題:我需要ssh從 docker 容器內部運行,而無需在/etc/passwd.

由於我無法存取主機,也無法存取容器本身內部的根存取權限,所以我只是繼續替換有問題的程式碼...


警告:在我的用例中,安全性不是一個問題,所以只要它能正常工作,我完全可以接受把事情搞砸。我不知道這是否會導致安全問題,因此請自行承擔風險。這是一個不惜一切代價完成工作的快速而骯髒的駭客:


在裡面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;
}

相關內容