看完這篇 Linux 許可權後,通透了

2021-12-31 08:00:02

我們在使用 Linux 的過程中,或多或少都會遇到一些關於使用者和群組的問題,比如最常見的你想要在某個路徑下執行某個指令,會經常出現這個錯誤提示 。

permission denied

反正我大概率見到這個錯誤都是在使用 FTP 傳輸檔案的時候,等了半天傳輸百分比還是零,我說網路這麼慢麼?怎麼都不傳輸呢?其實我不知道,這是由於許可權問題所致。

我一般的修復方式是直接賦予 777 許可權,或者直接使用 su 管理員登入。。。。。。

大家可能不太知道我說的是什麼,也有一些大佬可能覺得我這種方式太 low 了,不管怎樣,遇到這種問題就是說你得許可權不夠,為什麼呢?下面我們就需要來認識一下 Linux 中的使用者和群組了。

使用者和群組

在 Linux 中,關於檔案所有者分為三類,即檔案所有者、群組和其他人所屬,這裡分別解釋以下這三個概念

  • 檔案所有者

Linux 是一個多使用者多工系統,多使用者就意味著有些使用者建立的檔案是否對其他使用者可見,這是一種可見性問題,同時也是一種隱私性問題,為了考慮到每個人的隱私權,Linux 設計了檔案所有者的角色。如果你有一些資料和檔案的隱私性比較高,你就可以把檔案設定成 「只有我自己可見」 ,這就是檔案所有者的作用。

  • 群組

群組的這個概念用在團隊開發中,用處比較多的就是為專案設定許可權,比如你就職於一個銀行的外包部門,你和其他外包部門共同為某個銀行服務,所有的外包團體都使用一臺伺服器,這就會涉及到群組許可權的問題,你們外包部門開發的專案不想讓其他外包部門所看到,就會把該專案設定成群組可見。但是銀行是總負責人,所有銀行具有檢視你們所有外包部門專案的許可權,因此,你還需要設定銀行的許可權。

  • 其他人所屬

其他人和群組是相對的,其他人在群組之外,沒有許可權檢視群組內檔案的一種許可權關係。

除了上面三個概念之外,還有一個許可權級別最高的大佬,它就是 root,這個 root 許可權是最高的。

Linux 檔案許可權

在聊完上面使用者和群組的概念之後,接下來我們就來談一下檔案許可權要如何設定的問題,這塊內容是很重要的,因為這部分內容是很好解決 permission denied 問題的關鍵。

許可權屬性

首先登入 Linux 系統,使用 su - 可以切換成為 root 身份,然後執行 ls -al 會看到下面這些

image-20211225205433717

一共有七列內容,這七列內容如下圖所示。

image-20211225210504595

學習的時候可以直接使用 root ,因為後續的 chgrp,chown 等指令都需要 root 來處理,但是工作中強烈建議不要使用 root 許可權。

使用 exit 可以退出 root 身份。

上面這段指令中,ls 是 list 的意思,也就是列出,而選項 -al 則表示檔案詳細許可權和屬性。

  • 許可權,第一列表示的是許可權,許可權一共通過 10 個字元來表示,我們拿 home 許可權為例,來列舉各個字元表示的含義

image-20211226102008007

第一個字元表示的是檔案型別,檔案型別有很多種,一般 [d] 表示的是目錄,能用cd命令進入到這個目錄中。可以看到圖中幾乎所有都是目錄。

image-20211226102414780

如果是 [-] 則表示檔案,如果是 [l] 則表示連結檔案,如果是 [b] 則表示裝置檔案中的可隨機存取裝置,如果是 [c] 則表示為裝置檔案中的一次性讀取裝置(鍵盤、滑鼠)。

接下來的九個字元分為三組,三個一組,分別表示所屬人、所屬群組、其他所有者許可權,每組內的許可權都是三個 rwx 的組合,[r] 表示可讀,[w]表示可寫,[x] 表示可執行,這裡需要注意的是,如果沒有許可權,就會變為 -號。

  • 連結,這一列表示有多少檔名連結到這個節點(i-node)上,每個檔案都會將它的許可權和屬性記錄到檔案系統的 i-node 上,不過,我們使用的目錄樹卻是使用檔名來記錄的,因此每個檔名都會關聯到一個 i-node ,所以這個屬性就是記錄有多少檔案連結到了同一個 i-node 上。

什麼是 i-node ?

i-node 的描述方式很像是我們之前聊過的 Socket,Socket 就是一個四元組,有時會加上協定型別變為五元組,如果你不太清楚我說的是什麼,可以看下我的這篇文章 原來這才是 Socket!

我們知道,磁碟的最小儲存單位是磁區,作業系統在讀取磁區時,不會一個磁區接著一個磁區這樣讀取,因為效率太低,而是以為單位進行讀取,塊是由多個磁區組成的。

檔案中的資料都儲存在磁區中,但是我們並不知道哪一塊資料是我們需要的,為了儲存一些檔案的元資訊,比如檔案的建立者,建立日期,檔案的大小,開發人員提出了 i-node ,也就是索引節點。一般來說,i-node 具有如下內容

