第3章 Linux上文件的權限管理

3.1 文件/目錄的權限

3.1.1 文件的權限

每一個文件都有其全部者(u:user)、所屬組(g:group)和其餘人(o:other)對它的操做權限,a:all則同時表明這3者。權限包括讀(r:read)、寫(w:write)、執行(x:execute)。在不一樣類型的文件上讀、寫、執行權限的體現有所不一樣,因此目錄權限和普通文件權限要區分開來。node

在普通文件上:shell

r:可讀,可使用相似cat等命令查看文件內容;讀是文件的最基本權限,沒有讀權限,普通文件的一切操做行爲都被限制。windows

w:可寫,能夠編輯此文件;centos

x:可執行,表示文件可由特定的解釋器解釋並運行。能夠理解爲windows中的可執行程序或批處理腳本,雙擊就能運行起來的文件。bash

在目錄上:app

r:能夠對目錄執行ls以列出目錄內的全部文件;讀是文件的最基本權限,沒有讀權限,目錄的一切操做行爲都被限制。ide

w:能夠在此目錄建立或刪除文件/子目錄;工具

x:可進入此目錄,可以使用ls -l查看文件的詳細信息。能夠理解爲windows中雙擊就進入目錄的動做。測試

若是目錄沒有x權限,其餘人將沒法查看目錄內文件屬性(只能查看到文件類型和文件名,至於爲何,見後文),因此通常目錄都要有x權限。而若是隻有執行卻沒有讀權限,則權限拒絕。字體

通常來講,普通文件的默認權限是644(沒有執行權限),目錄的默認權限是755(必須有執行權限,不然進不去),連接文件的權限是777。固然,默認文件的權限設置方法是能夠經過umask值來改變的。

3.1.2 權限的表示方式

權限的模式有兩種體現:數字體現方式和字符體現方式。

權限的數字表示:"-"表明沒有權限,用0表示。

                r-----4

                w-----2

                x-----1

例如:rwx rw- r--對應的數字權限是764,732表明的權限數值表示爲rwx -wx -w-。

3.1.3 chmod修改權限

可以修改權限的人只有文件全部者和超級管理員。

chmod [OPTION]... MODE[,MODE]... FILE...
chmod [OPTION]... num_mode FILE...
chmod [OPTION]... --reference=RFILE FILE...

選項說明:
--reference=RFILE:引用某文件的權限做爲權限值
-R:遞歸修改,只對當前已存在的文件有效

(1). 使用數值方式修改權限

shell> chmod 755 /tmp/a.txt

(2). 使用字符方式修改權限

因爲權限屬性附在文件全部者、所屬組和其它上,它們三者都有獨立的權限位,全部者使用字母"u"表示,所屬組使用"g"來表示,其餘使用"o"來表示,而字母"a"同時表示它們三者。因此使用字符方式修改權限時,須要指定操做誰的權限。

chmod [ugoa][+ - =] [權限字符] 文件/目錄名

"+"是加上權限,"-"是減去權限,"="是直接設置權限

[root@xuexi tmp]# chmod u-x,g-x,o-x test        # 將ugo都去掉x權限,等價於chmod -x test
[root@xuexi tmp]# chmod a+x test                # 爲ugo都加上x權限,等價於chmod +x test

3.1.4 chgrp

更改文件和目錄的所屬組,要求組已經存在。

注意,對於連接文件而言,修改組的做用對象是連接的源文件,而非連接文件自己。

chgrp [OPTION]... GROUP FILE...
chgrp [OPTION]... --reference=RFILE FILE..

選項說明:
-R:遞歸修改
--reference=dest_file  file_list:引用某文件的group做爲文件列表的組,即將file文件列表的組改成dest_file的組

3.1.5 chown

chown能夠修改文件全部者和所屬組。

注意,對於連接文件而言,默認不會穿過連接修改源文件,而是直接修改連接文件自己,這和chgrp的默認是不同的。

chown [OPTION]... [OWNER][:[GROUP]] FILE...
chown [OPTION]... [OWNER][.[GROUP]] FILE...
chown [OPTION]... --reference=RFILE FILE...

選項說明:
--from=CURRENT_OWNER:CURRENT_GROUP:只修改當前全部者或所屬組爲此處指定的值的文件
--reference=RFILE:引用某文件的全部者和所屬組的值做爲新的全部者和所屬組
-R:遞歸修改。注意,當指定-R時,且同時指定下面某一個選項時對連接文件有不一樣的行爲
       -H:若是chown的文件參數是一個連接到目錄的連接文件,則穿過此連接文件修改其源目錄的全部者和所屬組
       -L:目錄中遇到的全部連接文件都穿越過去,修改它們的源文件的全部者和所屬組
       -P:不進行任何穿越,只修改連接文件自己的全部者和所屬組。(這是默認值)
       這3項若同時指定多項時,則最後一項生效

