1. 程式人生 > >Linux ACL訪問許可權控制詳解

Linux ACL訪問許可權控制詳解

在普通許可權中,Linux使用者對檔案只有三種身份,就是屬主、屬組和其他人;每種使用者身份擁有讀(read)、寫(write)和執行(execute)三種許可權。但是在實際工作中,這三種身份實在是不夠用,我們舉個例子來看看。



圖 1 ACL許可權簡介


圖 1 的根目錄中有一個 /project 目錄,這是班級的專案目錄。班級中的每個學員都可以訪問和修改這個目錄,老師也需要對這個目錄擁有訪問和修改許可權,其他班級的學員當然不能訪問這個目錄。需要怎麼規劃這個目錄的許可權呢?應該這樣:老師使用 root 使用者,作為這個目錄的屬主,許可權為 rwx;班級所有的學員都加入 tgroup 組,使 tgroup 組作為 /project 目錄的屬組,許可權是 rwx;其他人的許可權設定為 0。這樣這個目錄的許可權就可以符合我們的專案開發要求了。

有一天,班裡來了一位試聽的學員 st,她必須能夠訪問 /project 目錄,所以必須對這個目錄擁有 r 和 x 許可權;但是她又沒有學習過以前的課程,所以不能賦予她 w 許可權,怕她改錯了目錄中的內容,所以學員 st 的許可權就是 r-x。可是如何分配她的身份呢?變為屬主?當然不行,要不 root 該放哪裡?加入 tgroup 組?也不行,因為 tgroup 組的許可權是 rwx,而我們要求學員 st 的許可權是 r-x。如果把其他人的許可權改為 r-x 呢?這樣一來,其他班級的所有學員都可以訪問 /project 目錄了。

當出現這種情況時,普通許可權中的三種身份就不夠用了。ACL 許可權就是為了解決這個問題的。在使用 ACL 許可權給使用者 st 陚予許可權時,st 既不是 /project 目錄的屬主,也不是屬組,僅僅賦予使用者 st 針對此目錄的 r-x 許可權。這有些類似於 Windows 系統中分配許可權的方式,單獨指定使用者並單獨分配許可權,這樣就解決了使用者身份不足的問題。

ACL是Access Control List(訪問控制列表)的縮寫,不過在Linux系統中,ACL用於設定使用者針對檔案的許可權,而不是在交換路由器中用來控制資料訪問的功能(類似於防火牆)。

開啟ACL許可權

[[email protected] ~]# mount
/dev/sda1 on /boot type ext4 (rw)
/dev/sda3 on I type ext4 (rw)
…省略部分輸出…
#使用mount命令可以看到系統中已經掛載的分割槽,但是並沒有看到ACL許可權的設定
[[email protected] ~]# dumpe2fs -h /dev/sda3
#dumpe2fs是查詢指定分割槽檔案系統詳細資訊的命令
…省略部分輸出…
Default mount options: user_xattr acl
…省略部分輸出…

其中,dumpe2fs 命令可選的選項及其含義如下:

  • -h:僅顯示超級塊中的資訊,而不顯示磁碟塊組的詳細資訊;


使用 mount 命令可以査看到系統中已經掛載的分割槽,而使用 dumpe2fs 命令可以査看到這個分割槽檔案系統的詳細資訊。大家可以看到,我們的 ACL 許可權是 /dev/sda3 分割槽的預設掛載選項,所以不需要手工掛載。

不過我的 Linux 系統如果沒有預設掛載,則可以手工掛載嗎?當然可以,執行如下命令:

[[email protected] ~]# mount -o remount, acl /
#重新掛載根分割槽,並加入ACL許可權

使用 mount 命令重新掛載,並加入 ACL 許可權。不過使用此命令是臨時生效的。要想永久生效,需要修改 /etc/fstab 檔案,命令如下:

[[email protected] ~]#vi /etc/fstab
UUID=c2ca6f57-b15c-43ea-bca0-f239083d8bd2 /ext4 defaults, acl 1 1
#加入ACL許可權
[[email protected] ~]# mount -o remount /
#重新掛載檔案系統或重啟系統,使修改生效

在你需要開啟 ACL 許可權的分割槽行上(也就是說 ACL 許可權針對的是分割槽),手工在 defaults 後面加入",acl"即可永久在此分割槽中開啟 ACL 許可權。

ACL許可權設定

1) ACL許可權管理命令

我們知道了 ACL 許可權的作用,也知道了如何開啟 ACL 許可權,接下來學習如何査看和設定 ACL 許可權。命令如下:

[[email protected] ~]# getfacle 檔名
#檢視ACL許可權
[[email protected] ~]# setfacl 選項 檔名
#設定ACL許可權

