1. 程式人生 > >第3章 文件的權限管理

第3章 文件的權限管理

其他屬性 文件系統 strong 問題 ble wan centos 準備 行為


本文目錄:

3.1 文件/目錄的權限

3.2 實現權限的本質

3.3 umask說明

3.4 文件的擴展ACL權限

3.5 文件隱藏屬性

3.6 suid/sgid/sbit


3.1 文件/目錄的權限

3.1.1 文件的權限

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

在普通文件上:

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

w:可寫,可以編輯此文件;

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

在目錄上:

r:可以對目錄執行ls以列出目錄內的所有文件;讀是文件的最基本權限,沒有讀權限,目錄的一切操作行為都被限制。

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][+ - =] [權限字符] 文件/目錄名

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

[[email protected] tmp]# chmod u-x,g-x,o-x test        # 將ugo都去掉x權限,等價於chmod -x test
[[email protected] 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。

還是要說明的是,對文件有寫權限不代表能夠刪除該文件,因為刪除文件是要在目錄的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值。

[[email protected] tmp]# umask
0022
[[email protected] 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。

[[email protected] tmp]$ umask 021
[[email protected] tmp]$ touch b.txt
[[email protected] 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 目錄名   # -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,將使得目錄裏的文件只有root和所有者能刪除,即使其他用戶在此目錄上有rwx權限。

以1代表sbit。

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7011971.html

第3章 文件的權限管理