chown指定全部者和所屬組的方式有兩種,使用冒號和點。

shell> chown root.root test
shell> chown root:root test
shell> chown root test     # 只修改全部者
shell> chown :root test    # 自修改組
shell> chown .root test

3.2 實現權限的本質

涉及文件系統的知識點,若不理解,能夠先看看文件系統的內容。此處是以ext4文件系統爲例的,在其餘文件系統上結果可能會有些不同(centos 7上使用xfs文件系統時結果可能就不同),但本質是同樣的。

不一樣的權限表示對文件具備不一樣能力,如讀寫執行(rwx)權限,可是它是怎麼實現的呢?描述文件權限的數據放在哪裏呢?

首先,權限的元數據放在inode中,嚴格地說是放在inode table中,由於每一個塊組的全部inode組成一個inode table。在inode table中使用一列來存放數字型的權限,好比某文件的權限爲644。每次用戶要對文件進行操做時系統都會先查看權限,確認該用戶是否有對應的權限來執行操做。固然,inode table通常都已經加載到內存中,因此每次查詢權限的資源消耗是很是小的。

不管是讀、寫仍是執行權限,所體現出來的能力究其本質都是由於它做用在對應文件的data block上。

3.2.1 讀權限(r)

對普通文件具備讀權限表示的是具備讀取該文件內容的能力,對目錄具備讀權限表示具備瀏覽該目錄中文件或子目錄的能力。其本質都是具備讀取其data block的能力。

對於普通文件而言,可以讀取文件的data block,而普通文件的data block存儲的直接就是數據自己, 因此對普通文件具備讀權限表示可以讀取文件內容。

對於目錄文件而言,可以讀取目錄的data block,而目錄文件的data block存儲的內容包括但不限於:目錄中文件的inode號(並不是直接存儲,而是存儲指向inode table中該inode號的指針)以及這些文件的文件類型、文件名。因此可以讀取目錄的data block表示僅能獲取到這些信息。

目錄的data block內容示例以下:

例如:

shell> mkdir -p /mydata/data/testdir/subdir     # 建立testdir測試目錄和其子目錄subdir
shell> touch /mydata/data/testdir/a.log        # 再在testdir下建立一個普通文件
shell> chmod 754 /mydata/data/testdir        # 將testdir設置爲對其餘人只有讀權限

而後切換到普通用戶查看testdir目錄的內容。

shell> su - wangwu

shell> ll -ai /mydata/data/testdir/
ls: cannot access /mydata/data/testdir/..: Permission denied
ls: cannot access /mydata/data/testdir/a.log: Permission denied
ls: cannot access /mydata/data/testdir/subdir: Permission denied
ls: cannot access /mydata/data/testdir/.: Permission denied
total 0
? d????????? ? ? ? ?            ? .
? d????????? ? ? ? ?            ? ..
? -????????? ? ? ? ?            ? a.log ? d????????? ? ? ? ?            ? subdir

從結果中看出,testdir下的文件名和文件類型是可以讀取的,可是其餘屬性都不能讀取到。並且也讀取不到inode號,由於它並無直接存儲inode號,而是存儲了指向Inode號的指針,要定位到指針的指向須要執行權限。

3.2.2 執行權限(x)

執行權限表示的是可以執行。如何執行?執行這個詞不是很好解釋,能夠簡單的類比Windows中的雙擊行爲。例如對目錄雙擊就能進入到目錄,對批處理文件雙擊就能運行(有專門的解釋器解釋),對可執行程序雙擊就能運行等。

固然,讀權限是文件的最基本權限,執行權限能正常運行必須得配有讀權限。

對目錄有執行權限,表示能夠經過目錄的data block中指向文件inode號的指針定位到inode table中該文件的inode信息,因此能夠顯示出這些文件的所有屬性信息。

3.2.3 寫權限(w)

寫權限很簡單,就是可以將數據寫入分配到的data block。

對目錄文件具備寫權限,表示可以建立和刪除文件。目錄的寫操做實質是可以在目錄的data block中建立或刪除關於待操做文件的記錄。它要求對目錄具備執行權限,由於不管是建立仍是刪除其內文件,都須要將其data block中inode號和inode table中的inode信息關聯或刪除。

對普通文件具備寫權限,實質是可以改寫該文件的data block。

