Linux文件權限


Linux文件權限主要有以下幾個:

  1. ugo基本權限
  2. acl權限
  3. suid,sgid,sticky高級權限
  4. 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

小思考:

  1. 對於/root目錄中一個其他人有讀取權限的文件,新建一個用戶,能否查看該文件?
  2. 修改根目錄權限為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:--xgroup::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還包括除文件外的其它內容,如端口、進程等,以及其它細節方面的東西,我自己也還有好多不明白的,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM