特殊權限

1.1 SUID

談到SUID不得不說進程的安全上下文,那麼何爲進程的安全上下文?在我看來,進程的安全上下文應該分成上文和下文。

我們先來談談進程安全的上文,我們都明白,用戶有是權限的,命令或者所有的文件和目錄(在linux當中目錄實際上也是一個文件哦!)也是有權限的,文件的權限我們可以很直觀的通過ls命令看到:

[user1@A ~]$ ls -l /etc/passwd   #一個配置文件的權限

-rw-r--r--. 1 root root 2466 9月   9 19:35 /etc/passwd

 [user1@A ~]$ ls -ld /etc         #一個目錄的權限

drwxr-xr-x. 141 root root 8192 9月   9 19:36 /etc

[user1@A ~]$ ll `which cat`          #一個命令或者說是一個二進制程序文件的權限

-rwsr-xr-x. 1 root root 54080 11月  6 2016 /bin/cat

那麼用戶的權限怎樣理解和查看呢?剛開始我雖然接受了用戶是有權限的理論,但是實際上並不完全理解,也不知道去哪裏查看用戶有哪些權限,後來學習的時候長一點兒的時候,忽然想明白了,linux把用戶分類、分組實際就是一個權限的管理呀!!我們使用id命令查看一個用戶的時候顯示的信息其實就是用戶的權限。

[user1@A ~]$ id root ; id zhanghe

uid=0(root) gid=0(root) 組=0(root)

uid=1000(zhanghe) gid=1000(zhanghe) 組=1000(zhanghe),10(wheel)

好了,終於把用戶和文件的權限給說完了,可是這僅僅是一小步而已,距離把進程的安全的上文說明白還早呢!!繼續吧。我們在上面知道了用戶和文件(包括命令的二進制文件、正經文件、目錄) 都是有權限的。那麼當一個用戶使用cat命令訪問一個文件的時候,操作系統內部的權限動作是怎樣的呢?正面我們就以一個最常用的案例來說明:

[user1@A ~]$ cat /etc/shadow

那麼我們就來分析分析一個普通用戶cat  /etc/shadow時操作系統內部的權限運作:當我們在終端當中的bash當中輸入cat /etc/shadow時,bash會對cat /etc/shadow這一段字符串進行分析,首先bash根據空格分析出哪一段是命令部分和參數部分,然後根據PATH環境變量分析出命令的部分是否正確,能在PATH變量當中查找到的就是認爲正確的,如果bash沒有在PATH變量當中沒有找到命令部分的話就返回”command not found……”,就像下面這樣:

[user1@A ~]$ dkjg   #這是隨便輸入的

bash: dkjg: command not found...

接下來,user1用戶就會根據PATH變量的路徑找到cat命令對應的二進制文件位置。cat二進制文件“感受“到有用戶來訪問自己,就會根據自己inode文件當中記錄的權限,首先覈對一下來訪問自己是不是屬主,如果是屬主的話就按照屬主的權限來運行,如果不是屬主那就覈對一下來訪問自己的這個用戶有沒有在屬組裏面,如果在屬組裏面話,就按照屬組的權限進行運行,如果來訪問即不是屬主,也沒有包含在屬組裏面的話,那麼就按照其他人的權限進行運行。無論按照哪個權限,只要是運行起來之後,這個原本靜態的程序就變成了動態的進程,並且這個進程也是帶有權限的,注意!注意!!注意!!!cat進程所攜帶的權限與原本的cat二進制程序文件的權限一毛錢的關係也沒有,這個動態的、運行當中的進程所攜帶的權限是將其運行起來的那個用戶的權限,也就是說如果是user1用戶運行的cat命令,那麼cat進程所攜帶的權限就是user1所攜帶的權限。

到此,進程的安全上下文當中的上文就寫完了。

再補充一點知識之後再講進程安全上下文當中的下文部分。

如果你命令部分輸入正確了,但是參數部分你是胡亂輸入的話,那麼bash是不會去判斷你參數部分是不是輸入正確,你可能可以疑惑了,命令部分正確的輸入 ,但是參數部分胡亂輸入的話也是會報錯的呀?沒錯,這樣同樣也會報錯:“No such file or directory”,但是請你仔細看看,報錯並不是bash這個程序,而是你輸入的命令報錯的,就像下面這樣:

[user1@A ~]$ cd oiejg

-bash: cd: oiejg: No such file or directory   #真正報錯是cd這個命令,而不是bash程序。

再說的詳細一點,當用戶運行cat時,bash會在PATH變量當中找到cat對應二進制文件的絕對路徑(/bin/cat),提交給內核,內核會根據其路徑找到真正的cat命令在硬件當中的地址,然後把cat從硬件當中調用到內核當中的內核空間,然後再給cat進程分配真正在用戶空間的地址,接下來把cat進程放入到內存的的用戶空間,所以說真正的IO其實是兩個步驟。

好了,下面再說一下進程安全上下文當中的下文部分。

