跳至內容
出自 Arch Linux 中文维基

AppArmor 是一種強制訪問控制(Mandatory Access Control, MAC)系統,基於 Linux 安全模塊(Linux Security Modules, LSM)實現。

就像其他大多數的 Linux 安全模塊一樣,AppArmor 是對默認的的自主訪問控制(Discretionary Access Control, DAC)的補充,而非替代。因此,程序通過 AppArmor 獲取到的權限不可能大於原本在 DAC 下擁有的權限。

Ubuntu,SUSE 和許多其他的發行版默認使用 AppArmor,而 RHEL(及其衍生發行版)所使用的 SELinux 需要特定的用戶空間工具才能正常使用。SELinux 通過附加標籤的方式管理所有的文件、進程和對象,因而十分靈活。不過,普遍認為 SELinux 難以配置,且需要支持擴展屬性的的文件系統才能運作。相反,AppArmor 基於文件路徑,配置文件也相對簡單易懂。

AppArmor 通過對特定應用執定專用的規則集,主動保護作業系統和應用程式免受來自內外部的威脅,包括部分零日漏洞攻擊。安全策略決定了每個應用所能夠訪問的系統資源及其權限。沒有在安全配置文件中允許的訪問,將被默認攔截。AppArmor 隨附了一些默認策略,再結合使用高級靜態分析與基於學習的工具,即使是極其複雜的應用程式,用戶也可以在數小時內完成其 AppArmor 策略的編寫。

任何違反策略的訪問都將在系統日誌中報告。也可以通過配置 AppArmor,令其在越權訪問發生時,在用戶桌面實時彈出警告通知。

安裝

AppArmor 可以在所有的官方支持的內核中使用。

安裝 apparmor 以獲取管理 AppArmor 的用戶空間工具與庫。要在啟動時加載所有 AppArmor 安全配置文件,啟用 apparmor.service

要在每次引導時將 AppArmor 作為默認的安全模型啟用,設置以下的內核參數

lsm=landlock,lockdown,yama,integrity,apparmor,bpf
注意:lsm= 內核參數決定了 Linux 安全模塊的初始化順序。內核已配置的 lsm= 值可以通過 zgrep CONFIG_LSM= /proc/config.gz 查看,當前值可以通過 cat /sys/kernel/security/lsm 查看。
  • 確保 apparmor 是參數列表中的第一個「主要」模塊。[1]合法的值和順序的樣例可以在 security/Kconfig 查看。
  • lsm= 中不應包含 capability,因為它始終會被自動隱式包含。

自定義內核

自行編譯內核時,需要啟用以下選項:

CONFIG_SECURITY_APPARMOR=y
CONFIG_AUDIT=y

要讓內核在無需設置內核參數的前提下默認啟用 AppArmor Linux 安全模型,需要額外添加 CONFIG_LSM 選項,並將 apparmor 設定為列表中的第一個「主要」模塊。

CONFIG_LSM="landlock,lockdown,yama,integrity,apparmor,bpf"

使用方法

顯示當前狀態

檢測 AppArmor 是否成功啟動:

$ aa-enabled
Yes

顯示當前運行狀態,執行 aa-status(8)

# aa-status
apparmor module is loaded.
44 profiles are loaded.
44 profiles are in enforce mode.
 ...
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

complain 模式下,違反策略的訪問將被允許,但該行為會被記錄在日誌中。complain 模式常用於了解程序正常運行所需要的權限,或是測試新撰寫的配置文件是否合適。但是,需要注意的是,在配置文件中被設定為 deny 的規則在 complain 模式下仍然會強制執行。

enforce 模式下,違反策略的訪問將被拒絕,並記錄到日誌中。

解析配置文件

使用 apparmor_parser 以加載、卸載、重啟、緩存或是統計配置文件。默認行為(-a)是以 enforce 模式加載配置文件。要以 complain 模式加載,請使用 -C 參數。要覆蓋已有配置文件,使用 -r 參數。要刪除配置文件,使用 -R 參數。每次操作也可能應用到多個配置文件上。參見 apparmor_parser(8) 手冊頁面以了解詳情。

停用

要在當前會話臨時停用 AppArmor,執行以下命令以停用所有配置文件:

# aa-teardown 

要永久停用 AppArmor 配置文件,請停用 apparmor.service。要阻止內核加載 AppArmor,刪除在安裝 AppArmor 時添加的 lsm= 內核參數

配置

審計與生成配置文件

