Linux ACL 許可權

sparkdev發表於2016-05-28

ACL 是什麼

ACL的全稱是 Access Control List (訪問控制列表) ,一個針對檔案/目錄的訪問控制列表。它在UGO許可權管理的基礎上為檔案系統提供一個額外的、更靈活的許可權管理機制。它被設計為UNIX檔案許可權管理的一個補充。ACL允許你給任何的使用者或使用者組設定任何檔案/目錄的訪問許可權。

本文的演示環境為 ubuntu 16.04。

ACL有什麼用

既然是作為UGO許可權管理的補充,ACL自然要有UGO辦不到或者很難辦到的本事,例如:

  1. 可以針對使用者來設定許可權
  2. 可以針對使用者組來設定許可權
  3. 子檔案/目錄繼承父目錄的許可權

檢查是否支援ACL

ACL需要Linux核心和檔案系統的配合才能工作,當前我們能見到的大多數Linux發行版本預設都是支援的。但最好還是能夠先檢查一下:

sudo tune2fs -l /dev/sda1 |grep "Default mount options:"
Default mount options:                 user_xattr    acl

我們能夠看到預設情況下(Default mount options:)已經加入 acl 支援了。

如何設定ACL

我們可以使用setfacl和getfacl命令來設定或觀察檔案/目錄的acl許可權。

setfacl

引數不多,直接列出來了:

setfacl [-bkRd] [{-m|-x} acl引數] 檔案/目錄名
-m :配置後面的 acl 引數給檔案/目錄使用,不可與 -x 合用;
-x :刪除後續的 acl 引數,不可與 -m 合用;
-b :移除所有的 ACL 配置引數;
-k :移除預設的 ACL 引數;
-R :遞迴配置 acl;
-d :配置“預設 acl 引數”,只對目錄有效,在該目錄新建的資料會引用此預設值;

getfacl

getfacl 檔案/目錄名

下面我們透過一些示例來演示 ACL 許可權的基本用法。

針對使用者來設定許可權

筆者系統中的當前使用者是 nick,再建立兩個使用者 tester 和 tester1 用來進行測試:

$ sudo adduser tester
$ sudo adduser tester1

建立檔案 aclfile,檢查其預設的許可權資訊:

把使用者切換為 tester,發現沒有寫檔案的許可權:

這是因為 other 沒有寫 aclfile 檔案的許可權。

下面我們為 tester 使用者賦予讀寫 aclfile 檔案的許可權:

$ setfacl -m u:tester:rw aclfile

修改成功後再次以 tester 使用者的身份向 aclfile 檔案寫入資料,這次已經可以正常寫入了。檢視 aclfile 檔案的許可權:

$ ll aclfile

貌似並沒有發生什麼變化,只是在描述許可權的地方多出了一個 "+" 號。下面再看看 acl 許可權:

$ getfacl aclfile

多出了一些資訊,其中比較重要的是 user:tester:rw-,就是它讓使用者 tester 具有了讀寫 aclfile 的許可權。

針對使用者組來設定許可權

和針對使用者的設定幾乎一樣,只是把小寫的 u 換成小寫的 g 就行了。

子檔案/目錄繼承父目錄的許可權

這是一個很棒的例子,它能讓我們建立的子檔案或者子資料夾繼承父資料夾的許可權設定!

$ mkdir mydir
$ ll -d mydir
$ setfacl -m d:u:tester:rwx mydir
$ getfacl mydir

注意引數 d 在這裡起到了決定性的作用。下面是設定後的 mydir 目錄的許可權屬性:

這次多出了一些以 default 開頭的行,這些 default 許可權資訊只能在目錄上設定,然後會被目錄中建立的檔案和目錄繼承。下面分別在 mydir 目錄下建立檔案 testfile 和目錄 testdir,並檢視它們的 acl 許可權:

$ touch testfile
$ mkdir testdir
$ getfacl testfile
$ getfacl testdir

從上圖可以看到檔案 testfile 繼承了父目錄的 acl 許可權,因此使用者 tester 對它有讀寫許可權。下面再看看 testdir 目錄:

