權(quán)限抽象
一個(gè)完整的權(quán)限管理體系密似,要有合理的抽象。這里就包括對(duì)用戶葫盼、進(jìn)程残腌、文件、內(nèi)存贫导、系統(tǒng)調(diào)用等抽象废累。下面我將帶你一一了解。
首先脱盲,我們先來(lái)說(shuō)說(shuō)用戶和組。Linux 是一個(gè)多用戶平臺(tái)日缨,允許多個(gè)用戶同時(shí)登錄系統(tǒng)工作钱反。Linux 將用戶抽象成了賬戶,賬戶可以登錄系統(tǒng)匣距,比如通過(guò)輸入登錄名 + 密碼的方式登錄面哥;也可以通過(guò)證書(shū)的方式登錄。
但為了方便分配每個(gè)用戶的權(quán)限毅待,Linux 還支持組 (Group)賬戶尚卫。組賬戶是多個(gè)賬戶的集合,組可以為成員們分配某一類權(quán)限尸红。每個(gè)用戶可以在多個(gè)組吱涉,這樣就可以利用組給用戶快速分配權(quán)限刹泄。
組的概念有點(diǎn)像微信群。一個(gè)用戶可以在多個(gè)群中怎爵。比如某個(gè)組中分配了 10 個(gè)目錄的權(quán)限特石,那么新建用戶的時(shí)候可以將這個(gè)用戶增加到這個(gè)組中,這樣新增的用戶就不必再去一個(gè)個(gè)目錄分配權(quán)限鳖链。
而每一個(gè)微信群都有一個(gè)群主,Root 賬戶也叫作超級(jí)管理員,就相當(dāng)于微信群主音诈,它對(duì)系統(tǒng)有著完全的掌控惕蹄。一個(gè)超級(jí)管理員可以使用系統(tǒng)提供的全部能力。
此外灌侣,Linux 還對(duì)文件進(jìn)行了權(quán)限抽象(注意目錄也是一種文件)推捐。Linux 中一個(gè)文件可以設(shè)置下面 3 種權(quán)限:
1、讀權(quán)限(r):控制讀取文件顶瞳。
2玖姑、寫(xiě)權(quán)限(w):控制寫(xiě)入文件。
3慨菱、執(zhí)行權(quán)限(x):控制將文件執(zhí)行焰络,比如腳本、應(yīng)用程序等符喝。
然后每個(gè)文件又可以從 3 個(gè)維度去配置上述的 3 種權(quán)限:
1闪彼、用戶維度。每個(gè)文件可以所屬 1 個(gè)用戶协饲,用戶維度配置的 rwx 在用戶維度生效畏腕;
2、組維度茉稠。每個(gè)文件可以所屬 1 個(gè)分組描馅,組維度配置的 rwx 在組維度生效;
3而线、全部用戶維度铭污。設(shè)置對(duì)所有用戶的權(quán)限。
因此 Linux 中文件的權(quán)限可以用 9 個(gè)字符膀篮,3 組rwx描述:第一組是用戶權(quán)限嘹狞,第二組是組權(quán)限,第三組是所有用戶的權(quán)限誓竿。然后用-代表沒(méi)有權(quán)限磅网。比如代表所有維度可以讀寫(xiě)執(zhí)行。代表用戶維度不可以執(zhí)行筷屡,組維度不可以讀取涧偷,所有用戶維度不可以寫(xiě)入簸喂。
通常情況下,如果用ls -l查看一個(gè)文件的權(quán)限嫂丙,會(huì)有 10 個(gè)字符娘赴,這是因?yàn)榈谝粋€(gè)字符代表的是文件類型。常見(jiàn)的文件類型有管道文件跟啤、目錄文件诽表、鏈接文件等等。代表普通文件隅肥、代表目錄竿奏、代表管道。
現(xiàn)在思考以下 4 個(gè)問(wèn)題腥放。
1泛啸、文件被創(chuàng)建后,初始的權(quán)限如何設(shè)置秃症?
2候址、需要全部用戶都可以執(zhí)行的指令,比如ls种柑,它們的權(quán)限如何分配岗仑?
3、給一個(gè)文本文件分配了可執(zhí)行權(quán)限會(huì)怎么樣聚请?
4荠雕、可不可以多個(gè)用戶都登錄root,然后只用root賬戶驶赏?
問(wèn)題一:初始權(quán)限問(wèn)題
一個(gè)文件創(chuàng)建后炸卑,文件的所屬用戶會(huì)被設(shè)置成創(chuàng)建文件的用戶。誰(shuí)創(chuàng)建誰(shuí)擁有煤傍,這個(gè)邏輯很順理成章盖文。但是文件的組又是如何分配的呢?
這里 Linux 想到了一個(gè)很好的辦法蚯姆,就是為每個(gè)用戶創(chuàng)建一個(gè)同名分組椅寺。
比如說(shuō)zhang這個(gè)賬戶創(chuàng)建時(shí),會(huì)創(chuàng)建一個(gè)叫作zhang的分組蒋失。zhang登錄之后,工作分組就會(huì)默認(rèn)使用它的同名分組zhang桐玻。如果zhang想要切換工作分組篙挽,可以使用newgrp指令切換到另一個(gè)工作分組。因此镊靴,被創(chuàng)建文件所屬的分組是當(dāng)時(shí)用戶所在的工作分組铣卡,如果沒(méi)有特別設(shè)置链韭,那么就屬于用戶所在的同名分組。
再說(shuō)下文件的權(quán)限如何煮落?文件被創(chuàng)建后的權(quán)限通常是:
rw-rw-r--
也就是用戶敞峭、組維度不可以執(zhí)行,所有用戶可讀蝉仇。
問(wèn)題二:公共執(zhí)行文件的權(quán)限
前面提到過(guò)可以用which指令查看ls指令所在的目錄旋讹,我們發(fā)現(xiàn)在/usr/bin中。然后用ls -l查看ls的權(quán)限轿衔,可以看到下圖所示:
第一個(gè)-代表這是一個(gè)普通文件沉迹,后面的 rwx 代表用戶維度可讀寫(xiě)和執(zhí)行;第二個(gè)r-x代表組維度不可以寫(xiě)害驹;第三個(gè)r-x代表所有用戶可以讀和執(zhí)行鞭呕。后面的兩個(gè)root,第一個(gè)是所屬用戶宛官,第二個(gè)是所屬分組葫松。到這里你可能會(huì)有一個(gè)疑問(wèn):如果一個(gè)文件設(shè)置為不可讀,但是可以執(zhí)行底洗,那么結(jié)果會(huì)怎樣腋么?
答案當(dāng)然是不可以執(zhí)行,無(wú)法讀取文件內(nèi)容自然不可以執(zhí)行枷恕。
問(wèn)題三:執(zhí)行文件
在 Linux 中党晋,如果一個(gè)文件可以被執(zhí)行,則可以直接通過(guò)輸入文件路徑(相對(duì)路徑或絕對(duì)路徑)的方式執(zhí)行徐块。如果想執(zhí)行一個(gè)不可以執(zhí)行的文件未玻,Linux 則會(huì)報(bào)錯(cuò)。
當(dāng)用戶輸入一個(gè)文件名胡控,如果沒(méi)有指定完整路徑扳剿,Linux 就會(huì)在一部分目錄中查找這個(gè)文件。你可以通過(guò)echo $PATH看到 Linux 會(huì)在哪些目錄中查找可執(zhí)行文件昼激,PATH是 Linux 的環(huán)境變量庇绽。
問(wèn)題四:可不可以都 root
最后一個(gè)問(wèn)題是,可不可以都root橙困?
答案當(dāng)然是不行瞧掺!
到這里,用戶和組相關(guān)權(quán)限就介紹完了凡傅。接下來(lái)說(shuō)說(shuō)內(nèi)核和系統(tǒng)調(diào)用權(quán)限辟狈。 內(nèi)核是操作系統(tǒng)連接硬件、提供最核心能力的程序。
內(nèi)核提供操作硬件哼转、磁盤明未、內(nèi)存分頁(yè)、進(jìn)程等最核心的能力壹蔓,并擁有直接操作全部?jī)?nèi)存的權(quán)限趟妥,因此內(nèi)核不能把自己的全部能力都提供給用戶,而且也不能允許用戶通過(guò)shell指令進(jìn)行系統(tǒng)調(diào)用佣蓉。Linux 下內(nèi)核把部分進(jìn)程需要的系統(tǒng)調(diào)用以 C 語(yǔ)言 API 的形式提供出來(lái)披摄。部分系統(tǒng)調(diào)用會(huì)有權(quán)限檢查,比如說(shuō)設(shè)置系統(tǒng)時(shí)間的系統(tǒng)調(diào)用偏螺。
以上我們看到了 Linux 對(duì)系統(tǒng)權(quán)限的抽象行疏。接下來(lái)我們?cè)僬f(shuō)說(shuō)權(quán)限架構(gòu)的思想。
權(quán)限架構(gòu)思想
優(yōu)秀的權(quán)限架構(gòu)主要目標(biāo)是讓系統(tǒng)安全套像、穩(wěn)定且用戶酿联、程序之間相互制約、相互隔離夺巩。這要求權(quán)限系統(tǒng)中的權(quán)限劃分足夠清晰贞让,分配權(quán)限的成本足夠低。
因此柳譬,優(yōu)秀的架構(gòu)喳张,應(yīng)該遵循最小權(quán)限原則(Least Privilege)。權(quán)限設(shè)計(jì)需要保證系統(tǒng)的安全和穩(wěn)定美澳。比如:每一個(gè)成員擁有的權(quán)限應(yīng)該足夠的小销部,每一段特權(quán)程序執(zhí)行的過(guò)程應(yīng)該足夠的短。對(duì)于安全級(jí)別較高的時(shí)候制跟,還需要成員權(quán)限互相牽制舅桩。比如金融領(lǐng)域通常登錄線上數(shù)據(jù)庫(kù)需要兩次登錄,也就是需要兩個(gè)密碼雨膨,分別掌握在兩個(gè)角色手中擂涛。這樣即便一個(gè)成員出了問(wèn)題,也可以保證整個(gè)系統(tǒng)安全聊记。
同樣的撒妈,每個(gè)程序也應(yīng)該減少權(quán)限,比如說(shuō)只擁有少量的目錄讀寫(xiě)權(quán)限排监,只可以進(jìn)行少量的系統(tǒng)調(diào)用狰右。
權(quán)限劃分
此外,權(quán)限架構(gòu)思想還應(yīng)遵循一個(gè)原則舆床,權(quán)限劃分邊界應(yīng)該足夠清晰棋蚌,盡量做到相互隔離。Linux 提供了用戶和分組。當(dāng)然 Linux 沒(méi)有強(qiáng)迫你如何劃分權(quán)限附鸽,這是為了應(yīng)對(duì)更多的場(chǎng)景。通常我們服務(wù)器上重要的應(yīng)用瞒瘸,會(huì)由不同的賬戶執(zhí)行坷备。比如說(shuō) Nginx、Web 服務(wù)器情臭、數(shù)據(jù)庫(kù)不會(huì)執(zhí)行在一個(gè)賬戶下∈〕牛現(xiàn)在隨著容器化技術(shù)的發(fā)展,我們甚至希望每個(gè)應(yīng)用獨(dú)享一個(gè)虛擬的空間俯在,就好像運(yùn)行在一個(gè)單獨(dú)的操作系統(tǒng)中一樣竟秫,讓它們互相不用干擾。
到這里跷乐,你可能會(huì)問(wèn):為什么不用 root 賬戶執(zhí)行程序肥败? 下面我們就來(lái)說(shuō)說(shuō) root 的危害。
舉個(gè)例子愕提,你有一個(gè) Mysql 進(jìn)程執(zhí)行在 root(最大權(quán)限)賬戶上馒稍,如果有黑客攻破了你的 Mysql 服務(wù),獲得了在 Mysql 上執(zhí)行 Sql 的權(quán)限浅侨,那么纽谒,你的整個(gè)系統(tǒng)就都暴露在黑客眼前了。這會(huì)導(dǎo)致非常嚴(yán)重的后果如输。
黑客可以利用 Mysql 的 Copy From Prgram 指令為所欲為鼓黔,比如先備份你的關(guān)鍵文件,然后再刪除他們不见,并要挾你通過(guò)指定賬戶打款澳化。如果執(zhí)行最小權(quán)限原則,那么黑客即便攻破我們的 Mysql 服務(wù)脖祈,他也只能獲得最小的權(quán)限肆捕。當(dāng)然,黑客拿到 Mysql 權(quán)限也是非掣歉撸可怕的慎陵,但是相比拿到所有權(quán)限,這個(gè)損失就小多了喻奥。
分級(jí)保護(hù)
因?yàn)閮?nèi)核可以直接操作內(nèi)存和 CPU席纽,因此非常危險(xiǎn)。驅(qū)動(dòng)程序可以直接控制攝像頭撞蚕、顯示屏等核心設(shè)備润梯,也需要采取安全措施,比如防止惡意應(yīng)用開(kāi)啟攝像頭盜用隱私。通常操作系統(tǒng)都采取一種環(huán)狀的保護(hù)模式
如上圖所示纺铭,內(nèi)核在最里面寇钉,也就是 Ring 0。 應(yīng)用在最外面也就是Ring 3舶赔。驅(qū)動(dòng)在中間扫倡,也就是 Ring 1 和 Ring 2。對(duì)于相鄰的兩個(gè) Ring竟纳,內(nèi)層 Ring 會(huì)擁有較高的權(quán)限撵溃,可以改變外層的 Ring;而外層的 Ring 想要使用內(nèi)層 Ring 的資源時(shí)锥累,會(huì)有專門的程序(或者硬件)進(jìn)行保護(hù)缘挑。
比如說(shuō)一個(gè) Ring3 的應(yīng)用需要使用內(nèi)核,就需要發(fā)送一個(gè)系統(tǒng)調(diào)用給內(nèi)核桶略。這個(gè)系統(tǒng)調(diào)用會(huì)由內(nèi)核進(jìn)行驗(yàn)證语淘,比如驗(yàn)證用戶有沒(méi)有足夠的權(quán)限,以及這個(gè)行為是否安全等等删性。
權(quán)限包圍(Privilege Bracking)
之前我們討論過(guò)亏娜,當(dāng) Mysql 跑在 root 權(quán)限時(shí),如果 Mysql 被攻破蹬挺,整個(gè)機(jī)器就被攻破了维贺。因此我們所有應(yīng)用都不要跑在 root 上。如果所有應(yīng)用都跑在普通賬戶下巴帮,那么就會(huì)有臨時(shí)提升權(quán)限的場(chǎng)景溯泣。比如說(shuō)安裝程序可能需要臨時(shí)擁有管理員權(quán)限,將應(yīng)用裝到/usr/bin目錄下榕茧。
Linux 提供了權(quán)限包圍的能力垃沦。比如一個(gè)應(yīng)用,臨時(shí)需要高級(jí)權(quán)限用押,可以利用交互界面(比如讓用戶輸入 root 賬戶密碼)驗(yàn)證身份肢簿,然后執(zhí)行需要高級(jí)權(quán)限的操作,然后馬上恢復(fù)到普通權(quán)限工作蜻拨。這樣做可以減少應(yīng)用在高級(jí)權(quán)限的時(shí)間池充,并做到專權(quán)專用,防止被惡意程序利用缎讼。
用戶分組指令
上面我們討論了 Linux 權(quán)限的架構(gòu)收夸,接下來(lái)我們學(xué)習(xí)一些具體的指令。
查看
如果想查看當(dāng)前用戶的分組可以使用groups指令血崭。
上面指令列出當(dāng)前用戶的所有分組卧惜。第一個(gè)是同名的主要分組厘灼,后面從adm開(kāi)始是次級(jí)分組。
我先給你介紹兩個(gè)分組咽瓷,其他分組你可以去查資料:
adm 分組用于系統(tǒng)監(jiān)控设凹,比如/var/log中的部分日志就是 adm 分組。
sudo 分組用戶可以通過(guò) sudo 指令提升權(quán)限茅姜。
如果想查看當(dāng)前用戶围来,可以使用id指令,如下所示:
uid 是用戶 id匈睁;
gid 是組 id;
groups 后面是每個(gè)分組和分組的 id桶错。
如果想查看所有的用戶航唆,可以直接看/etc/passwd。
/etc/passwd這個(gè)文件存儲(chǔ)了所有的用戶信息院刁,如下圖所示:
創(chuàng)建用戶
創(chuàng)建用戶用useradd指令糯钙。
sudo useradd foo
sudo 原意是 superuser do,后來(lái)演變成用另一個(gè)用戶的身份去執(zhí)行某個(gè)指令退腥。如果沒(méi)有指定需要 sudo 的用戶任岸,就像上面那樣,就是以超級(jí)管理員的身份狡刘。因?yàn)?useradd 需要管理員身份享潜。這句話執(zhí)行后,會(huì)進(jìn)行權(quán)限提升嗅蔬,并彈出輸入管理員密碼的輸入界面剑按。
創(chuàng)建分組
創(chuàng)建分組用groupadd指令。下面指令創(chuàng)建一個(gè)叫作hello的分組澜术。
sudo groupadd hello
為用戶增加次級(jí)分組
組分成主要分組(Primary Group)和次級(jí)分組(Secondary Group)艺蝴。主要分組只有 1 個(gè),次級(jí)分組可以有多個(gè)鸟废。如果想為用戶添加一個(gè)次級(jí)分組猜敢,可以用usermod指令。下面指令將用戶foo添加到sudo分組盒延,從而foo擁有了sudo的權(quán)限缩擂。
sudo usermod -a -G sudo foo
代表append,代表一個(gè)次級(jí)分組的清單兰英, 最后一個(gè)foo是賬戶名撇叁。
修改用戶主要分組
修改主要分組還是使用usermod指令。只不過(guò)參數(shù)是小寫(xiě)的-g畦贸。
sudo usermod -g somegroup foo
文件權(quán)限管理指令
接下來(lái)我們學(xué)習(xí)文件管理相關(guān)的指令陨闹。
查看
我們可以用ls -l查看文件的權(quán)限楞捂,相關(guān)內(nèi)容在本課時(shí)前面已經(jīng)介紹過(guò)了。
修改文件權(quán)限
可以用chmod修改文件權(quán)限趋厉,chmod( change file mode bits)寨闹,也就是我們之前學(xué)習(xí)的** rwx,只不過(guò) rwx** 在 Linux 中是用三個(gè)連在一起的二進(jìn)制位來(lái)表示君账。
# 設(shè)置foo可以執(zhí)行
chmod +x ./foo
# 不允許foo執(zhí)行
chmod -x ./foo
# 也可以同時(shí)設(shè)置多個(gè)權(quán)限
chmod +rwx ./foo
因?yàn)?strong>rwx在 Linux 中用相鄰的 3 個(gè)位來(lái)表示繁堡。比如說(shuō)111代表,101代表r-x乡数。而rwx總共有三組椭蹄,分別是用戶權(quán)限、組權(quán)限和全部用戶權(quán)限净赴。也就是可以用9 個(gè) 1 代表rwxrwxrwx绳矩。又因?yàn)?img class="math-inline" src="https://math.jianshu.com/math?formula=%5Ccolor%7Bgreen%7D%7B111%7D" alt="\color{green}{111}" mathimg="1">10 進(jìn)制是 7,因此當(dāng)需要一次性設(shè)置用戶權(quán)限玖翅、組權(quán)限和所有用戶權(quán)限的時(shí)候翼馆,我們經(jīng)常用數(shù)字表示。
# 設(shè)置rwxrwxrwx (111111111 -> 777)
chmod 777 ./foo
# 設(shè)置rw-rw-rw-(110110110 -> 666)
chmod 666 ./foo
修改文件所屬用戶
有時(shí)候我們需要修改文件所屬用戶金度,這個(gè)時(shí)候會(huì)使用chown指令应媚。 下面指令修改文件所屬的用戶為。
chown bar ./foo
還有一些情況下猜极,我們需要同時(shí)修改文件所屬的用戶和分組中姜,比如我們想修改的分組位,用戶為跟伏,可以使用:
chown g.u ./foo