出自 Arch Linux 中文维基

本文包含了加固 Arch Linux 系統的常用建議與最佳實踐。

概念

  • 收緊安全措施有可能達到使系統無法使用的程度。安全性與便利性需要得到平衡。訣竅在於建立一個安全且有用的系統。
  • 最大的威脅是(並且一直都會是)用戶。
  • 最小權限原則:系統的每一部分應該只能訪問到它確實需要的東西,除此之外的則不可以。
  • 縱深防禦:多個獨立的層次能帶來更好的安全性。當一層防護被攻破時,另一層應該能夠阻止攻擊。
  • 保持一點點的偏執和多疑。如果有件事看起來太好了,不像是真的,那可能確實如此。
  • 永遠無法令系統 100% 安全,除非把機器從網絡上斷開,關掉電源,鎖進保險柜,用混凝土封住並不再使用它。
  • 為失敗做好準備。預先為安全措施被攻破的情況制定可供執行的計劃。

密碼

密碼是一個安全系統的關鍵。它可以保護你的用戶帳戶加密的文件系統SSH/GPG 密鑰。密碼也是讓計算機信任使用者的主要方式,所以安全性的很大一部分就在於選擇高強度的密碼並保護它們不被泄露。

選擇安全的密碼

密碼必須足夠複雜,不能輕易地被猜中(比如和個人信息有關的密碼),也不能輕易地被社會工程或暴力嘗試等方法 破解。強密碼的要點在於 長度隨機性。在密碼學中,密碼的質量被稱為它的 熵安全性

