什麼是「子系統登入」?

什麼是「子系統登入」?

的描述man login包含以下內容:

子系統登入由登入 shell 的第一個字元「*」表示。給定的主目錄將用作使用者實際登入的新檔案系統的根目錄。

我正在嘗試生成 *-shell,但不能。是什麼子系統登入我怎樣才能到達那裡?

我只能得到-bash貝殼,而我期待得到*-bash貝殼。

Debian 11 在這裡,如果有必要的話。

答案1

子系統登入似乎確實是個記錄不足的功能。可能需要瀏覽一些原始程式碼才能弄清楚。讓我們看看 Debian 11 的login.c

處理 a 的部分子系統登入開始於1151號線:

if (pwd->pw_shell[0] == '*') {  /* subsystem root */
        pwd->pw_shell++;    /* skip the '*' */
        subsystem (pwd);    /* figure out what to execute */
        subroot = true; /* say I was here again */
        endpwent ();    /* close all of the file which were */
        endgrent ();    /* open in the original rooted file */
        endspent ();    /* system. they will be re-opened */
#ifdef  SHADOWGRP
        endsgent ();    /* in the new rooted file system */
#endif
        goto top;   /* go do all this all over again */
}

如果在欄位開頭偵測到星號shell,則星號將被刪除(因此您實際上永遠不會*-bash在進程清單中看到 ),並subsystem()為此使用者登入呼叫函數。這pwd是一個結構體,其中包含相當於 中使用者行的資訊/etc/passwd

當觸發子系統登入時,所有密碼和群組條目處理也將終止。從這裡的評論你應該能夠猜測到子系統登入與chroot().

goto top; 跳回第 #717 行,有效地重新啟動身份驗證和會話設定過程,現在使用 chroot 內的設定檔。

subsystem()函數定義在子.c- 事實上,這是該文件中的唯一函數:

/*
 * subsystem - change to subsystem root
 *
 *  A subsystem login is indicated by the presence of a "*" as
 *  the first character of the login shell.  The given home
 *  directory will be used as the root of a new filesystem which
 *  the user is actually logged into.
 */

void subsystem (const struct passwd *pw)
{
    /*
     * The new root directory must begin with a "/" character.
     */

    if (pw->pw_dir[0] != '/') {
        printf (_("Invalid root directory '%s'\n"), pw->pw_dir);
        SYSLOG ((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name));
        closelog ();
        exit (EXIT_FAILURE);
    }

    /*
     * The directory must be accessible and the current process
     * must be able to change into it.
     */

    if (   (chdir (pw->pw_dir) != 0)
        || (chroot (pw->pw_dir) != 0)) {
        (void) printf (_("Can't change root directory to '%s'\n"),
                       pw->pw_dir);
        SYSLOG ((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));
        closelog ();
        exit (EXIT_FAILURE);
    }
}

在這裡我們有它:子系統登入chroot()是登入使用者主目錄的登入名,如 中指定的/etc/passwd。例如,如果您subsys在下列位置定義了使用者/etc/passwd

subsys:x:999:999:Subsystem login example:/home/subsys:*chrooted*

當該使用者使用(即從文字控制台或透過序列埠)登入時login,該使用者將被chroot,以便他們將看到其主目錄/home/subsys/.然後使用 中的設定檔重複身份驗證過程/home/subsys/etc

/etc/passwd請注意,在子系統登入的情況下,第一個字元之後的實際 shell 欄位的內容*將被有效忽略。 chroot 完成後,該login程序將讀取/home/subsys/etc/passwd該使用者將使用的真實 shell。

與往常一樣,在設定 chroot 時,您必須確保 chroot 中存在所有必要的程式庫檔案、設定檔和設備,因為在 chroot 中啟動的程式將無法存取 chroot 以外的任何內容。因此,在本例中,您必須至少建立minimal /home/subsys/lib, /home/subsys/etc(至少包括/home/subsys/etc/passwd, /home/subsys/etc/shadow/home/subsys/etc/pam.d/login也可能包括其他檔案)並且通常至少建立/home/subsys/dev/null.

/home/subsys/dev/ptmx根據您使用子系統登入的用途,您可能還需要其他設備:對於 shell,您可能devpts需要/home/subsys/dev/pts.你可以這樣設定它們:

# these steps need only be done once:
mkdir -p /home/subsys/dev/pts
mknod /home/subsys/dev/null c 1 3
mknod /home/subsys/dev/ptmx c 5 2
chmod 0666 /home/subsys/dev/null /home/subsys/dev/ptmx
# this needs to be re-done after every boot:
mount -t devpts none /home/subsys/dev/pts

因此,您/home/subsys/etc/passwd需要為 chrootsubsys使用者提供一個條目,如下所示:

subsys:x:999:999:A subsystem user:/subsyshome:/bin/bash

這意味著使用者的實際主目錄位於/home/subsys/subsyshome,並且您還需要提供/home/subsys/bin/bash它所需的所有庫。

相關內容