注意:

在 Oracle Linux 上使用 SELinux

簡介

SELinux 是一組核心模組和使用者空間工具,提供另一層系統安全、精確的存取控制、全系統管理原則,以及針對權限呈報攻擊改善緩和措施。

本教學課程將引導您使用這些使用者空間工具,協助讓系統以強制模式執行。

目標

在本實驗室中,您將瞭解:

必要條件

設定實驗室環境

注意:使用免費實驗室環境時,請參閱 Oracle Linux Lab Basics,瞭解連線和其他使用指示。

建立使用者

其他使用者稍後可以在本實驗室中測試指定 SELinux 使用者。

  1. 如果尚未連接,請開啟終端機並透過 ssh 連線至 ol8-server 系統。

    ssh oracle@<ip_address_of_ol8-server>
    
  2. 建立使用者並設定密碼。

    sudo useradd -u 8000 ralph
    echo "ralph:oracle" | sudo chpasswd
    
  3. 允許 SSH 連線。

    oracle 使用者帳戶複製 SSH 金鑰。

    sudo mkdir /home/ralph/.ssh
    sudo cp /home/oracle/.ssh/authorized_keys /home/ralph/.ssh/authorized_keys
    sudo chown -R ralph:ralph /home/ralph/.ssh
    sudo chmod 700 /home/ralph/.ssh
    sudo chmod 600 /home/ralph/.ssh/authorized_keys
    
  4. 開啟新的終端機並驗證 SSH 連線是否運作。

    ssh ralph@<ip_address_of_ol8-server>
    

    然後 exit 階段作業,並關閉終端機視窗。

SELinux 模式和狀態

Oracle Linux 預設會安裝 SELinux,並且以 Enforcing 模式執行。

  1. 檢查 SELinux 模式以確認。

    應設為 Enforcing

    getenforce
    
  2. 檢查 SELinux 狀態和模式。

    sestatus
    

    sestatus 指令輸出顯示 SELinux 狀態、原則與模式。

    範例輸出:

    SELinux status:                 enabled
    SELinuxfs mount:                /sys/fs/selinux
    SELinux root directory:         /etc/selinux
    Loaded policy name:             targeted
    Current mode:                   enforcing
    Mode from config file:          enforcing
    Policy MLS status:              enabled
    Policy deny_unknown status:     allowed
    Memory protection checking:     actual (secure)
    Max kernel policy version:      31
    

SELinux 安全標籤

