章 4. 認證和訪問控制

內容目錄

4.1. 一般的 Unix 認證
4.2. 管理帳號和密碼資訊
4.3. 好密碼
4.4. 設立加密的密碼
4.5. PAM 和 NSS
4.5.1. PAM 和 NSS 存取的組態檔案
4.5.2. 現代的集中式系統管理
4.5.3. “為什麼 GNU su 不支援 wheel 組”
4.5.4. 嚴格的密碼規則
4.6. 安全認證
4.6.1. 網際網路密碼安全
4.6.2. 安全 Shell
4.6.3. 網際網路額外的安全方式
4.6.4. root 密碼安全
4.7. 其它的存取控制
4.7.1. 訪問控制列表(ACLs)
4.7.2. sudo
4.7.3. PolicyKit
4.7.4. 限制存取某些服務端的服務
4.7.5. Linux 安全特性

當使用者(或程式)需要存取系統時,需要進行認證,確認身份是受信任。

[警告] 警告

PAM 的調配錯誤可能會鎖住你的系統。你必須有一個準備好的救援 CD,或者設立一個替代的 boot 分割槽。為了恢復系統,你需要使用它們啟動系統並糾正錯誤。

一般的 Unix 認證由 PAM (Pluggable Authentication Modules,即可插入的驗證模組) 下的 pam_unix(8) 模組提供。它的 3 個重要檔案如下,其內的條目使用 “:” 分隔。


/etc/passwd” 包含下列內容。

 ...
user1:x:1000:1000:User1 Name,,,:/home/user1:/bin/bash
user2:x:1001:1001:User2 Name,,,:/home/user2:/bin/bash
 ...

passwd(5) 中所述,這個檔案中被 “:” 分隔的每項含義如下。

  • 登入名

  • 密碼形式說明

  • 數字形式的使用者 ID

  • 數字形式的組 ID

  • 使用者名稱或註釋欄位

  • 使用者家目錄

  • 可選的使用者指令直譯器

/etc/passwd” 的第二項曾經被用來儲存加密後的密碼。在引入了 “/etc/shadow” 後,該項被用來說明密碼形式。


/etc/shadow” 包含下列內容。

 ...
user1:$1$Xop0FYH9$IfxyQwBe9b8tiyIkt2P4F/:13262:0:99999:7:::
user2:$1$vXGZLVbS$ElyErNf/agUDsm1DehJMS/:13261:0:99999:7:::
 ...

shadow(5) 中所述,這個檔案中被 “:” 分隔的每項含義如下。

  • 登入名

  • 加密後的密碼(開頭的 “$1$” 表示使用 MD5 加密。“*” 表示無法登入。)

  • 最後一次修改密碼的時間,其表示從 1970 年 1 月 1 日起的天數

  • 允許使用者再次修改密碼的天數間隔

  • 使用者必須修改密碼的天數間隔

  • 密碼失效前的天數,在此期間使用者會被警告

  • 密碼失效後的天數,在次期間密碼依舊會被接受

  • 帳號失效的時間,其表示從 1970 年 1 月 1 日起的天數

/etc/group” 包含下列內容。

group1:x:20:user1,user2

group(5) 中所述,這個檔案中被 “:” 分隔的每項含義如下。

  • 組名稱

  • 加密後的密碼(不會被真正使用)

  • 數字形式的組 ID

  • 使用 “,” 分隔的使用者名稱列表

[注意] 注意

/etc/gshadow” 為 “/etc/group” 提供了與 “/etc/shadow” 相似的功能,但沒有被真正地使用。

[注意] 注意

如果"auth optional pam_group.so" 這行新增到了"/etc/pam.d/common-auth",並且在"/etc/security/group.conf" 裡進行了設定,一個使用者的實際組就可以被動態新增。參見 pam_group(8).

[注意] 注意

base-passwd 軟體包包含了一份使用者和組的官方文件:“/usr/share/doc/base-passwd/users-and-groups.html”。

下面是一些管理帳號資訊的重要指令。


其中的一些功能只能被 root 使用。密碼和資料的加密參見 crypt(3)。

[注意] 注意

在設定了 PAM 和 NSS 的系統上(例如 Debian salsa 機器),本地的 “/etc/passwd”、“/etc/group” 和 “/etc/shadow” 可能不會被系統啟用使用。上述的命令即使處於這種環境下依舊是有效的。