不安全的密碼包括:

  • 個人可識別信息(如:狗的名字,出生日期,區號,最喜歡的視頻遊戲)
  • 對單詞簡單地替換一些字符(如:k1araj0hns0n),因為現代字典攻擊可以輕鬆對付它們
  • 在基本單詞或常見字符串的前後加上數字,符號或其他字符(如:DG091101%
  • 常見句子或詞典中單詞的序列(如:photocopyhauntbranchexpose),包括對其字符進行替換(如:Ph0toc0pyh4uN7br@nch3xp*se
  • 任何一個最常見的密碼

最好的選擇是由隨機來源生成的長密碼(越長越好)。使用長密碼很重要。弱哈希算法會使得一個8字符密碼的哈希值在幾小時之內便被攻破。

pwgenapgAUR 這樣的工具可生成隨機密碼,不過這些密碼可能很難記住:為了記住它們,一種方法(僅針對經常使用的密碼)是生成一個長密碼並記住一小段(這一小段要能保證最低限度的安全),暫時把完整的密碼寫下來。在一次次的密碼輸入過程中,嘗試著記住從一小段到一大段乃至全部密碼,隨著時間推移,密碼就會隨著肌肉記憶根深蒂固。這種方法很難,但是能保證密碼不會出現在破解用的字典裡,也可以抵禦「智能地」組合單詞並替換部分字符的暴力破解手段。

還有個方法可以產生安全性好的、看起來隨機的密碼,那就是從一句句子的每一個詞中提煉出一個符號。 例如 「the girl is walking down the rainy street」 這句話可以轉換為 t6!WdtR5 或是更加複雜的 t&6!RrlW@dtR,57。 這種方法可以更為簡單地幫助記憶密碼,但是請注意,不同字母出現在單詞開頭的概率不同 (Wikipedia:Letter frequency)。同時也要考慮 Diceware Passphrase[失效連結 2021-05-17 ⓘ] 中提到的方法,使用足夠數量的單詞。

另外一種有效的技術是寫下隨機生成的密碼並將其存儲在安全的地方,例如錢包、挎包或文件保險箱中。不少人在保護其物理貴重物品免受盜竊方面通常做得很好,並且與數字安全實踐相比,大多數人更容易理解物理安全最佳實踐。


將生成與記憶密碼兩者結合的 密碼管理器 也很有用,它可以保存長而複雜的隨機密碼,同時被一個方便記憶的主密碼保護著。主密碼必須僅用於此密碼管理器,特別注意要避免保存或通過任何網絡傳輸這個密碼。當然這個方法使用戶只能從裝有密碼管理器的系統上使用已保存的密碼(另一方面,這也可以視為額外的安全特性)。一些密碼管理器也提供智慧型手機應用,可用於查看密碼,以便在沒有安裝密碼管理器的系統上手動輸入。需要注意,一旦忘記主密碼,密碼管理器就引入了單點故障。

使用一長串相互無關的單詞作為密碼或許是有效的方法。原理在於,如果使用足夠長的短語,密碼長度所帶來的熵就可以抵消使用字典單詞所失去的熵。這個 XKCD 漫畫描繪了此方法中對於熵的權衡。如果您使用的單詞集很大(數千個單詞)並且您從中選擇 5-7 個甚至更多隨機單詞,則此方法提供了很大的熵,即使攻擊者知道你可能選擇的單詞集和你所選擇的單詞數量。參見Diceware

參閱 The passphrase FAQWikipedia:Password strength ,獲取額外背景信息。

維護密碼安全

一旦你選擇了一個強密碼,就一定要保證它的安全。當心 鍵盤記錄器(軟體層面 和 硬體層面),屏幕記錄器,社會工程肩窺,並避免對不同的伺服器(網站)使用重複密碼,以防止不安全的伺服器泄漏超出其範圍的信息。密碼管理器 可以幫助管理大量複雜密碼:將密碼從管理器複製粘貼到其他程序中時,記住每次粘貼完都清除複製緩衝區,並確保密碼不會「意外地」保存在任何類型的文件中(例如,不要將它們粘貼在普通的終端命令中,因為這些命令會存到 .bash_history 之類的文件裡)。

最好不要因為安全性強的密碼難記而選擇不安全的密碼,密碼是它們之間的一種平衡。與擁有許多相似的弱密碼相比,更好的做法是建立一個加密的安全密碼資料庫,資料庫由密鑰和一個強主密碼保護著。把密碼寫下來也許同樣有效[1],可以避開軟體中的潛在漏洞,同時也需要保證物理安全。

衡量密碼強度的另一個指標是它不能夠被輕易從其他地方恢復。

如果你使用與登錄密碼相同的磁碟加密密碼(這在登錄時自動掛載加密分區或目錄很有用),請確保 /etc/shadow 也在加密分區上,或者/並 使用強哈希算法(即 sha512/bcrypt,而不是 md5)來存儲密碼哈希(詳細信息請參閱 SHA password hashes)。

如果要備份密碼資料庫,請勿將備份的副本存儲在密碼保護之下(比如存儲在加密的驅動器或需要身份驗證的遠程存儲服務),而解鎖副本的密碼又存儲在副本中,這樣在需要時將無法訪問它(相當於把房間的鑰匙鎖在了房間裡)。一個有用的技巧是,使用主密碼的簡單哈希來加密存儲密碼資料庫的驅動器或帳戶。維護一份記錄備份位置的列表:如果有一天你覺得主密碼已被泄露,一是要更改所有資料庫備份的密碼,二是要使用從新主密碼派生的新哈希來保護存有資料庫的位置。

以安全的方式控制資料庫的版本可能非常複雜:如果你這樣做,那你必須有辦法更新所有資料庫版本的主密碼。主密碼泄露時,你可能並不能馬上知道:為了降低其他人在你意識到主密碼泄露之前發現密碼的風險,你可以選擇定期更改主密碼。如果你擔心自己失去了對資料庫副本的控制權,則需要根據主密碼的熵,在暴力破解主密碼所需的時間內更改資料庫副本中包含的所有密碼。

密碼的散列值

這篇文章的某些內容需要擴充。

原因: 提及密鑰導出函數,特別是 PBKDF2、bcrypt 和 scrypt,應當提及用法、優缺點,基於定製硬體的暴力攻擊應當特別提及。 (在 Talk:安全 中討論)

默認情況下,Arch 將用戶密碼散列值存儲在僅 root 可讀的 /etc/shadow 文件中,與存儲在所有人可讀的 /etc/passwd 文件中的其他用戶參數分開,請參閱 Users and groups#用戶信息存儲。另請參閱 #限制 root 權限

密碼使用 passwd 命令來設置,該命令使用 crypt 函數對密碼進行 拉伸,然後將它們保存在 /etc/shadow 中。請參閱 SHA password hashes。密碼也被 加鹽(salted),以抵禦 彩虹表 攻擊。

另請參閱 在 Linux 中密碼如何存儲(理解使用 shadow 工具的散列值化)

用 pam_pwquality 強制使用強密碼

pam_pwquality 提供針對 字典攻擊 的保護,並可用於配置在整個系統中實施的密碼策略。它基於 pam_cracklib,故也向後兼容其選項。

安裝 libpwquality 軟體包。

警告: root 帳戶默認不會受此策略影響。
注意: 可以用 root 帳戶來幫助想繞過策略的用戶設置他們的密碼。這在設置臨時密碼時很有用。
注意: 目前有關密碼的安全指南(例如來自 NIST 以及其他機構的指南)並不建議強制使用特殊字符,因為它們通常只會導致可預測的更改。

舉個例子,假設要強制執行下面的策略:

  • 如果密碼錯誤,則提示 2 次輸入密碼(retry 選項)
  • 最小長度為10個字符(minlen 選項)
  • 輸入新密碼時,新密碼應至少有 6 個字符與舊密碼不同(difok 選項)
  • 至少 1 個數字(dcredit 選項)
  • 至少 1 個大寫字母(ucredit 選項)
  • 至少 1 個小寫字母(lcredit 選項)
  • 至少 1 個除上述之外的其他字符(ocredit 選項)
  • 不能包含單詞 "myservice" 和 "mydomain"
  • 為 root 應用此策略

編輯 /etc/pam.d/passwd 文件,把它改成:

#%PAM-1.0
password required pam_pwquality.so retry=2 minlen=10 difok=6 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 [badwords=myservice mydomain] enforce_for_root
password required pam_unix.so use_authtok sha512 shadow

password required pam_unix.so use_authtok 用來告訴 pam_unix 模塊不要顯示輸入密碼的提示符,而採用 pam_pwquality 所提供的。

更多信息可以參考 pam_pwquality(8)pam_unix(8) 手冊頁。

CPU

微碼

關於如何為CPU微碼安裝重要安全更新的信息見微碼

硬體漏洞

有些 CPU 存在硬體漏洞。這些漏洞的列表見關於硬體漏洞的 Linux 內核文檔,其中也包含了修補方法選擇指南,有助於針對特定場景對內核自定義,從而修補這些漏洞。

要檢查是否受到已知漏洞影響,請運行:

$ grep -r . /sys/devices/system/cpu/vulnerabilities/

大部分情況下,更新內核和微碼能夠修補漏洞。

同步多線程(超線程)

注意: 這主要是使一些虛擬化程序受益的功能。在普通系統上啟用它幾乎沒有或沒有安全性益處。

同步多線程(SMT),在英特爾 CPU 上又稱超線程,這一硬體功能可能是 L1 Terminal Fault微架構數據採樣(Microarchitectural Data Sampling) 漏洞的來源。 Linux 內核和微碼更新含有針對已知漏洞的補丁,但是如果存在不受信任的虛擬化客戶機,則對於某些 CPU 可能仍然需要禁用 SMT

SMT 往往可以在系統固件中關閉。更多信息見主板或系統文檔。通過添加以下內核參數,也可以在內核中禁用 SMT:

mitigations=auto,nosmt

內存

存儲

靜態數據加密

靜態數據加密,最好是使用強密碼的全磁碟加密,是保護數據免受物理恢復的唯一方法。這在計算機關閉或相關磁碟卸載時提供了數據機密性。

然而,一旦計算機啟動並且驅動器被掛載,其數據將變得與未加密的驅動器一樣容易受到攻擊。因此,最佳做法是在不再需要數據分區時立即卸載它們。

你還可以使用存儲在 TPM 中的密鑰對驅動器進行加密,儘管它過去存在可以通過總線嗅探攻擊提取密鑰的漏洞。

某些程序,如 dm-crypt,允許用戶將 Loop file 加密為虛擬卷。當系統只有特定的部分需要加密時,這種方法可以替代全盤加密。

雖然 數據靜態加密wiki 中比較的基於塊設備或文件系統的加密類型對於保護物理媒體上的數據很有用,但大多數不能用於保護無法控制的遠程系統上的數據(例如雲存儲)。在某些情況下,個別文件加密會很有用。

以下是一些加密文件的方法:

  • 一些歸檔和壓縮工具還提供基本的加密功能。一些示例是 p7zip-p 標誌)、zip-e 標誌)。加密時要特別小心,因為這些工具可能使用自定義算法來實現跨平台兼容性[1]
  • GnuPG 可用來加密文件
  • age 是一款簡單易用的文件加密工具。它還支持多個收件人和使用 SSH 密鑰進行加密,這對於安全文件共享非常有用。

