SELinux 強制存取控制機制透過標籤化檔案、目錄和埠號,有效限制程式存取許可權,提升系統安全性。除了基本狀態查詢和布林值開關設定外,更可透過 semanage 指令管理自訂埠,並使用 audit2allow 工具建立客製化策略模組,精細調整系統安全策略。相對而言,AppArmor 則採用路徑強制方式,簡化設定檔管理,並提供更易於理解的語法和自動化工具,降低使用門檻。兩種機制各有優劣,系統管理員可依據實際需求選擇合適的方案。

SELinux 的基本操作與 Boolean 設定

SELinux(Security-Enhanced Linux)是一種強制存取控制(MAC)機制,用於增強 Linux 系統的安全性。本文將介紹 SELinux 的基本操作及其 Boolean 設定的方法。

檢視 SELinux 狀態

首先,我們需要檢查 SELinux 的目前狀態。可以使用 sestatus 指令來檢視:

[donnie@localhost ~]$ sudo sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28

在輸出結果中,我們關注兩個重要的專案:Current modeMode from config file。目前的執行模式是 enforcing,而設定檔中的模式則是 permissive。這表示雖然設定檔已經被修改為 permissive,但目前的執行模式仍然是 enforcing。要切換到 permissive 模式,需要執行 sudo setenforce 0 指令,或重新啟動系統。

SELinux Boolean 設定

SELinux Boolean 是用來控制 SELinux 策略的二元開關。每個 Boolean 代表一個二元選擇,不是允許就是禁止某個動作。可以使用 getsebool -a 指令來檢視所有 Boolean 的設定:

[donnie@localhost ~]$ getsebool -a
abrt_anon_write --> off
abrt_handle_event --> off
abrt_upload_watch_anon_write --> on
antivirus_can_scan_system --> off
antivirus_use_jit --> off
auditadm_exec_content --> on
...

若要檢視特定的 Boolean,可以省略 -a 選項,直接指定 Boolean 名稱。例如,檢視 httpd_enable_homedirs 的狀態:

[donnie@localhost html]$ getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off

此結果表示 Apache 伺服器無法存取使用者家目錄中的檔案。若要允許 Apache 存取特設定檔案,可以將相關的 Boolean 設定為 on

篩選 Boolean 設定

由於 Boolean 的數量眾多,可以使用 grep 指令來篩選特定的 Boolean。例如,檢視與網頁伺服器相關的 Boolean:

[donnie@localhost html]$ getsebool -a | grep 'http'
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
...

修改 Boolean 設定

若需要修改 Boolean 的設定,可以使用 setsebool 指令。例如,允許 Samba 伺服器存取使用者家目錄:

[donnie@localhost html]$ getsebool -a | grep 'home'
git_cgi_enable_homedirs --> off
git_system_enable_homedirs --> off
httpd_enable_homedirs --> off
samba_enable_home_dirs --> off
...
[donnie@localhost html]$ sudo setsebool samba_enable_home_dirs on
[donnie@localhost html]$ getsebool samba_enable_home_dirs
samba_enable_home_dirs --> on

預設情況下,使用 setsebool 修改的設定在系統重新啟動後會失效。若要使變更永久生效,需要加上 -P 選項:

[donnie@localhost html]$ sudo setsebool -P samba_enable_home_dirs on

內容解密:

  1. getsebool -a:列出系統中所有的 SELinux Boolean 設定。
  2. getsebool <boolean_name>:檢視特定 Boolean 的目前狀態。
  3. setsebool <boolean_name> <on/off>:修改 Boolean 的狀態。
  4. setsebool -P <boolean_name> <on/off>:永久修改 Boolean 的狀態,使其在系統重新啟動後仍然有效。

網路服務的 SELinux 防護機制

在 SELinux 的安全框架下,系統管理員能夠針對不同的網路服務進行精細的安全控制。這裡將重點介紹如何利用 SELinux 布林值和連線埠管理來保護網路服務,尤其是 Apache 網頁伺服器。

利用 SELinux 布林值保護網頁伺服器

SELinux 布林值允許管理員在不改變或重新編譯政策的情況下,動態地調整 SELinux 政策。對於網頁伺服器來說,有幾個重要的布林值需要了解:

  1. httpd_unified: 當使用 PHP 為基礎的內容管理系統(如 Joomla 或 WordPress)時,需要啟用此布林值,以允許 Apache 網頁伺服器與 PHP 引擎的各個元件正確互動。

    getsebool httpd_unified
    sudo setsebool -P httpd_unified on
    
  2. httpd_can_sendmail: 如果網站在表單提交時需要傳送郵件,或者需要設定一個具有網頁前端的郵件伺服器,則需要啟用此布林值。

    getsebool httpd_can_sendmail
    sudo setsebool -P httpd_can_sendmail on
    
  3. httpd_enable_cgi: 預設情況下,SELinux 允許 CGI 指令碼執行。然而,這可能帶來安全風險。如果確定不需要執行 CGI 指令碼,可以關閉此布林值。

    getsebool httpd_enable_cgi
    sudo setsebool -P httpd_enable_cgi off
    