SELinux 下的每個程序和系統資源都具有稱為 SELinux 環境的安全標籤。SELinux 相關資訊環境 (亦稱為 SELinux 標籤) 將焦點放在安全特性上,並確保在 SELinux 原則中參照物件的一致方式。

  1. 顯示檔案的 SELinux 安全標籤。

    ls -ldZ /etc/passwd
    

    範例輸出:

    -rw-r--r--. 1 root root system_u:object_r:passwd_file_t:s0 1892 Apr 13 14:39 /etc/passwd
    

    ls 輸出的 -Z 選項會顯示四個 SELinux 屬性欄位:

    • 使用者:system_u
    • 角色:object_r
    • 類型:passwd_file_t
    • 安全:s0

    這些當中最重要的是 SELinux 類型,主要的 SELinux targeted 原則規則都運用 SELinux 類型來定義允許在某個物件 (例如處理作業) 和另一個物件 (例如檔案) 之間進行互動。

  2. 列出可用的 SELinux 類型。

    seinfo --type | head
    
    • head 指令會將輸出限制為前十個輸出行。

    完整輸出顯示許多不同指令和服務 (例如 sshsshd) 的 SELinux 類型存在。

  3. 列出特定 SELinux 類型。

    grep 只會將輸出限制為僅包含 ssh 這個字的類型。

    seinfo -t | grep ssh
    
  4. 列出特定程序和配置檔的安全纜線。

    使用 ps 取得程序的安全性標籤。

    ps -efZ | grep sshd
    

    範例輸出:

    system_u:system_r:sshd_t:s0-s0:c0.c1023 root 2535      1  0 14:37 ?        00:00:00 /usr/sbin/sshd -D
    system_u:system_r:sshd_t:s0-s0:c0.c1023 root 18514  2535  0 15:21 ?        00:00:00 sshd: oracle [priv]
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 oracle 18528 18514  0 15:21 ? 00:00:00 sshd: oracle@pts/0
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 oracle 23611 18529  0 15:41 pts/0 00:00:00 grep --color=auto sshd
    

    使用 ls 會取得配置檔案的安全標籤。

    ls -lZ /etc/ssh/
    

    範例輸出:

    total 600
    -rw-r--r--. 1 root root     system_u:object_r:etc_t:s0      577388 Oct  9  2021 moduli
    -rw-r--r--. 1 root root     system_u:object_r:etc_t:s0        1770 Oct  9  2021 ssh_config
    drwxr-xr-x. 2 root root     system_u:object_r:etc_t:s0          28 Feb 18 08:51 ssh_config.d
    -rw-------. 1 root root     system_u:object_r:etc_t:s0        4268 Apr 13 14:37 sshd_config
    -rw-r-----. 1 root ssh_keys system_u:object_r:sshd_key_t:s0    537 Apr 13 14:37 ssh_host_ecdsa_key
    -rw-r--r--. 1 root root     system_u:object_r:sshd_key_t:s0    197 Apr 13 14:37 ssh_host_ecdsa_key.pub
    -rw-r-----. 1 root ssh_keys system_u:object_r:sshd_key_t:s0    432 Apr 13 14:37 ssh_host_ed25519_key
    -rw-r--r--. 1 root root     system_u:object_r:sshd_key_t:s0    117 Apr 13 14:37 ssh_host_ed25519_key.pub
    -rw-r-----. 1 root ssh_keys system_u:object_r:sshd_key_t:s0   2635 Apr 13 14:37 ssh_host_rsa_key
    -rw-r--r--. 1 root root     system_u:object_r:sshd_key_t:s0    589 Apr 13 14:37 ssh_host_rsa_key.pub
    

    sshd 常駐程式程序使用 sshd_t 類型。因此,在 targeted 原則中,預期有 sshd_t SELinux 屬性的規則,其中說明含有 sshd_t 的物件可以存取含有下列安全屬性的所有物件:

    • etc_t
    • sshd_key_t
    • ...

    同樣地,如果我們要檢查 ssh 指令,我們可以判斷 ssh_home_tssh_exec_t 之間的類似對應。

    ls -lZ /usr/bin/ssh
    

    範例輸出:

    -rwxr-xr-x. 1 root root system_u:object_r:ssh_exec_t:s0 775720 Oct  9  2021 /usr/bin/ssh
    
    ls -lZ ~/.ssh
    

    範例輸出:

    total 4
    -rw-------. 1 oracle oracle unconfined_u:object_r:ssh_home_t:s0 404 Apr 13 14:39 authorized_keys
    
  5. 取得使用者的安全相關資訊環境。

    其他感興趣的內容類型為 unconfined_t。具有此 SELinux 類型 (例如使用者) 的物件具有不受限的存取。此層次的存取意味著 SELinux 不會限制使用者可執行的工作,而且只有透過 DAC 權限加以禁止。DAC (自由存取控制) 是由傳統使用者、群組以及其他權限所處理的安全原則。

    例如,顯示 oracle 使用者的安全屬性。

    whoami
    
    id -Z
    

    範例輸出:

    [oracle@ol-selinux ~]$ whoami
    oracle
    [oracle@ol-selinux ~]$ id -Z
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    

SELinux 與網路服務

SELinux 會追蹤其內部資料庫內最常使用的網路型軟體套裝程式組態。此追蹤可讓 SELinux 保護系統,免於受到外部公開的服務攻擊。

因此,如果您將軟體配置為使用非標準目錄或連接埠,SELinux 可使服務無法運作。

