如何在 Ubuntu 中將 sudo 設定為不更改 $HOME 以及如何停用此行為?

如何在 Ubuntu 中將 sudo 設定為不更改 $HOME 以及如何停用此行為?

在 Ubuntu 12.04 上,當我的sudo -s$HOME 變數沒有改變時,所以如果我的普通用戶是regularuser,情況會是這樣的:

$ cd
$ pwd
/home/regularuser
$ sudo -s
# cd
# pwd
/home/regularuser

我很久以前就放棄了 Ubuntu,所以我不能確定,但我認為這是預設行為。所以,我的問題是:

  1. 這是怎麼做到的?配置在哪裡?
  2. 我該如何禁用它?

編輯: 感謝您的答案,這使事情變得更加清晰,但我想我必須添加幾個問題,才能獲得我正在尋找的答案。

  1. 在 Debian 中sudo -s,將 $HOME 變數改為/root.從我從答案和man sudo運行的 shell 中得到的結果sudo -s是 中給出的/etc/passwd,對嗎?
  2. /etc/passwd然而,在 Ubuntu 和 Debian 上,root 的shell都是/bin/bash.在這兩個系統中,就 $HOME 而言,我也找不到.profile或文件的差異在哪裡,因此 的行為有所不同。對此有什麼幫助嗎?.bashrcsudo -s

答案1

Sudo 有許多編譯時配置選項。您可以使用 列出您的版本中的設定sudo -V。 Debian wheezy 和 Ubuntu 12.04 中的配置之間的差異之一是HOMEUbuntu 中保留了環境變量,但 Debian 中不保留;兩個發行版都會刪除所有環境變量,除了一些明確標記為安全保存的環境變量。因此在 Ubuntu 上sudo -s保留,而在 Debian 上則被刪除,然後將其設定為目標使用者的主目錄。HOMEHOMEsudo

您可以在sudoers文件。運行visudo以編輯sudoers文件。有幾個相關選項:

  • env_keep確定保留哪些環境變數。用於Defaults env_keep += "HOME"保留呼叫者的HOME環境變數或Defaults env_keep -= "HOME"刪除它(並用目標使用者的主目錄取代它)。
  • env_reset確定是否重置環境變數。對於允許執行特定命令的規則來說,重置環境變數通常是必要的,但對於允許執行任意命令的規則來說,重置環境變數並沒有直接的安全優勢。
  • always_set_home如果設置,HOME即使由於env_reset被禁用或HOME位於env_keep列表中而被保留,也會被覆蓋。如果HOME不保留此選項則無效。
  • set_home類似於always_set_home,但僅適用於sudo -s,不適sudo用於使用明確命令呼叫時。

可以為給定的來源使用者、給定的目標使用者或給定的命令設定這些選項;sudoers詳細資訊請參閱手冊。

您始終可以透過傳遞 option來選擇覆蓋HOME給定的呼叫。sudo-H

shell 永遠不會覆蓋 的值HOME。 (HOME如果未設置,它會設置,但sudo總是HOME以一種或另一種方式設置。)

如果您執行sudo -isudo則會模擬初始登入。這包括設定HOME目標用戶的主目錄並調用登入外殼

答案2

使用sudo -H -i而不是sudo -s取得互動式登入 root shell:

sudo -H -i
cd
pwd -P  #  /private/var/root  (on Mac OS X 10.6.8)

man sudo

-H      The -H (HOME) option sets the HOME environment variable to
        the homedir of the target user (root by default) as
        specified in passwd(5).  By default, sudo does not modify
        HOME (see set_home and always_set_home in sudoers(5)).

答案3

這與「登入 shell」和「非登入 shell」的行為關係不大sudo,而與「登入 shell」和「非登入 shell」之間的差異有很大關係。快速解決方法是

$ sudo -i

可以看出:

$ sudo -s
# id
uid=0(root) gid=0(root) groups=0(root)
# echo $HOME
/home/msw
# exit
$ sudo -i
# echo $HOME
/root
# pwd
/root

正如 sudo 手冊中所述:

-i(模擬初始登入)選項將目標使用者的密碼資料庫條目指定的 shell 作為登入 shell 運行。這表示 shell 將讀取特定於登入名稱的資源文件,例如 .profile 或 .login。如果指定了命令,則會透過 shell 的 -c 選項將其傳遞到 shell 執行。如果未指定命令,則執行互動式 shell。

答案4

要分別擺脫sudo -sUbuntu 和 Debian 上的不同行為,您可以使用sudo包裝器(問題 4 的答案):

sudos() {
   local PATH="$(getconf PATH)" root_homedir
   root_homedir="$(sudo -H sh -c 'printf "%s" "$HOME"')"
   sudo sh -c 'export HOME="$0"; exec sh -i' "$root_homedir"
   return 0
}

sudo -k
sudos
{
logname
whoami
id -un
id -ur
echo "PATH: $PATH"
}
exit
echo "PATH: $PATH"

相關內容