selinux概念 由美國國家安全局(NSA)和SCC聯合開發的,強制訪問控制的安全模塊。2000年以GPL開源,linux2.6內核後集成在內核里。 不啟用selinux時,訪問模式叫:DAC(discretionary access control)自由訪問控制 在DAC模式下的進程能夠訪問哪些 ...
selinux概念
由美國國家安全局(NSA)和SCC聯合開發的,強制訪問控制的安全模塊。2000年以GPL開源,linux2.6內核後集成在內核里。
不啟用selinux時,訪問模式叫:DAC(discretionary access control)自由訪問控制
在DAC模式下的進程能夠訪問哪些資源是由啟用這個進程的用戶身份決定的,這個用戶能訪問的,這個進程都可以訪問。
啟用selinux時,訪問模式叫:MAC(Mandatory access control)強制訪問控制
在MAC模式下的進程能夠訪問哪些資源是由selinux設定的。
selinux的工作類型
selinux的工作類型定義在/etc/selinux/config文件中
centos7:
# cat /etc/selinux/config
# 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 three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
centos6:
# cat /etc/selinux/config
# 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
- targeted:保護常見的網路服務(預設工作類型)
- minimum:只對選擇的服務保護
selinux安全上下文
傳統linux,一切皆文件,由用戶,組,許可權控制訪問
在selinux中,一切皆對象(object),由存放在inode的擴展屬性域的安全元素所訪問控制。
查看inode的擴展屬性域的命令:
ls -Z
和ps -Z
。這些屬性起名叫標簽或context。
ls:
# ls -lZ -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg -rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 linux-3.10.67.tar.xz drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 scripts
ps:
# ps auxZ LABEL USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND system_u:system_r:init_t:s0 root 1 0.0 0.1 193788 6904 ? Ss 05:25 0:06 /usr/lib/systemd/systemd --swit system_u:system_r:kernel_t:s0 root 2 0.0 0.0 0 0 ? S 05:25 0:00 [kthreadd] system_u:system_r:kernel_t:s0 root 3 0.0 0.0 0 0 ? S 05:25 0:00 [ksoftirqd/0]
所以文件,埠,進程都具備安全標簽:安全上下文(security context)
安全上下位由5個元素組成:user:role:type:sensitivity:category
- user:登錄系統的用戶類型
- root:root用戶
- user_u:普通用戶
- system_u:系統用戶
- unconfined_t:自由進程/文件。多數本地進程都屬於此。
- role:定位文件,進程和用戶的用途。文件:object_r;進程和用戶:system_r
- type:數據類型。最常用的屬性,target策略就是根據type的值,控制可以訪問/不可訪問哪些資源。但是有個問題,每個資源只有唯一的type,當有多個別的東西想訪問同一個資源的時候就麻煩了,就要修改type成public_content_t(只讀,不可以修改這個資源);public_content_rw_t(讀寫)
- sensitivity:預設是s0
- category:target工作類型下,不使用。
- user:登錄系統的用戶類型
標簽/context分實際的標簽和期望標簽
實際標簽:使用ls -Z和ps -Z看到的標簽。
期望標簽:安裝操作系統後,系統給的標簽。標簽是可以修改的,所以有期望標簽,修改了某個文件的標簽後,這個文件的期望標簽和實際標簽就不一樣了。
查看文件,進程,埠的期望標簽:
semanage fcontext -l
# semanage fcontext -l | grep "/var/log/messages" /var/log/messages[^/]* all files system_u:object_r:var_log_t:s0 # ls -Z /var/log/messages -rw-------. root root system_u:object_r:var_log_t:s0 /var/log/messages
期望標簽存放在:/etc/selinux/targeted/contexts/files/目錄
# ls /etc/selinux/targeted/contexts/files/ file_contexts file_contexts.homedirs.bin file_contexts.subs file_contexts.bin file_contexts.local file_contexts.subs_dist file_contexts.homedirs file_contexts.local.bin media
selinux策略
- object:所以可以讀取的對象,包括文件,目錄,進程,埠
- subject:進程
- 當一個subject要訪問object時,selinux執行AVC(access vector cache)檢查,在AVC中,subject和object的許可權被緩存。
- 安全策略:定義subject讀取object的規則資料庫,規則中記錄了哪個類型的(type)的subject使用哪個方法讀取哪一個object是允許的還是拒絕的,並且定義了哪種行為是允許或拒絕的。
啟用selinux
查看selinux是啟用還是禁用
# getenforce
Enforcing
[root@localhost ~]# cat /etc/selinux/config
# 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 three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
enforcing:啟用狀態
permissive:沒啟用,但是違反了selinux的規則,只出警告信息而已。
disabled:禁用狀態。
臨時啟用:
# setenforce 1 # getenforce Enforcing
臨時禁用:
# setenforce 0 # getenforce Permissive
註意:使用命令setenforce,只能在Enforcing和Permissive間切換。不能從disabled狀態切換成Enforcing。
永久修改selinux啟用或禁用:修改文件/etc/selinux/config,重啟才生效。
禁用後(disabled而不是permissive)創建的文件就沒有標簽了,
而且【-rw-r--r--】後面沒有點,有點就說明有標簽。
# sestatus
SELinux status: disabled
# setenforce 1
setenforce: SELinux is disabled
# touch temp2
[root@localhost ~]# ls -Z temp2
-rw-r--r-- root root ? temp2
從disabled切換到enabled後,在看剛纔創建的temp2文件:
有點了,但是type是unlabeled_t
# getenforce
Enforcing
# ls -Z temp2
-rw-r--r--. root root system_u:object_r:unlabeled_t:s0 temp2
查看詳細狀態信息:
# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive//當前是禁用的
Mode from config file: enforcing//配置文件是啟用的
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 31
定義的策略存放在:SELinuxfs mount /sys/fs/selinux
avc緩存在avc目錄。
# ls /sys/fs/selinux/
access checkreqprot context disable load null policyvers status
avc class create enforce member policy reject_unknown user
booleans commit_pending_bools deny_unknown initial_contexts mls policy_capabilities relabel
安全布爾值存放在:/sys/fs/selinux/booleans
# pwd
/sys/fs/selinux/booleans
[root@localhost booleans]# ll ftp*
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_anon_write
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_connect_all_unreserved
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_connect_db
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_full_access
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_cifs
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_fusefs
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_nfs
-rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_passive_mode
文件ftpd_anon_write里的內容是2個0。從文件名字可以看出來是ftp的匿名寫,值是0,說明不允許匿名寫。
# cat ftpd_anon_write
0 0
管理文件安全標簽
1,修改標簽中的type:chcon-t file
測試標簽中type的作用,/var/log/messages文件的標簽中的type是var_log_t。
手動使用logger命令,往它裡面寫東西,發現是可以寫進去的。
修改它的type成tmp_t,再用logger寫,發現寫不進去了。
# ll /var/log/messages -Z
-rw-------. root root system_u:object_r:var_log_t:s0 /var/log/messages
# logger "test sdf "
# tail -1 /var/log/messages
Feb 29 18:33:32 localhost root: test sdf
# chcon -t tmp_t /var/log/messages
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:tmp_t:s0 /var/log/messages
# logger "test 2222sdf "
# grep "test 2222sdf " /var/log/messages
根據某個文件的標簽,修改:chcon --reference f1 f2
把文件f2的標簽修改成和文件f1完全一樣。
# ll -Z /tmp/website/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 aa
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
# chcon --reference /tmp/website/index.html /tmp/website/aa
# ll -Z /tmp/website/
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 aa
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
選項-R:遞歸修改目錄所有的文件
# ls /tmp/website/d1
11 22
# ll /tmp/website/d1/11 -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/11
# ll /tmp/website/d1/22 -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/22
# ll /tmp/website/d1/ -Zd
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/
# chcon -R --reference /var/www/html/ /tmp/website/d1/
# ll /tmp/website/d1/ -Zd
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/
# ll /tmp/website/d1/ -Z
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 11
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 22
2,cp命令和mv命令多標簽的影響。
cp命令type會改變。
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:var_log_t:s0 /var/log/messages
# cp /var/log/messages /root/
# ll -Z messages
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 messages
mv命令不改變type
# mv messages /tmp/
# ll /tmp/messages -Z
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 /tmp/messages
3,修改回原來的type,但是忘了原來的type是啥了怎麼辦,去看期望(原始)策略是啥。
# semanage fcontext -l | grep "/var/log/message"
/var/log/messages[^/]* all files system_u:object_r:var_log_t:s0
還有一種更簡單的方法:restorecon
# chcon -t tmp_t /var/log/messages
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:tmp_t:s0 /var/log/messages
# restorecon /var/log/messages
# ll -Z /var/log/messages
-rw-------. root root system_u:object_r:var_log_t:s0 /var/log/messages
把/var/log/messages回覆成原來的標簽後,有可能還log還是寫不進去,這時就要重啟服務了。systemctl rsyslog restart
4,修改httpd的預設根目錄,導致selinux標簽不對,網頁文件無法訪問。
修改httpd的配置文件/etc/httpd/conf/httpd.conf,把服務的目錄修改成/tmp/website/
# ll -Z /tmp/website/ -d drwxr-xr-x. root root unconfined_u:object_r:user_tmp_t:s0 /tmp/website/
type是user_tmp_t
在/tmp/website/建立index.html文件
# ll -Z /tmp/website/ -rw-r--r--. root root unconfined_u:object_r:user_tmp_t:s0 index.html
type是user_tmp_t
啟動httpd
在瀏覽器訪問index.html
結果是訪問不到
原因:/tmp/website/index.html的標簽的type不符合selinux對httpd的要求,所以httpd進程無法訪問它。
httpd能夠訪問的標簽是:httpd_sys_content_t。
而/tmp/website/index.html文件的type是user_tmp_t,所以httpd不可以訪問它,被selinux給擋住了。
# ll -Zd /var/www/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/
解決辦法:
1,安裝桌面小程式,能夠把selinux相關的信息顯示出來。(不安裝也無所謂)
2,添加/tmp/website/目錄的期望(預設)策略,到selinux。
添加選項:-a
指明type:-t
/tmp/website(/.*)?:正則表達式/tmp/website目錄自身和目錄下的所有文件的意思。
# semanage fcontext -a -t httpd_sys_content_t "/tmp/website(/.*)?"
# semanage fcontext -l | grep "/tmp/website"
tmp/website(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
3,由於/tmp/website/有了期望策略,所以恢復/tmp/website/的標簽成,預設標簽。
選項-R:遞歸修改目錄下的所有文件。
# restorecon -R /tmp/website/
# ll -Zd /tmp/website/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /tmp/website/
# ll -Z /tmp/website/
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
4,重啟httpd
5,當不想讓/tmp/website/是httpd的根目錄了,刪除它在selinux里的期望策略
刪除選項:-d
# semanage fcontext -d -t httpd_sys_content_t "/tmp/website(/.*)?"
管理埠標簽
1,查看埠期望(預設)策略:
http協議的埠的期望(預設)策略:80, 81, 443, 488, 8008, 8009, 8443, 9000是可以使用的。
所以不能把其他的埠用於http服務。
# semanage port -l
SELinux Port Type Proto Port Number
afs3_callback_port_t tcp 7001
afs3_callback_port_t udp 7001
# semanage port -l | grep http
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
2,添加埠到預設策略
選項-a:添加
選項-t:指定type
選項-p:指定傳輸層的協議(tcp或udp)類型
# semanage port -a -t http_port_t -p tcp 9932
[root@localhost ~]# semanage port -l | grep "^http_port_t"
http_port_t tcp 9932, 80, 81, 443, 488, 8008, 8009, 8443, 9000
3,從預設策略里刪除埠
# semanage port -d -t http_port_t -p tcp 9932
# semanage port -l | grep "^http_port_t"
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
4,把埠策略里的某個埠,移動到另一個策略
讓9000埠也能用於ssh服務。
# semanage port -l | grep "^http_port_t"
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
# semanage port -m -t ssh_port_t -p tcp 9000
# semanage port -l | grep "^ssh_port_t"
ssh_port_t tcp 9000, 22
# semanage port -l | grep "^http_port_t"
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443
管理selinux布爾值開關
布爾值的作用:細化控制某個服務里的某個小功能是否可以使用。
1,查看布爾值
State:是當前的狀態(記憶體中的)
Default:是預設值(本地磁碟存儲的)
# semanage boolean -l
SELinux boolean State Default Description
privoxy_connect_any (on , on) Allow privoxy to connect any
smartmon_3ware (off , off) Allow smartmon to 3ware
比如:
httpd_enable_cgi:控制httpd的cgi功能是否可用。
httpd_enable_homedirs:控制httpd是否可以訪問家目錄。
# semanage boolean -l | grep httpd_enable
httpd_enable_cgi (on , on) Allow httpd to enable cgi
httpd_enable_homedirs (off , off) Allow httpd to enable homedirs
另一種命令:getsebool
選項-a:查看全部布爾值
# getsebool -a | grep httpd_use
httpd_use_cifs --> off
httpd_use_fusefs --> off
2,修改布爾值:setsebool
只修改當前狀態(重啟後,恢覆成default):
# setsebool httpd_enable_homedirs=on
# semanage boolean -l | grep httpd_enable
httpd_enable_cgi (on , on) Allow httpd to enable cgi
httpd_enable_homedirs (on , off) Allow httpd to enable homedirs
httpd_enable_ftp_server (off , off) Allow httpd to enable ftp server
既修改當前狀態,也修改default狀態:
# semanage boolean -l | grep httpd_enable
httpd_enable_homedirs (off , off) Allow httpd to enable homedirs
# setsebool -P httpd_enable_homedirs=on
# semanage boolean -l | grep httpd_enable
httpd_enable_homedirs (on , on) Allow httpd to enable homedirs
3,查看都修改過哪些布爾值
# semanage boolean -l -C
SELinux boolean State Default Description
httpd_enable_homedirs (on , on) Allow httpd to enable homedirs
管理日誌
日誌工具: yum install -y setroubleshoot。有圖形界面。
使用下麵命令啟動圖形界面:
# sealert
1,查看由selinux的限制導致的服務不好用的日誌,日誌文件:/var/log/message
由selinux的限制導致的服務不好用的日誌的特點是有:setroubleshoot
字樣,並告訴使用sealert命令去查看詳細的日誌。選項-l後面的串是這條日誌的標識。
Mar 1 00:04:05 localhost python: SELinux is preventing in 。。。。。。。。
sealert -l 0d882054-5ff7-4693-bf09-7b02f763df6c
使用sealert查看:
# sealert -l 0d882054-5ff7-4693-bf09-7b02f763df6c
使用sealert輸出的日誌是保存在文件: /var/log/audit/audit.log
2,整理/var/log/audit/audit.log文件,輸出可讀的格式
# sealert -a /var/log/audit/audit.log
查看selinux幫助
安裝selinux幫助文檔:
# yum install selinux-policy-doc
查看與selinux相關的幫助文檔有哪些:
# man -k _selinux
如果沒有顯示出來,說明沒有更新man的資料庫,使用下麵的命令更新:
- centos6:
makewhatis
- centos7:
mandb
查看與ftp相關的selinux幫助:
# man 8 ftpd_selinux