--- title: 'Linux 安全、日誌、用戶與群組權限、文件權限' disqus: kyleAlien --- Linux 安全、日誌、用戶與群組權限、文件權限 === ## Overview of Content 如有引用該文章請標明 :smile_cat: Linux 沿用 Unix 文件權限的辦法,允許用會對於目錄、文件(這兩者有些許不同)設置不同的安全訪問,而這些權限又取決於你登入的帳戶 :::success * 如果喜歡讀更好看一點的網頁版本,可以到我新做的網站 [**DevTech Ascendancy Hub**](https://devtechascendancy.com/) 本篇文章對應的是 [**Linux 系統管理入門:安全性、用戶管理與權限設定指南**](https://devtechascendancy.com/linux-system-admin_user-file-permissions/) ::: [TOC] ## Linux 安全性 Linux 的安全核心是 **帳戶**,當你登入不同用戶時,就會有不同的權限;除了用戶以外還需要注意當前帳戶所在的群組,群組也有群組所使用的權限 ### 認識 `/etc` 目錄:系統設定檔 * Linux 系統中大部分 **系統設定檔案都存放在 `/etc` 目錄中**,所以系統的程式越多相對的 `/etc` 目錄也就越多;這相對的也會帶來幾個問題… 1. 不容易找到目標應用的設定檔 2. 不易維護(因為應用的設定分離到不同目錄中) * 目前常見的方式是 **將系統設定檔放置 `/etc` 下的子目錄**(也就是在 `/etc` 目錄下再創建目錄);以下範例,我們看看 systemd 的相關設定檔案放置在 `/etc/systemd` 目錄下 >  :::info * 有時設定子目錄會將檔名取為 `/etc/<設定檔>.d`,`.d` 代表的就是目錄 ::: :::warning * **可設定、不可設定的檔案?** * `/etc` 目錄下放置的都是 **可制定**(客制)的設定檔 * **`/usr` 目錄下放置的則是不可設定檔**(應用程式的相關細節) ::: ## 系統日誌 系統日誌是系統最重要的部分之一,如果不清楚系統哪裡錯誤,可以查找系統日誌檔來找出錯誤關鍵,而日誌系統的使用會依照 OS 系統版本有所不同 * **系統日誌**(以 Ubuntu 為例) * 傳統版 `syslogd` * 新版為 `rsyslogd`:它除了紀錄之外,還可以它載入一個將日誌資訊寫到資料函數庫的模組 :::success * **`/var/log` 目錄**也是放置日誌的位置嗎?是的! `/var/log` 目錄中很多檔案不是由系統日誌來維護的(可以是應用的日誌檔),要知道哪些是日誌屬於 `rsyslogd` 的,需要查看設定檔(之後會說明) ::: ### rsyslogd 設定檔:規則 & 擴充 * `rsyslogd` 的基礎設定檔案在 `/etc/rsyslog.conf` 或是在 `/etc/rsyslog.d` 目錄下; 內容包含傳統規則(由選擇符 `selector`、操作 `action` 組成),也包含了 rsyslogd 的擴充規則(規則以 `$` 開頭) >  * 接著,我們來看看 rsyslog 的 **傳統規則**(由選擇符 `selector`、操作 `action` 組成) ```shell= # rsyslog 格式 <selector> <action> ``` * **選擇符** `selector`:選擇符由兩個成分組成,分別是「設備」、「優先級」(可設定多個),`*` 代表萬用符 1. **`.` 前:代表設備** 2. **`.` 後:代表優先級**,由低到高為 `debug`, `info`, `notice`, `err`, `crit`, `alert`, `emerge`… 概念圖如下 > 如果設定為 `none` 則代表不輸出 ```mermaid graph LR selector --> 設備 selector --> 優先級 優先級 --> debug 優先級 --> info 優先級 --> notice 優先級 --> err...等等 ``` * **操作**`action`:不一定是寫日誌,也可以用來發訊息 ```shell= cat /etc/rsyslog.conf ``` >  上圖資訊對應下表說明 | 元數據 | 選擇符 | 操作 | | - | - | - | | `auth, autgpriv.* /var/log/auth.log` | `auth, autgpriv.*` | 寫入日誌到 `/var/log/auth.log` | | `daemon.* -/var/log/daemon.log` | `daemon.*` | 寫入日誌到 `-/var/log/daemon.log` | | `*.* -/var/log/syslog` | 所有設備 `*.*` 所有優先級 | `-/var/log/syslog` | :::info * 更多 rsyslog 可以查看 `rsyslog.conf(5)` ::: * **擴充歸則**(規則以 `$` 開頭)可稱為指令 ```shell= cat /etc/rsyslog.conf ``` >  可從上圖中我們還可以看到,它會設定生成的 Log 檔案的 `FileOwner` 檔案設定為 root,`FileGroup` 為 adm 群組...等等 > 這裡所說的是「Log 紀錄文件」的權限設置 :::info * 更多的 rsyslogd 設定可以查看 `rsyslogd(5)` ::: ### 使用 logger 寫入:故障排除 * 測試系統日誌最快的方法就是對指定的設備寫入日誌,可以用來查看設備是否正常運作;範例如下 以下範例對 `daemon.debug` 寫入資料 ```shell= # 寫入日誌 logger -p daemon.debug check log... 123 logger -p daemon.debug check log... 456 # 查看日誌 (只看最後兩筆) sudo cat /var/log/daemon.log | tail -n 2 ``` >  ### 核心日誌 * `rsyslogd` 抓取的日誌不僅是系統的各個裝置,也包括系統啟動訊息(`stsytemd`, `Upstart` 訊息),還有系統服務的伺服器... 等等 ```mermaid graph LR subgraph rsyslogd 日誌 stsytemd日誌 Upstart日誌 系統服務日誌 end ``` * 以前有一個 `klogd` 的守護進程負責為 `syslogd` 擷取核心的日誌訊息,之後也併入了 `rsyslogd` 中 > `dmesg` 命令就是顯示從日誌中獲取的訊息 ## Linux User 用戶 在 Linux 系統中,使用者(User)是作業系統中的一個重要概念,用於管理對系統資源的存取權限 使用者可以是一個人或一個程序,每個使用者都有一個唯一的使用者識別碼(UID)和一個或多個使用者群組識別碼(GID) > GID 下個小節說明 ### User & UID 概念 * 進入 Linux 系統的 **用戶都會被分配 ==唯一== ID(UID)**,但我們在登入系統時不會使用 UID 作為帳號登入,我們會使用登入名 (Username) 登入 ```java= // 概念程式 Map<"UserName", "UUID"> // 紀錄 UserName 對應 UID ``` * **Linux「用戶」的特性**:用戶同時代表了權限控制,會有關於到是否可以訪問某種特定進程 or 用戶資源 * **系統用戶**:UID 在 500 以下 > 後台服務都對應了一個系統服務 * **普通用戶**:UID 在 500 以上 ### `/etc/passwd` 文件 * Linux 系統使用一個專門的文件(`/etc/passwd`)來匹配用戶名以及 UUID 還有其他重要的訊息,它的對應格式如下 ```shell= ## 輸出格式 root:x:0:0:root:/root:/bin/bash ``` 對應訊息(每個訊息之間使用 `:` 隔開數據) | 原數據(從左到右介紹) | 描述 | | - | - | | `root` | 用戶名 | | `x` | 加密過的 Passwd | | `0` | UID | | `0` | GID | | `root` | 用戶描述 (真實姓名) | | `/root` | 用戶的家目錄 | | `/bin/bash` | 用戶使用的 Shell | :::info * root 用戶 UID、GID 固定是 0 ::: >  * 原本該文件有保存加密的密碼,但是這個文件是所有用戶都可訪問的,基於安全性 **有關於用戶密碼的部分已經移動到 `/etc/shadow` 文件中** (只有特定應用可以訪問) :::warning * `/etc/passwd` 文件是全域文件,盡量不要去手動修改它,否則可能導致某修用戶無法登入 > 可以使用其他 shell 工具去操作帳戶 ::: ### `/etc/shadow` 文件 * `/etc/shadow` 文件只有 root 才可以訪問 ```shell= ## 查看文件 sudo cat /etc/shadow ``` 其中內容會保存每個用戶的使用紀錄、限制,其格式如下 ```shell= ## 輸出格式 alien:$y$j9T$MIPKSjvDFVS24HA8OhEOs0$FHW29Tbal1faccdcCYERau3xGHHAP1Z199.zp8KEl98:19409:0:99999:7::: ``` 對應訊息(每個訊息之間使用 `:` 隔開數據) | 原數據(從頭開始) | 描述 | | - | - | | alien | 用戶名 | | \$y\$j9T$MIP...省略 | 加密過的 Passwd | | 19409 | 上次修改密碼後過幾天 | | 0 | 多少天後能修改密碼 | | 99999 | 多少天必須修改密碼 | | 7 | 密碼過期前幾天提醒用戶 | | (空) | 密碼過期後幾天禁用用戶 | | (空) | 用戶被禁用的日期 (ISO8061 天數) | | (空) | 預留字段 | :::info * `/etc/shadow` 文件為密碼儲存提供靈活的方法、函數庫、工具,而之後它還是很快 **被 `PAM` 框架給取代** PAM 沒有引進新的檔案,而是繼續使用 `/etc/shadow` 檔案,只是 PAM 可以外掛許多身份驗證的插件,並幫我們訪問 `/etc/shadow` 文件 > 這裡用「取代」可能不夠正確… 因為 PAM 可以與 `/etc/shadow` 文件一起使用,但是 PAM 框架的自由度高,導致 PAM 框架的光彩更大,進而掩蓋了 `/etc/shadow` 文件 ::: ### 添加用戶:useradd * 使用 useradd 命令可以快速創建一個用戶 (如果 PATH 沒有這個路徑,那可以在 `/usr/sbin` 目錄下尋找看看) 1. 查看創建用戶時的預設參數 -D ```shell= ## 查看創建用戶時給予的預設值 (-D 是 Default 的意思) useradd -D ``` >  依照上圖所示,針對幾個比較少見的設定值說明 | useradd 後返回的資訊 | 說明 | | - | - | | `INACTIVE` | 密碼過期後是否禁用 | | `EXPIRE` | 該用戶的過期時間 | | `SKEL` | **使否將 `/etc/skel` 目錄下的內容複製到要創建的帳戶底下(包含一些 `.bashrc` ... 檔案)** | | `CREATE_MAIL_SPOOL` | 是否創建一個接收 mail 的文件 | :::info * **`/etc/skel` 目錄**:該目錄下包含了 bash shell 環境的標準啟動文件 >  ::: 2. useradd 預設是「**不會創建一個帳戶目錄**」,如果要創建帳戶目錄(`/home` 目錄下)就可以使用 `-m` 操作 ```shell= sudo useradd -m account_m ## home 目錄下就會有一個 `account_m` ls -la /home/ ## account_m 目錄下的檔案就是從 `/etc/skel 複製出來的檔案` ls -la /home/account_m ``` > 從下圖中,我們可以看到在 `/home` 目錄下確實創建出了 `account_m` 資料夾 >  3. `-D` 之後接參數就可以修改創建用戶時的預設值 > 以下修改 Shell 預設值為 `/bin/tsch` ```shell= ## 改變預設 bash shell useradd -D -s /bin/tsch ``` ### 刪除用戶:userdel * `userdel` 命令可以用來刪除用戶,但是!它默認 **只會刪除 `/etc/passwd` 檔案中的用戶訊息**,其他相關的用呼資料都不會刪除(用戶目錄不會刪除) 如果 **要刪除其他用戶資料則需添加 `-r` 操作** ```shell= ## 查看所有用戶 tail /etc/passwd ## 刪除 `account_no_options` 用戶 userdel -r account_no_options ## 再次查看是否被刪除 tail /etc/passwd ``` >  ### 修改用戶權限、密碼 * 當用戶創建完成後,要修改用戶的設定(`/etc/passwd`)有以下幾種方式,每方式修改的目標也不同 1. `usermod`:可以修改大部分 `/etc/passwd` 中的設定字段,其 options 與 `useradd` 差不多 | usermod options | 功能 | | -------- | -------- | | -c | 備注字段 | | -e | 修改過期日期 | | -g | 修改默認群組 | | -l | 修改用戶名(username) | | -p | 修改用戶密碼 | | -L | 鎖定帳戶 | | -U | 解除已鎖定帳戶 | 2. `passwd`(修改自己的密碼) & `chpasswd`(修改其他用戶密碼): ```shell= echo "Account_m:456" > test.txt sudo chpasswd < test.txt ``` 3. 修改特定用戶訊息 `chsh` (修改 shell)、`chfn`(修改 finger 讀取到的數據)、`chage`(修改帳戶有效日期) ## Linux Group 群組 如果是針對單用戶來說,帳戶 (User) 權限就足以安全的控管權限,而如果需要 **共享某個進程、資源,就不方便使用**;所以 Linux 多了 Group 的控管概念,讓權限拓展到更廣泛的群組,讓同一個群組內的使用者可以共享資料 ### Group & GID 概念:主、次要群 * 每個群組都有「**唯一的 GID**」,該 GID 對應了一個唯一的組名 (可以透過群組名找到對應的 GID) ```java= // 概念程式 Map<"群組名" : "GID"> // 紀錄 用戶名對應的 GID ``` :::info * 新創建的使用者,沒有指定 Group 會怎樣? 這部分到不用擔心,**Ubuntu 預設會為每個用戶創建各自的群組** > 假設你創建了 Apple 帳號,它就會幫你創建一個 Apple 群組 ```mermaid graph LR Shell --> 系統 -.-> |創建帳戶| Apple帳戶 系統 -.-> |創建群組| Apple群組 ``` ::: * **群組的差異**:在 Linux 系統中,每個使用者都屬於一個 **主群組(`primary group`)** 和 **次要群組(`secondary group`)** ```mermaid graph LR subgraph 使用者 主群組 次要群組 end ``` * **Primary group 是一個使用者帳號的主要群組**: 這個群組會被指定為使用者在建立檔案時的預設群組。當使用者建立檔案時,該檔案的群組權限(`group ownership`)會被設定為使用者的 `primary group` * **Secondary group 則是其他使用者群組**: 使用者可以隨時加入或退出這些群組,但這些群組並不會影響使用者建立檔案的預設群組。 > 在命令行中,使用 `usermod -g` 來修改使用者的 `primary group`,而使用 `usermod -aG` 來將使用者加入一個 secondary group ### `/etc/group` 文件 * `/etc/group` 文件用來保存 Linux Group 的相關訊息,在這個文件中我們可以看到系統中的全部群組 ```shell= ## 輸出格式 root:x:0: ``` 對應訊息(每個訊息之間使用 `:` 隔開數據) | 原數據(從左到右) | 描述 | | - | - | | root | 群組名 | | x | 加密過的 Group Passwd | | GID | UID | | (空) | 用戶列表(屬於這個群組的用戶) | :::info root Group ID 固定是 0 ::: :::danger * 請不要直接修改(編輯)這個 `/etc/group` 文件,可以用 Shell 命令來修改;像是可以用 `usermod -aG` 來添加用戶的群組 > 使用指令修改是一種安全操作 ```shell= ## 將 alien 用戶添加到 account_m 群組中 usermod -aG account_m alien ## 將 alien 原有的群組移除,將 alien 群組設定為 account_m usermod -G account_m alien ``` >  ::: :::success 1. **Group 密碼**:使用 Group 密碼,可以讓非這個 Group 的成員 **暫時** 成為著個組的成員 2. 在 `etc/group` 文件中可能會發現,原本應該出現在群組的成員沒有在列表中,**這是因為創建群組時,默認群組設置 不會出現在該列表中**; 默認群組設置可以用以下指令查看 ```shell= ## 查看默認設置 useradd -D ``` >  ::: ### 創建群組:groupadd、添加群組:usermod * `groupadd` 可以創建一個新群組,但是它並沒有將某個用戶加入該群組的功能,但這個操作可以透過 `usermod -aG` 來補足 ```shell= ## 創建 hello_group 群組 sudo groupadd hello_group tail /etc/group ``` >  指定用戶並操作用戶的群組,範例如下 ```shell= ## 將 alien 用戶指定為 hello_group 群組的成員 sudo usermod -G hello_group alien cat /etc/group | grep hello ## 將 account_m 用戶指定為 hello_group 群組的成員 sudo usermod -G hello_group account_m cat /etc/group | grep hello ``` > 從下圖中,我們可以看到用戶 `alien`、`account_m` 都在 `hello_group` 群組中 >  :::info * 如果該帳戶已經被登入,並在它登入後才修改群組,那修改後的群組關係必須要 **重新登入後才會作用** ::: ### 修改群組:groupmod * `usermod -aG` 命令可以用來修改(新增)使用者的群組,但如果要直接修改 `/etc/group` 內容可以用 `groupmod` 命令 > usermod 命令是站在使用者的角度來操作群組,`groupmod` 命令是直接針對群組設定做操作 ```shell= tail -1 /etc/group ## 將新組名 my_group 設定給 hello_group(取代舊群組名) sudo groupmod -n my_group hello_group tail -1 /etc/group ``` >  ## 文件、資料夾權限 在 Linux 中每個文件都有所屬的 `Owner`, `Group` ### 文件、資料夾權限符 * 使用 `ls -l` 命令就可以查看到當前目錄下所有的文件,包括其權限 ```shell= ls -l ``` >  權限符號就是 前面那一個字串(10 碼組成),下表會介紹常見的權限符號,由左到右來介紹這 10 碼 | 碼順序 | 說明 | 補充 | | - | - | - | | 0 | 文件類型(用符號區分) | `-` 目錄、連結、`b` 塊設備、`c` 字符設備、`n` 網路設備 | | 1 | r | 針對 **當前用戶**,文件可讀性 | | 2 | w | 針對 **當前用戶**,文件可寫性 | | 3 | x | 針對 **當前用戶**,文件可執行性 | | 4 | r | 針對 **相同群組的用戶**,文件可讀性 | | 5 | w | 針對 **相同群組的用戶**,文件可執行性 | | 6 | x | 針對 **相同群組的用戶**,文件可執行性 | | 7 | r | 針對 **其他用戶**,文件可讀性 | | 8 | w | 針對 **其他用戶**,文件可執行性 | | 9 | x | 針對 **其他用戶**,文件可執行性 | * 文件的權限是「**八進制**」的算法,如下表(這邊我們只看其中一組 `rwx` 就好,另外兩組是一樣的) | 權限字符 | 2 進制 | 8 進制 | | -------- | -------- | -------- | | -\-\- | 000 | 0 | | -\-x | 001 | 1 | | -w- | 010 | 2 | | -wx | 011 | 3 | | r-\- | 100 | 4 | | r-x | 101 | 5 | | rw- | 110 | 6 | | rwx | 111 | 7 | ### 默認文件、資料夾權限:umask * 所謂的默認權限就是你在創建文件、資料夾時系統會默認的權限 :::danger 而其中「文件」、「資料夾」默認的權限並不一樣 ::: * `umask` 命令:文件的默認權限可以透過 `umask` 命令查看;而 **默認權限就是由 666(文件)、777(目錄) 減去 umask 的數值決定** > 做 AND 掩碼運算 ```kotlin= umask touch createFile mkdir createDir ls -laF ``` >  :::info * **umask 預設值** umask 的預設值是由 PAM (`Pluggable Authentication Modules)` 模組所設定,而不是直接由某個文件設定 PAM 是一種通用的身份驗證架構,它可以讓系統管理員在設定身份驗證機制時更有彈性。在 Ubuntu 22 中,umask 的預設值是由 **`pam_umask` 模組** 所控制 * **更改 umask 數值** umask 的預設值,可以編輯 `/etc/login.defs` 文件,並修改其中的 UMASK 設定 也可以編輯個別使用者的 `~/.profile` 或 `~/.bashrc` 文件,並在其中加入 umask 命令來設定使用者的 umask 值 ::: ### 修改文件、資料夾權限:chmod * **`chmod` 命令**:可以透過該命令來修改文件、資料夾的權限 1. **直接指定**:一般使用方式就是直接指定 8 進位權限 > 格式:chmod options mode file ```shell= ## 修改 createFile 權限為 777 chmod 777 createFile ``` 2. **透過符號**:透過符號來操作檔案、文件權限,以下列出幾個常見的設定選項 > 格式:chmod [ugoa] [+-=] [rxw...] | 指定目標 | 符號 | 說明 | | -------- | -------- | -------- | | 權限作用目標 | u | 當前用戶 | | | g | Group 用戶 | | | o | 其他用戶 | | | a | 全部用戶 | | 指定權限 | + | 添加權限 | | | - | 減少權限 | | | = | 指定權限 | | 權限 | r | 可讀 | | | w | 可寫 | | | x | 可執行 | | | u | 把權限設定為跟 User 設定相同 | | | g | 把權限設定為跟 Group 設定相同 | | | o | 把權限設定為跟 Other 設定相同 | | | s | 運行時設定的 GID, UID (常用於共享文件) | ### 修改文件、資料夾所屬、群組:chown/chgrp * **`chgrp` 命令**:該命可以修改文件、資料夾的群組 > 格式:chgrp group file ```shell= ls -laF createFile ## 改變文件所群組 sudo chgrp MyNewAccount createFile ls -laF ``` >  * **`chown` 命令**:該命令可以指定該文件、資料夾的所有者 > 格式:chown options owner[.group] file :::info 可以使用 `-R` 遞歸設定資料夾內所有的文件 ::: ```shell= ls -laF createFile ## 改變文件所屬 sudo chown MyNewAccount createFile ls -laF createFile ``` >  **`chown` 命令也可以只修改文件 Group** ```shell= sudo groupadd MyNewGroup ls -laF createFile ## 修改檔案群組 sudo chown .MyNewGroup createFile ls -laF createFile ``` >  :::info * 一次性修改 Owner & Group,只需要在指定 Owner 時在後面加上 `.` 就會連同 Group 一起修改為當前登入用戶的 Group ```shell= sudo chown alien. createFile ``` >  ::: ### umask 的額外訊息:創建共享文件 * 還記得 `umask` 其實列出了 4 個數字嘛?我們那時並沒有說明第一碼 那第一個碼(數字)就是文件的額外訊息;每個文件、目錄還儲存了 **額外的 3 個額外訊息** | 儲存訊息 | 說明 | 補充 | | - | - | - | | 設定用戶 (SUID) | 當文件被使用時,程序會以 **文件所屬主 (Owner) 的權限運行** | | | 設定群組 (SGID) | 同上,運行時程序會以 **文件所屬組 (Group) 的權限運行** | **SGID 對於 共享文件 很重要** | | 黏著位 | 進程結束後,文件還留存在內存中(這就是黏著) | | 使用命令 `chmod` 就可以啟用 `SGID`,**它可以強制讓該目錄下創建的文件都設定為該目錄的所屬群**;其第一碼對應的八進位跟意義如下 | 二進位 | 八進位 | 說明 | | - | - | - | | 000 | 0 | 清零 | | 001 | 1 | 設定黏著位 | | 010 | 2 | SGID | | 011 | 3 | SGID + 黏著位 | | 100 | 4 | SUID | | 101 | 5 | SUID + 黏著位 | | 110 | 6 | SUID + SGID | | 111 | 7 | SUID + SGID + 黏著位 | * 「**共享文件**」的概念就是 ^1.^ 將文件指定為某一群組 Group,之後,^2.^**在該資料夾底下創建的文件都是指定 Group 的文件**,藉此達到只要是該群組的成員都可以操控該資料夾的內容 創建共享文件的範例如下… ```shell= ## 創建共用資料夾 mkdir share_dir ## 查看該資料夾的詳細資訊 ls -ld share_dir ## 創建共享的群組 share_group sudo groupadd share_group ## 改變資料夾的群組 sudo chgrp share_dir ./share_dir ## 確認該資料夾是否已改變群組 ls -ld share_dir ## 設置 share_dir 的 SGID sudo chmod g+s ./share_dir/ ## 確認該資料夾是否已改變 SGID 設置 ls -ld share_dir ``` > 設定成功後 `./share_dir/` 資料夾 x 會轉變成 s > >  在分享資料夾下創建文件,就會發現該文件的預設群組就變成 `share_group` ```shell= ## 在共享資料夾創建文件 touch ./share_dir/testFile ## 查看該文件的群組 ls -l ./share_dir/testFile ``` >  ## Appendix & FAQ :::info ::: ###### tags: `Linux Shell`
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.