首先推薦一個linux權限的視頻:Linux權限管理之基本權限,講的非常好,看完后就基本明白了。
一、文件權限及所屬
1、文件有三種類型的權限,為了方便期間,可以用數字來代替,這樣可以通過數字的加減,用一個數字就能標識這個文件的權限了,例如7=4+2+1,表示讀寫執行3個權限都有,6=4+2,表示有讀寫權限沒有執行權限等等
2、聯想web應用的rbac權限管理等,linux下同樣有用戶權限的管理,用戶有用戶名和用戶組,一般創建用戶時同時會創建同名的用戶所屬組。
先root賬號登錄隨便新建一個目錄和一個文件
#新建目錄
mkdir abc #新建文件 touch abc.txt #查看 ls -all
查看時會發現:
#d開頭的為目錄,-開頭為文件,還有l開頭的為軟鏈接等
drwxr-xr-x 2 root root 4096 Jun 6 10:23 abc -rw-r--r-- 1 root root 0 Jun 6 10:23 abc.txt
先看上方藍色的部分,第一位為標識符,去掉第一位,后面每三位分隔,以abc文件夾為例:d | rwx | r-x | r-x
所以abc文件夾中表示owner擁有rwx(7),group擁有rx(5),other擁有rx(5)。
同樣上方文件中紅色的部分,依次為所有者的名稱和所屬組的名稱,也就是abc文件夾的所有者為root,所屬組為root。此時:
a、如果是root用戶來訪問這個abc文件夾,相當與owner,擁有7的權限
b、如果一個新的用戶名test用戶組為root來訪問abc文件夾,則相當於group,擁有5的權限
c、如果一個新的用戶名test用戶組為test的來訪問abc文件夾,則相當與other,擁有5的權限
二、文件各權限的作用
本來還想邊測試邊說,但是太麻煩了,直接說結果吧。可以自己新建一個用戶,然后修改權限來自己測試下。
1、目錄
a、進入目錄,即cd命令,所需要的權限為執行權限(x)
b、查看目錄內的文件,即ls命令,需要的權限為讀取權限(r)
c、創建刪除目錄內的文件夾/文件,即mkdir/touch命名,需要的權限為寫如權限(w)
順便說下目錄只影響下一級的,隔代不影響,好比一個目錄abc/sub/,如果abc沒有w權限,但sub有w權限,則可以在sub中創建文件,當然abc也需要有x權限,否則都進不去更不用說創建了,但只要能進去(可以通過切換root管理員的方法),就不會再受abc的影響,只會受sub的影響。
一般我們目錄會給5(rx)的權限,也就是讀取和執行權限,只有圖片上傳或緩存等目錄需要創建的才會給7(rwx)的權限
2、文件
a、文件打開,可以用cat/vim命令打開,所需權限為讀取權限(r)
b、文件修改,可以用cat/vim命令打開並保存,所需權限為寫入權限(w)
c、文件執行,可以直接./abc.out等執行,所需要權限為執行權限(x)
這里需要說明的的是php無論是命令行執行(類似運行 php abc.php)還是web端執行,名為執行,實際上是讀取文件到php內核中取解析,所以只要有讀取權限(r)就可以,同樣例如abc.sh,如果直接運行./abc.sh需要的是執行權限(x),但是運行 sh abc.sh 命令需要的是讀取權限(r)。
一般我們文件會給4(r)權限,也就是讀取權限,只有日志、緩存等需要向文件中寫入內容的才會給6(rx)權限
之所以上方沒有說755,777、644權限,而僅僅是是說單個的權限,是因為你的網站目錄所屬的權限不能確保與執行時所用的用戶什么關系,也就是說執行時的用戶可能是owner、可能是group也可能是other
三、php執行時的權限
我們自己在ssh連接linux操作時必須要有個用戶名才能登錄操作,同樣php要想處理php相關的文件,也是在某個用戶下操作的,而用戶是在哪里創建或定義的呢,一般會是在安裝php環境時創建的,例如apache,nginx等環境都會默認創建用戶和用戶組,而php的讀取時就用此用戶來讀取,可以通過查看配置文件來確認:
#apache在配置文件httpd.conf
User www
Group www
#nginx在配置文件nginx.conf
user www www;
或者是通過命令查看進程:
#查看apache進程 ps -ef|grep httpd #查看nginx進程 ps -ef|grep nginx #查看php-pfm進行 ps -ef|grep php-pfm
以apache為例會顯示:
root 1663 1 0 09:14 ? 00:00:00 /www/wdlinux/apache/bin/httpd//主進程 www 1697 1663 0 09:14 ? 00:00:05 /www/wdlinux/apache/bin/httpd//子進程 www 1698 1663 0 09:14 ? 00:00:05 /www/wdlinux/apache/bin/httpd
第一列就是顯示的哪個用戶在執行它,主要看非root下的。上方說明是www用戶在運行apache進程來處理php文件。一般來說apache/nginx會以root來啟動主線程,然后fork出子線程來處理具體的業務,而子進程在創建時會根據配置文件中的用戶名和用戶組通過setuid和setgid命令來設置有效用戶名和有效用戶組。需要注意的是“有效”這兩個字,例如,某個用戶名為test,其所屬組test,而apache中配置文件中設置的用戶名為test,但是用戶組設置為abc,這時就可能很疑惑了,那組到底是按照用戶名所屬的組還是配置文件中設置的組呢?答案是設置的,因為通過setgid變更了,具體谷歌百度搜索“有效用戶”、“實際用戶”、“setuid函數”等關鍵字。
這里需要注意的是,如果有安裝php-pfm,則應該還需要查看php-pfm執行時的用戶名及用戶組。(php-pfm的用戶最好和nginx一致)
默認的可能是nobody或者apache等其它的用戶及用戶組,上方是已修改過的。此時應該在網站目錄中用ls-all來確認下網站文件是屬於哪個用戶,分幾種情況說明下吧:
a、例如網站所有者是這樣:
drwxr-xr-x 2 www www 4096 Jun 6 10:23 system drwxr-xr-x 2 www www 4096 Jun 6 10:23 tmp -rw-r--r-- 1 www www 0 Jun 6 10:23 index.php ...
網站所有者為www,而php執行者也為www,那說明是具有owner權限,上方system文件夾中755中的55根本不起作用,只要是7xx就會以7(rwx)的權限來執行。
b、如果網站所有者是這樣:
drwxr-xr-x 2 test www 4096 Jun 6 10:23 system drwxr-xr-x 2 test www 4096 Jun 6 10:23 tmp -rw-r--r-- 1 test www 0 Jun 6 10:23 index.php ...
網站所有者為test,所屬組為www,而php執行者為www,執行組為www,那說明是說在同一組中,具有group權限,上方system文件夾中755中的7和5不起作用,只要是x5x就會以5(rx)的權限來執行。
c、如果網站所有者是這樣:
drwxr-xr-x 2 test test 4096 Jun 6 10:23 system drwxr-xr-x 2 test test 4096 Jun 6 10:23 tmp -rw-r--r-- 1 test test 0 Jun 6 10:23 index.php ...
網站所有者為test,所屬組為test,而php執行者為www,執行組為www,那說明是說根本沒什么關系,具有other權限,上方system文件夾中755中的75不起作用,只要是xx5就會以5(rx)的權限來執行。
所以不能簡單的說修改權限為755,644什么的,還需要確認程序的執行者和網站的所有者才能確定權限。
目前好多集成環境為了省事(嗯,lanmp、lnmp等),將php的執行權限和網站所在目錄都設置為www,此時一般創建完目錄后為755,創建文件后為644,當php執行時,起作用的目錄權限為7(所有目錄擁有創建刪除權限)和文件權限6(所有文件具有寫權限),這種是不是挺不安全的?正常應該是目錄為5,文件為4,當有特殊需求時才將權限設為7。如果出現上方說的這種情況,修改的方法一是修改apache/nginx的用戶和用戶組,二是修改網站文件的所有者和所有組這兩個方向來修改(推薦比較簡單),以確保網站的安全。
以上,只是基礎的權限說明。
2018.07.08補充:
補充下php在cli模式下的運行,一開始以為命令行`php xxx.php`這種命名是以PHP用戶來運行,但實際上不是的,而是以當前用戶來執行,類似在xxx.php文件中通過mkdir創建一個文件夾,生成的文件夾所屬用戶和組並不是php的www用戶,而是當前身份的root用戶。所以當涉及到通過cli命令來創建文件等時,需要修改到php的用戶來執行,類似 `sudo -u www php xxx.php`,同樣如果用到計划任務,在crontab中,也需要指定php的www用戶來執行,否則就會創建出所屬root用戶的文件,然后如果普通的web操作還修改此文件,很容易會出現權限不足的情況。