文件/目錄訪問控制是Linux操作系統安全的重要組成部分。傳統的Linux操作系統支持用戶-用戶組-其它用戶的訪問控制機制,來限定系統用戶對文件/目錄的訪問權限,該機制已經廣泛為用戶所接受和應用。而在實際的使用過程中,用戶意識到在很多應用場景該機制并不能靈活、高效地滿足訪問控制需求,因而自Linux內核2.6版本開始便支持更為靈活的ACL(訪問控制列表)機制。本文將通過實例來詳細介紹這兩種機制的原理及使用。
1、傳統的用戶-用戶組-其他用戶(UGO)訪問控制機制
UGO(user,group,other)模式原理
Linux系統中的每個文件和目錄都有訪問許可權限,通過其確定誰可以通過何種方式對文件和目錄進行訪問和操作。文件或目錄的訪問權限分為只讀,只寫和可執行三種。以文件為例,只讀權限表示只允許讀其內容,而禁止對其做任何的更改操作;只寫權限允許對文件進行任何的修改操作;可執行權限表示允許將該文件作為一個程序執行。文件被創建時,文件所有者自動擁有對該文件的讀、寫和可執行權限,以便于對文件的閱讀和修改。用戶也可根據需要把訪問權限設置為需要的任何組合。
有三種不同類型的用戶可對文件或目錄進行訪問:文件所有者,同組用戶、其他用戶。所有者一般是文件的創建者。它可以允許同組用戶有權訪問文件,還可以將文件的訪問權限賦予系統中的其他用戶。在這種情況下,系統中的每一位用戶都能訪問該用戶擁有的文件或目錄。
每一個文件或目錄的訪問權限都有三組,每組用三位表示,分別為文件屬主的讀、寫和執行權限;與屬主同組的用戶的讀、寫和執行權限;系統中其他用戶的讀、寫和執行權限。當用ls-l命令顯示文件或目錄的詳細信息時,最左邊的一列為文件的訪問權限。例如:
#ls-l
總計76
-rw-------1rootroot79711-0620:41anaconda-ks.cfg
drwxr-xr-x2rootroot409611-0613:50Desktop
-rw-r--r--1rootroot4484311-0620:40install.log
-rw-r--r--1rootroot751311-0620:35install.log.syslog
橫線代表空許可(即表示不具有該權限)。r代表只讀,w代表寫,x代表可執行。注意:這里共有10個位置。第1個字符指定了文件類型。在通常意義上,一個目錄也是一個文件。如果第1個字符是橫線,表示是一個非目錄的文件。如果是d,表示是一個目錄。后面的9個字符每三個構成一組,依次表示文件主、組用戶、其他用戶對該文件的訪問權限。
確定了一個文件的訪問權限后,用戶可以利用Linux系統提供的chmod命令來重新設定不同的訪問權限。也可以利用chown命令來更改某個文件或目錄的所有者。
2、擴展的訪問控制列表(ACL)方式
為什么要采用ACL
UGO訪問控制機制在很多情況下難以滿足實際文件/目錄訪問授權的需求,比如,要設定一個組中的部分用戶對特定的文件/目錄具有讀取和訪問權限(rw-),而另外一部分用戶只能具備讀權限(r--);這在傳統的Linux訪問控制中無法通過單純地建立新的組和用戶來實現。因此,為了解決這些問題,人們提出了一種新的訪問控制方法,也就是訪問控制列表(ACL,AccessControlList)。
ACL是一個POSIX(可移植操作系統接口,PortableOperatingSystemInterface)標準。目前,支持ACL需要內核和文件系統的支持?,F在2.6內核配合EXT2/EXT3,JFS,XFS,ReiserFS等文件系統都是可以支持ACL的。在目前主流的發行套件,如RedHatEnterpriseLinux(RHEL)5、RHEL6、Fedora16等等,都已經支持ACL。
ACL的類型及權限位
ACL是由一系列的AccessEntry所組成的。每一條AccessEntry定義了特定的類別可以對文件擁有的操作權限。AccessEntry主要包括6個,可分為兩大類:一類包括owner、owninggroup和other,對應傳統UGO機制中的user、group和other;一類則包括nameduser、namedgroup和mask。這六類的主要說明如下:
user:相當于Linux里文件所有者的permission
nameduser:定義了額外的用戶可以對此文件擁有的permission
group:相當于Linux里group的permission
namedgroup:定義了額外的組可以對此文件擁有的permission
mask:定義了nameduser,namedgroup和group的最大權限
other:相當于Linux里other的permission
舉個簡單的例子,對于如下的ACLEntry的定義:
#file:example.xml
#owner:liyang
#group:operation
user::rwx
user:shengping:rw-
group::rw-
group:dev:r-x
mask::rwx
other::r—
其中,前面三個以#開頭的定義了文件名、文件的所有者和所有者所在的組。后面緊跟著的六行則說明了如下的問題:
user::rwx說明文件所有者擁有讀寫和執行權限
user:shengping:rw-定義了用戶shengping擁有對文件的讀寫權限
group::rw-說明文件的group擁有讀寫權限
group:dev:r-x定義dev組擁有對文件的讀和執行權限
mask::rwx定義了mask的權限為讀
other::r--定義了other用戶的權限為讀
值得特別注意的是:mask的rwx權限定義,決定了user:shengping,group和group:dev對文件的最大權限分別是rw、rw和rx。這也是mask這個ACLEntry的用途所在,可以用它來批量控制權限。當然,在實際的使用過程中,并不需要用戶對該Entry直接進行操作,而只需要使用相應的setfacl命令即可,系統將會根據該命令的執行來自動生成上述Entry項,這其中就包含了mask這個Entry項。
#p#副標題#e#
ACL的基本命令
ACL的主要命令有2個:getfacl和setfacl。Getfacl用于或取文件或者目錄的ACL權限信息,而setfacl則用于設置文件或者目錄的ACL權限信息。下面分別對他們的使用進行簡單介紹。
Getfacl-獲取ACL權限信息
getfacl命令用于獲取文件的ACL權限信息,其基本用法為:getfacl[文件/目錄名]。
舉個例子,首先,使用touch命令先建立一個測試文件acl_test:
$touchfileacl_test
然后,使用ls命令來查看該文件的權限訪問屬性,發現其并沒有加入acl權限,因為沒有出現“+”符號:
$ls-lacl_test
-rw-rw-r--1gavingavin012-2011:49acl_test
接著,使用getfacl命令來獲取文件的ACL權限信息,得到如下結果:
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rw-
group::rw-
other::r—
值得注意的是:即使該文件系統上沒有開啟ACL選項,getfacl命令仍然可用,不過只顯示默認的文件訪問權限,即與ls-l顯示的內容相似。
Setfacl-設置ACL權限
為了設置文件的ACL權限,需要使用setfacl命令來詳細設置文件的訪問權限,其基本用法如下:
setfacl–[參數][文件/目錄],其常用的參數及作用如下所示:
-m:建立一個ACL規則
-x:刪除一個ACL規則
-b:刪除全部的ACL規則
-set:覆蓋ACL規則
下面來詳細介紹如何使用setfacl來設置文件/目錄的ACL權限。
(1)添加/修改ACL規則
需要使用-m選項來進行操作。
舉個例子,使用該命令為用戶gavin和組test設置acl_test文件的讀寫權限,并使用getfacl查看設置結果:
$setfacl-mu:gavin:rw,g:test:racl_test
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rw-
user:gavin:rw-
group::rw-
group:test:r--
mask::rw-
other::r—
在上面的命令示例中,可以清楚地看到加粗部分user:gavin、group:test、mask這3個ACLEntry的出現,表明對文件進行了ACL權限設置,否則,不會出現該標識。為了進一步驗證,我們使用ls-l來查看該文件的權限位中是否多了“+”這個標識位,如下所示:
$ls-lacl_test
-rw-rw-r--+1gavingavin012-2011:49acl_test
其中,user:gavin、group:test為我們設置的訪問權限,而mask::rw為自動添加的內容。
(2)刪除ACL規則
使用-x選項可以方便地刪除指定用戶對指定文件/目錄的訪問權限。
以下示例刪除用戶gavin對文件acl_test的訪問權限:
$setfacl-xu:gavinacl_test
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rw-
group::rw-
group:test:r--
mask::rw-
other::r--
$ls-lacl_test
-rw-rw-r--+1gavingavin012-2011:49acl_test
通過上述2段ACL權限顯示的對比可以清楚地看到:用戶gavin對于文件acl_test的訪問權限已經完全刪除了,表現為user:gavin:rw-已經不存在了。這里提醒注意的是:我們不能夠通過setfacl命令來指定刪除用戶/組對文件/目錄的某一個特定權限(如r、w或者x)。同時,也可以看到,使用ls-l命令顯示文件的9個權限位還是沒有改變,因為改變的只是ACL權限,而不是最基本的user、group和others權限。
(3)刪除文件/目錄的所有ACL規則
使用-b選項可以刪除文件/目錄的ACL權限。如下命令將刪除文件acl_test的所有ACL權限。可以看到,使用getfacl命令來查看是,mask項已經消失,即該文件已經沒有了所有的ACL權限:
$setfacl-bacl_test
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rw-
group::rw-
other::r—
(4)覆蓋文件的原有ACL規則
需要使用--set選項。此處需要強調一下-m選項和--set選項的區別:-m選項只是修改已有的配置或是新增加一些;而--set選項和-m不同,它會把原有的ACL項全都刪除,并用新的替代。另外,--set選項的參數中一定要包含UGO的設置,不能象-m一樣只是添加ACL就可以了。
以下示例該選項的使用方法:
$setfacl--setu::rw,g::rw,o::r,u:gavin:rwx,g:test:rxacl_test
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rw-
user:gavin:rwx
group::rw-
group:test:r-x
mask::rwx
other::r--
$ls-lacl_test
-rw-rwxr--+1gavingavin012-2011:49acl_test
這里需要提醒注意的是:上述acl_test文件的權限標識位中的group的rwx權限,并不是表明acl_test文件所屬用戶的用戶組對其有x權限,實際上只具有rw權限,而是因為在group:test:r-x中指定了test這個組具有x權限,所以ACL機制在這個標識位上進行了體現,在實際的應用中要特別注意,切記不要弄混淆了。
(5)其他選項
除了上述介紹的4類用法外,setfacl還可以使用如下一些選項,如下表,供大家在實際使用中參考:
為目錄創建默認ACL
在日常的使用過程中,經常是通過對目錄來設定ACL權限來滿足應用的需求,而很少僅僅通過設置特定的文件來實現,因為這樣做比較繁瑣和低效。因此,下面就介紹如何來為目錄創建默認的ACL。
如果希望在一個目錄中新建的文件和目錄都使用同一個預定的ACL,那么我們可以使用默認ACL(DefaultACL)。在對一個目錄設置了默認的ACL以后,每個在目錄中創建的文件都會自動繼承目錄的默認ACL作為自己的ACL。
具體的設置命令為:setfacl-d[目錄名]。
下面的例子對新建的test目錄進行ACL權限設置,并在其中新建了test1和test2文件,來看看默認ACL的設置情況。
首先,對文件夾test進行ACL權限查看如下:
$getfacltest
#file:test
#owner:gavin
#group:gavin
user::rwx
group::rwx
other::r-x
接著,對其進行權限設置如下:
$setfacl-d-mg:test:rtest
$getfacltest
#file:test
#owner:gavin
#group:gavin
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:test:r--
default:mask::rwx
default:other::r-x
可以看到,經過setfacl設置后,該文件夾的權限增加了以default開始的幾項,表明設置成功。
然后,建立兩個新的文件,然后查看他們的ACL權限信息如下:
$touchtest1test2
$getfacltest1
#file:test1
#owner:gavin
#group:gavin
user::rw-
group::rwx#effective:rw-
group:test:r--
mask::rw-
other::r--
$getfacltest2
#file:test2
#owner:gavin
#group:gavin
user::rw-
group::rwx#effective:rw-
group:test:r--
mask::rw-
other::r--
可以清楚地看到:文件test1和test2自動繼承了test設置的ACL。
備份和恢復ACL
目前,Linux系統中的主要的文件操作命令,如cp、mv、ls等都支持ACL。因此,在基本的文件/目錄操作中可以很好地保持文件/目錄的ACL權限。然而,有一些其它的命令,比如tar(文件歸檔)等常見的備份工具是不會保留目錄和文件的ACL信息的。因此,如果希望備份和恢復帶有ACL的文件和目錄,那么可以先把ACL備份到一個文件里,待操作完成以后,則可以使用--restore選項來恢復這個文件/目錄中保存的ACL信息。
下面給出一個具體的例子來進行說明。
(1)獲取文件acl_test的ACL權限
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rwx
user:test:r--
group::---
mask::r--
other::---
(2)將該文件的ACL權限保存至acl_test.acl文件中并進行查看
$getfaclacl_test>acl_test.acl
$catacl_test.acl
#file:acl_test
#owner:gavin
#group:gavin
user::rwx
user:test:r--
group::---
mask::r--
other::---
(3)使用tar命令進行文件操作,并查看生成文件acl.tar的ACL權限,發現其并不具備ACL權限
$tarczvfacl.taracl_test
acl_test
$getfaclacl.tar
#file:acl.tar
#owner:gavin
#group:gavin
user::rw-
group::rw-
other::r--
(4)刪除acl_test文件,并釋放acl.tar,查看其ACL權限,發現經過tar命令后,acl_test文件不在具備第(1)步顯示的任何ACL權限,表明tar命令不能保持文件的ACL權限
$rm-rfacl_test
$tar-xzvfacl.tar
acl_test
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rwx
group::r--
other::---
(5)使用命令從文件恢復acl_test的ACL權限,進行查看,表明成功恢復。
$setfacl--restoreacl_test.acl
$getfaclacl_test
#file:acl_test
#owner:gavin
#group:gavin
user::rwx
user:test:r--
group::---
mask::r--
other::---