1. 程式人生 > >[kernel]access control lists(ACL)

[kernel]access control lists(ACL)

l命令 rep ces echo all lin 假設 文件的權限 use

一、 為什麽要使用ACL

先讓我們來簡單地復習一下Linux的文件權限。
在 linux下,對一個文件(或者資源)可以進行操作的對象被分為三類: file owner(文件的擁有者),group(組,註意不一定是文件擁有者所在的組), other (其他)而對於每一類別又分別定義了read, write and execute/search 權限 (這裏不討論SUID, SGID以及Sticky bit的設置)通過ls -l命令就我們就可以列出一個文件的權限

代碼:

[leonard@localhost ~]$ ls -l
-rw-rw---- 1 leonard admin 0 Jul 3 20:12 test.txt
在這裏說明了對於test.txt這個文件leonard用戶(由是file owner)擁有read & write權限. 所有屬於admin 組的用戶(group)擁有read & write 權限. 其他任何用戶(other)
對於文件沒有任何的權限

如果我們現在希望john這個用戶也可以對test.txt文件進行讀寫操作. 我自己大概會想到
以下幾種辦法 (這裏假設john不屬於admin group)

  1. 給文件的other類別增加讀和寫的權限. 這樣由於john會被歸為other類別,那麽他也將擁有讀寫的權限。

  2. 將john加入到admin group. 那麽john會被歸為group類別,那麽他將擁有讀寫的權限。

  3. 設置sudo, 使john能夠以leonard的身份對test.txt進行操作,從而獲得讀寫權限。

第一種做法的問題在於所有用戶都將對test.txt擁有讀寫操作,顯然這種做法不可取。

第二種做法的問題在於john被賦予了過多的權限.所有屬於admin組的文件,john都可以擁
有其等同的權限了。

第三種做法雖然可以達到只限定john用戶一人擁有對test.txt文件的讀寫權限.但是需要
對sudoers文件進行嚴格的格式控制. 而且當文件數量和用戶很多的時候,這種方法就相當
地不靈活了。看來好像都沒有一個很好的解決方案. 其實問題就出在Linux 文件權限裏面,對於other的定義過於廣泛,以至於很難把權限限定於一個不屬於file owner和group的用戶身上. 那Access Control List (ACL)就是用來幫助我們解決這個問題的。

簡單地來說ACL就是可以設置特定用戶或者用戶組對於一個文件/文件夾的操作權限. 需要
掌握的命令也只有三個: getfacl, setfacl, chacl

在接下去討論之前大家可以先安裝上ACL的RPM包
代碼:

rpm -ivh libacl-2.2.39-1.1 acl-2.2.39-1.1.i386.rpm

如果配置好了yum可以直接安裝這兩個包

yum -y install libacl acl

另外還需要磁盤分區的支持永久啟用acl。我這裏以自己的分區/data為例

vi /etc/fstab

LABEL=/data /data ext3 defaults,acl 1 2
在啟用了acl參數之後重新加載/data分區

mount -o remount /data

cat /etc/mtab | grep /data

/dev/sda5 /data ext3 rw,acl 0 0
出現上面的信息代表分區的acl功能已經正常加載

二、ACL的名詞定義

先來看看在ACL裏面每一個名詞的定義.這些名詞我大多從man page上摘下來雖然有些枯燥,
但是對於理解下面的內容還是很有幫助的

ACL 是由一系列的Access Entry所組成的. 每一條Access Entry定義了特定的類別可以對
文件擁有的操作權限. Access Entry有三個組成部分: Entry tag type, qualifier
(optional), 權限

我們先來看一下最重要的Entry tag type, 它有以下幾個類型

ACL_USER_OBJ: 相當於Linux裏file_owner的權限
ACL_USER: 定義了額外的用戶可以對此文件擁有的權限
ACL_GROUP_OBJ: 相當於Linux裏group的權限
ACL_GROUP: 定義了額外的組可以對此文件擁有的權限
ACL_MASK: 定義了ACL_USER, ACL_GROUP_OBJ和ACL_GROUP的最大權限 (這個我下面還會專門討論)
ACL_OTHER: 相當於Linux裏other的權限
讓我們來據個例子說明一下. 下面我們就用getfacl命令來查看一個定義好了的ACL文件

代碼:

[root@zyq-server data]# getfacl test.txt

file: test.txt