若要顯示 SELinux 對於系統標準連接埠的認知,我們必須使用 SELinux 公用程式 semanage。Oracle Linux 預設不會安裝此公用程式,因此請加以安裝。

  1. 判斷哪一個套裝軟體提供公用程式。

    sudo dnf whatprovides semanage
    

    結果顯示 /usr/sbin/semanagepolicycoreutils-python-utils 套裝軟體的一部分。

  2. 安裝套裝軟體與任何相依性。

    sudo dnf install -y policycoreutils-python-utils
    
  3. 檢查 sshd 允許哪些連接埠 SELinux。

    sudo semanage port -l | grep ssh
    

    範例輸出:

    ssh_port_t                     tcp      22
    
  4. 新增連接埠至 SELinux 原則。

    如果我們要變更連接埠,SSH 協助程式監聽 2222 或變更其儲存預設組態的位置;則需要通知 SELinux,讓我們要進行這些變更。您可以再次使用 semanage 新增原則規則來允許自訂連接埠。

    sudo sudo semanage port -a -t ssh_port_t -p tcp 2222
    
    • -a 選項會新增類型為 -t 的新原則規則。
  5. 檢查 SELinux 目前允許的連接埠。

    sudo semanage port -l | grep ssh
    

    範例輸出:

    ssh_port_t                     tcp      2222, 22
    
  6. 修改 SELinux 原則中的連接埠。

    我們要將 SSH 協助程式對應至連接埠 443。重複相同的指令,但隨著使用中的訊息而發生錯誤。

    sudo semanage port -a -t ssh_port_t -p tcp 443
    

    範例輸出:

    ValueError: Port tcp/443 already defined
    

    發生錯誤,因為我們嘗試將連接埠 443 從 http_port_t 類型切換為 ssh_port_t 類型。若要這樣做,請使用修改連接埠物件記錄的 -m 選項。

    sudo semanage port -m -t ssh_port_t -p tcp 443
    

SELinux 使用者

每位 Linux 使用者都會使用 SELinux 原則對應至 SELinux 使用者。此方式允許 Linux 使用者根據其 SELinux 使用者對應來繼承限制。Oracle Linux 中的預設對應是 __default__ 登入,此登入對應至 SELinux unconfined_u 使用者。

  1. 取得所有目前 Linux 使用者對應的清單。

    sudo semanage login -l
    
    • 請注意,未列出我們的 oracle 使用者,因此對應至 unconfined_u 使用者。
  2. 列出 SELinux 使用者。

    seinfo -u
    
  3. 限制使用者的動作。

    雖然預設 Linux 使用者未受限制,但是使用者的動作可能會根據應用程式 domain 產生限制。domain 是多種具有相同 SELinux 類型的物件。

    如果我們想要封鎖使用者使用 X Window 系統、sudo 以及網路,會發生什麼情況?

    SELinux 具有該使用者。

    若要驗證,我們需要有另一個 Linux 使用者。我們將使用使用者 ralph

    1. 建立 guest_u 的新對應。

      sudo semanage login -a -s guest_u ralph
      
    2. 驗證對應。

      sudo semanage login -l
      
    3. 測試 ralph 無法存取網路。

      繼承自 guest_u 的限制只有在登入後才會發生,而不會執行 sudosu

      開啟 new 終端機,並以 ralph 使用者的身分透過 ssh 連線至 ol8-server 系統。

      ssh ralph@<ip_address_of_ol8-server>
      
    4. 檢查使用者的相關資訊環境。

      id; id -Z
      

      範例輸出:

      uid=8000(ralph) gid=8000(ralph) groups=8000(ralph) context=guest_u:guest_r:guest_t:s0
      guest_u:guest_r:guest_t:s0
      
    5. 顯示使用者目前程序的安全相關資訊環境:

      ps axZ
      

      輸出顯示對應至 guest_u 的使用者 ralph,且可登入。但是,ralph 無法存取網路。

    6. 測試與 ping 的網路連線。

      ping localhost
      

      範例輸出:

      ping: socket: Permission denied
      
    7. 此外,也使用 curl 來測試網路。

      curl ifconfig.me
      

      範例輸出:

      curl: (6) Could not resolve host: ifconfig.me
      

      訊息會指出 curl 無法將 ifconfig.me 的 DNS 名稱解析為 IP 位址。DNS 是 Linux 網路服務,需要開啟通訊埠,因此 SELinux guest_u 使用者會封鎖它。

    8. 關閉目前的終端機視窗。

      我們已完成使用者 ralph 的測試,請關閉該終端機視窗。

      exit
      

