SELinux
訪問控制機制:
DAC:Discretionary Access Control,自主訪問控制:
基於文件或數據被文件系統賦予的訪問權限(r,w,x)的方式實現的訪問控制機制;
MAC:Mandatory Access Control,強制訪問控制:
對於文件或數據的訪問權限不是針對用戶身份來設定,當某個用戶發起某個進程之後,該進程是否能夠操縱或處理此文件或數據,取決於進程和文件是否具備可以匹配的domain和type;
SELinux就是MAC訪問控制機制在Linux系統中的實現;
SELinux工作於Linux內核中:
RHEL 4.0:測試性的加入了SELinux安全組件;
RHEL 5.0:在安全操作系統時強制安裝此組件,但可以在安裝時選擇關閉相應功能;
RHEL 6.0+:在安裝操作系統時強制安裝此組件,且在系統啓動之後自動啓動其功能;
SELinux依賴於安全策略結果進行相應的訪問控制管理,策略結果已知的有三種:
strict:對於每個文件都有嚴格的規定其類型,對於每個進程都要設定特定的域,進程的域和文件的類型必須嚴格匹配,才能允許進程訪問此文件;
mls:multi-level security,多級安全策略結果集;
targeted:僅對有限個進程進行SELinux的強制訪問控制管控;只要進程的域和文件的類型屬於某同一大類,就可以匹配,就可以允許進程訪問文件;在RHEL系操作系統中爲此策略結果;
所有有限個進程,指的是那些容易被***並且會對系統造成安全隱患的進程;
Sandbox:
在Linux系統中,能夠完成真實操作的實體,是進程;
subject, action(operation), object
subject:進程
action(operation):open, close, read, write, modify, delete, chmod, chown, ...
object:文件,進程,套接字,鏈接,...
SELinux爲每個文件提供了一套安全標籤,也爲每個進程提供了一套安全標籤,這些安全標籤可以稱爲SELinux的安全上下文(security context);
user-identify:role:domain|type:sencitivity
user-identify:SELinux的用戶身份標識,通常指用戶的類型;
role:角色
domain|type:進程的域或文件的類型;
sencitivity:敏感度;
注意:在targeted策略結果集中,僅關心進程的domain和文件的type能否匹配,與其他的安全上下文標識沒有關係;
SELinux的策略庫:
規則庫:存放規則
規則:進程的哪個域可以以哪種方式訪問或操縱哪些類型的文件;存放於/etc/selinux/targeted/policy目錄中;
/etc/sysconfig/selinux文件中定義了SELinux的工作模式和使用的策略結果集;
SELINUX=enforcing
SELINUXTYPE=targeted
SELinux的工作模式:
enforcing - SELinux security policy is enforced.
permissive - SELinux prints warnings instead of enforcing.
disabled - No SELinux policy is loaded.
注意:
1.凡是從enforcing或permissive模式切換至disabled模式,或者從disabled模式切換至enforcing或permissive模式,都必須經過操作系統的重新引導才能生效;
2.從enforcing模式到permissive模式的切換,可以直接使用命令行工具完成且立即生效;
setenforce命令:
setenforce - modify the mode SELinux is running in.
setenforce [ Enforcing | Permissive | 1 | 0 ]
1:Enforcing
0:Permissive
getenforce命令:
getenforce - get the current mode of SELinux
注意:使用setenforce命令修改的SELinux的工作模式會立即生效,但並非永久有效;如果想要使被修改的SELinux的工作模式永久有效,則需要修改/etc/sysconfig/selinux文件中的SELINUX參數的值,並重新引導操作系統;
查看進程或文件的SELinux的安全上下文:
文件安全上下文查看:
ls -Z|--context [file]
進程安全上下文查看:
ps auxZ
ps -efZ
修改文件的安全上下文:
chcon命令:
chcon - change file SELinux security context
-t, --type=TYPE:直接設置目標文件的類型;
-R, --recursive:遞歸地修改目錄中所有文件,包括子目錄中的文件;
--reference=RFILE:參考RFILE所代表的文件的安全上下文,爲目標文件設置完全相同的安全上下文;
使用場景:
通常在進程的安全上下文與文件的安全上下文類型不相符合或不能匹配的時候使用;
如:設置httpd虛擬主機對應的文檔根目錄的安全上下文;
restorcon命令:
restorecon - restore file(s) default SELinux security contexts.
-R, -r:遞歸修改指定目錄及其子目錄的安全上下文爲默認值;
查看或修改策略中的內容:
getsebool命令:
getsebool - get SELinux boolean value(s)
-a:Show all SELinux booleans.
setsebool命令:
setsebool - set SELinux boolean value
-P:If the -P option is given, all pending values are written to the policy file on disk. So they will be persistent across reboots.
使用場景:支持二進制策略修改的系統服務;
vsftpd的匿名用戶的上傳功能被SELinux限制的場景:
~]# setsebool -P ftpd_anon_write on
~]# setsebool -P ftpd_full_access=1
samba服務中samba用戶訪問自己的家目錄的共享結果被SELinux限制的場景:
~]# setsebool -P samba_enable_home_dirs on
samba服務中共享的目錄是由管理員自行創建並指定的:
chcon -t samba_share_t /path/to/directory
semanage命令:
semanage - SELinux Policy Management tool
注意:如果沒有此命令,需要安裝policycoreutils-python程序包即可;
semanage port命令:
-a, --add
Add a record of the specified object type
-d, --delete
Delete a record of the specified object type
-m, --modify
Modify a record of the specified object type
-l, --list
List records of the specified object type
示例:
~]# semanage port -a -t http_port_t -p tcp 8088
tcp_wrappers:tcp封裝器;
僅僅就是一個庫:libwrap.so
功能:對能夠訪問到調用了libwrap.so庫的應用程序服務的客戶端主機進行基於IP地址的訪問控制;
庫調用的方法:
靜態編譯:
動態鏈接:
判斷一個應用程序服務是否能夠接受tcp_wrappers的訪問控制:
1.對於動態鏈接至libwrap.so的應用程序:
ldd /PATH/TO/APP_BINARY_FILE | grep libwrap.so
2.對於靜態編譯libwrap庫至應用程序中的:
strings /PATH/TO/APP_BINARY_FILE
利用strings命令查看指定的應用程序的二進制文件中,是否包含有/etc/hosts.allow, /etc/hosts.deny;如果有此類信息,則說明其將libwrap庫以靜態的方式編譯進應用程序,即可以支tcp_wrappers的訪問控制;
常用的基於tcp_wrappers進行訪問控制的服務:sshd, vsftpd;
tcp_wrappers的配置文件:
/etc/hosts.allow
/etc/hosts.deny
配置文件的匹配順序:
/etc/hosts.allow --> /etc/hosts.deny --> 默認規則:允許所有主機數據放行;
獲取配置文件的幫助的方法:
~]# man hosts.allow
~]# man hosts.deny
~]# man hosts_access(推薦)
~]# man hosts_options
配置文件的格式:
daemon_list : client_list [ : shell_command ]
daemon_list : client_list : option : option ...
daemon_list:
1.單個應用程序服務文件的名稱;
如:vsftpd;
2.多個應用程序服務文件的名稱列表,用","分隔;
如:vsftpd, sshd;
3.通配符:ALL
不加區分的表示所有受到tcp_wrappers控制的應用程序服務文件;
client_list:
1.單個主機的IP地址或主機名稱,如果使用主機名稱,必須保證在本機能夠實現名稱解析;
2.網絡地址:
1) 如果寫掩碼,必須是以完整的子網掩碼錶示的網絡地址,如果使用前綴長度來表示則無效;
如:172.16.0.0/255.255.0.0是有效的;
172.16.0.0/16是無效的;
2) 如果不寫掩碼,可以使用簡短格式:
如:172.16.
3.通配符:
ALL:所有的客戶端主機;
LOCAL:所有的主機名稱中不包含"."字符的客戶端主機;
KNOWN:所有的能夠被當前主機正確完成名稱解析的客戶端主機;
UNKNOWN:所有的不能被當前主機正確完成名稱解析的客戶端主機;
PANANOID:所有的正向解析結果和反向解析結果不一致的客戶端主機;
如:www.qhdlink.com --> 192.168.100.1
192.168.100.1 --> www.qhdink.org
: option
allow:允許,主要用於hosts.deny文件中,定義允許放行的訪問控制規則;
deny:阻止,拒絕,主要用於hosts.allow文件中,定義阻止訪問的訪問控制規則;
spawn shell_command:當規則能夠匹配主機時,執行後面的shell命令;
示例1:
拒絕172.16.72.1主機利用ssh協議訪問172.16.69.2主機;
可以在/etc/hosts.allow中拒絕:
sshd : 172.16.72.1 : deny
可以在/etc/hosts.deny中拒絕:
sshd : 172.16.72.1
示例2:
拒絕172.16.0.0/16中的所有主機,但允許172.16.0.1主機利用ssh協議訪問172.16.69.2主機;
/etc/hosts.deny:
sshd : 172.16.0.0/255.255.0.0 EXCEPT 172.16.0.1
示例3:
僅允許172.16.0.0/16中的所有主機,但拒絕172.16.72.1主機利用ssh協議訪問到172.16.69.2主機;
方案1:
/etc/hosts.deny
sshd : ALL EXCEPT 172.16. EXCEPT 172.16.72.1
方案2:
/etc/hosts.deny
sshd : ALL
/etc/hosts.allow
sshd : 172.16. EXCEPT 172.16.72.1
spawn使用示例:
/etc/hosts.deny
sshd : ALL EXCEPT 172.16.0.0/255.255.0.0 EXCEPT 172.16.72.1 : spawn /bin/echo $(date) %c attempt to login %s >> /var/log/tcp_wrap_sshd.log
常用的內建宏:
%c Client information: user@host, user@address, a host name, or just an address, depending on how much information is available.
%s Server information: daemon@host, daemon@address, or just a daemon name, depending on how much information is available.
nss & pam
nss --> nsswitch:Name Service Switch,名稱服務開關;
名稱解析:將人類能夠識別和使用的自然語言的符號轉換成計算機能夠識別和使用的數字符號的過程;包括:
主機名 --> IP地址;
用戶名 --> UID;
組名 --> GID;
服務名 --> PORT;
網絡接口名稱 --> MAC地址;
...
解析:根據已知的信息(關鍵字,key)查找某個特定的存儲庫,從而能夠獲取到與該已知信息有關的或者相匹配的其他信息的過程;
存儲庫:
文件;
RDBMS;
No-SQL;
LDAP;
...
login:
nsswitch:通用服務框架:爲應用程序提供簡潔且高效的接口;名稱解析服務的代理程序;
作用:承上啓下:
承上:提供統一的配置和調用接口;
啓下:向各種形式的存儲庫的使用接口發出調用;
在Linux系統中實現名稱解析服務的通用框架:nss相關的庫;
/lib64/libnss*
/usr/lib64/libnss*
/usr/lib64/libnss3.so:nss服務框架接口,用於承上;
其他的libnss*.so庫文件,都是用於訪問各種存儲庫的接口(驅動);
爲了能夠正確的訪問存儲庫,爲每種用到解析庫的應用程序,通過一個特定配置文件定義存儲庫的訪問方式:
/etc/nsswitch.conf
配置文件的格式:
db: store_format1 store_format2 ...
每種存儲中都可以根據查找鍵進行查找,且每次查找都會有返回狀態:
STATUS => SUCCESS | NOTFOUND | UNAVAIL | TRYAGAIN
對應每一種狀態返回值,都有相應的行爲:
ACTION => return | continue
注意:除了SUCCESS狀態的默認行爲是return之外,其餘的狀態的默認行爲都是continue;
自定義狀態和行爲的關係組合:
[STATUS=ACTION]
[!STATUS=ACTION]
示例:
hosts: files [NOTFOUND=return] dns
獲取解析結果的命令:
getent命令:
getent - get entries from Name Service Switch libraries
getent database [key ...]
示例:
getent passwd root
getent hosts www.qhdlink.com
pam:
pam:Pluggable Authentication Modules;可插入式認證模塊;
通用的認證服務框架;
實現:提供了與各類型的存儲庫進行交互的通用實現解決方案,主要依靠相應的認證功能模塊;
模塊存放的路徑:/lib64/security/pam_*.so
配置文件:每個基於pam做認證的應用程序都需要有相應的配置文件,其中定義了應用程序如何利用pam實現各種所需的認證功能;
1.全局認證配置文件:/etc/pam.conf
格式:
service type control module-path module-arguments
2.各個應用程序的專用配置文件:/etc/pam.d/*APP_NAME*
格式:
type control module-path module-arguments
type:
account:
與賬號管理相關的非認證類功能;通常是賬號審計,包括:過期時間,資源可用性等;
auth:
與賬號的認證和授權有關的功能;
password:
與用戶賬戶修改密碼時的複雜度的規定有關的功能;
session:
通過認證和賬戶審計之後,用戶獲取到服務之前或使用服務完成之後,需要進行的附加審計操作;如:日誌記錄等;
control:同一種type的多個檢查之間如何進行關聯和組合;
有兩種實現方式:
1.簡單實現:使用一個關鍵詞來定義;
required:在認證時,如果本條目沒有被滿足,那麼最終本次的認證一定失敗;但是本次認證過程並不會因此而中斷,而是在整個棧所有的規則運行完畢之後,最終給出"認證失敗"的信號;
隱性的一票否決權;
requisite:在認證時,如果本條目沒有被滿足,那麼本地認證一定失敗;而且整個棧立即終止並返回"認證失敗"的信號;
顯式的一票否決權;
如果本條目被滿足,則需要繼續參考其他條目;
sufficient:在認證時,如果本條目被滿足,且本條目之前沒有任何required條目被判斷爲失敗,則整個棧立即終止並返回"認證成功"的信號;
條件式一票通過;
如果本條目沒有被滿足,則還需要繼續參考其他的條目規則;
optional:該條目僅在整個棧中只此一條時纔有決定作用,否則無論該條目被滿足或沒有被滿足都與最終的認證結果無關;
include:將其他的配置文件中的所有規則包含至當前條目,此條目是否被滿足,取決於被指定文件的最終認證結果;
有可能影響當前棧的最終認證結果;
substack:將其他的配置文件中的所有規則包含至當前條目,與include不同,其認證結果不影響當前棧;
2.詳細實現:使用一個或多個"statsu=action"標記進行組合定義;
[value1=action1 value2=action2 ...]
value的值包括:
success, open_err, symbol_err, service_err, system_err, buf_err, perm_denied, auth_err, cred_insufficient, authinfo_unavail, user_unknown, maxtries, new_authtok_reqd, acct_expired, session_err, cred_unavail, cred_expired, cred_err, no_module_data, conv_err, authtok_err, authtok_recover_err, authtok_lock_busy, authtok_disable_aging, try_again, ignore, abort, authtok_expired, module_unknown, bad_item, conv_again, incomplete, and default.
action的值:
ok, done, die, bad, ignore, N, reset, ...
module-path:被調用的模塊所在的路徑;
相對路徑:相對於/lib64/security目錄而言的模塊路徑;
絕對路徑:/lib64/security/*.so
module-arguments:各個被調用的模塊的專有模塊參數;
通常來講,同一個模塊如果需要多個參數時,只需要將各個參數以空白字符分隔即可;如果需要在單個參數中使用空格等空白字符,可以用中括號([])將整個參數包裹起來;
認證模塊:
pam_shells.so
用戶賬戶默認登錄shell是否爲安全shell;凡是在/etc/shells文件中以單行被列舉出的shell,都屬於安全shell,反之則爲非安裝shell;
如:在/etc/pam.d/sshd第一行添加如下認證信息:
auth required pam_shells.so
pam_limits.so
系統資源分配管控模塊;
在用戶級別實現對指定用戶限制其可以使用的資源總量;
ulimit命令:可以查看或臨時的調整系統資源的使用限制,僅root用戶能進行調整;
-n #:設置打開的文件數;
修改配置文件可以是資源使用的限制永久生效:
/etc/security/limits.conf
/etc/security/limits.d/*
格式:
<domain> <type> <item> <value>
<domain>
1.單個用戶;
2.組,組內所有用戶賬戶成員;
3.*,表示所有用戶,通常用於設置默認值;
<type>
soft:
hard:
-:既是soft也是hard;
<item>
nofile:同時打開的文件的最大數量值;
nproc:併發啓動的進程的最大數量值;
locks:打開的文件鎖的最大數量值;