owner: root

group: family

user::rw-
user:zyq:rw-
group::rw-
group:jackuser:rw-
mask::rw-
other::---
前面三個以#開頭的定義了文件名,文件所有者和文件擁有組. 這些信息沒有太大的作用,我
們可以用 –omit-header來省略掉
user::rw- 定義了ACL_USER_OBJ, 說明file owner擁有讀和寫的權限

user:zyq:rw- 定義了ACL_USER,這樣用戶zyq就擁有了對文件的讀寫權限,實現了我們一開始要達到的目的

group::rw- 定義了ACL_GROUP_OBJ,說明文件的group擁有read和write 權限

group: jackuser:rw- 定義了ACL_GROUP,使得jackuser組擁有了對文件的read 和write權限

mask::rw- 定義了ACL_MASK的權限為read and write

other::— 定義了ACL_OTHER的沒有任何權限操作此文件

從這裏我們就可以看出ACL提供了我們可以定義特定用戶和用戶組的功能. 那麽接下來我們就來
看一下如何設置一個文件的ACL

三、 如何設置ACL文件

首先我們還是要講一下設置ACL文件的格式. 從上面的例子中我們可以看到每一個Access Entry都是由三個被:號分隔開的字段所組成. 第一個就是Entry tag type

user 對應了ACL_USER_OBJ和ACL_USER
group 對應了ACL_GROUP_OBJ和ACL_GROUP
mask 對應了ACL_MASK
other 對應了ACL_OTHER
第二個字段稱之為qualifier.也就是上面例子中的zyq和jackuser組.它定義了特定用戶和用戶組,對於文件的權限.這裏我們也可以發現只有user和group才有qualifier,其他的都為空.
第三個字段就是我們熟悉的權限了. 它和Linux的權限一樣定義,這裏就不多講了
下面我們就來看一下怎麽設置test.txt這個文件的ACL讓它來達到我們上面的要求

一開始文件沒有ACL的額外屬性

代碼:

[root@zyq-server data]# ll test.txt
-rw-r--r-- 1 root root 0 12-27 22:55 test.txt
[root@zyq-server data]# getfacl test.txt

file: test.txt

owner: root

group: root

user::rw-
group::r--
other::r--

[root@zyq-server data]# getfacl -c test.txt
user::rw-
group::r--
other::r--
我們先讓用戶zyq擁有對test.txt文件的讀寫權限

代碼:

[root@zyq-server data]# setfacl -m u:zyq:rw test.txt
[root@zyq-server data]# getfacl -c test.txt
user::rw-
user:zyq:rw-
group::r--
mask::rw-
other::r--
這時我們就可以看到zyq用戶在ACL裏面已經擁有了對文件的讀寫權限. 這個時候如果我們
查看一下linux的權限我們還會發現一個不一樣的地方

代碼:

[root@zyq-server data]# ll test.txt
-rw-rw-r--+ 1 root root 0 12-27 22:55 test.txt
在文件權限的最後多了一個+號. 當任何一個文件擁有了ACL_USER或者ACL_GROUP的值以後我
們就可以稱它為ACL文件.這個+號就是用來提示我們的
我們還可以發現當一個文件擁有了ACL_USER或者ACL_GROUP的值時ACL_MASK同時也會被定義

接下來我們來設置jackuser組擁有read 權限

代碼:

[root@zyq-server data]# ll test.txt
-rw-rw-r--+ 1 root root 0 12-27 22:55 test.txt
[root@zyq-server data]#
[root@zyq-server data]# setfacl -m g:jackuser:r test.txt
[root@zyq-server data]# getfacl -c test.txt
user::rw-
user:zyq:rw-
group::r--
group:jackuser:r--
mask::rw-
other::r--

[root@zyq-server data]# ll test.txt
-rw-rw-r--+ 1 root root 0 12-27 22:55 test.txt
到這裏就完成了我們上面講到的要求.是不是很簡單呢

四、ACL_MASK 和 Effective 權限

這裏需要重點講一下ACL_MASK, 因為這是掌握ACL的另一個關鍵,在Linux 文件權限裏面大家都知道比如對於rw-rw-r–來說, 第二組中的那個rw-是指文件組的權限. 但是在ACL裏面這種情況只是在ACL_MASK不存在的情況下成立. 如果文件有ACL_MASK值,那麽當中那個rw-代表的就是mask值而不再是group 權限了

