Centos SELinux安全策略

一、SELinux簡介

SELinux(Secure Enhanced Linux)安全增強的Linux是由美國國家安全局NSA針對計算機基礎結構安全開發的一個全新的Linux安全策略機制。SELinux可以允許系統管理員更加靈活的來定義安全策略。

SELinux是一個內核級別的安全機制,從Linux2.6內核之後就將SELinux集成在了內核當中,因爲SELinux是內核級別的,所以我們對於其配置文件的修改都是需要重新啓動操作系統才能生效的。

現在主流發現的Linux版本里面都集成了SELinux機制,CentOS/RHEL都會默認開啓SELinux機制。

二、SELinux基本概念

我們知道,操作系統的安全機制其實就是對兩樣東西做出限制:進程系統資源(文件、網絡套接字、系統調用等)。

在之前學過的知識當中,Linux操作系統是通過用戶和組的概念來對我們的系統資源進行限制,我們知道每個進程都需要一個用戶才能執行。

在SELinux當中針對這兩樣東西定義了兩個基本概念:域(domin)和上下文(context)。

域就是用來對進行進行限制,而上下文就是對系統資源進行限制

我們可以通過 ps -Z 這命令來查看當前進程的域的信息,也就是進程的SELinux信息:

[root@xiaoluo ~]# ps -Z
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2503 pts/0 00:00:00 su
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2511 pts/0 00:00:00 bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 3503 pts/0 00:00:00 ps

通過 ls -Z 命令我們可以查看文件上下文信息,也就是文件的SELinux信息:

[root@xiaoluo ~]# ls -Z
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 Desktop
-rw-r--r--+ root root system_u:object_r:admin_home_t:s0 install.log
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log.syslog

在稍後我們來探討一下這些字段所代表的含義。

三、策略

在SELinux中,我們是通過定義策略來控制哪些域可以訪問哪些上下文。

在SELinux中,預置了多種的策略模式,我們通常都不需要自己去定義策略,除非是我們自己需要對一些服務或者程序進行保護

在CentOS/RHEL中,其默認使用的是目標(target)策略,那麼何爲目標策略呢?

目標策略定義了只有目標進程受到SELinux限制,非目標進程就不會受到SELinux限制,通常我們的網絡應用程序都是目標進程,比如httpd、mysqld,dhcpd等等這些網絡應用程序。

我們的CentOS的SELinux配置文件是存放在 /etc/sysconfig/ 目錄下的 selinux 文件,我們可以查看一下里面的內容:

複製代碼
[root@xiaoluo ~]# cat /etc/sysconfig/selinux 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted   // 我們的CentOS使用的策略就是目標策略
複製代碼

四、SELinux模式

SELinux的工作模式一共有三種 enforcing、permissive和disabled 

enforcing  強制模式:只要是違反策略的行動都會被禁止,並作爲內核信息記錄

permissive  允許模式:違反策略的行動不會被禁止,但是會提示警告信息

disabled  禁用模式:禁用SELinux,與不帶SELinux系統是一樣的,通常情況下我們在不怎麼了解SELinux時,將模式設置成disabled,這樣在訪問一些網絡應用時就不會出問題了。

上面也說了SELinux的主配置文件是 /etc/sysconfig/selinux 

複製代碼
[root@xiaoluo ~]# cat /etc/sysconfig/selinux 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing  //  我們看到SELinux默認的工作模式是enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 
複製代碼

我們SELinux默認的工作模式是enforcing,我們可以將其修改爲 permissive或者是disabled

我們如果要查看當前SELinux的工作狀態,可以使用 getenforce 命令來查看:

[root@xiaoluo ~]# getenforce 
Enforcing

當前的工作模式是 enforcing,我們如果要設置當前的SELinux工作狀態,可以使用 setenforce [0|1] 命令來修改,setenforce 0表示設置成 permissive,1表示enforcing

注意:】通過 setenforce 來設置SELinux只是臨時修改,當系統重啓後就會失效了,所以如果要永久修改,就通過修改SELinux主配置文件

複製代碼
[root@xiaoluo ~]# setenforce 0
[root@xiaoluo ~]# getenforce
Permissive

[root@xiaoluo ~]# setenforce 1
[root@xiaoluo ~]# getenforce 
Enforcing
複製代碼

 

 

