’logname’ 實用程序的適當替代品?
該
logname
實用程序不久前對許多使用者變得無法使用,因為它依賴於出於安全考慮而故意破壞的東西,如此處所述。當我閱讀討論時,該功能不太可能恢復。我曾經有過一段時間使用變通方法,但現在我覺得它們開始落在我的腳下,所以我正在尋找一個合適的長期解決方案,我很驚訝地看到,似乎沒有太多.
最常連結到的解決方案在此處提供,但它源自此處也存在提示,即通過環境變數提出的解決方案
SUDO_USER
不可移植。另一個建議的解決方案是創建一個包含使用者名的文件並編寫一個 bash 別名或類似的東西來模擬日誌名功能,但我不會稱這是一個適當的替代,至少因為它假設環境的可控性可能至少在某些情況下,並不總是可能的,最好說。
who
來自這裡的解決方案很有趣,但我找不到任何有關是否存在相關可靠性或可移植性限制的資訊。除了這些方法之外,這個領域的空氣正在迅速變得稀薄,所以我決定在這裡提問,希望對這個話題和我迄今為止的想法有一些新的意見。
TL,DR:您可能想要,即使它的行為並不總是匹配。但它並不是在所有發行版上都開箱即用。請注意,我的回答假設 Linux,它不適用於其他 Unix 變體。
/proc/*PID*/loginuid``logname
我認為您不會找到完全令人滿意的答案,因為您對所做的事情沒有明確的期望
logname
。一方面,您目前正在使用logname
基於 utmp 記錄的記錄 — 將使用者與終端相關聯的記錄,並且這些記錄會根據終端仿真器的意願進行更新(許多人不會)。另一方面,您期望“更改使用者名的可能性應僅限於超級使用者”。utmp 記錄不是這種情況!正如您引用的評論執行緒中所解釋的,utmp 記錄大部分時間都有效,但它們可以被偽造。定義“用於登錄控制台的使用者名”是有問題的。名義上的情況已經很清楚了,但是複雜的情況下也有很多。如果一個使用者呼叫
su
並附加到另一個使用者的螢幕會話會發生什麼?如果使用者附加到另一個使用者的 X11 或 VNC 會話會發生什麼?你如何將程序跟踪到終端——你如何處理沒有控制終端的程序?Linux 實際上確實有一個“登錄 UID”的概念。它對於每個程序都是可見的。此資訊由核心跟踪,但由使用者區決定何時讓核心知道登錄發生。這通常通過pam_loginuid完成。在引擎蓋下,它是通過寫入來完成的。Linux 的登錄 UID 遵循程序祖先,這並不總是正確的定義,但具有簡單的好處。
/proc/*PID*/loginuid``/proc/self/loginuid
請注意,如果程序的登錄 UID 是 4294967295,則該程序可能會更改它。Init 以登錄 UID 4294967295 開始(等於 -1 作為 32 位值);這通常表示不屬於任何登錄會話的程序。只要登錄過程正確設置登錄 UID(就在它設置從 root 到登錄使用者的真實 UID 之前),就可以了。但是如果有一種方法可以在沒有設置登錄 UID 的情況下登錄,那麼使用者可以聲明他們選擇的任何登錄 UID。因此,只有在系統上執行程序的所有方式都經過設置登錄 UID 的步驟時,此資訊才是可靠的——忘記一個並且資訊變得無用。
在實驗上,在 Debian jessie 機器上,我所有登錄 UID 為 -1 的長期執行的程序都是系統服務。但是有一些方法可以執行登錄 UID 為 -1 的程序,例如通過 incron。我不知道還有多少其他方法;incron 是我嘗試的第一個並且它有效。在 Ubuntu 16.04 機器上,
pam_loginuid
lightdm 的條目被註釋掉了,我沒有調查原因。也許 Ubuntu 的 lightdm 和 incron 應該被認為是安全漏洞,但事實是今天你不能依賴登錄 UID 在主要發行版中開箱即用。另請參見Loginuid,是否應允許更改(可變與否)?,這是關於防止 root 更改登錄 UID 的核心選項。但請注意,它只有在登錄 UID 設置為適當的值後才有效;如果使用者在登錄 UID 仍設置為 -1 的情況下執行程序,那麼他們可以將其設置為任何他們想要的。實際上,將 init 切換到不同的值(例如 -2)並
pam_loginuid
覆蓋該值會更安全;那麼 -1 將永遠不會發生,而 -2 將表示“未知”。