內容解密:

  • getsebool 命令用於查詢 SELinux 布林值的狀態。
  • setsebool -P 命令用於設定 SELinux 布林值,-P 引數使得變更在重啟後仍然有效。
  • 正確組態這些布林值對於確保網頁伺服器的安全至關重要。

保護網路連線埠

每個網路守護程式都被分配特定的連線埠或連線埠集合來監聽。SELinux 可以防止惡意軟體使守護程式監聽非標準連線埠,從而保護系統安全。

使用 semanage port -l 命令可以列出允許的連線埠:

sudo semanage port -l

要檢視 Apache 網頁伺服器可以監聽的連線埠,可以使用 grep 命令過濾輸出:

sudo semanage port -l | grep 'http'

這將顯示與 http 相關的連線埠型別,例如 http_port_t,它允許 Apache 監聽特定的連線埠,如 80、443 等。

內容解密:

  • semanage port -l 命令列出所有被 SELinux 允許的連線埠。
  • 使用 grep 命令可以過濾出與特定服務(如 http)相關的連線埠。
  • 這有助於管理員瞭解哪些連線埠是被允許的,從而更好地組態和保護網路服務。

設定 Apache 監聽非標準連線埠

如果嘗試將 Apache 組態為監聽一個非標準連線埠(例如,將 Listen 80 改為 Listen 82),並重啟 Apache,可能會遇到錯誤。SELinux 日誌會記錄相關的拒絕訊息,並建議使用 semanage 命令將該連線埠新增到允許列表中。

sudo semanage port -a -t http_port_t -p tcp 82

內容解密:

  • 將非標準連線埠新增到 SELinux 的允許列表中,可以使 Apache 正確監聽該連線埠。
  • semanage port -a 命令用於新增新的連線埠,-t http_port_t 指定了連線埠型別,-p tcp 指定了協定。
  • 這樣可以確保 Apache 能夠在指定的非標準連線埠上正常執行。

SELinux 的進階應用:自訂埠與政策模組

在前面的章節中,我們已經瞭解了 SELinux 的基本概念和操作方式。在本章節中,我們將探討 SELinux 的進階應用,包括如何為 Apache 設定自訂埠以及如何建立自訂的 SELinux 政策模組。

為 Apache 設定自訂埠

當我們需要 Apache 在非標準的埠上監聽時,SELinux 預設會阻止這種行為。以下是一個實際操作的例子:

首先,假設我們要讓 Apache 在埠 82 上監聽。我們需要使用 semanage 命令來新增這個埠到 SELinux 的允許列表中:

sudo semanage port -a -t http_port_t -p tcp 82

這條命令的解釋如下:

  • -a 表示新增一個新的埠。
  • -t http_port_t 指定了這個埠的型別為 http_port_t,也就是 HTTP 服務所使用的埠型別。
  • -p tcp 指定了這個埠使用的協定是 TCP。
  • 82 是我們要新增的埠號。

新增完成後,我們可以透過以下命令來驗證:

sudo semanage port -l | grep 'http_port_t'

輸出結果應該包含我們剛剛新增的埠號 82。

內容解密:

  1. semanage port -a:用於新增一個新的埠到 SELinux 的允許列表中。
  2. -t http_port_t:指定了這個埠的型別為 http_port_t,確保 Apache 可以在這個埠上監聽。
  3. -p tcp:指定了這個埠使用的協定是 TCP,這是 HTTP 服務通常使用的協定。

完成上述步驟後,我們可以重新啟動 Apache 服務:

sudo systemctl restart httpd
sudo systemctl status httpd

如果一切正常,Apache 應該能夠成功啟動並在埠 82 上監聽。

當我們不再需要這個自訂埠時,可以使用以下命令來刪除它:

sudo semanage port -d -t http_port_t -p tcp 82

這條命令會將埠 82 從 SELinux 的允許列表中移除。

建立自訂的 SELinux 政策模組

有時候,我們可能會遇到一些問題,無論是透過更改型別還是設定 Boolean 值都無法解決。在這種情況下,我們需要建立自訂的 SELinux 政策模組。

以下是建立自訂政策模組的步驟:

  1. 切換到 permissive 模式:在建立自訂政策模組之前,先將 SELinux 切換到 permissive 模式,以確保我們捕捉到所有相關的錯誤訊息。
  2. 誘發 SELinux 錯誤:執行可能觸發 SELinux 錯誤的操作,以便在日誌中記錄相關的錯誤訊息。
  3. 使用 audit2allow 建立自訂政策模組:使用 audit2allow 命令來分析日誌中的錯誤訊息,並建立自訂的政策模組。

例如:

grep dict /var/log/audit/audit.log | audit2allow -M dovecot_dict