[root@xiaoluo ~]# ls -Z

-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 Desktop
-rw-r--r--+ root root system_u:object_r:admin_home_t:s0 install.log
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log.syslog

 

我們可以通過 ls -Z 這個命令來查看我們文件的上下文信息,也就是SELinux信息,我們發現其比傳統的 ls 命令多出來了 system_u:object_r:admin_home_t:s0 這個東西,我們現在就來分析一下這段語句所代表的含義

system_u:object_r:admin_home_t:s0

這條語句通過:劃分成了四段,第一段 system_u 代表的是用戶,第二段 object_r 表示的是角色,第三段是SELinux中最重要的信息,admin_home 表示的是類型,最後一段 s0 是跟MLS、MCS相關的東西,暫時不需要管

system_u  指的是SElinux用戶,root表示root賬戶身份,user_u表示普通用戶無特權用戶,system_u表示系統進程,通過用戶可以確認身份類型,一般搭配角色使用。身份和不同的角色搭配時有權限不同,雖然可以使用su命令切換用戶但對於SElinux的用戶並沒有發生改變,賬戶之間切換時此用戶身份不變,在targeted策略環境下用戶標識沒有實質性作用。

object_r  object_r一般爲文件目錄的角色、system_r一般爲進程的角色,在targeted策略環境中用戶的角色一般爲system_r。用戶的角色類似用戶組的概念,不同的角色具有不同的身份權限,一個用戶可以具備多個角色,但是同一時間只能使用一個角色。在targeted策略環境下角色沒有實質作用,在targeted策略環境中所有的進程文件的角色都是system_r角色。

admin_home  文件和進程都有一個類型,SElinux依據類型的相關組合來限制存取權限。

五、實例

下面我們通過一個實例來看一下上下文 context 的值和SELinux的訪問控制

比如說我搭建好了一個Web服務器,我們知道www服務器其默認網頁存放位置是在 /var/www/html 這個目錄下,我們如果在這裏新建一個 index.html 測試頁面,啓動我們的www服務器,刷新就能見到其內容了,這時我們如果是在我們的 /home 目錄下建立一個 index.html 頁面,然後將其移動到 /var/www/html 這個目錄下,再刷新頁面,其還會不會正常顯示呢?

首先我們啓動我們的 httpd 服務:

 

[root@xiaoluo ~]# service httpd restart

Stopping httpd:                                            [  OK  ]
Starting httpd: httpd: apr_sockaddr_info_get() failed for xiaoluo
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]

 

然後打開瀏覽器,輸入我們的 127.0.0.1 來訪問,此時看到的界面是Apache的測試界面:

 

因爲我們此時的 /var/www/html 下還不存在任何頁面:

[root@xiaoluo home]# ll /var/www/html/
total 0

接下來我們在 /home 目錄下建立一個 index.html 的頁面,然後將其移動到我們的 /var/www/html 目錄下

複製代碼
[root@xiaoluo home]# vi index.html

This is a test about SELinux

[root@xiaoluo home]# mv index.html /var/www/html/

[root@xiaoluo html]# cd /var/www/html/
[root@xiaoluo html]# ls
index.html
複製代碼

此時,按照正常情況,因爲html目錄下存在了一個index.html的頁面,我們此時如果刷新瀏覽器頁面,應該會跳轉到index.html頁面的

 

但是事實我們發現,頁面還是在這個測試頁面,到底是爲什麼呢?這個就跟我們的SELinux的安全策略有關係了,我們可以去 /var/log/audit 這個目錄下查看audit.log 這個文件,從中找出錯誤信息

複製代碼
[root@xiaoluo html]# tail /var/log/audit/audit.log 