讓我們來看下面這個例子

代碼:

[root@zyq-server data]# ll test.sh
-rwxrw-r-- 1 root family 0 12-27 23:04 test.sh

這裏說明test.sh文件只有file owner: root擁有read, write, execute/search 權限. Family組只有讀和寫的權限。現在我們想讓用戶zyq也對test.sh具有和root一樣的權限。

代碼:

[root@zyq-server data]# setfacl -m u:zyq:rwx test.sh
[root@zyq-server data]# getfacl -c test.sh
user::rwx
user:zyq:rwx
group::rw-
mask::rwx
other::r--
這裏我們看到zyq已經擁有了rwx的權限. mask值也被設定為rwx.那是因為它規定了ACL_USER,ACL_GROUP和ACL_GROUP_OBJ的最大值現在我們再來看test.sh的Linux 權限, 它已經變成了

代碼:

[root@zyq-server data]# ll test.sh
-rwxrwxr--+ 1 root family 0 12-27 23:04 test.sh

那麽如果現在family組的用戶想要執行test.sh的程序會發生什麽情況呢? 它會被權限 deny.原因在於實際上family組的用戶只有讀和寫的權限.這裏當中顯示的rwx是ACL_MASK的值而不是group的權限,所以從這裏我們就可以知道,如果一個文件後面有+標記,我們都需要用getfacl來確認它的權限,以免發生混淆

下面我們再來繼續看一個例子
假如現在我們設置test.sh的mask為read only,那麽family組的用戶還會有write 權限嗎?

代碼:

[root@zyq-server data]# setfacl -m mask::r test.sh
[root@zyq-server data]# getfacl -c test.sh
user::rwx
user:zyq:rwx #effective:r--
group::rw- #effective:r--
mask::r--
other::r--
這時候我們可以看到ACL_USER和ACL_GROUP_OBJ旁邊多了個#effective:r–, 這是什麽意思呢?讓 我們再來回顧一下ACL_MASK的定義. 它規定了ACL_USER, ACL_GROUP_OBJ和ACL_GROUP的最大權限.那麽在我們這個例子中他們的最大權限也就是read only.雖然我們這裏給ACL_USER和ACL_GROUP_OBJ設置了其他權限,但是他們真正有效果的只有read權限.
這時我們再來查看test.sh的Linux 文件權限時它的group 權限也會顯示其mask的值(i.e. r–)

代碼:

[root@zyq-server data]# ll test.sh
-rwxr--r--+ 1 root family 0 12-27 23:04 test.sh

五、 Default ACL

上面我們所有講的都是Access ACL, 也就是對文件而言. 下面我簡單講一下Default ACL. Default ACL是指對於一個目錄進行Default ACL設置,並且在此目錄下建立的文件都將繼承此目錄的ACL.同樣我們來做一個試驗說明比如現在leonard用戶建立了一個dir目錄

代碼:

[root@zyq-server data]$ mkdir mydir
我希望所有在此目錄下建立的文件都可以被smbuser用戶所訪問. 那麽我們就應該對mydir目錄設置Default ACL.我先利用root用戶在/data/創建一個mydir的文件夾,然後將這個文件夾的default user權限設置為smbuser可以rw- 以root身份在mydir目錄下創建一個test.txt的文件。其他的不做限制,然後切換到smbuser。發現smbuser用戶可以修改 test.txt文件中的內容但是無法在mydir目錄中創建和刪除文件/文件夾

代碼:

[root@zyq-server data]# id
uid=0(root) gid=0(root) groups=0(root)
[root@zyq-server data]# ll mydir/
總計 0
[root@zyq-server data]# getfacl mydir/

file: mydir/

owner: root

group: root

user::rwx
group::r-x
other::r-x

[root@zyq-server data]# setfacl -m d:smbuser:rw mydir/
[root@zyq-server data]# getfacl mydir/

file: mydir/

owner: root

group: root

user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:smbuser:rw-
default:group::r-x
default??:rwx
default:other::r-x