選項:

  • -m:設定 ACL 許可權。如果是給予使用者 ACL 許可權,則使用"u:使用者名稱:許可權"格式賦予;如果是給予組 ACL 許可權,則使用"g:組名:許可權" 格式賦予;
  • -x:刪除指定的 ACL 許可權;
  • -b:刪除所有的 ACL 許可權;
  • -d:設定預設 ACL 許可權。只對目錄生效,指目錄中新建立的檔案擁有此預設許可權;
  • -k:刪除預設 ACL 許可權;
  • -R:遞迴設定 ACL 許可權。指設定的 ACL 許可權會對目錄下的所有子檔案生效;

2) 給使用者和使用者組新增ACL許可權

舉個例子,就來看看圖 1 中的許可權怎麼分配。我們要求 root 是 /project 目錄的屬主,許可權是 rwx;tgroup 是此目錄的屬組,tgroup 組中擁有班級學員 zhangsan 和 lisi,許可權是 rwx;其他人的許可權是 0。這時,試聽學員 st 來了,她的許可權是 r-x。我們來看具體的分配命令。

[[email protected] ~]# useradd zhangsan
[[email protected] ~]# useradd lisi
[[email protected] ~]# useradd st
[[email protected] ~]# groupadd tgroup
#新增需要試驗的使用者和使用者組,省略設定密碼的過程
[[email protected] ~]# mkdir /project #建立需要分配許可權的目錄
[[email protected] ~]# chown root:tgroup /project/
#改變/project目錄的屬主和屬組
[[email protected] ~]# chmod 770 /project/
#指定/project目錄的許可權
[[email protected] ~]# ll -d /project/
drwxrwx--- 2 root tgroup 4096 1月19 04:21 /project/
#檢視一下許可權,已經符合要求了
#這時st學員來試聽了,如何給她分配許可權
[[email protected] ~]# setfacl -m u:st:rx /project/
#給使用者st賦予r-x許可權,使用"u:使用者名稱:許可權" 格式
[[email protected] /]# cd /
[[email protected] /]# ll -d project/
drwxrwx---+ 3 root tgroup 4096 1月19 05:20 project/
#使用ls-l査詢時會發現,在許可權位後面多了一個"+",表示此目錄擁有ACL許可權
[[email protected] /]# getfacl project
#檢視/prpject目錄的ACL許可權
#file: project <-檔名
#owner: root <-檔案的屬主
#group: tgroup <-檔案的屬組
user::rwx <-使用者名稱欄是空的,說明是屬主的許可權
user:st:r-x <-使用者st的許可權
group::rwx <-組名欄是空的,說明是屬組的許可權
mask::rwx <-mask許可權
other::--- <-其他人的許可權

大家可以看到,st 使用者既不是 /prpject 目錄的屬主、屬組,也不是其他人,我們單獨給 st 使用者分配了 r-x 許可權。這樣分配許可權太方便了,完全不用先辛苦地規劃使用者身份了。

我想給使用者組賦予 ACL 許可權可以嗎?當然可以,命令如下:

[[email protected] /]# groupadd tgroup2
#新增測試組
[[email protected] /]# setfacl -m g:tgroup2:rwx project/
#為組tgroup2紛配ACL許可權,使用"g:組名:許可權"格式
[[email protected] /]# ll -d project/
drwxrwx---+ 2 root tgroup 4096 1月19 04:21 project/
#屬組並沒有更改
[[email protected] /]# getfacl project/
#file: project/
#owner: root
#group: tgroup
user::rwx
user:st:r-x
group::rwx
group:tgroup2:rwx <-使用者組tgroup2擁有了rwx許可權
mask::rwx
other::--

3) 最大有效許可權mask

mask 是用來指定最大有效許可權的。mask 的預設許可權是 rwx,如果我給 st 使用者賦予了 r-x 的 ACL 許可權,mj 需要和 mask 的 rwx 許可權"相與"才能得到 st 的真正許可權,也就是 r-x "相與"rwxtj 出的值是 r-x,所以 st 使用者擁有 r-x 許可權。

如果把 mask 的許可權改為 r--,和 st 使用者的許可權相與,也就是 r--"相與"r-x 得出的值是 r--,st 使用者的許可權就會變為只讀。大家可以這麼理解:使用者和使用者組所設定的許可權必須在 mask 許可權設定的範圍之內才能生效,mask許可權就是最大有效許可權。

不過我們一般不更改 mask 許可權,只要給予 mask 最大許可權 rwx,那麼任何許可權和 mask 許可權相與,得出的值都是許可權本身。也就是說,我們通過給使用者和使用者組直接賦予許可權,就可以生效,這樣做更直觀。

補充:邏輯與運算的運算子是"and"。可以理解為生活中所說的"並且"。也就是相與的兩個值都為真,結果才為真;有一個值為假,與的結果就為假。比如 A 相與 B,結果入表 2 所示。

表 2 邏輯與運算
A B and


那麼兩個許可權相與和上面的結果類似,我們以讀(r)許可權為例,結果如表 3 所示。