從圖中可以看出,testdir 目錄不僅繼承了 tester 的訪問許可權,還繼承了父目錄上的 default 許可權。也就是說我們透過這種方式設定在目錄上的許可權可以被子目錄遞迴的繼承下去。

更改 ACL 許可權

-m 選項其實是在更改檔案和目錄的 ACL 許可權

  • 當一個使用者或組的 ACL 許可權不存在時,-m 選項執行的是新增操作,
  • 如果一個使用者或組的 ACL 許可權已經存在時,-m 選項執行的是更新操作。

我們重新建立一個 aclfile 檔案,透過下面的命令設定 tester 使用者對它的訪問許可權:

$ setfacl -m u:tester:rwx aclfile

這時 -m 選項是在新增 ACL 許可權。然後我們修改 tester 使用者的許可權,移除其對 aclfile 的執行許可權:

$ setfacl -m u:tester:rw aclfile

這時 -m 選項是在更改現有的 ACL 許可權。接下來再讓我們試一下為不同的使用者或組設定 ACL 許可權:

$ setfacl -m g:tester1:rwx aclfile

這次是新新增了 group tester1 的許可權,並且沒有影響 tester 使用者的許可權。

--set 選項會先清除掉原有的 ACL 許可權,然後新增新的許可權
我們接著設定 aclfile 檔案的 ACL 許可權:

$ setfacl --set u::rw,u:tester2:rwx,g::r,o::- aclfile

需要注意的是一定要包含 UGO 許可權的設定,不能象 -m 一樣只包含 ACL 許可權。o::- 是另一個需要注意的地方,其完整的寫法是 other::-,就像 u::rw 的完整寫法是 user::rw- 一樣。通常我們可以把 "-" 省略,但是當許可權位只包含 "-" 時,就至少要保留一個。如果寫成了o::,就會報錯。

刪除 ACL 許可權

有新增就有刪除,我們可以透過 setfacl 命令的 -x 選項來刪除指定使用者或組的 ACL 許可權,還可以透過 -b 選項來清除檔案和目錄上所有的 ACL 許可權。
我們建立一個新的測試檔案 aclfile,並設定下面的 ACL 許可權:
$ setfacl -m u:tester:rwx,u:tester1:rw,g:tester2:rwx aclfile
下面透過 -x 選項刪除 group tester2 的 ACL 許可權(注意命令中只指定了組的名稱而沒有指定許可權資訊):

$ setfacl -x g:tester2 aclfile

檢視一下結果,發現下圖中已經沒有 group:tester2 的許可權資訊了:

下面透過 -b 選項一次性刪除 aclfile 上所有的 ACL 許可權:

$ setfacl -b aclfile

-b 選項直接清除了檔案上的所有 ACL 許可權。這個行為對於目錄來說也是一樣的,這裡就不再演示了。

備份和恢復 ACL 許可權

常見的檔案操作命令 cp 和 mv 等都支援 ACL 許可權,只是 cp 命令需要加上 -p 引數。但是 tar 等常見的備份工具不會保留目錄和檔案的 ACL 許可權資訊。如果希望備份和恢復帶有 ACL 許可權的檔案和目錄,可以先把 ACL 許可權資訊備份到一個檔案裡,然後再用 -restore 選項來恢復這些資訊。下面演示 ACL 許可權的儲存和恢復。我們先建立下面的目錄結構:

並分別為 acldir 目錄和 aclfile 檔案設定 ACL 許可權:

然後使用下面的命令匯出 acldir 目錄的 ACL 許可權資訊並儲存到檔案 acldir.acl 檔案中:

$ getfacl -R acldir > acldir.acl

接下來刪除掉 acldir 目錄的 ACL 許可權:

$ setfacl -R -b acldir

現在 acldir 目錄及其子檔案上的 ACL 許可權都被刪除掉了。最後我們再透過下面的命令把它們的 ACL 許可權都恢復回來:

$ setfacl --restore acldir.acl

之前刪除的 ACL 許可權全都恢復回來了!

 

參考:
acl man page
ACL許可權詳解

相關文章