的描述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
它所需的所有庫。