仍是要說明的是,對文件有寫權限不表明可以刪除該文件,由於刪除文件是要在目錄的data block中刪除該文件的記錄,也就是說刪除權限是在目錄中定義的。

 

因此,對目錄文件和普通文件而言,讀、寫、執行權限它們的依賴關係以下圖所示。

3.3 umask說明

umask值用於設置用戶在建立文件時的默認權限。對於root用戶(其實是UID小於200的user),系統默認的umask值是022;對於普通用戶和系統用戶,系統默認的umask值是002。

默認它們的設置是寫在/etc/profile和/etc/bashrc兩個環境配置文件中。

shell> grep -C 5 -R 'umask 002'  /etc | grep 'umask 022'  
/etc/bashrc-       umask 022
/etc/csh.cshrc-    umask 022
/etc/profile-      umask 022

相關設置項以下:

if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
   umask 002
else
   umask 022
fi

執行umask命令能夠查看當前用戶的umask值。

[root@xuexi tmp]# umask
0022
[longshuai@xuexi tmp]$ umask
0002

執行umask num能夠臨時修改umask值爲num,但這是臨時的,要永久有效,須要寫入到環境配置文件中,至於寫入到/etc/profile、/etc/bashrc、~/.bashrc仍是~/.bash_profile中,看你本身的需求了。不過通常來講,不會去永久修改umask值,只會在特殊條件下臨時修改下umask值。

umask是如何決定建立文件的默認權限的呢?

若是建立的是目錄,則使用777-umask值,如root的umask=022,則root建立目錄時該目錄的默認權限爲777-022=755,而普通用戶建立目錄時,權限爲777-002=775.

若是建立的是普通文件,在Linux中,深刻貫徹了一點:文件默認不該該有執行權限,不然是危險的。因此在計算時,可能會和想象中的結果不同。若是umask的三位都爲偶數,則直接使用666去減掉umask值,由於6減去一個偶數仍是偶數,任何位都不可能會有執行權限。如root建立普通文件時默認權限爲666-022=644,而普通用戶建立普通文件時默認權限爲666-002=664。

若是umask值某一位爲奇數,則666減去umask值後再在奇數位上加1。如umask=021時,建立文件時默認權限爲666-021=645,在奇數位上加1,則爲646。

[longshuai@xuexi tmp]$ umask 021
[longshuai@xuexi tmp]$ touch b.txt
[longshuai@xuexi tmp]$ ls -l b.txt
-rw-r--rw- 1 longshuai longshuai 0 Jun  7 12:02 b.txt

總之計算出後默認都是沒有執行權限的。

3.4 文件的擴展ACL權限

在計算機相關領域,全部的ACL(access control list)都表示訪問控制列表。

文件的owner/group/others的權限就是一種ACL,它們是基本的ACL。不少時候,只經過這3個權限位是沒法徹底合理設置權限問題的,例如如何僅設置某單個用戶具備什麼權限。這時候須要使用擴展ACL。

擴展ACL是一種特殊權限,它是文件系統上功能,用於解決全部者、所屬組和其餘這三個權限位沒法合理設置單個用戶權限的問題。因此,擴展ACL能夠針對單一使用者,單一檔案或目錄裏的默認權限進行r,w,x的權限規範。

須要明確的是,擴展ACL是文件系統上的功能,且工做在內核,默認在ext4/xfs上都已開啓。

在下文中,都直接以ACL來表示代替擴展ACL的稱呼。

3.4.1 查看文件系統是否開啓ACL功能

對於ext家族的文件系統來講,要查看是否開啓acl功能,使用dumpe2fs導出文件系統屬性便可。

shell> dumpe2fs -h /dev/sda2 | grep -i acl
dumpe2fs 1.41.12 (17-May-2010)
Default mount options:    user_xattr acl

對於xfs文件系統,則沒有直接的命令能夠輸出它的相關信息,須要使用dmesg來查看。其實無需關注它,由於默認xfs會開啓acl功能。

shell> dmesg | grep -i acl
[    1.465903] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
[    2.517705] SGI XFS with ACLs, security attributes, no debug enabled

開啓ACL功能後,不表明就使用ACL功能。是否使用該功能,不一樣文件系統控制方法不同,對於ext家族來講,經過mount掛載選項來控制,而對於xfs文件系統,mount命令根本不支持acl參數(xfs文件系統如何關閉或啓用的方法本人也不知道)。

3.4.2 設置和查看ACL

設置使用setfacl命令。

setfacl [options] u:[用戶列表]:[rwx] 目錄/文件名    # 對用戶設置使用u
setfacl [options] g:[組列表]:[rwx]   目錄/文件名    # 對組設置使用g