[root@zyq-server data]# cd mydir/
[root@zyq-server mydir]# touch test.txt
[root@zyq-server mydir]# su - smbuser
[smbuser@zyq-server ~]$ cd /data/mydir/
[smbuser@zyq-server mydir]$ touch a
touch: 無法創建 “a”: 權限不夠
[smbuser@zyq-server mydir]$ rm test.txt
rm: 無法刪除 “test.txt”: 權限不夠
[smbuser@zyq-server mydir]$ echo hello world>>test.txt
[smbuser@zyq-server mydir]$ cat test.txt
hello world
這裏我們可以看到ACL定義了default選項, smbuser用戶擁有了default的read, write, excute/search 權限.但是卻無法刪除和創建文件。經過試驗,發現還必須將mydir目錄的ACL_USER修改為smbuser後,切換到smbuser用戶才能夠在 mydir目錄中創建和刪除文件/文件夾

[root@zyq-server data]# setfacl -m u:smbuser:rwx mydir/
[root@zyq-server data]# getfacl -c mydir/
user::rwx
user:smbuser:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:smbuser:rw-
default:group::r-x
default??:rwx
default:other::r-x

[root@zyq-server data]# su - smbuser
[smbuser@zyq-server ~]$ cd /data/mydir/
[smbuser@zyq-server mydir]$ touch a
[smbuser@zyq-server mydir]$ ll
總計 4
-rw-rw-r--+ 1 smbuser family 0 12-27 23:43 a
-rw-rw-r--+ 1 root root 19 12-27 23:33 test.txt
[smbuser@zyq-server mydir]$ rm * -rf
[smbuser@zyq-server mydir]$

下面的試驗我們看到在mydir下建立的文件或文件夾都自動的加上了default的權限

[root@zyq-server mydir]# su - smbuser
[smbuser@zyq-server ~]$ cd /data/mydir/
[smbuser@zyq-server mydir]$ ll
總計 0

-rw-rw-r--+ 1 root root 0 12-27 23:48 a
-rw-rw-r--+ 1 root root 0 12-27 23:48 test.tt
[smbuser@zyq-server mydir]$ rm * -rf
[smbuser@zyq-server mydir]$ touch test.txt
[smbuser@zyq-server mydir]$ ll
總計 0

-rw-rw-r--+ 1 smbuser family 0 12-27 23:48 test.txt
[smbuser@zyq-server mydir]$ getfacl -c test.txt
user::rw-
user:smbuser:rw-
group::r-x #effective:r--
mask::rw-
other::r--

[smbuser@zyq-server mydir]$ mkdir smbuserdir
[smbuser@zyq-server mydir]$ getfacl -c smbuserdir/
user::rwx
user:smbuser:rw-
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:smbuser:rw-
default:group::r-x
default??:rwx
default:other::r-x

[smbuser@zyq-server mydir]$ ll
總計 4
drwxrwxr-x+ 2 smbuser family 4096 12-27 23:49 smbuserdir
-rw-rw-r--+ 1 smbuser family 0 12-27 23:48 test.txt
六、 ACL 相關命令

前面的例子中我們都註意到了getfacl命令是用來讀取文件的ACL, setfacl是用來設定文件的Acess ACL. 這裏還有一個chacl是用來改變文件和目錄的Access ACL and Default ACL. 它的具體參數大家可以去看man page. 我只想提及一下chacl -B. 它可以徹底刪除文件或者目錄的ACL屬性(包括Default ACL). 比如你即使用了setfacl -x刪除了所有文件的ACL屬性,那個+號還是會出現在文件的末尾.所以正確的刪除方法應該是用chacl -B.
用cp來復制文件的時候我們現在可以加上-p選項.這樣在拷貝文件的時候也將拷貝文件的ACL屬性.對於不能拷貝的ACL屬性將給出警告.mv命令將會默認地移動文件的ACL屬性. 同樣如果操作不允許的情況下會給出警告

七. 需要註意的幾點

如果你的文件系統不支持ACL的話,你也許需要重新mount你的file system

mount -o remount, acl [mount point]
如果用chmod命令改變Linux 文件權限的時候相應的ACL值也會改變.反之改變ACL的值,相應的文件權限也會改變

八. 參考資料

man acl 個人感覺man page已經講的比較詳細,只是上面名詞比較多看起來會比較繁瑣
http://www.suse.de/~agruen/acl/linux-acls/online/ 如果你英語不錯的話可以看一下這篇關於POSIX ACL的介紹,上面有許多不錯的例子


本文來自 williamchu 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/u010735120/article/details/81094009?utm_source=copy

[kernel]access control lists(ACL)