Security Enhanced Linux, SELinux

SELinux

為了因應與時俱增的安全威脅,美國國家安全局 (National Security Agency, NSA) 發展了一套處理機敏資料的規則,NSA 發現許多安全漏洞都起因於一般使用者繞過了本機安全機制而起,例如為了方便起見將目錄的權限設為 777,但它卻潛藏著將所有資訊洩漏給其他人的危險。

在 Unix-like 系統,存取控制取決於自主存取控制 (Discretionary Access Control, DAC),它是依據當時使用者的身份來決定存取的權限,也就是根據檔案的擁有者 (Owner)、群組 (Group)、其他 (Other) 的讀寫執行 (r,w,x) 權限來作規範,權限的規範除了太單純之外,對 root 完全無控制能力,對運行中的程序本身也無法作限制。

NSA 為系統發展了在使用者權限之上的一套強制存取控制 (Mandatory Access Control, MAC) 的機制,這些機制有一套規則,也就是所謂的 policy,定義了所有的檔案、目錄、資源都是物件 (object),且明訂了什麼樣的程序 (process) 或使用者可以存取那些物件,只要沒有明訂可以的,通通拒絕存取。

對 SELinux 而言,所有的檔案都是一個物件,並在 inode 上儲存了相關的擴充屬性,稱之為安全內容 (Security Context),一共可分成 5 類:
user:使用者屬性,root 擁有 root 值、其他使用者的值是 user_u、一般程序是 system_u。
role:定義檔案、程序、使用者的角色,檔案是 object_r、程序是 system_r、使用者也是 system_r。
type:檔案或程序的型別,也就是什麼型別的程序才能存取什麼型別的檔案。
sensitivity:機密類別。
category:類似 DAC 中 group 的功能,但是可以對 root 的存取作管控。

我們可以用 ls -Z 來看安全內容 (security context) 的內容:
# ls  -Z  /etc/passwd  /var/log/messages  /root/.bashrc
-rw-r–r–  root root system_u:object_r:etc_t /etc/passwd
-rw-r–r–  root root root:object_r:user_home_t /root/.bashrc
-rw——-  root root system_u:object_r:var_log_t /var/log/messages

一般而言,目錄底下的檔案會繼承目錄的安全內容 (security context):
# ls  -Zd  /etc  /etc/hosts  /etc/services  /etc/fstab

drwxr-xr-x  root root system_u:object_r:etc_t          /etc
-rw-r–r–  root root system_u:object_r:etc_t          /etc/fstab
-rw-r–r–  root root system_u:object_r:etc_t          /etc/hosts
-rw-r–r–  root root system_u:object_r:etc_t          /etc/services

當然,特殊的檔案會有它獨特的安全內容 (security context):
# ls  -Z  /etc/shadow /etc/aliases

-rw-r–r–  root root system_u:object_r:etc_aliases_t /etc/aliases
-r——–  root root system_u:object_r:shadow_t /etc/shadow

在 Red Hat Enterprise Linux 並不是所有的程序都受到保護,以官方文件說明,只有 88 項程序受到保護,要查詢該程序是否受到保護,可用 px -ZC PROCESS_NAME 來查詢,只要其 type 型別是 unconfined_t 者,都是還沒在 RHEL5 中納入安全控管的範圍之中:
# ps  -ZC  syslogd,bash,init,vsftpd,Xorg,nautilus
LABEL                             PID TTY          TIME CMD
system_u:system_r:init_t            1 ?        00:00:00 init
system_u:system_r:syslogd_t      2557 ?        00:00:00 syslogd
system_u:system_r:ftpd_t         3351 ?        00:00:00 vsftpd
system_u:system_r:xdm_t:SystemLow-SystemHigh 4134 tty7 01:08:56 Xorg
root:system_r:unconfined_t:SystemLow-SystemHigh 4419 ? 00:00:05 nautilus
root:system_r:unconfined_t:SystemLow-SystemHigh 5714 pts/0 00:00:00 bash

==============================

Policy

SELinux 有一套機制作安全管控,要管控那些地方、範圍大小就取決於我們要使用那套規則,也就是 policy,SELinux 最嚴謹的是 strict policy,所有的內容都要控管。而 Red Hat 則是使用 targeted policy,只控管特定的檔案和資源,雖然在 /etc/sysconfig/selinux 之中可以將 policy 改成 strict,但是並沒有用,因為 Red Hat 並沒將這一部份的功能實作出來,所以僅能使用 targeted policy。

policy  規定了那些物件是可以被使用的,也規定了使用者是否可以使用那些物件,而使用 Type 型別是安全限制的方式,它可以用 chcon 指令來變更安全內容:
# ls  -Z  install.log
-rw-r–r–  root root root:object_r:user_home_t install.log
# chcon  -t  etc_t  install.log (將 install.log 的 type 改成 etc_t
# ls  -Z  install.log