選項說明:
-m:設定ACL權限(modify)
-x:刪除指定的ACL權限,能夠指定用戶、組和文件來刪除(remove)
-M:寫了ACL條目的文件,將今後文件中讀取ACL條目,須要配合-m,因此-M指定的是modify file
-X:寫了ACL條目的文件,將今後文件中讀取ACL條目,須要配合-x,因此-X指定的是remove file
-n:不重置mask
-b:刪除全部的ACL權限
-d:設定默認ACL權限,只對目錄有效,設置後子目錄(文件)繼承默認ACL,只對將來文件 有效
-k:刪除默認ACL權限
-R:遞歸設定ACL權限,只對目錄有效,只對已有文件有效

查看使用getfacl命令

getfacl filename

案例:假設現有目錄/data/videos專門存放視頻,其中有一個a.avi的介紹性視頻。該目錄的權限是750。如今有一個新用戶加入,但要求該用戶對該目錄只有查看的權限,且只能看其中一部視頻a.avi,另外還要求該用戶在此目錄下沒有建立和刪除文件的權限。

 

1.準備相關環境。

shell> mkdir -p /data/videos
shell> chmod 750 /data/videos
shell> touch /data/videos/{a,b}.avi
shell> echo "xxx" >/data/videos/a.avi
shell> echo "xxx" >/data/videos/b.avi
shell> chown -R root.root /data/videos

2.首先設置用戶longshuai對/data/videos目錄有讀和執行權限。

shell> setfacl -m u:longshuai:rx /data/videos

3.如今longshuai對/data/videos目錄下的全部文件都有讀權限,由於默認文件的權限爲644。要設置longshuai只對a.avi有讀權限,先設置全部文件的權限都爲不可讀。