在上文我們講到了進程攜帶的權限其實是運行者的權限,所以當user1運行cat /etc/passwd的時,cat進程所攜帶的權限就是user1用戶的權限,然後cat進程再去訪問/etc/passwd,同樣的,passwd文件也是會根據inode當中記錄的權限對來訪問的進程進行權限覈對,發現user1不是passwd的屬主,也沒有在root組裏面(passwd文件的屬主和屬組默認都是root),就按照其他人的權限訪問(只讀權限),所以普通用戶user1就成功用cat命令查看到了passwd裏面的內容。

終於,終於把進程的安全上下文講完了,解釋起來有點麻煩,但是如果明白了之後,其實挺簡單的!進程安全上下文其實是爲解釋SUID做鋪墊的,當您理解了進程的安全上下文之後再去理解SUID也變得非常的簡單了,其實一句話就可以了:“所謂的SUID其實就是打破了進程安全上下文當中的上文”。那麼是怎樣打破的呢?

當user1去執行cat /etc/passwd的時候,cat進程攜帶的權限其實是user1的權限,但是如果如果給cat賦予了SUID權限的話,那麼user1再運行cat命令的時候,一旦運行起來了之後,cat進程所攜帶的權限就是cat二進制文件的權限,cat自己的權限屬主和屬組都是root,也就是說cat進程所攜帶的權限不是user1的權限了,而是root的權限,所以說所謂的SUID就是打破了進程安全上下文當中的上文。其實給一個命令SUID權限是非常危險的,爲什麼呢?

[root@A ~]# su - user1 -c "cat /etc/shadow"   #原本user1沒有權限查看/etc/shadow

cat: /etc/shadow: 權限不夠

[root@A ~]# chmod u+s `which cat`    #給cat二進制文件加上SUID權限

[root@A ~]# su - user1 -c "cat /etc/shadow"  #然後user1再查看shadow文件,成功了!!

bin:*:15980:0:99999:7:::

daemon:*:15980:0:99999:7:::

adm:*:15980:0:99999:7:::

所以說輕易不要給命令賦予SUID權限,其實系統當中一個現在的有SUID權限的命令就是passwd:

[user1@A ~]$ ll `which passwd`

-rwsr-xr-x. 1 root root 30768 11月 24 2015 /usr/bin/passwd

這個命令普通用戶在使用的時候也會暫時獲取root的權限,可能你又疑惑了,如果普通用戶運行passwd命令有root的權限,豈不是普通用戶想修改誰的密碼就修改誰的密碼嗎?其實我們用腿想一下就知道了,linux做爲一款優秀成熟的操作系統肯定不會出這樣重大的漏洞的,那麼是怎樣解決這個問題的呢?其實在內核代碼就已經做了規定,普通用戶使用passwd命令的時候是不允許攜帶任何參數的,只能赤裸裸的使用passwd命令修改自己的密碼,就像下面演示的一樣,

[user1@A ~]$ passwd root  #user1想去修改root的密碼

passwd: Only root can specify a user name.   #只有根用戶才能指定用戶名稱。

 

好了,到此,SUID就講完了,那麼來一遍完整的演示:

 [root@A ~]# ll `which cat`

-rwxr-xr-x. 1 root root 54080 11月  6 2016 /usr/bin/cat

[root@A ~]# su - user1 -c "cat /etc/shadow"

cat: /etc/shadow: 權限不夠

[root@A ~]# chmod u+s `which cat`

[root@A ~]# su - user1 -c "cat /etc/shadow"

bin:*:17110:0:99999:7:::

daemon:*:17110:0:99999:7:::

抽象理解

進程的安全上下文就像“一把普通菜刀”,這把菜刀有多大的權利取決於誰拿着這把菜刀!皇帝(root)可以殺所有人,甚至可以自殺;普通百姓拿着這把菜刀權利就小的很,只能搞搞與自己相關的東西。

suid就像“尚方寶劍”,這把寶劍有多大的權利取決於這把劍自身!無論認誰拿尚方寶劍都可以“上斬昏君下斬佞臣”。

1.2 SGID

SGID可以用於文件也可以用於目錄,用於文件時與suid類似,當程序運行於進程時屬組是程序文件的屬組,但是很少這樣用,經常還是用在目錄上,當用到目錄上時,在目錄裏面創建的文件或者子目錄都會繼承目錄的屬組,僅僅是繼承屬組。

先演示沒有sgid權限的場景

[root@linuxprobe ~]# mkdir -m 777 /public

[root@linuxprobe ~]# ll -d /public/

drwxrwxrwx 2 root root 6 6月   4 10:52 /public/

[root@linuxprobe ~]# su - zhanghe -c "touch /public/zhanghe.txt;ls -ld /public/zhanghe.txt"

-rw-rw-r-- 1 zhanghe zhanghe 0 6月   4 10:53 /public/zhanghe.txt   #在public目錄裏面創建文件的屬主和屬組與public目錄沒有關係,目錄是root:root,而用戶創建文件的權限是zhanghe:zhanghe