image-20211226112609911

具體關於 i-node 的內容,我們後面還會再說。

  • 然後第三列表示這個檔案的所屬人,由圖可見,大部分檔案的所屬人都是 root 使用者。
  • 第四列表示這個檔案的所屬群組,在 Linux 系統下,你登入的賬號會新增到一個或者多個所有人群組中,這一欄就表示對應的群組許可權。
  • 第五列表示檔案大小,預設單位為位元組(Bytes)。
  • 第六列為建立這個檔案的日期和最近修改日期,從圖中可以看到,這個日期格式有可能不是我們想要的,如果要顯示完整的日期格式,可以使用 ls -l --full-time,包括年、月、日、時間。

如果想要讓系統預設的語系變為英文的話,那麼你可以修改系統組態檔 /etc/locale.conf,首先我們可以檢視一下系統都支援哪些語言。

image-20211226190051442

修改預設語言,輸入

vi /etc/profile

在檔案的最後輸入

export LANG="en_US.UTF-8"

就可以切換成為英文,如果想使用中文,可以輸入

export LANG="zh_CN.GB18030"

然後使用 esc + :wq 儲存,儲存之後使用

source /etc/profile

即可完成設定。

  • 第七列為檔名,有一類特殊的檔名,它表示著隱藏檔案,如果檔名之前多一個 . ,那就表示隱藏檔案。

許可權的重要性

  • 提供系統保護:非許可權使用者不能操作具有某些許可權的功能和資料。
  • 適合團隊開發和資料共用:團隊所有組成員和個人所屬能夠共用專案。

如果沒有恰當的設定系統許可權,可能會造成某些洩密事件或者其他不可忽視的後果,所以許可權問題大家要引起重視,下面我們就來聊一聊如何設定系統許可權。

改變系統許可權和屬性

我們現在知道檔案許可權對於一個系統安全的重要性了,現在就要聊一聊如何修改檔案許可權了。常用的修改檔案許可權的指令有

  • chgrp :改變檔案所屬群組
  • chown:改變檔案所有者
  • chmod:改變檔案許可權

chgrp

chgrp 就是 change group 的縮寫,我覺得李納斯把縮寫用到了極致,這也許是我們現在對於縮寫這麼流行的原因。chgrp 能夠改變檔案群組,不過,要改變群組的話,要被改變的群組名稱要在 /etc/group 檔案記憶體在才行,否則就會顯示錯誤。

chown

既然 chgrp 能夠改變檔案群組,那麼 chown 能夠改變檔案所有者,同樣也需要注意的是,檔案所有者必須是系統中存在的賬號,也就是在 /etc/passwd 這個檔案中有記錄的使用者名稱才可改變。除此之外,chown 還可以直接修改群組名稱。

chmod

變更檔案許可權使用的是 chmod 這個指令,但是,許可權的設定有兩種方式,可以分別使用數位或者符號進行許可權變更。

  • 使用數位改變檔案許可權

Linux 檔案基本許可權有 9 種,分別是 owner/group/others 三種身份加自己的 read/write/execute 許可權,這九個許可權三個為一組,我們可以使用數位表示各個許可權。

一般 r 表示 4;w 表示 2;x 表示 1,每種身份各自的許可權是需要累加的,比如 rwx 就表示 4 + 2 + 1 = 7。比如我們最常見的 chmod 777 它就表示賦予所有的許可權,也就是說誰都能看/寫/執行,所以這種檔案也存在極大的安全問題。使用數位改變檔案許可權是我們最常用的一種方式。

  • 使用符號改變檔案許可權

九種檔案許可權分別對應著:(1) user (2) group (3) others,所以我們可以藉由 u,g,o 來代表三種身份的許可權。除此之外,a 代表 all 即全部的身份。

比如我們想要給 -rwxr-xr-x 設定許可權,那麼我們所使用的命令應該是

chmod u=rwx,go=rx .filename

如果我們想要給所有人增加寫入許可權,就可以這麼操作

chmod a+w .filename

如果我們想給所有人去掉寫入許可權,就可以這麼寫入指令

chmod a-w .filename

我們上面列出了三種指令,分別是 =、+、- 號,= 號表示賦值指定許可權,+ 號表示增加許可權,- 號表示去掉某些許可權,在 + 和 - 的狀態下,只要沒找到指令的專案,那麼該許可權不會發生變動。

Linux 目錄和檔案許可權

我們上面聊的都是檔案許可權,檔案是容納資料的地方,這些檔案包括一般文字檔案、資料庫檔案、二進位制檔案等,許可權對於檔案的意義在於

  • r(read):可以讀取檔案的實際內容,比如讀取文字檔案的文字內容
  • w(write):可以新增、編輯或者修改檔案中的內容(不包括刪除檔案)
  • x(execute):使檔案具有被檔案系統執行的許可權。