SELinux Booleans

SELinux booleans 可在程式實際執行時變更特定原則,無須瞭解如何撰寫 SELinux 原則。Oracle Linux 提供許多內建的 ooleans,或者熟悉 SELinux 原則的管理員也可以自行撰寫。如果實行的原則是選擇性的,就會鼓勵管理員將原則寫入群體。

  1. 取得生物及其意義的清單。

    切換回您以 oracle 身分登入的終端機,然後執行下列命令。

    sudo semanage boolean -l
    

    範例輸出:

    SELinux boolean                State  Default Description
    
    abrt_anon_write                (off  ,  off)  Allow abrt to anon write
    abrt_handle_event              (off  ,  off)  Allow abrt to handle event
    abrt_upload_watch_anon_write   (on   ,   on)  Allow abrt to upload watch anon write
    antivirus_can_scan_system      (off  ,  off)  Allow antivirus to can scan system
    antivirus_use_jit              (off  ,  off)  Allow antivirus to use jit
    auditadm_exec_content          (on   ,   on)  Allow auditadm to exec content
    authlogin_nsswitch_use_ldap    (off  ,  off)  Allow authlogin to nsswitch use ldap
    authlogin_radius               (off  ,  off)  Allow authlogin to radius
    ...
    
    • 輸出會說明每個布林值的功能,以及是否啟用 (on) 或停用 (off)。
  2. 僅取得布林值與其狀態的清單。

    sudo 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
    authlogin_nsswitch_use_ldap --> off
    authlogin_radius --> off
    authlogin_yubikey --> off
    ...
    
  3. 取得單一布林值的狀態。

    如果已知布林值名稱,請將名稱傳遞為引數,以便僅取得該布林值狀態。

    sudo getsebool virt_use_nfs
    
  4. 查詢布林值的 SELinux 原則。

    默認在 SELinux 原則中觸發布林值是什麼?SELinux 提供查詢這些規則的公用程式。

    sesearch -b virt_use_nfs -A
    

    範例輸出:

    allow fsdaemon_t autofs_t:dir { getattr open search }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:dir { getattr ioctl lock open read search }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:dir { getattr ioctl lock open read search }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:dir { getattr ioctl lock open read search }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:dir { getattr open search }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:dir { getattr open search }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:file { getattr ioctl lock open read }; [ virt_use_nfs ]:True
    allow fsdaemon_t nfs_t:lnk_file { getattr read }; [ virt_use_nfs ]:True
    ...
    
  5. 查詢布林值是否允許存取。

    根據條件式布林值是否允許特定存取的相關資訊?回答問題:使用者偵測是否允許從使用者網域 (user_t) 轉換為偵測網域 (ping_t)?

    sesearch -s user_t -t ping_t -c process -p transition -AT
    

    範例輸出:

    allow user_t ping_t:process transition; [ selinuxuser_ping ]:True
    
    • 如果啟用 user_ping SELinux 布林,便允許轉換。
  6. 啟用布林值。

    是否允許 KVM 儲存 Samba 分享上的影像 ?也有一個布林值。

    1. 尋找布林值。

      sudo semanage boolean -l | grep virt | grep samba
      

      範例輸出:

      virt_use_samba                 (off  ,  off)  Allow virt to use samba
      
    2. 將布林值變更為啟用。

      sudo setsebool virt_use_samba on
      

      或者

      sudo semanage boolean -m --on virt_use_samba
      
    3. 檢查目前狀態。

      getsebool virt_use_samba
      
    4. 確保變更不會重新啟動。

      sudo setsebool -P virt_use_samba on
      
  7. 顯示本機 SELinux 原則自訂項目。

    瞭解我們已更改預設設定,可以顯示這些本機自訂項目。

    sudo semanage boolean -l -C
    

    範例輸出:

    SELinux boolean                State  Default Description
    
    virt_use_samba                 (on   ,   on)  Allow virt to use samba
    
    • 輸出顯示預設值為 on。預設值會在讓交換器永久變更,並將擱置中值寫入磁碟上的原則檔案之後變更。