文件系統

如果用 sysctl 啟用了內核的 fs.protected_hardlinksfs.protected_symlinks 選項,內核就可以防止出現硬連結和軟連結(符號連結)相關的安全問題。因此將全局可寫的目錄獨立出來不再具有安全方面的優勢。

使包含全局可寫目錄的文件系統保持獨立 仍然可以作為一種防止惡意程序填充垃圾內容使磁碟空間耗盡的粗略手段。但是,把 /var/tmp 所在分區塞滿也足以使系統停止響應。處理這種問題的更靈活的機制是存在的(比如 磁碟配額),並且某些 文件系統 自身就帶有相關功能(Btrfs 的子卷可以設置配額)。

掛載點

根據最小權限原則,掛載文件系統時應該採用最為嚴格的掛載選項(在不損失功能的情況下)。

相關的掛載選項有:

  • nodev: 文件系統中,禁止解釋任何字符或屏蔽特殊設備。
  • nosuid: 禁止 set-user-identifier 或 set-group-identifier 標誌位生效。
  • noexec: 禁止文件系統裡的任何二進位文件直接運行。
    • /home 上設置 noexec 選項會禁用可執行腳本,影響 Wine* 、PyCharm 、 Steam.NET等軟體正常運行。
      • Wine 不需要 exec 標誌來打開 Windows 二進位文件。僅當 Wine 本身安裝在 /home 中時才需要它。
      • 為了保持 Steam 正常工作,你可以通過在 fstab 中添加以下內容來讓 /home/user/.local/share/Steamexec標誌掛載 :
        /home/user/.local/share/Steam  /home/user/.local/share/Steam  none defaults,bind,user,exec,nofail  0  0
        
    • 部分軟體包(比如編譯 nvidia-dkms)可能需要 /var 目錄下有 exec 權限。

用於存放數據的文件系統應該堅持使用 nodevnosuidnoexec 掛載。

可能的文件系統劃分參考:

  • /var
  • /home
  • /dev/shm
  • /tmp
  • /boot
提示:使用 GPT 分區自動掛載 時,ESP 和 XBOOTLDR 分區始終使用noexec,nosuid,nodev掛載選項。

文件訪問權限

默認的 文件權限 對幾乎所有文件都賦予了讀權限,修改文件權限可以在取得了非 root 帳戶(如httpnobody 帳戶)的攻擊者面前隱藏有價值的信息。

例如:

# chmod 700 /boot /etc/{iptables,arptables}

需要考慮的一些路徑是:

可以修改默認的 Umask 0022 來為新建的文件提高安全性。NSA RHEL5 安全指南建議將 umask 設置為 0077 以獲得最充分的安全性,這將使得新文件無法被創建者之外的用戶讀取。要修改 umask,參見 Umask#Set the mask value

備份

本文或本章節可能需要合併到系統備份

附註: 有專門的系統備份頁面。(在 Talk:安全 中討論)

定期創建重要數據的備份。定期測試備份的完整性。定期測試備份是否可以恢復。

確保至少一份數據副本離線存儲,即不以任何方式連接到存在威脅的系統。勒索軟體和其他破壞性攻擊也可能攻擊任何連接的備份系統。

參見 系統備份

SATA SSD 凍結模式

參見 固態硬碟#從睡眠中喚醒時設置SSD為"frozen"狀態

帳戶設置

