Linux文件許可權
- 2019 年 10 月 3 日
- 筆記
Linux文件許可權主要有以下幾個:
- ugo基本許可權
- acl許可權
- suid,sgid,sticky高級許可權
- selinux
ugo基本許可權
一個文件對應三種許可權對象,分別文件的所有者user、所屬組group和其他人other
每個許可權對象對應三種許可權,分別是讀r、寫w和執行x
許可權數字對應關係
許可權名稱 | 十進位 | 二進位 |
---|---|---|
r | 4 | 0100 |
w | 2 | 0010 |
x | 1 | 0001 |
這麼設計的目的是rwx任意組合不會互相影響
相關操作舉例
$ touch file1 $ ls -l file1 -rw-r--r-- 1 root root 0 Jul 14 15:15 file1 $ mkdir dir1 drwxr-xr-x 1 root root 4096 Jul 14 15:15 dir1
默認的文件許可權為0644
默認的目錄許可權為0755
之所以默認許可權為這些,是因為umask的值
$ umask 0022
umask默認值為0022,則目錄默認許可權為0777-0022=0755
而默認的文件許可權在此基礎上減去執行許可權變為0644
至於0644、0755前面的0是什麼,我們在高級許可權中再介紹
umask命令只能臨時生效,退出再登錄後就又還原成默認的了,如果想要永遠生效,可以更改/etc/profile或~/.bash_profile(沒有則添加,有則修改)
而r、w、x三種許可權對於目錄和文件所表示的意義也不同,如下表
許可權名稱 | 文件 | 目錄 |
---|---|---|
r | 可查看文件內容,如cat file1 | 可列出目錄內容,如ls dir1 |
w | 可更改文件內容,如echo 1 >> file1 | 可創建或刪除目錄中的文件(對於無x許可權的目錄,w許可權無效) |
x | 可作為命令被執行 | 可進入目錄,如cd dir1;可訪問目錄中的文件(當然也要看文件的許可權) |
許可權更改
格式1 chmod {許可權對象}{賦值符號}{許可權} {文件名}
其中{許可權對象}可以是u、g、o、a中的一種,分別代表所有者user、所屬組group、其他人other、所有人all
格式2 chmod {許可權數字} {文件名}
$ chmod u+x file1 $ chmod g+w,o-r,u=wrx file1 $ chmod 755 file1
小思考:
- 對於/root目錄中一個其他人有讀取許可權的文件,新建一個用戶,能否查看該文件?
- 修改根目錄許可權為777,新建一個用戶,能否刪除/etc目錄?
acl許可權
上面的文件file1,root用戶有rw許可權,root組用戶和其他人有r許可權,此時,我想讓tom用戶擁有x許可權,怎麼辦?單憑ugo基本許可權,貌似不能實現這種操作,這就要用到我們現在要說的acl許可權了
acl許可權是對ugo基本許可權的擴展,用來實現對文件許可權更精細的操控
- 查看acl許可權
$ getfacl file1 # file: file1 # owner: root # group: root user::rw- group::r-- other::r--
此時沒有acl許可權
- 添加acl許可權
$ setfacl -m u:tom:x file1 $ ls -l file1 -rw-r-xr--+ 1 root root 0 Oct 12 23:10 file1 $ getfacl file1 # file: file1 # owner: root # group: root user::rw- user:tom:--x group::r-- mask::r-x other::r--
添加完acl許可權後發現,ls -l 的結果有了變化:
其中所屬組的許可權變成了rx,而原來是r,許可權 -rw-r-xr– 後面多了個 +
先說 +,表示該文件有acl擴展許可權
此時 getfacl 查看acl許可權發現,較最初無acl許可權時多了兩行
user:tom:–x
mask::r-x
此時 ls -l 所展示的所屬組處的r-x其實不是所屬組的許可權,而是mask許可權,而什麼又是mask許可權呢?
mask許可權會隨著新設置的acl的許可權的變化而變化,它是該文件所有acl許可權和group許可權的並集,即此時mask的許可權為 user:tom:–x 和 group::r– 許可權的並集 r-x; 如果再添加一條acl許可權,使tony組的用戶有寫入許可權 setfacl -m g:jack:w,則此時mask的許可權為 rwx
mask許可權的作用是為了臨時限制acl許可權,舉例說明,此時file1的詳細許可權為
user::rw-
user:tom:–x
group::r–
mask::r-x
other::r–
假設此時不只有tom有acl許可權,jack、andy等人也有好多acl許可權,此時要臨時降低他們的許可權,如何操作?難道用 setfacl -b file1 命令刪除所有acl許可權,如果用戶多的話,刪完再一個個地添加,這得多麼麻煩呀!此時只需要臨時禁止mask許可權便可
$ setfacl -m m::- file1 $ getfacl file1 # file: file1 # owner: root # group: root user::rw- user:tom:--x #effective:--- group::r-- #effective:--- mask::--- other::r--
此時tom的有效許可權是 『—』,因為mask許可權掩蓋了所有acl許可權
但實際真這樣么,其實這裡有個小問題,tom用戶對file1是有讀許可權的,因為mask禁用所有許可權後,tom用戶便重新屬於了other,而other對file1是有讀許可權的
suid,sgid,sticky高級許可權
現在來說一說前面的許可權數字,0755、0664中的0是什麼意思;這一位代表的便高級許可權的數字,0表示沒有高級許可權,1代表sticky(粘滯位),2代表sgid,4代表suid
- suid
suid只能作用於可執行的二進位文件上,為什麼?
suid的作用是使執行該二進位程式的人擁有二進位文件所有者的許可權
所以suid只能作用於可執行的文件
看例子:
#### 當前為root帳號 $ ll file2 -rw-r----- 1 root root 0 Oct 12 01:37 /root/file2 #### 切換為tom帳號 $ cat file2 cat: file2: Permission denied #### 查看/etc/shadow文件,該文件用於存儲用戶密碼 $ ll /etc/shadow ---------- 1 root root 685 Oct 12 01:42 /etc/shadow #### 當前為tom用戶,修改密碼操作 $ passwd #### ... #### 最後發現在tom用戶通過passwd密令更改了/etc/shadow文件 #### 為什麼tom能通過passwd命令修改對於tom沒有w許可權/etc/shadow文件 #### 而tom不能通過cat命令查看對於tom沒有r許可權的file2文件 $ ll /usr/bin/cat -rwxr-xr-x. 1 root root 54080 Nov 6 2016 /usr/bin/cat $ ll /usr/bin/passwd -rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
通過例子可以看出,passwd命令與cat命令的區別在於passwd的許可權是『-rwsr-xr-x』,而cat命令的許可權是『-rwxr-xr-x』,這裡passwd許可權中原來所有者的x許可權處變成了s,所以tom在通過passwd命令修改沒有w許可權的/etc/shadow時,會自動擁有/etc/shadow文件所有者root的許可權(雖然文件對於root也沒有w許可權,但root用戶有一切許可權,即使文件對root沒有許可權也無所謂)
- guid
關於sgid,它有兩個作用。一個是同suid類似,當sgid加在一個可執行的二進位文件時,使執行該文件的用戶擁有它的所屬組的所有許可權;再一個就是,如果sgid加在一個目錄上,則在該目錄下創建的文件或目錄的所屬組和該目錄一樣,且創建的目錄也會自動加上sgid
$ ll dir2 -d drwx--s--- 4 root tom 32 Oct 15 22:16 dir2 # dir2許可權為2710,即0710又加了個sgid # 此時umask為022,默認值 $ touch dir2/file1 $ ll dir2 -rw-r--r-- 1 root tom 0 Oct 15 22:20 file1 $ mkdir dir2/dir21 drwxr-sr-x 2 root tom 6 Oct 15 22:14 dir21 # dir21目錄繼承了dir2的sgid和所屬組tom $ umask 777 $ mkdir dir2/dir22 d-----S--- 2 root tom 17 Oct 15 22:16 dir22 # dir22目錄繼承了dir2的sgid,但由於dir22對於所屬組沒有x許可權, # 所以代表sgid的s變成了大寫的,大寫的S代表無效, # 另外,suid加在對於所屬主沒有x許可權的文件上也是大寫的S
- sticky
我們知道,/tmp目錄對於任何人都是可讀可寫可進入的,根據前面ugo許可權可知,當一個目錄對用戶可寫時,用戶可以隨意刪除移動目錄內的文件
$ ll /tmp/xxx.log -rw-r--r-- 1 root root 122 Sep 9 16:02 /tmp/xxx.log $ su - tom $ rm -f /tmp/xxx.log rm: cannot remove 『/tmp/xxx.log』: Operation not permitted
為什麼tom不能刪除對於tom可寫的/tmp目錄下的xxx.log文件呢?
$ ll -d /tmp drwxrwxrwt. 33 root root 8192 Oct 15 22:46 /tmp/
可以看到/tmp的許可權多了個t,這便是sticky
sticky的目的是讓用戶只能刪除移動自己的文件,對於不屬於自己的文件,沒許可權刪除或移動
對於sticky,目錄必須對other有x許可權,否則t變成大寫,無效,why?
想想也容易理解,如果目錄沒有x許可權,那麼就不能進入目錄,就更別提刪除移動目錄內的文件了,此時要sticky許可權又有何用
說明:當使用chmod為文件或目錄添加suid或sgid時,只能是『chomd u+s/g+s file』,而不能是『chmod o+s file』,o+s加也加不上;而給目錄加sticky時,也只能是『chmod o+t dir』;給目錄加suid和給文件加sticky都能加上,但又有什麼用呢?沒啥用
SELinux
selinux是對標準linux許可權的增強
所有作業系統的訪問控制都是以關聯的客體和主體的某種類型的訪問控制屬性為基礎的。
怎麼理解這句話?
作業系統:當然是linux等作業系統
訪問控制:前面說的許可權都可以說是訪問控制
客體(object):主要是指文件、目錄、埠等
主體(subject):主要是指進程
訪問控制屬性:對應標準linux許可權的讀寫執行等許可權,而對應selinux則叫做安全上下文(Security Context)
舉例來說,主體進程httpd要訪問一個客體網頁文件a.html時,在沒有selinux的情況下,需要看a.html的訪問控制屬性(即讀取執行許可權)是否對主體httpd進程開放
再看selinux的安全上下文是什麼
# 查看文件的安全上下文 $ ll -Z /var/www/html -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 a.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html # 查看進程的安全上下文 $ ps -ZC httpd LABEL PID TTY TIME CMD system_u:system_r:httpd_t:s0 8083 ? 00:00:01 httpd system_u:system_r:httpd_t:s0 8094 ? 00:00:00 httpd # 查看埠安全上下文 $ semanage port -l | egrep '<80>' http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
這裡主要說的是文件許可權,對於進程和埠安全上下文先不做說明
在開啟selinux的前提下,httpd伺服器可以訪問到index.html,而不能訪問到a.html(會報403錯誤).為什麼呢?原因就在於其安全上下文上
a.html的安全上下文:unconfined_u:object_r:admin_home_t:s0
index.html的安全上下文:unconfined_u:object_r:httpd_sys_content_t:s0
以分號分隔的幾種安全上下文分別代表:USER:ROLE:TYPE[LEVEL[:CATEGORY]]
在默認安全策略targeted中,USER和ROLE對於文件幾乎沒什麼影響,主要是TYPE,這裡httpd不能訪問a.html的原因也是由於兩個文件的TYPE不同
selinux中有兩種安全策略, targeted(常見的網路服務httpd、vsftpde受selinux控制)和strict(每個進程都受selinux的控制,這裡主要說下targeteda,這也是默認的安全策略
- 修改文件安全上下文
$ chcon -t httpd_sys_content_t /var/www/html/a.html $ ll -Z /var/www/html/a.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/a.html
- selinux安全上下文規則
# 查看規則 $ semanage fcontext -l | grep "/var/www/html" ... /var/www/html(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 ... # 添加規則(/var/www/html目錄的所有php文件安全上下文標籤為admin_home_t) $ semanage fcontext -a -t admin_home_t "/var/www/html/(.*.php)" $ touch /var/www/html/1.php && ll -Z /var/www/html/1.php -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/1.php # 為什麼新建的文件沒有按照規則來生成admin_home_t標籤的文件?因為文件生成是是根據父目錄來的 # 如何讓文件按照規則來改變安全上下文標籤呢? 需要用到下面的命令:restorecon # 重置規則 $ restorecon -RFv /var/www/html # 將該目錄按照該目錄內的所有規則重置安全上下文標籤 restorecon reset /var/www/html/1.php context unconfined_u:object_r:httpd_sys_content_t:s0->system_u:object_r:admin_home_t:s0
關於文件許可權的selinux,就說到這裡,selinux還包括除文件外的其它內容,如埠、進程等,以及其它細節方面的東西,我自己也還有好多不明白的,