在系統安裝時建立一個帳號或使用 passwd(1) 指令時,你應該選擇一個好密碼,它應該由 6 到 8 個字元組成,其中包含下列根據 passwd(1) 設定的每個組合中的一個或多個字元。

  • 小寫字母

  • 數字 0 到 9

  • 標點符號

[警告] 警告

密碼中不要使用可以猜到的詞。帳號名、身份證號碼、電話號碼、地址、生日、家庭成員或寵物的名字、字典單詞、簡單的字元序列(例如 “12345” 或 “qwerty”)等都是糟糕的選擇。

下面是一些用於 生成加鹽的加密密碼 的獨立工具。


現代的類 Unix 系統(例如 Debian 系統)提供 PAM (Pluggable Authentication Modules,插入式驗證模組)NSS(Name Service Switch,名稱服務切換) 機制給本地系統管理員,使他們能夠調配自己的系統。它們的功能可以概括為以下幾點。

  • PAM 給應用軟體提供了一個靈活的認證機制,因此涉及到了密碼資料的交換。

  • NSS 提供了一個靈活的名稱服務機制,它經常被 C 標準庫使用,使例如 ls(1) 和 id(1) 這樣的程式獲得使用者和組名稱。

PAM 和 NSS 系統必須保持調配一致。

PAM 和 NSS 系統中重要的軟體包如下。


  • libpam-doc 中 “The Linux-PAM System Administrators' Guide” 是瞭解 PAM 調配的必要文件。

  • glibc-doc-reference 中的 “System Databases and Name Service Switch” 是瞭解 NSS 調配的重要文件。

[注意] 注意

你可以使用 “aptitude search 'libpam-|libnss-'” 指令檢視更多的相關軟體包。NSS 縮寫也可能意味著 “Network Security Service,網路安全服務”,它不同於 “Name Service Switch,名稱服務切換”。

[注意] 注意

PAM 是為每個程式初始化環境變數為系統預設值的最基礎方法。

systemd 下, libpam-systemd 軟體包被安裝用來管理使用者登入,透過為 logindsystemd 控制組層級中註冊使用者會話來實現。參見 systemd-logind(8)、logind.conf(5)和 pam_systemd(8)。

現代的集中式系統管理可以使用集中式的輕量目錄存取協議(LDAP)伺服器進行部署,從而通過網路管理許多類 Unix 和 非類 Unix 系統。輕量目錄存取協議的開源實現是 OpenLDAP 軟體

LDAP 伺服器使用帶有 PAM 和 NSS 的libpam-ldaplibnss-ldap 軟體包為 Debian 系統提供帳號資訊。需要一些動作來啟用 LDAP(我沒有使用過這個設定,並且下面的資訊純粹是第二手的資訊。請在這種前提下閱讀下列內容。)。

  • 你通過執行一個程式,例如獨立的 LDAP 背景程式 slapd(8),來建立集中式的 LDAP 伺服器。

  • 你在 “/etc/pam.d/” 目錄中的 PAM 組態檔案裡,使用 “pam_ldap.so” 替代預設值 “pam_unix.so”。

    • Debian 使用 “/etc/pam_ldap.conf” 作為 libpam-ldap 的組態檔案,“/etc/pam_ldap.secret” 作為儲存 root 密碼的檔案。

  • 你在 “/etc/nsswitch.conf” 檔案中改變 NSS 調配,使用 “ldap” 替代預設值(“compat” 或 “file”)。

    • Debian 使用 “/etc/libnss-ldap.conf” 作為 libnss-ldap 的組態檔案。

  • 為了密碼的安全,你必須讓 libpam-ldap 使用 SLL(或 TLS)連線。

  • 為了確保 LDAP 網路開銷資料的完整性,你必須讓 libpam-ldap 使用 SLL(或 TLS)連線。

  • 為了減少 LDAP 網路流量,你應該在本地執行 nscd(8) 來快取任何 LDAP 搜尋結果。

參見由 libpam-doc 軟體包提供的 pam_ldap.conf(5) 中的文件和 “/usr/share/doc/libpam-doc/html/”,以及 glibc-doc 軟體包提供的 “info libc 'Name Service Switch'”。

類似地,你可以使用其它方法來設定另一種集中式的系統。

[注意] 注意

這裡的資訊也許不夠完全滿足你的安全需求,但這也是一個好的開始.

安全 Shell (SSH) 程式使用安全認證來提供不安全網路上兩個不可信任主機之間的安全加密通訊。它由 OpenSSH 客戶端, ssh(1), 和 OpenSSH 後臺背景程式(daemon), sshd(8)組成.SSH 使用埠轉發特性,可以給 POP 和 X 之類的不安全的協議通訊建立隧道,使其可以在網際網路上安全傳輸。

客戶端可以使用如下方式來認證自己:基於主機的認證、公鑰認證、質疑應答認證、密碼認證。使用公鑰認證,可以實現遠端免密碼登入。參見 節 6.3, “伺服器遠端存取和工具 (SSH)”.

為阻止人們使用 root 許可權存取你的機器,你需要做下面的操作。

  • 阻止對硬碟的物理存取

  • 鎖住 UEFI/ BIOS 來阻止從可移動介質啟動

  • 為 GRUB 互動式會話設定密碼

  • 鎖住 GRUB 選單,禁止編輯

如果可以物理存取硬碟,則可以使用下面的步驟,相對簡單的重置密碼。

  1. 將硬碟拿到一個可以設定 UEFI/BIOS 從 CD 啟動的電腦。

  2. 使用緊急介質啟動系統(Debian 啟動磁碟, Knoppix CD, GRUB CD, …)。

  3. 用讀寫存取掛載根分割槽。

  4. 編輯根分割槽的"/etc/passwd"檔案,使 root 帳號條目的第二段為空。

對於 grub-rescue-pc ,即使用緊急介質啟動的電腦,如果有編輯 GRUB 選單條目 (參見 節 3.1.2, “第二階段:引載加載程序”) 的許可權,在啟動時,使用下面的步驟更加簡單。

  1. 使用核心參數啟動系統來修改一些事情,比如說,"root=/dev/hda6 rw init=/bin/sh".

  2. 編輯 "/etc/passwd" 檔案,使 root 帳號條目的第二段為空。

  3. 重啟系統。

系統的 root shell 現在可以無密碼存取了。

[注意] 注意

一旦某人擁有 root shell 存取許可權,他能夠存取任何內容,並可以重設系統上的任何密碼。此外,他可以使用 johncrack 等軟體包的暴力破解工具來比較所有使用者的密碼 (參見 節 9.5.11, “系統安全性和完整性檢查”)。被破解的密碼,可以用來和其它系統進行比較。

為避免這些相關問題,僅有的理論上的軟體解決方案是使用 dm-crypt 和 initramfs (參見 節 9.9, “資料加密提示”)加密 root 分割槽(或 "/etc" 分割槽) 。這樣的話,你總是需要密碼來啟動系統。

在密碼基於認證和檔案許可權之外,系統也有其它的訪問控制。

[注意] 注意

參見 節 9.4.16, “Alt-SysRq 鍵” 來限制核心的安全警告金鑰(SAK)功能。

訪問控制列表 ACL 是在 節 1.2.3, “檔案系統權限” 裡面解釋的普通許可權的一個超集。

在現代桌面環境中,你會遇到 ACL 行為。比如,當一個已經格式化的 USB 儲存裝置自動掛載到 "/media/penguin/USBSTICK",一個普通使用者 penguin 能夠執行:

 $ cd /media/penguin
 $ ls -la
total 16
drwxr-x---+ 1 root    root    16 Jan 17 22:55 .
drwxr-xr-x  1 root    root    28 Sep 17 19:03 ..
drwxr-xr-x  1 penguin penguin 18 Jan  6 07:05 USBSTICK

在第 11 列的 "+" 表示 ACL 在使用。如果沒有 ACL,一個普通使用者 penguin 應該不能夠像這樣列出目錄內容,因為 penguin 不在 root 組。你能夠按如下方式檢視 ACL:

 $ getfacl .
# file: .
# owner: root
# group: root
user::rwx
user:penguin:r-x
group::---
mask::r-x
other::---