shell> chmod 640 /data/videos/*

4.而後再單獨設置a.avi的讀權限。

shell> setfacl -m u:longshuai:r /data/videos/a.avi

到此就設置完成了。查看/data/videos/和/data/videos/a.avi上的ACL信息。

shell> getfacl /data/videos/
getfacl: Removing leading '/' from absolute path names
# file: data/videos/
# owner: root
# group: root
user::rwx
user:longshuai:r-x         # 用戶longshuai在此文件上的權限是r-x
group::r-x
mask::r-x
other::---
shell> getfacl /data/videos/a.avi
getfacl: Removing leading '/' from absolute path names
# file: data/videos/a.avi
# owner: root
# group: root
user::rw-
user:longshuai:r--         # 用戶longshuai在此文件上的權限是r--
group::r--
mask::r--
other::---

3.4.3 ACL:mask

設置mask後會將mask權限與已有的acl權限進行與計算,計算後的結果會成爲新的ACL權限。

設定mask的方式爲:

setfacl -m m:[rwx] 目錄/文件名

注意:默認每次設置文件的acl都會重置mask爲這次給定的用戶的值。既然如此,要如何控制文件上的acl呢?若是一個文件上要設置多個用戶的acl,重置mask後就會對已有用戶的acl從新計算,而使得acl權限得不到有效的控制。使用setfacl的"-n"選項,它表示這次設置不會重置mask值。

例如:

當前的acl權限:

shell> getfacl /data/videos                     
getfacl: Removing leading '/' from absolute path names
# file: data/videos
# owner: root
# group: root
user::rwx
user:longshuai:rwx
group::r-x
mask::rwx
other::---

設置mask值爲rx。

shell> setfacl -m m:rx /data/videos

shell> getfacl /data/videos       
getfacl: Removing leading '/' from absolute path names
# file: data/videos
# owner: root
# group: root
user::rwx
user:longshuai:rwx #effective:r-x
group::r-x
mask::r-x
other::---

設置mask後,它提示有效權限是r-x。這是rwx和r-x作與運算以後的結果。

再設置longshuai的acl爲rwx,而後查看mask,會發現mask也被重置爲rwx。

shell> setfacl -m u:longshuai:rwx /data/videos

shell> getfacl  /data/videos
getfacl: Removing leading '/' from absolute path names
# file: data/videos
# owner: root
# group: root
user::rwx
user:longshuai:rwx
group::r-x
mask::rwx
other::---

因此,在設置文件的acl時,要使用-n選項來禁止重置mask。

shell> setfacl -m m:rx /data/videos

shell> setfacl -n -m u:longshuai:rwx /data/videos

shell> getfacl  /data/videos
getfacl: Removing leading '/' from absolute path names
# file: data/videos
# owner: root
# group: root
user::rwx
user:longshuai:rwx              #effective:r-x
group::r-x
mask::r-x
other::---

3.4.4 設置遞歸和默認ACL權限

遞歸ACL權限只對目錄裏已有文件有效,默認權限只對將來目錄裏的文件有效。

設置遞歸ACL權限:

setfacl -m u:username:[rwx] -R 目錄名

設置默認ACL權限:

setfacl -m d:u:username:[rwx] 目錄名

3.4.5 刪除ACL權限

setfacl -x u:用戶名 文件名       # 刪除指定用戶ACL
setfacl -x g:組名 文件名         # 刪除指定組名ACL
setfacl -b 文件名                # 指定文件刪除ACL,會刪除全部ACL

3.5 文件隱藏屬性

chattr:change file attributes

lsattr:list file attributes

chattr [+ - =] [ai] 文件或目錄名

經常使用的參數是a(append,追加)和i(immutable,不可更改),其餘參數略。

設置了a參數時,文件中將只能增長內容,不能刪除數據,且不能打開文件進行任何編輯,哪怕是追加內容也不能夠,因此像sed等須要打開文件的再寫入數據的工具也沒法操做成功。文件也不能被刪除。只有root才能設置。

設置了i參數時,文件將被鎖定,不能向其中增刪改內容,也不能刪除修改文件等各類動做。只有root才能設置。能夠將其理解爲設置了i後,文件將是永恆不變的了,誰都不能動它。

例如,對/etc/shadow文件設置i屬性,任何用戶包括root將不能修改密碼,並且也不能建立用戶。

shell> chattr +i /etc/shadow

此時若是新建一個用戶。

shell> useradd newlongsuai
shell> useradd: cannot open /etc/shadow        # 提示文件不能打開,被鎖定了

lsattr查看文件設置的隱藏屬性。

shell> lsattr /etc/shadow
----i--------e- /etc/shadow         # i屬性說明被鎖定了,e是另外一種文件屬性,忽略它

刪除隱藏屬性:

shell> chattr -i /etc/shadow
shell> lsattr /etc/shadow
-------------e- /etc/shadow

再來一例:

shell> chattr +a test1.txt        # 對test1.txt設置a隱藏屬性
shell> echo 1234>>test1.txt     # 追加內容是容許的行爲
shell> cat /dev/null >test1.txt    # 可是清空文件內容是不容許的
-bash: test1.txt: Operation not permitted

3.6 suid/sgid/sbit

3.6.1 suid

suid只針對可執行文件,即二進制文件。它的做用是對某個命令(可執行文件)授予全部者的權限,命令執行完成權限就消失。通常是提權爲root權限。

例如/etc/shadow文件全部人都沒有權限(root除外),其餘用戶連看都不容許。

shell> ls -l /etc/shadow
----------. 1 root root 752 Apr  8 12:42 /etc/shadow

可是他們卻能修改本身的密碼,說明他們必定有必定的權限。這個權限就是suid控制的。

shell> ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 30768 Feb 22  2012 /usr/bin/passwd

其中的"s"權限就是suid,它出如今全部者位置上(是root),其餘用戶執行passwd命令時,會暫時擁有全部者位的rwx權限,也就是root的權限,因此能向/etc/shadow寫入數據。

suid必須和x配合,若是沒有x配合,則該suid是空suid,仍然沒有執行命令的權限,全部者都沒有了x權限,suid依賴於它因此更不可能有x權限。空的suid權限使用大寫的"S"表示。

數字4表明suid,如4755。

3.6.2 sgid

針對二進制文件和目錄。

  • 針對二進制文件時,權限升級爲命令的所屬組權限。
  • 針對目錄時,目錄中所創建的文件或子目錄的組將繼承默認父目錄組,其本質仍是提高爲目錄所屬組的權限。此時目錄應該要有rx權限,普通用戶才能進入目錄,若是普通用戶有w權限,新建的文件和目錄則以父目錄組爲默認組。

以2表明sgid,如2755,和suid組合如6755。

3.6.3 sbit

只對目錄有效。對目錄設置sbit,將使得目錄裏的文件只有全部者能刪除,即便其餘用戶在此目錄上有rwx權限,即便是root用戶。

以1表明sbit。

 

2017-08-17補充:suid/sgid/sbit的標誌位都做用在x位,當原來的x位有x權限時,這些權限位則爲s/s/t,若是沒有x權限,則變爲S/S/T。例如,/tmp目錄的權限有個t位,使得該目錄裏的文件只有其全部者自己能刪除。

相關文章
相關標籤/搜索