我們口中的操作系統,一般指的是:一個操作系統核心+各種擴展應用程序。但從專業的角度來講,操作系統就是那個核心(通常稱之為內核),就是將底層硬件進行抽象和虛擬化,並向使用者提供各種功能接口的軟件程序。這是一種非常特殊的軟件程序,它的特殊之處就在於:操作系統是使用者運行其他應用程序的底層軟件基礎,也是硬件功能被集中管理和調用的統一接口。它向上層隱藏了硬件結構的丑陋和不易操作,使得使用者在使用計算機時變得更加簡單;向下層屏蔽了底層硬件無法理解的使用者發出的復雜指令,將其翻譯成二進制序列,使得硬件可以更加快捷的予以執行。
Linux內核,從它誕生的那天開始,變表現出極強的生命力,源自於UNIX的很多的哲學思想被沿用在Linux中。一切皆文件!多麼簡單但卻又復雜的一句話。說它簡單,是因為對於用戶來講,每一個系統的資源,包括各種硬件(磁盤、內存、網絡等)和軟件都是以一種可訪問甚至是可編輯可修改的文件的方式來展現,用戶不必再去思考底層的技術了;說它復雜,是因為這種抽象和虛擬是在大量的驅動程序和數以百計的接口函數的支撐下得以完成的。
在這樣的一套系統中,使用者可以用自己掌握的自然語言向計算機發號施令,而計算機也會非常忠誠地予以執行,無論成功與否。這種簡化給使用者帶來了極大的便利,但也同時會給計算機帶來很多的安全問題。比如說:誰能在什麼時間對什麼文件進行什麼操作?結果如何,成功還是失敗?如果成功會有怎樣的影響?如果失敗,是否會予以記錄?……等等。
安全秘笈第一式——自主訪問控制(DAC)
要知道,在操作系統出現之初,是沒有用戶的概念的,那個時候每個使用者都會在獲得計算機使用權時,將自己所攜帶的鍵盤及顯示器等設備連接到計算機所提供的某個接口上,這些設備被統一的稱為“終端設備”。只要使用者將這些設備接入,即可使用計算機的各種資源。而且計算機的資源是公共的,不屬於任何人的。一開始,資源充足,大家相安無事;但是隨著使用者數量的增加,資源卻沒有本質的變化,從而必然會導致資源危機。這個時候,就會出現資源競爭的問題了。每個人都企圖占用更多的CPU計算時間,占用更多的內存空間,設置後來磁盤存儲介質發明之後,這樣的外部存儲空間也成為競爭極為激烈的一種資源。甚至到了後來,這種競爭變得極其的殘酷。那麼,會不會有某些使用者在不經其他使用者同意的情況下,將其他使用者的數據修改或刪除,或者將其他使用者正在運行的程序強行終止呢?因為通過這種方式可以很直接的獲取到很多的可用資源。而在整個過程中,操作者是這個操作的主體,即使其操作不當也不會有任何的懲罰,全靠其自身的道德規范來約束,但有時這種約束顯得螳臂擋車,毫無力度可言。操作系統的開發和維護人員很顯然想到了這個問題,所以,為了防止這樣的惡性事件的發生,他們在操作系統中給每個用戶定義了一個身份,只有使用以這個身份來接受系統的認證,已確定使用者的合法性。在文件系統出現之後,定義了使用者所對應的用戶身份對於各種資源的訪問權限,只有滿足權限要求才能繼續使用計算機的資源。於是這樣一來,用戶能否完成某個操作,不取決於使用者本身是怎麼樣的社會角色,而是使用者在計算機中的身份映射——用戶,能不能完成對資源的訪問以及後續的如刪除、修改等操作。後來我們把這種資源管理的機制稱為自主訪問控制(DAC,Discretionary Access Control)。那麼,什麼是DAC呢?
DAC主要的內容包括以下幾個概念:主體、客體、權限(rwx)、所有權(ugo)。
在這個模型中,主體是用戶的身份,客體是資源或者說是文件(切記:一切皆文件)。由客體的屬主對自己的客體進行管理,由主體自己決定是否將自己的客體訪問權限或部分訪問權限授予其他主體,這種控制方式是自主的。也就是說,在自主訪問控制下,用戶可以按自己的意願,有選擇地與其他用戶共享他的文件。
DAC是一種相對比較寬松但是卻很有效的保護資源不被非法訪問和使用的手段。說它寬松,是因為他是自主控制的,在保護資源的時候是以個人意志為轉移的;說它有效,是因為可以明確的顯式的指出主體在訪問或使用某個客體時究竟是以何種權限來實施的,任何超越規定權限的訪問行為都會被訪問控制列表判定後而被阻止。
接下來我們來看看DAC到底是怎麼工作的。但是,我們需要了解一個前提,我們需要知道這樣的一個問題:在訪問客體資源的時候,並不是使用者進入到計算機中,以主體的身份來完成這樣的訪問工作。每當我們需要使用計算機系統資源的時候,我們都需要去打開一個應用程序,在操作系統中,我們可以把這樣的已經被啟動並加載至內存中的應用程序稱為進程。但是,不管是應用程序還是要訪問的文件資源,都是存儲在外部存儲設備中的數據,想要定位和查找他們,就必須依靠文件系統才能實現。這個時候,文件系統所規定的權限就會生效了。
因此,我們所定義的DAC系統有兩個至關重要的標准:
1.文件的所有權:系統中的每個文件(一些特殊文件可能沒有,如塊設備文件等)都有所有者。在DAC系統中,文件的所有者是創建這個文件的計算機的使用者(或事件,或另一個文件)。那麼此文件的自主訪問控制權限由它的創建者來決定如何設置和分配;
2.訪問權限:文件的所有者擁有訪問權限,並且可以將訪問權限分配給自己及其他用戶。
上述兩個標准說明:
1.文件的所有權的優先級高於訪問權限
1)文件的所有者即便沒有任何權限,也可以在為自己分配權限之後獲得訪問文件的能力。
2)非文件的所有者即便已經獲得了訪問權限,也可能會被所有者隨時收回,從而導致無權訪問該文件。
2.權限是文件訪問的關鍵
1)無論是不是文件的所有者,關系到使用者能否訪問文件的最直接的因素是其所對應的用戶是否獲得了可訪問該文件的權限
2)使用者被分配的何種權限,就只能以該權限所規定的操作來訪問文件,無法越權。
那麼所有權和權限是如何規定和標識的呢?
在Linux所支持的默認的文件系統(早期的是ext系列,後來是xfs)中,所有權被分成三類,即:文件的擁有者,文件的所屬組,其他人
1.文件的擁有者:也稱為屬主,標記為u,默認情況下,創建文件的用戶就是其屬主;
2.文件的所屬組:也稱為屬組,標記為g,除了屬主之外,還可以被哪些用戶共同擁有。由於這樣的用戶可能不止一個,所以不方便用某個用戶名來標識,因此以組的方式來標識。
3.其他人:標記為o,除了文件的屬主和屬組之外的其他所有使用者的統稱。
在在Linux所支持的默認的文件系統(早期的是ext系列,後來是xfs)中,權限被分成三種,即:讀權限,寫權限,執行權限
1.讀權限:
1)對於目錄來說,擁有讀權限的用戶可以浏覽該目錄中的文件名;如果同時擁有執行權限,則該用戶可以查看目錄的元數據,目錄中的文件名及這些文件的元數據信息。
2)對於非目錄文件來說,擁有讀權限的用戶在對存放該文件的目錄有讀權限和執行權限的前提下可以查看該文件的內容。
2.寫權限:
1)對於目錄來說,擁有寫權限的用戶必須要同時擁有執行權限,才可以在該目錄中新建、修改和刪除文件名
2)對於非目錄文件來說,擁有寫權限的用戶在對存放該文件的目錄有讀權限和執行權限的前提下可以在該文件的末尾追加內容;如果想要修改和刪除該文件內容,必須同時擁有讀權限
3.執行權限:
1)對於目錄來說,執行權限是最最基本的權限了。擁有執行權限的用戶可以在路徑表示中引用此目錄,並且如果該用戶同時擁有讀權限,便可以進入到此目錄中,可以查看目錄的元數據。
2)對於非目錄的文件來說,擁有執行權限的用戶可以將此文件當作命令來執行,也就是說可以把這個文件直接載入內存,讓其運行起來成為進程或者通過其他的解釋工具將他裡面保存的命令、語句解釋出來並執行。在ext系列和xfs文件系統中,對於非目錄文件的執行權限限制還是非常大的。除非用戶明確為之分配,否則系統絕不會為這些非目錄文件添加執行權限的。
請看下面的例子:
[root@localhost~]#mkdir/test
[root@localhost~]#chmod744/test
[root@localhost~]#echo"Iamroot">/test/a.txt
以root用戶的身份在根目錄下創建名為test的目錄,將其權限設置為744,並在目錄中創建名為a.txt的空文件,查看其權限如下:
[root@localhost~]#ls-ld/test
drwxr--r--2rootroot18Jun1517:14/test
[root@localhost~]#ls-l/test
total0
-rw-r--r--1rootroot0Jun1516:53a.txt
下面換用一個非root組的普通用戶zhao來進行測試(注意/test目錄的其他人位置沒有執行權限):
[zhao@localhost~]$ls/test
ls:cannotaccess/test/a.txt:Permissiondenied
a.txt
[zhao@localhost~]$stat/test
File:‘/test’
Size:18Blocks:0IOBlock:4096directory
Device:802h/2050dInode:550Links:2
Access:(0744/drwxr--r--)Uid:(0/root)Gid:(0/root)
Access:2016-07-0216:23:04.786001145+0800
Modify:2016-07-0216:23:17.265001996+0800
Change:2016-07-0216:23:17.265001996+0800
Birth:-
[zhao@localhost~]$ls/test/a.txt
ls:cannotaccess/test/a.txt:Permissiondenied
[zhao@localhost~]$stat/test/a.txt
stat:cannotstat‘/test/a.txt’:Permissiondenied
[zhao@localhost~]$ls-l/test
ls:cannotaccess/test/a.txt:Permissiondenied
total0
???????????????a.txt
之所以會有這樣的結果,完全和/test目錄上對其他人沒有執行權限有關。如果加上執行權限,其結果為:
[root@localhost~]#chmod745/test
[root@localhost~]#su-zhao
Lastlogin:WedJun1517:17:19CST2016onpts/0
[zhao@localhost~]$ls/test
a.txt
[zhao@localhost~]$ls-l/test
total0
-rw-r--r--1rootroot0Jun1516:53a.txt
[zhao@localhost~]$stat/test
File:‘/test’
Size:18Blocks:0IOBlock:4096directory
Device:802h/2050dInode:550Links:2
Access:(0745/drwxr--r-x)Uid:(0/root)Gid:(0/root)
Access:2016-07-0216:23:04.786001145+0800
Modify:2016-07-0216:23:17.265001996+0800
Change:2016-07-0216:24:16.761006056+0800
Birth:-
[zhao@localhost~]$stat/test/a.txt
File:‘/test/a.txt’
Size:0Blocks:0IOBlock:4096regularemptyfile
Device:802h/2050dInode:34455Links:1
Access:(0644/-rw-r--r--)Uid:(0/root)Gid:(0/root)
Access:2016-07-0216:23:17.265001996+0800
Modify:2016-07-0216:23:17.265001996+0800
Change:2016-07-0216:23:17.265001996+0800
Birth:-
這樣設置以後,就不會再有錯誤報告了。
同樣的,我們再來一組實驗:
[root@localhost~]#chmod752/test
[root@localhost~]#su-zhao
Lastlogin:SatJul216:24:18CST2016onpts/0
[zhao@localhost~]$>/test/zhao.txt
-bash:/test/zhao.txt:Permissiondenied
按照大家的理解,只有有寫權限就能創建文件的,但是事實確是這樣的。原因很簡單,/test目錄上對其他人沒有執行權限,因此/test目錄的文件名就不能被zhao用戶在使用路徑時引用。即使有寫權限,又能怎樣!
[root@localhost~]#chmod753/test
[root@localhost~]#su-zhao
Lastlogin:SatJul216:31:02CST2016onpts/0
[zhao@localhost~]$>/test/zhao.txt
在其他人的權限位上增加了執行權限之後,結果成功了,原因如上。我們繼續實驗:
[zhao@localhost~]$ls/test
ls:cannotopendirectory/test:Permissiondenied
[zhao@localhost~]$stat/test
File:‘/test’
Size:33Blocks:0IOBlock:4096directory
Device:802h/2050dInode:550Links:2
Access:(0753/drwxr-x-wx)Uid:(0/root)Gid:(0/root)
Access:2016-07-0216:23:04.786001145+0800
Modify:2016-07-0216:32:24.216039314+0800
Change:2016-07-0216:32:24.216039314+0800
Birth:-
有趣的事情來了,我們無法看到/test目錄中的內容,但是卻能看到它的元數據哦。下面還有其他有趣的事情:
[zhao@localhost~]$ls/test
ls:cannotopendirectory/test:Permissiondenied
[zhao@localhost~]$ls-l/test
ls:cannotopendirectory/test:Permissiondenied
[zhao@localhost~]$echozhao>/test/zhao.txt
[zhao@localhost~]$cat/test/zhao.txt
zhao
[zhao@localhost~]$ls-l/test/zhao.txt
-rw-r--r--1zhaozhao5Jul216:34/test/zhao.txt
[zhao@localhost~]$stat/test/zhao.txt
File:‘/test/zhao.txt’
Size:5Blocks:8IOBlock:4096regularfile
Device:802h/2050dInode:11282Links:1
Access:(0644/-rw-r--r--)Uid:(1000/zhao)Gid:(1000/zhao)
Access:2016-07-0216:32:24.216039314+0800
Modify:2016-07-0216:34:42.186048728+0800
Change:2016-07-0216:34:42.186048728+0800
Birth:-
對目錄沒有讀權限,所以無法看到其中的文件名;但是可以看到其中zhao用戶自己創建的文件的中寫入數據,並且能夠查看其內容及元數據。
相信看了這些例子以後,大家應該可以明白一點這些權限的在文件系統中的作用了。那我們接下來繼續。
[root@localhost~]#chmod756/test
[root@localhost~]#ls-ld/test
drwxr-xrw-2rootroot33Jul216:32/test
[root@localhost~]#su-zhao
Lastlogin:SatJul216:32:22CST2016onpts/0
[zhao@localhost~]$cd/test
-bash:cd:/test:Permissiondenied
[zhao@localhost~]$ls-l/test
ls:cannotaccess/test/a.txt:Permissiondenied
ls:cannotaccess/test/zhao.txt:Permissiondenied
total0
???????????????a.txt
???????????????zhao.txt
[zhao@localhost~]$rm-f/test/zhao.txt
rm:cannotremove‘/test/zhao.txt’:Permissiondenied
[zhao@localhost~]$>/test/zhao2.txt
-bash:/test/zhao2.txt:Permissiondenied
看到了麼?其他人的位置上除了一個執行權限,其他都有了,然而,結果是無法查看文件的一般屬性,無法刪除目錄中已有的文件,也無法在其中創建新的文件。誠然,擁有寫權限的用戶確實能夠完成文件名的創建、刪除、和修改,但用戶既不能進入到目錄中,也不允許在書寫路徑時引用這個目錄名稱,因此即便你有寫權限又當如何。
總的來說,執行權限是目錄的最基本權限,所以,大家在ext系列或者xfs文件系統中創建出來的新目錄,一般都會有執行權限的。大多數都是755的權限,有些是700的權限,但不管如何,確保目錄的權限中有執行權限是訪問目錄和使用目錄的基礎。
接下來,我們繼續說權限。假設有一個目錄的權限被設置為:
[root@localhost~]#chmod777/test
[root@localhost~]#ls-ld/test
drwxrwxrwx3rootroot44Jul217:00/test
[root@localhost~]#ls-l/test
total8
-rw-r--r--1rootroot10Jul217:00a.txt
drwxr-xr-x2rootroot6Jul217:00root
-rw-r--r--1zhaozhao5Jul216:34zhao.txt
小伙伴們對這樣的權限設置作何感想呢?
請大家思考一個問題:作為一個普通的用戶wang來講,能不能在a.txt文件中添加內容?能不能把a.txt的內容清空或者酌情添加些內容呢?答案就是看情況咯。
請大家再思考要給問題:作為一個普通的用戶wang來講,能不能把a.txt這個文件名給刪除了?能不能把a.txt這個文件的名字改為wang.txt?先別著急回答,仔細想一想再說。好了,現在公布答案,那就是:當然可以。
如下例子所示:
[wang@localhost~]$echowang>/test/a.txt
-bash:/test/a.txt:Permissiondenied
[wang@localhost~]$vim/test/a.txt
Iamroot
~
~
~
~
~
"/test/a.txt"[readonly]1L,10C
請注意擴展編輯模式(有人稱之為末行模式,我以前也這麼叫)中顯示的“readonly”,明確的告訴你那是只讀的。如果你很任性的進入了插入模式則會有這樣的信息:
Iamroot
~
~
~
~
~
--INSERT--W10:Warning:Changingareadonlyfile
當然,接下來你仍然可以很任性的去修改,只是在你保存的時候,回事這樣的提示:
Iamwang
~
~
~
~
~
E45:'readonly'optionisset(add!tooverride)
而事實上,如果你在保存的時候綴加了“!”以表示你要強制保存的決心,那麼操作的最終結果是:成功!這個操作大家可以自行測試。
我們再來試試改名和刪除文件的操作:
[wang@localhost~]$mv/test/a.txt/test/wang.txt
[wang@localhost~]$ls-l/test
total8
drwxr-xr-x2rootroot6Jul217:00root
-rw-r--r--1wangwang10Jul217:24wang.txt
-rw-r--r--1zhaozhao5Jul216:34zhao.txt
[wang@localhost~]$rm-rf/test/root
[wang@localhost~]$ls-l/test
total8
-rw-r--r--1wangwang10Jul217:24wang.txt
-rw-r--r--1zhaozhao5Jul216:34zhao.txt
看起來非常的順利就完成了。即便是root用戶創建的目錄和文件,說改就改,說刪就刪,完全不去理會root受得了受不了。
以上的操作能夠成功,說明對其他人來講,在目錄上有rwx的權限還是非常危險的,所以大家切記,目錄上的權限默認就是除了屬主之外的權限保持為r-x就好,如果再此基礎上增加了w權限,會帶來很多莫名其妙的結果,徒增煩惱啊。
為了免除這樣的煩惱,我們有提出了很多的補救措施。比如,給其他人的權限位上加上一個粘滯位“t”,那麼每個用戶就只能修改和刪除那些屬主為自己的文件了,甚至連剛剛的強制保存都無法做到了。至於其他的兩個特殊權限SUID和SGID,相信大家也能夠搞明白了,那個並不復雜。
然而,在眾多的主體中,有一個主體是個例外,他就是大名鼎鼎的root,作為系統管理員,可以凌駕於DAC之上。它是唯一一個不受DAC權限控制的用戶。看下面的例子:
[root@localhost~]#chmod-R000/test
[root@localhost~]#mkdir/test/root
[root@localhost~]#echo"Iamroot">/test/a.txt
[root@localhost~]#ls-l/test
total4
----------1rootroot10Jul217:00a.txt
drwxr-xr-x2rootroot6Jul217:00root
----------1zhaozhao5Jul216:34zhao.txt
看到了吧,這個就是無敵的root,強大的root。以至於被大家認為它就是系統中的神一樣的存在!所以一大波有計劃有組織的破解root的行動就此展開。如果成功,瞬間封王;如果不成,那就繼續呗。
我們舉一個例子來說明一下:
假如我們在傳統的DAC的控制模式下,使用普通用戶zhao登錄到系統,以這樣的普通用戶的身份想要使用下面的命令來創建一個文件
[zhao@localhost~]$id
uid=1000(zhao)gid=1000(zhao)groups=1000(zhao)
[zhao@localhost~]$mkdir/test/test
那麼請大家思考一下,這樣的操作是如何完成的呢?使用者進入到計算機中親自完成的麼?顯然不可能是。使用者僅僅是完成了這個命令中的字符串的鍵入而已。剩下的就是等待結果罷了。
那麼這個創建目錄的過程到底是怎麼完成的呢?
首先,shell將命令行展開,根據空白字符,將整行分割成單個字,識別出mkdir並欲將其作為命令來處理;接下來就是判斷這個命令是shell內置的命令還是外部命令了。
[zhao@localhost~]$typemkdir
mkdiris/bin/mkdir
[zhao@localhost~]$ls-l/bin/mkdir
-rwxr-xr-x.1rootroot79720Nov202015/bin/mkdir
經過判斷,mkdir並非內置命令,於是通過在用戶登錄時定義好的PATH變量來定位mkdir命令所對應的二進制文件的路徑,而後需要在外部存儲器上找到並嘗試將以mkdir為名的可執行的二進制文件啟動為進程。在真正的執行該文件之前,文件系統會參照/bin/mkdir文件的訪問權限來判斷zhao用戶是否有啟動執行此文件的權限。幸運的是在該文件的其他人的權限位上,明顯有一個執行權限,而對於這個文件來講,zhao用戶也屬於其他人的范圍。但這沒關系,因為zhao用戶已經具備了啟動mkdir進程的基本條件,於是文件/bin/mkdir被加載到內存中,系統進一步將mkdir進程的屬主和數組標識為zhao用戶及zhao用戶的主要組zhao組。
然後,由mkdir進程繼續後面的工作。依靠內核中的文件系統,在指定的路徑(也就是/test目錄)中查找是否有一個名為test的目錄文件,如果已經存在,mkdir進程報告錯誤並退出執行;如果不存在,再檢查/test目錄的權限設置,查看zhao用戶在此目錄中是否具有寫權限和執行權限,如下所示:
[zhao@localhost~]$ls-ld/test
drwxr-xr-x2rootroot6Jun1514:52/test
從該目錄的權限設定來看,屬於其他認的zhao用戶是不具有寫操作的權限的,因此zhao用戶不管使用哪個進程發起的寫操作,都會被拒絕。
[zhao@localhost~]$touch/test/zhao
touch:cannottouch‘/test/zhao’:Permissiondenied
如果想要zhao用戶可以創建這個目錄文件,必須給予zhao用戶對目錄/test的寫權限和執行權限,可以修改其他人位置的權限,也可以實用facl單獨為zhao用戶設置權限。
方案一:
[root@localhost~]#chmod757/test
[root@localhost~]#ls-ld/test
drwxr-xrwx2rootroot6Jun1514:52/test
方案二:
[root@localhost~]#getfacl/test
getfacl:Removingleading'/'fromabsolutepathnames
#file:test
#owner:root
#group:root
user::rwx
user:zhao:rwx
group::r-x
mask::rwx
other::r-x
這樣就可以讓zhao用戶獲得在此目錄中創建、修改、刪除文件名等寫操作了,並且在創建該目錄的同時設置這個目錄文件的所有權和訪問權限。所有權的設定很簡單,創建這個目錄文件的用戶賬戶zhao即為此目錄文件的屬主;創建這個目錄文件的用戶賬戶zhao的基本組zhao即為此目錄文件的屬組。訪問權限的設定要根據系統中設置的umask(權限遮罩碼)進行設定即可,即:從rwx的權限中刪除在umask中明確排除的權限。
DAC的內容就寫這麼多吧。