Windows 下面判斷檔案是否能夠執行的因素是看副檔名, 比如 .exe, .bat, .com 等等,但是在 Linux 中,判斷檔案是否具有可執行許可權是直接判斷檔案有沒有 x 這個許可權,和檔名無關。

但是在 Linux 中,不只有檔案具有許可權,目錄也有許可權,檔案是存放實際資料的地方,而目錄是記錄檔案所在位置的清單,我們只有通過目錄才能找到檔案放在哪裡!許可權對於不同的目錄,也代表著不同的概念。

  • r (read contents in directory):表示具有讀取目錄結構清單的許可權,所以如果你具有讀取一個目錄的許可權時,就代表你可以查詢目錄下的檔案,所以你就可以使用 ls 將目錄的內容顯示出來。
  • w(modify contents of directory):寫入許可權表示你具有對檔案目錄和目錄中的檔案進行修改的操作,主要包括
    • 刪除已經存在的檔案和目錄。
    • 建立新的檔案和目錄。
    • 將已存在的檔案或目錄進行改名。
    • 移動目錄內檔案、目錄位置。
  • x(access directory):這執行許可權有啥用?總不能目錄也能夠被執行把?其實並不是這樣,執行許可權表示著你有沒有許可權進入到指定目錄下,也就是 cd(change directory)

Linux 檔案種類和擴充套件名

想必大家都聽說過這樣一句話:任何裝置在 Linux 下都是檔案,但是檔案也分為多種,除了上面介紹過的一般檔案(-)目錄檔案(d) 之外,還包括下面這些檔案型別

  • 常規檔案(regular file):常規檔案就是我們使用 ls -al 所顯示出來的屬性,也就是上面我們列出的第一個字元,

image-20211227155846515

檔案型別又可以分為

  1. 純文字檔案(ASCII),這是 Linux 系統中最多的一種檔案型別,純文字檔案是我們能夠直接看到的資料,你可以使用 cat 來直接看到這部分內容。比如我們最常用的設定 Linux 靜態 ip 的檔案 ens33 ,就可以使用 cat 命令來輸出
cat ifcfg-ens33

image-20211227161304116

  1. 二進位制檔案,在 Linux 中,檢視二進位制檔案可以使用 xxd 或者 od 進行格式化輸出
  2. 資料格式檔案,資料檔案直接使用 cat 讀取會顯示亂碼,但是它能夠通過 last 指令進行輸出
  • 目錄,目錄沒什麼好說的,就是表示一個檔案清單,目錄的表示就是 [d],也就是 directory。
  • 連結檔案(link),連結檔案就是某些程式執行時需要和這些連結檔案進行連結才能執行的一種檔案型別。
  • 裝置與裝置檔案(device),Linux 下的裝置分為兩種,塊裝置和字元裝置:

塊裝置是一個能儲存固定大小塊資訊的裝置,它支援以固定大小的塊,磁區或群集讀取和(可選)寫入資料。每個塊都有自己的實體地址。通常塊的大小在 512 - 65536 之間。所有傳輸的資訊都會以連續的塊為單位。塊裝置的基本特徵是每個塊都較為對立,能夠獨立的進行讀寫。常見的塊裝置有 硬碟、藍光光碟、USB 盤

塊裝置一般位於 /dev/sda 下,它的第一個屬性為 [b]

image-20200330104419700

另一類 I/O 裝置是字元裝置。字元裝置以字元為單位傳送或接收一個字元流,而不考慮任何塊結構。字元裝置是不可定址的,也沒有任何尋道操作。常見的字元裝置有 印表機、網路裝置、滑鼠、以及大多數與磁碟不同的裝置

image-20200330113116106

字元裝置最大的特點就是一次性讀取,不能夠截斷輸出,舉例來說,你不可能將滑鼠一下跳到另外一個地方,而是採用平滑移動的方式才可以,字元裝置的第一個屬性是 [c]

  • 資料介面檔案(sockets):資料介面檔案顧名思義就是利用 socket 承接網路資料的,它的屬性是 [s],一般在 /run 或者 /tmp 這些目錄中看到。
  • 資料輸送檔案(FIFO,pipe):FIFO 也是一種特殊型別的檔案,它的主要目的在於解決多個程式同時存取一個檔案所造成的的錯誤問題,它的第一個屬性為 [p]

Linux 擴充套件名

說到這個擴充套件名其實就很頭疼,Linux 中是沒有擴充套件名這個概念的,但是又有一些擴充套件名的命名方式,這就很尷尬,所以暫且成為擴充套件型別吧。一般有下面幾種

  • *.sh ,這是一個執行指令碼或者批次處理指令碼,一般也被稱為 shell 指令碼,裡面是一些 shell 語法寫的指令。
  • .tar,.tar.gz,.zip,*.tgz,這種擴充套件型別是打包的壓縮檔案,根據不同的打包方式有不同的擴充套件型別
  • .html ,.php :網頁相關檔案,分別代表 HTML 和 PHP 語法的網頁檔案。

看完這篇 Linux 許可權後,通透了!