用了sgid權限之後的場景

[root@linuxprobe ~]# mkdir -m 777 /test

[root@linuxprobe ~]# ll -d /test

drwxrwxrwx 2 root root 6 6月   4 10:55 /test

[root@linuxprobe ~]# chmod g+s /test;ls -ld /test   #加上sgid權限

drwxrwsrwx 2 root root 6 6月   4 10:56 /test

[root@linuxprobe ~]# su - zhanghe -c "touch /test/zhanghe.txt;ls -ld /test/zhanghe.txt"

-rw-rw-r-- 1 zhanghe root 0 6月   4 10:59 /test/zhanghe.txt

抽象理解

sgid對目錄使用時就是讓此目錄裏創建的文件繼承該目錄的屬組,就是這麼簡單,根本也用不着抽象,但是這個知識點還挺常用,我們應該講一下sgid會用到什麼場景當中(下文摘自《鳥哥的私房菜》):

有兩個用戶tom和jerry,兩個用戶除了屬性自己的用戶組之外還屬於project組,兩個用戶需要共同擁有對/srv/ahome目錄的開發權,且該目錄不允許其他人進入查閱,請先用傳統的權限實現,然後再用sgid實現。

準備工作

[root@linuxprobe ~]# groupadd project   #創建一個用戶組project

[root@linuxprobe ~]# useradd -G project tom  #把tom用戶加入到project裏面

[root@linuxprobe ~]# useradd -G project jerry  #把jerry用戶加入到project裏面

 [root@linuxprobe ~]# id tom ; id jerry

uid=1002(tom) gid=1003(tom) 組=1003(tom),1002(project)

uid=1003(jerry) gid=1004(jerry) 組=1004(jerry),1002(project)

實現的方式

我們只要把/srv/ahome的屬組改成project,然後把權限改成770,即可以實現上述要求。

[root@linuxprobe /]# mkdir /srv/ahome

[root@linuxprobe /]# chmod 770 /srv/ahome

[root@linuxprobe /]# chgrp project /srv/ahome

[root@linuxprobe /]# ll   /srv/ahome -d

drwxrwx--- 2 root project 6 6月   4 14:56 /srv/ahome

這樣就好了嗎?我們可以試一試

[root@linuxprobe /]# su - tom -c "touch /srv/ahome/tom.txt"

[root@linuxprobe /]# su - jerry -c "touch /srv/ahome/jerry.txt"

[root@linuxprobe /]# ll /srv/ahome/

-rw-rw-r-- 1 jerry jerry 0 6月   4 15:12 jerry.txt

-rw-rw-r-- 1 tom   tom   0 6月   4 15:11 tom.txt

通過上面的操作我們可以知道,在/srv/ahome這個目錄裏面tom的文件對jerry來講是其他人,也就是說jerry在對tom創建的文件進行操作時,是以其他人的身份進行操作的,只有讀的權限,相互之間並不能修改,這是不符合要求,我們想實現他們之間可以相互編輯,我們可以這麼做:

[root@linuxprobe /]# rm -rf /srv/ahome/*

[root@linuxprobe /]# chmod g+s /srv/ahome/

[root@linuxprobe /]# su - tom -c "touch /srv/ahome/tom.txt"

[root@linuxprobe /]# su - jerry -c "touch /srv/ahome/jerry.txt"

我們再看兩個文件的權限:

[root@linuxprobe /]# ll /srv/ahome/

-rw-rw-r-- 1 jerry project 0 6月   4 15:19 jerry.txt

-rw-rw-r-- 1 tom   project 0 6月   4 15:19 tom.txt

當tom再去訪問jerry的文件時是以屬組的權限去訪問的,這樣相互之間就有讀寫權限,可以相互編輯文件。

 

 

 

1.3 sticky

我們如果把一個目錄的屬組改爲開發組,開發組裏面的成員都對目錄有讀寫執行的權限,開發組有那麼多人,如果一個要看另一個不順眼將其文件刪除了怎麼辦?所以有了sticky權限,當我們對一個目錄使用了sticky權限 之後,用戶只能刪除自己的文件,而不能刪除別的文件。

/tmp/和/usr/tmp這兩個目錄默認有sticky權限。

[root@linuxprobe ~]# ll /tmp/ -d ; ll /usr/tmp/ -d

drwxrwxrwt. 79 root root 8192 6月   4 10:52 /tmp/

drwxrwxrwt. 20 root root 4096 6月   4 09:01 /usr/tmp/

那麼誰可以刪除呢?

l  root

l  文件所有者

l  該目錄所有者

 

suid針對文件,以所有者身份執行

sgid針對文件時,以所有組的身份執行;針對目錄時,繼承目錄的屬組。

stickty,針對目錄,只能刪除自己的文件。/tmp和/var/tmp,只有自己可以銷燬。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章