不要日常使用 root 帳戶

根據最小權限原則,不要日常使用 root 帳戶。給每個使用系統的人建立一個沒有特權的用戶帳戶。必要時使用 Sudo 臨時以高權限訪問。

在失敗的登錄嘗試後強制延時一段時間

將下方的行添加至 /etc/pam.d/system-login 即可在失敗的登錄嘗試後延時至少 4 秒:

/etc/pam.d/system-login
auth optional pam_faildelay.so delay=4000000

4000000 是延時的微秒數。

在三次登錄嘗試失敗後封鎖用戶

pambase 20200721.1-2時,pam_faillock.so 默認啟用,在15分鐘內3次失敗的登錄嘗試之後會封鎖用戶10分鐘(見 FS#67644)。這一封鎖只適用於密碼認證(如登陸及 sudo),通過 SSH 的公鑰認證仍然會被接受。為防止徹底拒絕服務,該封鎖對於 root 禁用。

要解鎖用戶,執行:

$ faillock --reset --user username

默認情況下,封鎖機制為每個用戶一個文件,位於 /run/faillock/。刪除或清空此文件及可解鎖該用戶——該目錄是由 root 所有,但文件是由該用戶所有,故 faillock 命令只會清空文件,因此並不需要 root。

pam_faillock.so 模塊可通過文件 /etc/security/faillock.conf 配置。封鎖參數:

  • unlock_time — 封鎖時間(單位為秒,默認10分鐘)。
  • fail_interval — 導致封鎖的失敗嘗試時間範圍(單位為秒,默認15分鐘)。
  • deny — 封鎖前允許的登錄失敗次數(默認為3)。
提示:鎖定的主要目的是減緩暴力攻擊,使其變得不可行。因此,如果由於密碼輸入錯誤而導致的鎖定變得過於頻繁,請優先考慮放寬嘗試次數,而不是減少鎖定時間。
注意: deny = 0 會禁用封鎖。

默認情況下,重新啟動後所有用戶鎖都會丟失。如果攻擊者可以重新啟動計算機,則鎖定持續存在會更安全。要使鎖定持續存在,請將 /etc/security/faillock.conf 中的 dir 參數更改為 /var/lib/faillock

更改無需重啟即可生效。更多配置選項見 faillock.conf(5) ,如啟用 root 帳戶封鎖、在中心化登錄(如 LDAP)情況下禁用等。

限制進程數量

在有很多用戶或存在不可信用戶的系統上,限制每個用戶同時可運行的進程數很重要,這樣可以防止 fork bombs 以及其他拒絕服務攻擊。/etc/security/limits.conf 決定了每個用戶或組可以運行的進程數,默認情況下為空(除了有用的注釋)。將以下行添加到此文件將限制所有用戶每位最多運行 100 個活動進程,除非他們使用 prlimit 命令將此次會話的最大值顯式地提高到 200。可以根據用戶應當運行的進程數量或當前管理的系統的硬體條件來確定這些值。

* soft nproc 100
* hard nproc 200

當前每個用戶運行的進程數量可以使用 ps --no-headers -Leo user | sort | uniq -c 查看。這可以幫助確定合適的進程限額。

使用 Wayland

儘量使用 Wayland 代替 Xorg。Xorg 的設計早於現代安全實踐,並且被許多人認為是不安全的。例如,Xorg 應用程式可能會在不活動時記錄擊鍵。

如果必須運行 Xorg,建議避免以 root 身份運行,參考Xorg#沒有 root 權限的 Xorg。 在 Wayland 中,Xwayland 兼容層將自動使用無root權限的 Xorg。

限制 root 權限

按照系統的設計,root 用戶是系統中最強大的用戶。審計 root 用戶帳戶也很困難。因此,重要的是儘可能多地限制root用戶帳戶的使用。有多種方法可以保持 root 用戶的權力,同時限制其造成損害的能力。

用 sudo 替代 su

本文或本章節可能需要合併到sudo

附註: 這是一篇專門說明 sudo 的文章。(在 Talk:安全 中討論)

出於多種原因,使用 sudo 進行特權訪問比 su 更好。

  • sudo 記錄了普通權限用戶運行每個特權命令的日誌。
  • root 用戶的密碼不需要告知每個請求 root 權限的用戶。
  • sudo 可以防止用戶意外地以 root 身份執行無需該權限的命令,因為 sudo 並沒有為 root 創建完整的終端。這符合 最小權限原則
  • 可以為單個用戶啟用單個程序的 root 權限,而不用為了運行一個程序啟用該用戶對 root 的完整訪問權。例如,要授予用戶 alice 對特定程序的訪問權限:
# visudo
/etc/sudoers
alice ALL = NOPASSWD: /path/to/program

另外,也可以為所有用戶開放單個程序。例如允許以普通用戶身份從伺服器掛載 Samba 共享:

%users ALL=/sbin/mount.cifs,/sbin/umount.cifs

這將允許 users 組中的所有用戶從任何機器 (ALL) 運行此系統的 /sbin/mount.cifs/sbin/umount.cifs 命令。

提示:

visudo 使用指定版本的 nano 而不是 vi

/etc/sudoers
Defaults editor=/usr/bin/rnano

Export # EDITOR=nano visudo 被認為存在嚴重安全風險,因為任何程序都可以作為 EDITOR

使用 sudo 編輯文件

以 root 身份運行文本編輯器可能會變成安全漏洞,因為許多編輯器可以運行任意 shell 命令或更改正在編輯的文件以外的文件。要避免這一風險,請用 sudoedit filename(等同於 sudo -e filename)編輯文件。這將使用普通用戶的權限來編輯文件的副本,在編輯器關閉後會使用 sudo 覆蓋原始文件。可以通過設置 SUDO_EDITOR 環境變量來更改所使用的編輯器:

$ export SUDO_EDITOR=vim

也可以使用類似 rvim 這樣的編輯器,它功能受限,以便以 root 用戶身份安全運行。

限制 root 登錄

正確配置 sudo 後,完全的 root 權限就可以被嚴格限制或停用,且不會損失太多可用性。要禁用 root 而允許使用 sudo,可以運行 passwd -l root

僅允許特定用戶

PAMpam_wheel.so 模塊可以做到僅允許 wheel 組中的用戶使用 su 登錄。編輯 /etc/pam.d/su/etc/pam.d/su-l 兩份文件,去掉以下行的注釋:

# Uncomment the following line to require a user to be in the "wheel" group.
auth		required	pam_wheel.so use_uid

這一行表示只有已經能夠運行特權命令的用戶才能以 root 用戶身份登錄。

拒絕 SSH 登錄

即使你不想禁止 root 用戶在本地登錄,也最好 禁止 root 通過 SSH 登錄[損壞的連結:無效的章節]。這樣做的目的是在用戶可以在遠程完全破壞系統之前添加額外的一層安全保護。

強制訪問控制

Mandatory access control(MAC, 強制訪問控制)是一種安全策略,它與 Arch 以及大部分 Linux 發行版默認使用的 Discretionary access control (DAC, 自主訪問控制)有很大的不同。MAC 本質上是對照著一個安全規則集,檢查程序的每一個可能對系統造成影響的操作。與 DAC 方式相比,用戶不能修改 MAC 的規則集。使用幾乎任何強制訪問控制系統都將顯著提高計算機的安全性,儘管它們的實現方式存在差異。

基於路徑的強制訪問控制

基於路徑的訪問控制是一種簡單的訪問控制形式,它根據文件的路徑提供相應的權限。這種方式有個缺點,就是當文件改變路徑以後相應的權限並沒有隨著文件一起移動。從積極的方面來說,基於路徑的 MAC 可以在更廣泛的文件系統上實現,這與基於標籤的另一種可選方案是不同的。

AppArmor 是一個由 Canonical 維護的 MAC 實現,它被看做是 SELinux 的簡化版替代方案。

Tomoyo 是另一種提供訪問控制的系統,簡單而易用。它的使用方式和內部實現都被設計得足夠簡單,需要的依賴也很少。

基於標籤的強制訪問控制

基於標籤的訪問控制意味著每份文件都帶有擴展屬性用於決定它的安全權限。雖然這類系統應該比基於路徑的控制更靈活,但它只適用於支持這些擴展屬性的文件系統。

SELinux 是一個基於 NSA 的項目,用於提高 Linux 的安全性。它完整實現了 MAC,將系統用戶與角色獨立開來。它實現了一個非常強大的多級 MAC 策略,可以在系統擴大和改變得超出其原始配置時也能輕鬆控制系統。

訪問控制表 (ACLs)

Access Control Lists(ACLs,訪問控制表)是以某種方式將規則直接附加到文件系統的一種可選方法。ACLs 將程序的實際操作與允許的操作對照,來實現訪問控制。

內核加固

內核自我保護 / 漏洞防護

linux-hardened 相較於 linux 使用了 基本內核加固補丁集 和更多安全相關的編譯時配置選項。也可以使用自定義編譯選項來把握安全性和性能之間的平衡,而不是使用強調安全性的默認選項。

如果你用了內核代碼樹以外的驅動,比如 NVIDIA,可能會需要切換到它的 DKMS 包。

用戶空間 ASLR 比較

linux-hardened 包為用戶空間進程提供了改進的 ASLR(Address Space Layout Randomization,地址空間布局隨機化)實現。paxtest 命令可用於獲取所提供熵的估計值:

64 位進程
linux-hardened
Anonymous mapping randomization test     : 32 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 26 quality bits (guessed)
Heap randomization test (PIE)            : 40 quality bits (guessed)
Main executable randomization (ET_EXEC)  : No randomization
Main executable randomization (PIE)      : 32 quality bits (guessed)
Shared library randomization test        : 32 quality bits (guessed)
VDSO randomization test                  : 32 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 40 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 40 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 44 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 44 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 32 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 34 quality bits (guessed)
Randomization under memory exhaustion @~0: 32 bits (guessed)
Randomization under memory exhaustion @0 : 32 bits (guessed)
linux
Anonymous mapping randomization test     : 28 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 13 quality bits (guessed)
Heap randomization test (PIE)            : 28 quality bits (guessed)
Main executable randomization (ET_EXEC)  : No randomization
Main executable randomization (PIE)      : 28 quality bits (guessed)
Shared library randomization test        : 28 quality bits (guessed)
VDSO randomization test                  : 20 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 30 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 30 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 22 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 22 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 28 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 28 quality bits (guessed)
Randomization under memory exhaustion @~0: 28 bits (guessed)
Randomization under memory exhaustion @0 : 28 bits (guessed)
32 位進程(運行在 x86_64 內核上)
linux-hardened
Anonymous mapping randomization test     : 16 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 22 quality bits (guessed)
Heap randomization test (PIE)            : 27 quality bits (guessed)
Main executable randomization (ET_EXEC)  : No randomization
Main executable randomization (PIE)      : 18 quality bits (guessed)
Shared library randomization test        : 16 quality bits (guessed)
VDSO randomization test                  : 16 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 24 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 24 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 28 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 28 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 18 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 16 quality bits (guessed)
Randomization under memory exhaustion @~0: 18 bits (guessed)
Randomization under memory exhaustion @0 : 18 bits (guessed)
linux
Anonymous mapping randomization test     : 8 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 13 quality bits (guessed)
Heap randomization test (PIE)            : 13 quality bits (guessed)
Main executable randomization (ET_EXEC)  : No randomization
Main executable randomization (PIE)      : 8 quality bits (guessed)
Shared library randomization test        : 8 quality bits (guessed)
VDSO randomization test                  : 8 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 19 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 19 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 11 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 11 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 8 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 13 quality bits (guessed)
Randomization under memory exhaustion @~0: No randomization
Randomization under memory exhaustion @0 : No randomization

限制訪問內核日誌

注意: 這個功能在 linux-hardened 中是默認打開的。

內核日誌包含了那些試圖利用內核漏洞(如敏感內存地址)的攻擊者的有用信息。kernel.dmesg_restrict 標記可以禁止不帶 CAP_SYS_ADMIN 能力的進程訪問內核日誌(默認只有 root 運行的進程帶有該能力)。

/etc/sysctl.d/50-dmesg-restrict.conf
kernel.dmesg_restrict = 1

限制訪問 proc 文件系統中的內核指針

注意: linux-hardened 默認設置是 kptr_restrict=2 而不是 0

kernel.kptr_restrict 設置為 1 將針對沒有 CAP_SYSLOG 的普通用戶隱藏 /proc/kallsyms 中的內核符號地址,這使得利用內核漏洞動態解析地址/符號變得更加困難。這對預編譯好的 Arch Linux 內核沒有多大幫助,因為攻擊者可以直接下載到內核包並從那裡手動獲取符號,但如果你正在編譯自己的內核,這可以幫助減輕本地根攻擊。這樣做以後會影響非 root 用戶運行部分 perf 命令(雖然很多 perf 功能本身就需要 root 權限)。更多信息請參見 FS#34323

kernel.kptr_restrict 設置為 2 將隱藏 /proc/kallsyms 中的內核符號地址,而忽略用戶的權限。

/etc/sysctl.d/50-kptr-restrict.conf
kernel.kptr_restrict = 1

禁用 BPF 即時編譯

Linux 內核有一個功能,就是將 BPF/Seccomp 規則集編譯為原生代碼來優化性能。net.core.bpf_jit_enable 標誌位應設置為 0 以獲得最大安全性。

BPF/Seccomp 編譯在特定領域中很有用,比如各類動態服務(類似 Mesos 和 Kubernetes 這樣的集群管理平台),它通常不適用於桌面用戶或靜態服務。JIT 編譯器為攻擊者提供了進行堆噴射攻擊 (Heap spraying attack) 的可能性。在這種攻擊中,他們用惡意代碼填充內核堆,然後利用另一個漏洞執行此代碼,比如解除引用一個不正確的函數指針。2018 年早先公布的 幽靈 漏洞,是其最為突出的一次利用過程。

ptrace 的可調用範圍

Arch 默認啟用了 Yama LSM,提供了 kernel.yama.ptrace_scope 標誌位作為開關。默認情況下這個開關是打開的,它可以使得沒有 CAP_SYS_PTRACE 能力的進程無法對其作用域之外的其他進程執行 ptrace 調用。雖然許多調試工具需要 ptrace 來實現某些功能,但這一修改顯著提高了安全性。如果沒有此功能,且不使用命名空間等額外隔離層的情況下,同一用戶運行的進程之間基本沒有隔離。調試器可以附加到現有進程的能力證明了這個弱點確實存在。

示例:由於上述原因功能受限的程序

注意: 你仍然可以以 root 身份執行這些命令(例如允許某些用戶使用 sudo,且無論是否需要密碼)。
  • gdb -p $PID
  • strace -p $PID
  • perf trace -p $PID
  • reptyr $PID

隱藏進程

警告:
  • 這可能會導致某些應用程式出現問題,例如在沙盒和 Xorg 中運行的應用程式(請參閱解決方法)。
  • 當所使用的 systemd 版本大於 237.64-1 時,這可能會導致 D-BusPulseAudiobluetooth 出現問題。

其他用戶的進程通常可以在 /proc 訪問到,而內核有能力向非特權用戶隱藏這些進程,按照 此處 記錄的方法以 hidepid=gid= 選項掛載 proc 文件系統即可。

這使得入侵者收集正在運行的進程信息變得異常艱難,同樣艱難的還包括判斷是否存在特權運行的守護進程、其他用戶是否正在運行敏感程序,甚至無法捕捉到其他用戶運行的任何程序,更無法捕捉到特定的程序是否正在運行(假設該程序不會因為其自身行為暴露自己),並且作為額外的優勢,那些通過外部參數傳遞敏感信息的、寫得不那麼好的程序現在可以防範本地竊聽了。

filesystem 軟體包提供的 proc 用戶組 相當於一個白名單,包含了有權訪問其他用戶進程信息的用戶。如果用戶或服務需要訪問除自身以外的 /proc/<pid> 目錄,請 將他們加入該用戶組

例如,把除了 proc 組中用戶之外的其他用戶的進程信息都隱藏起來:

/etc/fstab
proc	/proc	proc	nosuid,nodev,noexec,hidepid=2,gid=proc	0	0

要使用戶會話正常工作,需要為 systemd-logind 添加例外:

/etc/systemd/system/systemd-logind.service.d/hidepid.conf
[Service]
SupplementaryGroups=proc

沙盒程序

另請參閱 Wikipedia:Sandbox (computer security)

注意: 用戶命名空間配置項 CONFIG_USER_NS 當前在 linux(v4.14.5或更高版本)、linux-lts(v4.14.15或更高版本)和 linux-hardened 中啟用。關閉它可能會導致程序無法開啟某些沙盒功能。由於會增加本地提權的可能性,非特權用法默認是禁用的,啟用它需要將 kernel.unprivileged_userns_clone sysctl 設置為 1

Firejail

Firejail 是一個易於使用的、簡單的工具,用於沙盒化程序和伺服器。建議將 Firejail 也用於瀏覽器以及其他網絡應用程式,就像對待正在運行的伺服器程序一樣。

bubblewrap

bubblewrap 是一個由 Flatpak 開發的基於 setuid 的沙盒程序,其資源占用比 Firejail 更小。雖然它缺少某些功能,例如文件路徑白名單,但 bubblewrap 確實提供了 bind mounts 的功能,能夠創建 user/IPC/PID/network/cgroup 命名空間,並且可以支持簡單和 複雜的沙盒

chroots

手動構造 chroot jail 也是可以的。

Linux containers

在不使用 KVM 和 VirtualBox 又需要更大程度隔離的情況下,Linux Containers(Linux 軟體容器)是一個不錯的選擇。LXC 使用自己的虛擬硬體,在現有內核之上的 pseudo-chroot 內運行。

其他虛擬化技術

使用類似 VirtualBoxKVMXenQubes OS(基於 Xen)的完全虛擬化技術,可以在運行有風險的應用程式或瀏覽危險網站時提高隔離性和安全性。

網絡與防火牆

防火牆

雖然源裡面的 Arch 內核能夠啟用 Netfilteriptablesnftables,但它們默認是關閉的。因此強烈建議配置防火牆來保護系統上運行的服務。許多資料(包括 ArchWiki)沒有明確說明哪些服務值得保護,因此啟用防火牆是一個很好的預防措施。

內核參數

作用於網絡的內核參數可以使用 Sysctl 來設置。要查詢具體方法,請參閱 Sysctl#TCP/IP stack hardening

SSH

為了減輕 暴力攻擊,建議強制使用基於密鑰的身份驗證。對於 OpenSSH,請參閱 OpenSSH#Force public key authentication。另外,Fail2banSshguard 通過監控日誌並寫入 iptables 規則 提供了較少形式的保護,但這樣做可能會使伺服器拒絕服務,因為攻擊者可以偽裝成管理員的地址並發送欺騙性的數據包。

你可以用雙因素身份驗證來進一步強化身份驗證。Google Authenticator(Google 身份驗證器)使用一次性密碼 (OTP) 提供兩步驗證過程。

拒絕 root 登錄也是一種很好的做法,既可以跟蹤入侵,也可以在 root 訪問之前添加額外的安全層。對於 OpenSSH,請參閱 OpenSSH#Deny

DNS

本文或本章節的事實準確性存在爭議。

原因: 由於 HSTS 技術,瀏覽器可能可以識別出 DNS 欺騙。(在 Talk:安全 中討論)


默認情況下,多數系統上的 DNS 查詢請求的發送和接收是不加密的,並且不驗證數據是否來自規範的伺服器,這可能導致 中間人攻擊,攻擊者攔截用戶的 DNS 查詢並修改響應數據為 釣魚 網站的 IP 地址,導致釣魚網站收集用戶的寶貴信息。用戶和瀏覽器/其他軟體都不會知道發生了什麼,因為 DNS 協議始終將查詢結果視為合法的。

DNSSEC 是一套標準,要求 DNS 伺服器向客戶端出示 DNS 數據的原始驗證證明、曾經的驗證失敗記錄和數據完整性。然而這一標準尚未廣泛使用。啟用 DNSSEC 後,攻擊者無法修改您的 DNS 查詢請求和返回的結果,但仍可以讀取它們。

DNSCrypt 以及後來的替代協議 DNS over TLSDNS over HTTPS,使用加密技術來保護與 DNS 伺服器的通信,系統層面上通常只採用其中一種協議。有關實現這些協議的軟體,請參閱 Domain name resolution#DNS servers

如果你有一個域名,請設置 Sender Policy Framework(發件人策略框架)來抵禦電子郵件欺騙。

代理

代理通常用作應用程式和網絡之間的附加層,攔截不受信任的來源的數據。從攻擊面上看,以較低權限運行的小代理的攻擊面明顯小於使用最終用戶權限運行的複雜應用程式。

例如,DNS 解析器是在 glibc 中實現的,它與應用程式連結(可能以root身份運行),因此 DNS 解析器中的 bug 可能導致本機執行遠程代碼。而這可以安裝充當代理的 DNS 緩存伺服器(例如 dnsmasq)來避免。[2]

管理 SSL 證書

本文或本章節可能需要合併到Transport Layer Security

附註: 有一篇專門介紹傳輸層安全協議的文章。(在 Talk:安全 中討論)

請參閱 OpenSSLNetwork Security Services(NSS,網絡安全服務)來管理各自的伺服器端 SSL 證書。值得注意的是,與此相關的 Let’s Encrypt 項目也支持這些協議。

默認的 Internet SSL 證書信任鏈由 ca-certificates 包及其依賴項提供。請注意,Arch 依賴於信任源(例如 ca-certificates-mozilla)來提供受系統信任的證書。

有時你可能需要暫時更改默認設置。例如,當你讀到這一 新聞 並希望手動解除證書信任,而不是等到信任源提供商這樣做,在 Arch 的體系裡非常簡單:

  1. 以 .crt 格式獲取相應的證書(示例:查看, 下載;如果是現有的受信任的根證書頒發機構,你也可以在系統路徑中找到它)
  2. 將其複製到 /etc/ca-certificates/trust-source/blacklist/
  3. 以 root 身份運行 update-ca-trust

要檢查黑名單是否按預期那樣工作,請重新打開瀏覽器並通過其 GUI 執行此操作,現在瀏覽器應顯示其為不受信任。

軟體包驗證

如果沒有正確地對包進行簽名,包管理器就有可能 受到攻擊,甚至可能會影響原本具有 簽名機制 的包管理器。Arch 默認採用軟體包簽名機制,並依賴來自 5 個可信主密鑰的信任網絡。詳情請參閱 pacman/Package signing

訂閱漏洞告警

訂閱國家漏洞資料庫 (National Vulnerability Database) 提供的常見漏洞和披露 (Common Vulnerabilities and Exposure, CVE) 安全警報更新,相關內容可以在 NVD 下載頁 上找到。Arch Linux Security Tracker 是一個特別有用的資源,它結合了 Arch Linux 安全通報 (ASA),Arch Linux 漏洞組 (AVG) 以及 CVE 數據集,且以表格形式呈現。另請參閱 Arch Security Team(Arch 安全團隊)。

警告: 不要試圖進行 部分升級,因為 Arch Linux 不支持部分升級且可能導致系統不穩定,要升級組件時應升級整個系統。另外,系統更新不及時可能會使以後的更新過程更加複雜。

物理安全

理論上如果有足夠的時間和計算資源,對計算機的物理訪問都將會變成 root 權限的訪問。但通過設置足夠的障礙可以獲得切實的安全保障。

攻擊者只需連接惡意的 IEEE 1394(火線接口),Thunderbolt 或 PCI Express 設備即可在下次啟動時完全控制計算機,因為它們可以完全訪問內存。[3] 你無法阻止類似這樣的操作,包括修改硬體本身的操作(比如將惡意固件刷到設備上)。但是,絕大多數攻擊者都沒有這樣的知識和信心。

#磁碟加密 將在計算機被盜時保護數據,但經驗豐富的攻擊者可以給計算機安裝惡意固件,在用戶下次登錄時獲取加密的數據。

鎖定 BIOS

向 BIOS 添加密碼可防止其他人啟動到可行動裝置,否則這和其他人對計算機具有 root 訪問權限基本相同。你應該確保你的磁碟在引導順序中處於第一位,並且可以的話禁用其他引導設備。

引導加載程序 (Bootloader)

保護引導加載程序非常重要。因為有一個神奇的內核參數叫做 init=/bin/sh,它會使得任何用戶的登錄限制完全無用。

Syslinux

Syslinux 支持 用密碼保護引導加載程序。它允許為每個菜單項設置密碼或為整個引導程序設置密碼。

GRUB

GRUB 也可以設置引導密碼。詳情請參閱 GRUB/Tips and tricks#Password protection of GRUB menu。它還支持 加密的 /boot,這樣只會使引導程序的部分代碼保持未加密狀態。GRUB 的配置、內核initramfs 都是加密的。

啟動分區置於可移動快閃記憶體上

一個較為流行的做法是將啟動分區放在可移動快閃記憶體上,在沒有它的情況下系統便無法啟動。這個想法的支持者經常使用 全盤加密,有些還用到了放在啟動分區上的 分離加密頭

自動註銷

如果你用的是 BashZsh,則可以設置 TMOUT 的值,使 shell 在超時後自動註銷。

例如,下面的腳本內容將使用戶自動從虛擬控制台(非 X11 中的終端模擬器)註銷:

/etc/profile.d/shell-timeout.sh
TMOUT="$(( 60*10 ))";
[ -z "$DISPLAY" ] && export TMOUT;
case $( /usr/bin/tty ) in
	/dev/tty[0-9]*) export TMOUT;;
esac

如果確實想要所有 Bash/Zsh 提示符(包括 X 中的)都有超時,請使用:

$ export TMOUT="$(( 60*10 ))";

請注意,shell 中運行的某些命令(例如:SSH 會話或沒有 TMOUT 支持的其他 shell)將使上述設置失效。但是如果你主要使用 VC 以 root 身份重新啟動僵死的 GDM/Xorg,那麼這非常有用。

防範惡意 USB 設備

請安裝 USBGuard,這是一個軟體框架,通過基於設備屬性的基本白名單和黑名單功能,幫助保護計算機免受惡意 USB 設備(例如 BadUSB[失效連結 2021-11-19 ⓘ]PoisonTapLanTurtle)的侵害。

重新構建軟體包

軟體包可以去除不需要的功能並重新構建,這樣可以縮小受攻擊範圍。例如,bzip2 可以在沒有 bzip2recover 的情況下重新構建,以試圖規避 CVE-2016-3189 漏洞。強化安全的自定義編譯參數也可以手動或通過包裝器在編譯時加入。

參考資料