表 3 讀許可權相與
A B and
r r r
r - -
- r -
- - -


所以,"rwx"相與"r-x",結果是"r-x";"r--"相與"r-x",結果是"r--"。

修改最大有效許可權的命令如下:

[[email protected] /]# setfacl -m m:rx project/
#設定mask許可權為r-x,使用"m:許可權"格式
[[email protected] /]# getfacl project/
#file:project/
#owner:root
#group:tgroup
user::rwx
group::rwx #effective:r-x
mask::r-x
#mask許可權變為r-x
other::--

4) 預設ACL許可權和遞迴ACL許可權

我們已經給 /project 目錄設定了 ACL 許可權,那麼,在這個目錄中新建一些子檔案和子目錄,這些檔案是否會繼承父目錄的 ACL 許可權呢?我們試試吧。

[[email protected] /]# cd /project/
[[email protected] prq'ect]# touch abc
[[email protected] prq'ect]# mkdir d1
#在/project目錄中新建了abc檔案和d1目錄
[[email protected] project]#ll
總用量4
-rw-r--r-- 1 root root 01月19 05:20 abc
drwxr-xr-x 2 root root 4096 1月19 05:20 d1
#這兩個新建立的檔案許可權位後面並沒有"+",表示它們沒有繼承ACL許可權

子檔案 abc 和子目錄 d1 因為是後建立的,所以並沒有繼承父目錄的 ACL 許可權。當然,我們可以手工給這��個檔案分配 ACL 許可權,但是如果在目錄中再新建檔案,都要手工指定,則顯得過於麻煩。這時就需要用到預設 ACL 許可權。

預設 ACL 許可權的作用是:如果給父目錄設定了預設 ACL 許可權,那麼父目錄中所有新建的子檔案都會繼承父目錄的 ACL 許可權。預設 ACL 許可權只對目錄生效。命令如下:

[[email protected] /]# setfacl -m d:u:st:rx /project/
#使用"d:u:使用者名稱:許可權"格式設定預設ACL許可權
[[email protected] project]# getfacl project/
# file: project/
# owner: root
# group: tgroup
user:: rwx
user:st:r-x
group::rwx
group:tgroup2:rwx
mask::rwx
other::--
default:user::rwx <-多出了default欄位
default:user:st:r-x
default:group::rwx
default:mask::rwx
default:other::--
[[email protected] /]# cd project/
[[email protected] project]# touch bcd
[[email protected] project]# mkdir d2
#新建子檔案和子目錄
[[email protected] project]# ll 總用量8
-rw-r--r-- 1 root root 01月19 05:20 abc
-rw-rw----+ 1 root root 01月19 05:33 bcd
drwxr-xr-x 2 root root 4096 1月19 05:20 d1
drwxrwx---+ 2 root root 4096 1月19 05:33 d2
#新建的bcd和d2已經繼承了父目錄的ACL許可權

大家發現了嗎?原先的 abc 和 d1 還是沒有 ACL 許可權,因為預設 ACL 許可權是針對新建立的檔案生效的。

再說說遞迴 ACL 許可權。遞迴是指父目錄在設定 ACL 許可權時,所有的子檔案和子目錄也會擁有相同的 ACL 許可權。

[[email protected] project]# setfacl -m u:st:rx -R/project/
#-R遞迴
[[email protected] project]# ll
總用量8
-rw-r-xr--+ 1 root root 01月19 05:20 abc
-rw-rwx--+ 1 root root 01月19 05:33 bcd
drwxr-xr-x+ 2 root root 4096 1月19 05:20 d1
drwxrwx--+ 2 root root 4096 1月19 05:33 d2
#abc和d1也擁有了ACL許可權

總結一下:預設 ACL 許可權指的是針對父目錄中新建立的檔案和目錄會繼承父目錄的 ACL 許可權,格式是"setfacl-m d:u:使用者名稱:許可權 檔名";遞迴 ACL 許可權指的是針對父目錄中已經存在的所有子檔案和子目錄繼承父目錄的 ACL 許可權,格式是"setfacl-m u:使用者名稱: 許可權 -R 檔名"。

5) 刪除ACL許可權

我們來看看怎麼刪除 ACL 許可權,命令如下:

刪除指定的ACL許可權:

[[email protected] /]# setfacl -x u:st /project/
#刪除指定使用者和使用者組的ACL許可權
[[email protected] /]# getfacl project/
# file:project/
# owner: root
# group: tgroup
user::rwx
group::rwx
group:tgroup2:rwx
mask::rwx
other::--
#st使用者的許可權已被刪除

刪除所有ACL許可權:

[[email protected] /]# setfacl -b project/
#會刪除檔案的所有ACL許可權
[[email protected] /]# getfacl project/
#file: project/
#owner: root
# group: tgroup
user::rwx
group::rwx
other::--
#所有ACL許可權已被刪除