SELinux 檔案相關資訊環境

執行 SELinux 時,所有檔案和目錄都會以 SELinux 相關資訊環境標示。我們將檢查一些管理檔案系統標籤的指令。

其中一個常見的範例是為 Nginx 的文件根目錄建立新目錄。

  1. 與三個檔案一起建立新目錄。

    sudo mkdir -p /web
    sudo touch /web/file{1,2,3}
    
  2. 檢查新目錄和檔案標籤。

    ls -lZ /web
    

    範例輸出:

    total 0
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file1
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file2
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file3
    
    • 新目錄的內容類型和檔案為 default_t

    注意:新建立的檔案和目錄會繼承其父目錄的 SELinux 類型。

  3. 變更暫時標籤。

    進行疑難排解或測試時,我們可以暫時變更內容。

    sudo chcon -R -t httpd_sys_content_t /web/
    
    ls -lZ /web
    
  4. 將標籤回復成預設值。

    將內容切換回預設內容類型。

    sudo restorecon -R -v /web/
    

    範例輸出:

    [oracle@ol-selinux ~]$ sudo restorecon -R -v /web/
    Relabeled /web from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0
    Relabeled /web/file1 from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0
    Relabeled /web/file2 from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0
    Relabeled /web/file3 from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0
    [oracle@ol-selinux ~]$ ls -lZ /web
    total 0
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file1
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file2
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file3
    
  5. 進行標籤永久變更。

    若要使變更永久且在重新啟動後存留,請使用 semanage fcontext 指令。-a 會將記錄新增至檔案 /etc/selinux/targeted/contexts/files/file_contexts.local,而 -t 則定義該類型。

    sudo semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
    

    注意:使用 semanage fcontext 變更 SELinux 相關資訊環境時,建議使用檔案或目錄的完整路徑,以避免在檔案系統重新標示之後或在執行 restorecon 之後標示檔案。

  6. 檢查相關資訊環境。

    ls -ldZ /web; ls -lZ /web
    

    範例輸出:

    [oracle@ol-selinux ~]$ ls -ldZ /web; ls -lZ /web
    drwxr-xr-x. 2 root root unconfined_u:object_r:default_t:s0 45 Apr 14 19:00 /web
    total 0
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file1
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file2
    -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file3
    

    請注意前後關聯並未變更,我們認為。

  7. 顯示新建立的檔案與目錄的內文 。

    sudo semanage fcontext -C -l
    

    範例輸出:

    [oracle@ol-selinux ~]$ sudo semanage fcontext -C -l
    SELinux fcontext                                   type               Context
    
    /web(/.*)?                                         all files          system_u:object_r:httpd_sys_content_t:s0 
    
  8. 將變更套用至環境定義。

    sudo restorecon -R -v /web
    

    範例輸出:

    [oracle@ol-selinux ~]$ sudo restorecon -R -v /web
    Relabeled /web from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    Relabeled /web/file1 from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    Relabeled /web/file2 from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    Relabeled /web/file3 from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    
  9. 移除新的 SELinux 環境定義。

    sudo semanage fcontext -d "/web(/.*)?"
    
    • 此範例會傳送建立環境定義時所用的正規表示式,並將其置於檔案的上下文記錄開頭。因為這是正規表示式,所以用引號括住。
  10. 套用變更並驗證傳回給 default_t 的相關資訊環境。

    sudo restorecon -R -v /web; ls -ldZ /web; ls -lZ /web
    

查看顯示公用程式的 man 頁面。然後使用學到的工具,將 SELinux 維持在 Enforcing 模式。

其他相關資訊

請參閱其他相關資源:

其他學習資源

探索 docs.oracle.com/learn 上的其他實驗室,或前往 Oracle Learning YouTube 通道存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。

如需產品文件,請瀏覽 Oracle Help Center