-rw-r–r–  root root root:object_r:etc_t install.log

但是我們可能無法知道或記得所有的型別 (type),我們可以用 chcon –reference 來複製其他物件的型別:
#chcon  –reference  參照物件  改變物件
# ls  -Z  anaconda-ks.cfg
-rw——-  root root system_u:object_r:user_home_t anaconda-ks.cfg
# ls  -Z  /etc/shadow
-r——–  root root system_u:object_r:shadow_t /etc/shadow
# chcon  –reference  /etc/shadow anaconda-ks.cfg (將 anaconda-ks.cfg 的型別改變成和 /etc/shadow 一樣)
# ls  -Z  anaconda-ks.cfg
-rw——-  root root system_u:object_r:shadow_t anaconda-ks.cfg

改變了物件的型別之後,我們可以用 restorecon 來回復物件原本的型別:
# ls  -Z  install.log  anaconda-ks.cfg
-rw——-  root root system_u:object_r:shadow_t anaconda-ks.cfg
-rw-r–r–  root root root:object_r:etc_t install.log

# restorecon  install.log  anaconda-ks.cfg
# ls  -Z  install.log  anaconda-ks.cfg

-rw——-  root root root:object_r:user_home_t anaconda-ks.cfg
-rw-r–r–  root root root:object_r:user_home_t install.log

==============================

管理 SELinux

SELinux 的 policy 可以在 /etc/sysconfig/selinux 中作設定,policy 可以是 Disabled (完全關閉)、Enforcing (正常使用,這是預設值)、以及 Permissive (偵錯模式,只作記錄或警告,但不會真正限制存取),可以直接在 /etc/sysconfig/selinux 文件中作修改,也可以用 setenforce 來作設定,但只有 enforcing (1) 及 permissive (0) 兩種設定方式,要關閉還是要去修改 /etc/sysconfig/selinux 檔案,或在 GRUB 選項中設定 selinux=0。另外,也可用 getenforce 來得知現在的 policy:
# setenforce 0
# getenforce

Permissive
# setenforce 1
# getenforce

Enforcing

Red Hat 也提供了 system-config-selinux 圖形介面的管理工具:
#system-config-selinux

system-config-selinux

system-config-selinux

當 SELinux 拒絕存取時,會產生記錄,登錄到記錄檔中,若系統的 auditd 有啟動的話,記錄檔會記錄到 /var/log/audit/audit.log 中,如果 auditd 沒有啟動,記錄則會記到 /var/log/messages 裡。

==============================

semanage

SELinux 提供了模組化管理的機制,Red Hat 也實作了這一部份,要使用的模組則載入,不必全部條目全部載入之後,再將型別設成 unconfined_t,使得 SELinux 在管理上更加方便。SELinux 在管理上提供了 semanage 指令,它可以變更設定檔,然後編譯成模組,然後再載入 SELinux,semanage 用法:
#semanage
semanage {login|user|port|interface|fcontext|translation} -l [-n]
semanage login -{a|d|m} [-sr] login_name
semanage user -{a|d|m} [-LrRP] selinux_name
semanage port -{a|d|m} [-tr] [ -p protocol ] port | port_range
semanage interface -{a|d|m} [-tr] interface_spec
semanage fcontext -{a|d|m} [-frst] file_spec
semanage translation -{a|d|m} [-T] level

semanage 在使用時,第一個參數必須帶功能 (function) 名稱,共分為 6 種功能:
login:指派 user_u 給登入的使用者
user:管理 sysadm_r、object_r、staff_r 等
port:管理服務存取非標準的埠
interface:管理網路介面並指派安全內容
fcontext:檔案的安全內容,restorcon 參照的型別就是這個
translation:將 sensitivity 和 categories 類別代號轉譯成名稱

SELinux 的 policy 儲存成二進位檔案 (binary),一般的查閱方式是無法瀏覽的,我們可以用 semanage fcontext -l 來查閱其內容,通常服務執行時會帶一個型別,而和此服務相關物件的型別會與服務的型別相似:
# ps  -ZC  named
LABEL                             PID TTY          TIME CMD
root:system_r:named_t 18399 ?        00:00:00 named

# semanage  fcontext  -l  |  cut  -d:  -f3  |  sort  -u  |  grep  named (找出和 named 相關的型別)
named_cache_t
named_checkconf_exec_t
named_conf_t
named_exec_t
named_log_t
named_var_run_t
named_zone_t

由上我們大致可以知道 named 的設定檔 named.conf 其型別是 named_conf_t、記錄檔的型別是 named_log_t,有了這份 fcontext,我們可以用 restorecon 來回復檔案安全內容的型別。