要創建新的配置文件,確保 Audit 框架英語Audit framework正在運行,因為 Arch Linux 使用 systemd,內核日誌默認不會保存到文件中。AppArmor 可以從用戶空間的 auditd 進程抓取內核日誌,從而協助編寫配置文件。

注意:AppArmor audit 消息使用 AVC 記錄格式,使用 ausearch 搜索時可能破壞 audit 日誌的解析。在此查看漏洞報告:[2][3][4]

可以使用 aa-genprof(8)aa-autodep(8) 創建新的 AppArmor 配置文件。新創建的配置文件默認處於 complain 模式:此模式下,違反規則的行為僅會被記錄,不會被拒絕。要交互式地創建配置文件,可以使用 apparmor 包中的 aa-logprof(8)。配置完成後,請使用 aa-enforce(8) 將配置文件設置為 enforce 模式。此模式下,配置文件中的規則將被嚴格執行。此外,可以重複執行 aa-logprof(8) 以添加額外的規則,也可以使用 aa-complain(8) 將配置文件重新設置為 complain 模式。可以在此找到更為詳細的教程:AppArmor wiki - Profiling with tools

需要注意的是,aa-logprof(8) 也提供 deny 規則。不過根據 AppArmor 的設計邏輯,除非規則明確允許,否則任何行為都將被拒絕,因此嚴格來說沒有必要使用 deny 規則。不過,deny 規則有以下兩個用途:

  1. deny 規則的優先級比 allow 規則更高,在 /etc/apparmor.d/abstractions 中的許多 abstraction 中都有使用,用來阻斷任何對重要文件(夾)的訪問。這樣做能防止創建 allow 規則時可能的疏忽,使得配置文件不會太寬鬆。
  2. deny 規則執行時不會在日誌中記錄,使得後續執行 aa-logprof 時產生更為簡潔的日誌。需要注意的是,即使是在 complain 模式下,deny 規則也會被嚴格執行――因此,如果程序在 complain 模式下還是會出錯,應該檢查在某一配置文件或其包含的 abstraction 中,是否有一條 deny 規則導致了此問題。

另外,也可以手動編寫配置文件, 在此查看教程:AppArmor wiki - Profiling by hand

除了 /etc/apparmor.d/ 中的默認配置文件外,在 /usr/share/apparmor/extra-profiles/ 中還有更多預定義的配置文件。不過,這些配置文件並非一定適用於生產環境,因此可能需要手動修改或使用 aa-logprof(8)

也可以在 apparmor.d 項目處找到額外的 AppArmor 規則集。不過,直到撰寫本文時,該項目並非穩定可用。

解讀配置文件

配置文件是可讀性很高的文本文件,保存在 /etc/apparmor.d/ 下,定義了某個可執行文件的權限。以下是一個典型的配置文件:

/etc/apparmor.d/usr.bin.test
#include <tunables/global>