type=CRED_DISP msg=audit(1369575601.957:289): user pid=3637 uid=0 auid=0 ses=44 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='op=PAM:setcred acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success'
type=USER_END msg=audit(1369575601.957:290): user pid=3637 uid=0 auid=0 ses=44 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='op=PAM:session_close acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success'
type=AVC msg=audit(1369575729.534:291): avc:  denied  { getattr } for  pid=3619 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
type=SYSCALL msg=audit(1369575729.534:291): arch=c000003e syscall=4 success=no exit=-13 a0=7f34198634f8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=7f341985ff60 items=0 ppid=3612 pid=3619 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1369575729.535:292): avc:  denied  { getattr } for  pid=3619 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
type=SYSCALL msg=audit(1369575729.535:292): arch=c000003e syscall=6 success=no exit=-13 a0=7f34198635c8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=1 items=0 ppid=3612 pid=3619 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1369575736.549:293): avc:  denied  { getattr } for  pid=3618 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
type=SYSCALL msg=audit(1369575736.549:293): arch=c000003e syscall=4 success=no exit=-13 a0=7f34198634f8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=7f341985ff60 items=0 ppid=3612 pid=3618 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1369575736.549:294): avc:  denied  { getattr } for  pid=3618 comm="httpd" path="/var/www/html/index.html" dev=sda2 ino=538738 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
type=SYSCALL msg=audit(1369575736.549:294): arch=c000003e syscall=6 success=no exit=-13 a0=7f34198635c8 a1=7fffbc87bee0 a2=7fffbc87bee0 a3=1 items=0 ppid=3612 pid=3618 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
複製代碼

從這個日誌文件中,我們就可以看到刷新頁面不出來index.html的原因就是因爲我們的SELinux安全策略所導致的

我們通過 ls -Z 命令先來看看剛移動過來的 index.html 的上下文信息

[root@xiaoluo html]# ls -Z
-rw-r--r--. root root unconfined_u:object_r:home_root_t:s0 index.html

我們發現其第三個字段的類型是 home_root_t,這是爲什麼呢?因爲我們剛纔是在 /home 目錄下創建的這index.html文件,所以其默認會繼承上一層目錄的SELinux的類型信息,我們可以查看一下 /home 這個目錄的上下文信息:

[root@xiaoluo html]# ls -Z -d /home/
drwxr-xr-x. root root system_u:object_r:home_root_t:s0 /home/

我們看到,其第三個字段和我們剛纔的index.html相同,由此可以看出文件的context值是受上一級目錄影響的,一般情況下它們會繼承上一級目錄的context值,但是,一些安裝服務產生的文件context值會例外,不繼承上級目錄的context值,服務會自動創建它們的context值,比如沒有裝http服務的時候/var/目錄下時沒有www目錄的,安裝httpd服務後該服務會自動創建出所需的目錄,並定義與服務相關的目錄及文件才context值,它們並不會繼承上級目錄的context值

[root@xiaoluo html]# ls -Z -d /var
drwxr-xr-x. root root system_u:object_r:var_t:s0       /var

[root@xiaoluo html]# ls -Z -d /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/

此時我們發現我們的 /var/www/html 這個目錄的上下文類型是 httpd_sys_content_t, 而我們剛纔移動過來的 index.html 的類型卻是 home_root_t,因爲我們此時的SELinux的工作模式是 enforcing,所以對於違反策略的行動是被禁止的,所以我們刷新頁面並不會出現我們的index.html裏面的信息,那麼我們這個時候應該解決這個問題呢?

通常解決辦法由兩種:

①直接將SELinux的工作模式設置成 disabled,這樣就不會出現策略攔截問題了,但是這樣的話我們的系統就沒有SELinux安全防護了

②通過 restorecon 或者 chcon 命令來修復我們的文件上下文信息

命令 restorecon 可以用來恢復文件默認的上下文:

restorecon -R -v /var/www/html/index.html  //-R 表示遞歸,如果是目錄,則該目錄下的所有子目錄、文件都會得到修復  

命令 chcon 可以改變文件的上下文信息,通常我們使用一個參照文件來進行修改:

chcon --reference=/var/www/html/index.html /var/www/html/test.html

這裏我們通過使用 restorecon 命令來恢復我們文件默認的上下文:

[root@xiaoluo html]# restorecon -v index.html 
restorecon reset /var/www/html/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

[root@xiaoluo html]# ls -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

我們看到,使用 restorecon 命令以後,index.html的上下文信息就繼承了上一級目錄 html 這個目錄的上下文信息了,這個時候我們再刷新頁面就可以看到我們index.html裏面的內容了

 

通過這個實例我們就明白了文件的上下文信息與SELinux之間的關係了,並知道了通過查看 /var/log/audit/audit.log 這個日誌文件的信息找出錯誤所在,以及通過 restorecon 命令來修復我們的文件的上下文信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章