這裡:

  • "user::rwx"、"group::---" 和 "other::---" 相應的為普通所有者、組和其它人的許可權。

  • ACL "user:penguin:r-x" 執行普通使用者 penguin 有 "r-x" 許可權。這個能夠讓 "ls -la" 列出目錄內容。

  • ACL "mask::r-x" 設定上層繫結許可權。

更多資訊參見 "POSIX Access Control Lists on Linux"、acl(5)、 getfacl(1) 和 setfacl

sudo(8) 程式是為了使一個系統管理員可以給使用者受限的 root 許可權並記錄 root 活動而設計的。sudo 只需要一個普通使用者的密碼。安裝 sudo 軟體包並通過設定 “/etc/sudoers” 中的選項來使用它。參見 “/usr/share/doc/sudo/examples/sudoers” 和 節 1.1.12, “sudo 調配” 中的調配示例。

我將 sudo 用於單使用者系統(參見 節 1.1.12, “sudo 調配”)是為了防止自己可能做出的愚蠢行為。就我個人而言,我認為使用 sudo 會比使用 root 帳號作業系統來得好。例如,下列指令將 “some_file” 的擁有者改變為 “my_name”。

$ sudo chown my_name some_file

當然如果你知道 root 密碼(比如自行安裝 Debian 的使用者所做的),任何使用者賬號都可以使用 “su -c” 讓任何指令以 root 執行。

PolicyKit 是在類 Unix 作業系統中控制整個系統許可權的一個作業系統元件。

新的 GUI 圖形介面程式,在設計的時候,不是作為特權程序來執行。它們通過 PolicyKit 來和特權程序通訊,執行管理操作。

在 Debian 系統中,PolicyKit 限制了屬於 sudo 組的使用者帳號的這種操作。

參見 polkit(8)。

對系統安全而言,儘可能的禁用服務程式,是一個好的主意。網路服務是危險的。有不使用的服務,不管是直接由後臺背景程式(daemon)啟用,還是通過super-server 程式啟用,都被認為是安全風險。

許多程式,比如說 sshd(8), 使用基於 PAM 的存取控制。也還有許多方式來限制存取一些服務端的程式。

參見 節 3.5, “系統管理”節 4.5.1, “PAM 和 NSS 存取的組態檔案”節 5.7, “Netfilter 網路過濾框架”

[提示] 提示

NFS 和其它基於 RPC 的程式,需要啟用 Sun RPC 服務。

[提示] 提示

如果你遠端存取最新的 Debian 系統有問題,看下在"/etc/hosts.deny"裡是否存在"ALL: PARANOID"這樣討厭的調配,請把它註釋掉。(但是你必須注意這種行為所帶來的安全風險。)

Linux 核心已經發展和支援在傳統的 UNIX 實現裡面沒有的安全特徵。

Linux 支援 擴充套件屬性,擴充套件了傳統的 UNIX 屬性 (參見 xattr(7))。

Linux 把傳統的超級使用者相關的特權分開到不同的單元,被稱為 capabilities(7),它能夠獨立的啟用和停用。從 2.2 版本核心開始,Capabilities 是一個執行緒獨立的屬性。

Linux Security Module (LSM) 安全模組框架 提供了一個多方面的安全檢查機制,和新的核心擴充套件關聯。例如:

這些擴充套件緊縮的權力模型比普通的類 Unix 安全模型策略更加嚴格,甚至 root 的權力也被限制。建議你閱讀 kernel.org 上的 Linux 安全模組(LSM)框架文件

Linux 的 namespaces 封裝了一個全域性系統資源到一個抽象的概念,全域性系統資源在 namespace 內對程序可見,並且 namespace 有它們自己的全域性資源隔離例項。 對其它程序全域性資源的可見性的改變是,同一個 namespace 的成員可見,但是對非同一個 namespace 的其它程序不可見。從核心 5.6 版本起,有 8 種 namespaces (參見 namespaces(7), unshare(1), nsenter(1))。

在 Debian 11 Bullseye (2021) 中, Debian 使用 unified cgroup hierarchy(統一 cgroup 層級架構) (亦稱為 cgroups-v2)。

namespacescgroups 一起來隔離它們的程序,允許資源控制的使用示例是:

這些功能不能夠透過 節 4.1, “一般的 Unix 認證” 實現。這些高階話題大部分超出了本介紹文件的範圍。