profile test /usr/lib/test/test_binary {
    #include <abstractions/base>

    # Main libraries and plugins
    /usr/share/TEST/** r,
    /usr/lib/TEST/** rm,

    # Configuration files and logs
    @{HOME}/.config/ r,
    @{HOME}/.config/TEST/** rw,
}

@ 符號開頭的字符串是在 abstraction(/etc/apparmor.d/abstractions/),tunables(/etc/apparmor.d/tunables/或配置文件本身中定義的變量。#include 將其他配置文件中的內容包含到此配置文件中來。路徑後的字符是訪問權限。使用 AppArmor 的通配符語法以實現模式匹配。

以下權限涵蓋了最常見的使用場景:

  • r — 讀取:讀取數據
  • w — 寫入:創建,刪除,寫入文件,或是附加內容到文件尾部
  • m — 映射:將文件映射為可執行內存
  • x — 執行:執行文件。需要在前面加上修飾符,形如 px(執行時切換配置文件)

注意,定義的權限始終無法使程序獲得大於原本在 DAC 中擁有的權限。

此處僅提到了很淺顯的內容。要查詢更為詳細的文檔,請查看 apparmor.d(5) 手冊頁和 官方文檔

提示與技巧

拒絕訪問後發出桌面通知

當AppArmor拒絕了程序的訪問後,通知進程可以顯示桌面通知。通過以下步驟,可以在登錄時自動啟動aa-notify進程:

安裝Audit framework並且啟動/啟用用戶空間的Linux Audit進程。之後將你的桌面用戶添加到 audit用戶組,從而允許其讀取審計日誌(audit logs):

# groupadd -r audit
# gpasswd -a user audit

Add audit group to auditd.conf:

/etc/audit/auditd.conf
log_group = audit
提示:You may use other already existing system groups like wheel or adm.

Install python-notify2 and python-psutil.

Create a desktop launcher with the below content:

~/.config/autostart/apparmor-notify.desktop
[Desktop Entry]
Type=Application
Name=AppArmor Notify
Comment=Receive on screen notifications of AppArmor denials
TryExec=aa-notify
Exec=aa-notify -p -s 1 -w 60 -f /var/log/audit/audit.log
StartupNotify=false
NoDisplay=true

Reboot and check if the aa-notify process is running:

$ pgrep -ax aa-notify
注意:Depending on your specific system configuration there could be A LOT of notifications displayed.

For more information, see aa-notify(8).

緩存配置文件以提高 AppArmor 啟動速度

Since AppArmor has to translate the configured profiles into a binary format it may significantly increase the boot time. You can check current AppArmor startup time with:

$ systemd-analyze blame | grep apparmor

To enable caching AppArmor profiles, uncomment:

/etc/apparmor/parser.conf
## Turn creating/updating of the cache on by default
write-cache

To change default cache location add:

/etc/apparmor/parser.conf
cache-loc=/path/to/location
注意:Since 2.13.1 default cache location is /var/cache/apparmor/, previously it was /etc/apparmor.d/cache.d/.

Reboot and check AppArmor startup time again to see improvement:

$ systemd-analyze blame | grep apparmor

排錯

無法啟動 Samba SMB/CIFS 服務

參見 Samba#AppArmor_權限問題

aa-logprof 無法抓取事件

Audit framework英語Audit framework 日誌可能包含特殊字符 0x1d[5]。這個問題有一個 AppArmor bug report。解決辦法是執行以下命令:

# aa-logprof -f <(sed 's/\x1d.*//' < /var/log/audit/audit.log)

升級到 AppArmor v4 後無法登錄

在非常罕見的情況下,升級到 AppArmor v4 會導致無法登錄到任何帳戶

系統日誌中可能包含類似如下內容的錯誤:

unix_chkpwd[1612]: check pass; user unknown
unix_chkpwd[1612]: password check failed for user (john)
gdm-password][1574]: pam_unix(gdm-password:auth): authentication failure; logname= uid=0 euid=0 tty=/dev/tty1 ruser= rhost=  user=john
kernel: audit: type=1400 audit(1730844640.468:171): apparmor="DENIED" operation="capable" class="cap" profile="unix-chkpwd" pid=1612 comm="unix_chkpwd" capability=2  capname="dac_read_search"
kernel: audit: type=1400 audit(1730844640.468:172): apparmor="DENIED" operation="capable" class="cap" profile="unix-chkpwd" pid=1612 comm="unix_chkpwd" capability=1  capname="dac_override"

這可能是由於 root 帳戶無法讀取 /etc/shadow 和/或 /etc/gshadow 導致的(例如,這些文件的權限位(Permission bits)尚未設定)。因此,可以試試以下解決辦法:

  1. 重啟,然後停用 AppArmor(在啟動時編輯 Bootloader 參數,或者使用尚未啟用 AppArmor 的 fallback 啟動項)。
  2. root 身份登錄,然後設定正確的文件權限:chmod 600 /etc/shadow /etc/gshadow
  3. 再次重啟。

不同 Linux 發行版之間的區別

Information you find often is about AppArmor on Ubuntu, which can be confusing, since Ubuntu carries a lot of kernel patches regarding AppArmor. Other distributions may also carry their own kernel patches, while Arch Linux uses a close-to-mainline kernel.

For example, while apparmor.d(5) already documents dbus rules, they require support from AppArmor userspace tools, kernel and D-Bus daemon[6]. The corresponding kernel patch[7] is applied by Ubuntu, but not included in mainline Linux and official Arch kernels. (Support also varies by D-Bus implementation.)

AppArmor-specific kernel patches applied by Ubuntu can be found at (replace oracular with the codename of the Ubuntu version you are interested in):

https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/oracular/log/?qt=grep&q=UBUNTU%3A+SAUCE%3A+apparmor

The ABI versions supported by the userland tools can be found in /etc/apparmor.d/abi/. The ABI supported by the currently running kernel can be shown with:

$ aa-features-abi --extract

參見