這條命令會從 /var/log/audit/audit.log 日誌檔案中篩選出包含 dict 的錯誤訊息,並使用 audit2allow 建立一個名為 dovecot_dict 的自訂政策模組。

  1. 載入自訂政策模組:使用 semodule 命令來載入我們剛剛建立的自訂政策模組。
semodule -i dovecot_dict.pp
  1. 重新載入 SELinux 政策:使用以下命令來重新載入 SELinux 政策,以使新的政策模組生效。
semodule -R

圖表翻譯:

此圖示呈現了建立自訂 SELinux 政策模組的流程,包括切換到 permissive 模式、誘發 SELinux 錯誤、使用 audit2allow 建立自訂政策模組、載入自訂政策模組以及重新載入 SELinux 政策。 圖表翻譯: 此圖示詳細呈現了建立自訂 SELinux 政策模組的整個過程,從切換到 permissive 模式開始,直到重新載入 SELinux 政策為止,每一步驟都清晰地展示出來。

AppArmor 的基礎與應用

AppArmor 是 SUSE 和 Ubuntu 家族 Linux 發行版中預設的強制存取控制(MAC)系統。雖然其設計目的是與 SELinux 類別似,但運作模式卻有很大差異。

SELinux 與 AppArmor 的主要區別

  1. SELinux

    • 對所有系統程式和物件(如檔案、目錄、網路埠)進行標籤化。
    • 標籤儲存在檔案和目錄的 inode 擴充套件屬性中。
  2. AppArmor

    • 使用路徑強制,即指定要控制的可執行檔路徑。
    • 無需在檔案或目錄的擴充套件屬性中插入標籤。

AppArmor 的優勢

  • 簡化的組態:AppArmor 為每個個別應用程式提供設定檔(profile),而非像 SELinux 那樣提供系統範圍的保護。
  • 易於撰寫設定檔:相比 SELinux 的策略,AppArmor 的設定檔語法更簡單,且提供自動化工具協助建立自訂設定檔。

檢視 AppArmor 設定檔

  1. 安裝 lxc 套件以取得更多範例

    sudo apt install lxc
    
  2. 檢視 /etc/apparmor.d/ 目錄下的設定檔

    donnie@ubuntu3:/etc/apparmor.d$ ls -l
    total 72
    drwxr-xr-x 5 root root 4096 Oct 29 15:21 abstractions
    drwxr-xr-x 2 root root 4096 Nov 15 09:34 cache
    drwxr-xr-x 2 root root 4096 Oct 29 14:43 disable
    ...
    -rw-r--r-- 1 root root 125 Jun 14 16:15 usr.bin.lxc-start
    -rw-r--r-- 1 root root 281 May 23 2017 usr.lib.lxd.lxd-bridge-proxy
    -rw-r--r-- 1 root root 17667 Oct 18 05:04 usr.lib.snapd.snap-confine.real
    -rw-r--r-- 1 root root 1527 Jan 5 2016 usr.sbin.rsyslogd
    -rw-r--r-- 1 root root 1469 Sep 8 15:27 usr.sbin.tcpdump
    

理解設定檔與抽象化檔案

  • 所有文字檔都是 AppArmor 的設定檔。
  • abstractions 子目錄包含可被多個設定檔參照的抽象化檔案,避免重複編寫相同程式碼。

在 Ubuntu 上安裝更多設定檔

執行以下命令以安裝更多設定檔:

sudo apt install apparmor-profiles apparmor-profiles-extra

AppArmor 設定檔範例與抽象化檔案

部分抽象化檔案列表:

donnie@ubuntu3:/etc/apparmor.d/abstractions$ ls -l
total 320
-rw-r--r-- 1 root root 695 Mar 15 2017 apache2-common
drwxr-xr-x 2 root root 4096 Oct 29 15:21 apparmor_api
-rw-r--r-- 1 root root 308 Mar 15 2017 aspell
-rw-r--r-- 1 root root 1582 Mar 15 2017 audio
...
-rw-r--r-- 1 root root 705 Mar 15 2017 web-data
-rw-r--r-- 1 root root 739 Mar 15 2017 winbind
-rw-r--r-- 1 root root 585 Mar 15 2017 wutmp
-rw-r--r-- 1 root root 1819 Mar 15 2017 X
-rw-r--r-- 1 root root 883 Mar 15 2017 xad
-rw-r--r-- 1 root root 673 Mar 15 2017 xdg-desktop

AppArmor 工作流程圖示

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title SELinux 與 AppArmor 安全強化實戰

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

圖表翻譯: 此圖示展示了 AppArmor 的基本工作流程。首先,AppArmor 被啟動並載入相關的設定檔。接著,它會檢查受控應用程式的行為是否符合設定檔中的規則。如果行為符合規則,則允許存取;否則,AppArmor 將拒絕存取並將相關資訊記錄到日誌中。