POSIX ACL详解
一、 為什么要使用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包
代碼:
如果配置好了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:mask::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:mask::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:mask::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的介紹,上面有許多不錯的例子
總結
以上是生活随笔為你收集整理的POSIX ACL详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云旺即时通信OpenIM(一)基础学
- 下一篇: 记录一次玩客云安装homeassiste