Linux 系統管理入門:安全性、用戶管理與權限設定指南

Linux 系統管理入門:安全性、用戶管理與權限設定指南

Overview of Content

本章章將帶你認識了解 Linux 系統安全性相關的各個方面,包括 /etc 目錄、系統日誌、用戶管理、群組管理以及文件與資料夾權限的設定與管理

Linux 沿用 Unix 文件權限的辦法,允許用會對於目錄、文件(這兩者有些許不同)設置不同的安全訪問,而這些權限又取決於登入的帳戶

個人程式分享時比較注重「縮排」,所以可能不適合手機的排版閱讀,建議切換至「電腦版」、「平板版」視窗看

寫文章分享不易,如有引用參考請詳註出處,如有指導、意見歡迎留言(如果覺得寫得好也請給我一些支持),感謝 😀


Linux 安全性

Linux 的安全核心是 帳戶,當你登入不同用戶時,就會有不同的權限;除了用戶以外還需要注意當前帳戶所在的群組,群組也有群組所使用的權限

認識 /etc 目錄:系統設定檔

● Linux 系統中大部分 系統設定檔案都存放在 /etc 目錄中,所以系統的程式越多相對的 /etc 目錄也就越多;這相對的也會帶來幾個問題…

A. 不容易找到目標應用的設定檔

B. 不易維護(因為應用的設定分離到不同目錄中)

● 目前常見的方式是 將系統設定檔放置 /etc 下的子目錄(也就是在 /etc 目錄下再創建目錄);以下範例,我們看看 systemd 的相關設定檔案放置在 /etc/systemd 目錄下

● 有時設定子目錄會將檔名取為 /etc/<設定檔>.d.d 代表的就是目錄

可設定、不可設定的檔案?

/etc 目錄下放置的都是 可制定(客制)的設定檔

/usr 目錄下放置的則是不可設定檔(應用程式的相關細節)


系統日誌

系統日誌是系統最重要的部分之一,如果不清楚系統哪裡錯誤,可以查找系統日誌檔來找出錯誤關鍵,而日誌系統的使用會依照 OS 系統版本有所不同

系統日誌(以 Ubuntu 為例)

● 傳統版 syslogd

● 新版為 rsyslogd:它除了紀錄之外,還可以它載入一個將日誌資訊寫到資料函數庫的模組

/var/log 目錄也是放置日誌的位置嗎?是的!

/var/log 目錄中很多檔案不是由系統日誌來維護的(可以是應用的日誌檔),要知道哪些是日誌屬於 rsyslogd 的,需要查看設定檔(之後會說明)


rsyslogd 設定檔:規則 & 擴充

rsyslogd 的基礎設定檔案在 /etc/rsyslog.conf 或是在 /etc/rsyslog.d 目錄下;

內容包含傳統規則(由選擇符 selector、操作 action 組成),也包含了 rsyslogd 的擴充規則(規則以 $ 開頭)

● 接著,我們來看看 rsyslog 的 傳統規則(由選擇符 selector、操作 action 組成)


# rsyslog 格式

<selector>            <action>

選擇符 selector:選擇符由兩個成分組成,分別是「設備」、「優先級」(可設定多個),* 代表萬用符

A. . 前:代表設備

B. . 後:代表優先級,由低到高為 debug, info, notice, err, crit, alert, emerge… 概念圖如下

graph LR selector --> 設備 selector --> 優先級 優先級 --> debug 優先級 --> info 優先級 --> notice 優先級 --> err...等等

如果設定為 none 則代表不輸出

操作action:不一定是寫日誌,也可以用來發訊息


cat /etc/rsyslog.conf

上圖資訊對應下表說明

元數據選擇符操作
auth, autgpriv.* /var/log/auth.logauth, autgpriv.*寫入日誌到 /var/log/auth.log
daemon.* -/var/log/daemon.logdaemon.*寫入日誌到 -/var/log/daemon.log
*.* -/var/log/syslog所有設備 *.* 所有優先級-/var/log/syslog

● 更多 rsyslog 可以查看 rsyslog.conf(5)

擴充歸則(規則以 $ 開頭)可稱為指令


cat /etc/rsyslog.conf

可從上圖中我們還可以看到,它會設定生成的 Log 檔案的 FileOwner 檔案設定為 root,FileGroup 為 adm 群組...等等

這裡所說的是「Log 紀錄文件」的權限設置

● 更多的 rsyslogd 設定可以查看 rsyslogd(5)

使用 logger 寫入:故障排除

● 測試系統日誌最快的方法就是對指定的設備寫入日誌,可以用來查看設備是否正常運作;範例如下

以下範例對 daemon.debug 寫入資料


# 寫入日誌
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 訊息),還有系統服務的伺服器... 等等

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) 登入


// 概念程式

Map<"UserName", "UUID">    // 紀錄 UserName 對應 UID

Linux「用戶」的特性:用戶同時代表了權限控制,會有關於到是否可以訪問某種特定進程 or 用戶資源

系統用戶:UID 在 500 以下

後台服務都對應了一個系統服務

普通用戶:UID 在 500 以上

/etc/passwd 文件

● Linux 系統使用一個專門的文件(/etc/passwd)來匹配用戶名以及 UUID 還有其他重要的訊息,它的對應格式如下


## 輸出格式
root:x:0:0:root:/root:/bin/bash

對應訊息(每個訊息之間使用 : 隔開數據)

原數據(從左到右介紹)描述
root用戶名
x加密過的 Passwd
0UID
0GID
root用戶描述 (真實姓名)
/root用戶的家目錄
/bin/bash用戶使用的 Shell

● root 用戶 UID、GID 固定是 0

● 原本該文件有保存加密的密碼,但是這個文件是所有用戶都可訪問的,基於安全性 有關於用戶密碼的部分已經移動到 /etc/shadow 文件中 (只有特定應用可以訪問)

/etc/passwd 文件是全域文件,盡量不要去手動修改它,否則可能導致某修用戶無法登入

可以使用其他 shell 工具去操作帳戶

/etc/shadow 文件

/etc/shadow 文件只有 root 才可以訪問


## 查看文件
sudo cat /etc/shadow

其中內容會保存每個用戶的使用紀錄、限制,其格式如下


## 輸出格式

alien:$y$j9T$MIPKSjvDFVS24HA8OhEOs0$FHW29Tbal1faccdcCYERau3xGHHAP1Z199.zp8KEl98:19409:0:99999:7:::

對應訊息(每個訊息之間使用 : 隔開數據)

原數據(從頭開始)描述
alien用戶名
$y$j9T$MIP…省略加密過的 Passwd
19409上次修改密碼後過幾天
0多少天後能修改密碼
99999多少天必須修改密碼
7密碼過期前幾天提醒用戶
(空)密碼過期後幾天禁用用戶
(空)用戶被禁用的日期 (ISO8061 天數)
(空)預留字段

/etc/shadow 文件為密碼儲存提供靈活的方法、函數庫、工具,而之後它還是很快 PAM 框架給取代

PAM 沒有引進新的檔案,而是繼續使用 /etc/shadow 檔案,只是 PAM 可以外掛許多身份驗證的插件,並幫我們訪問 /etc/shadow 文件

這裡用「取代」可能不夠正確… 因為 PAM 可以與 /etc/shadow 文件一起使用,但是 PAM 框架的自由度高,導致 PAM 框架的光彩更大,進而掩蓋了 /etc/shadow 文件

添加用戶:useradd

● 使用 useradd 命令可以快速創建一個用戶 (如果 PATH 沒有這個路徑,那可以在 /usr/sbin 目錄下尋找看看)

A. 查看創建用戶時的預設參數 -D


## 查看創建用戶時給予的預設值 (-D 是 Default 的意思)

useradd -D

依照上圖所示,針對幾個比較少見的設定值說明

useradd 後返回的資訊說明
INACTIVE密碼過期後是否禁用
EXPIRE該用戶的過期時間
SKEL使否將 /etc/skel 目錄下的內容複製到要創建的帳戶底下(包含一些 .bashrc … 檔案)
CREATE_MAIL_SPOOL是否創建一個接收 mail 的文件

/etc/skel 目錄:該目錄下包含了 bash shell 環境的標準啟動文件

B. useradd 預設是「不會創建一個帳戶目錄」,如果要創建帳戶目錄(/home 目錄下)就可以使用 -m 操作


sudo useradd -m account_m

## home 目錄下就會有一個 `account_m`
ls -la /home/

## account_m 目錄下的檔案就是從 `/etc/skel 複製出來的檔案`
ls -la /home/account_m

從下圖中,我們可以看到在 /home 目錄下確實創建出了 account_m 資料夾

C. -D 之後接參數就可以修改創建用戶時的預設值

以下修改 Shell 預設值為 /bin/tsch


## 改變預設 bash shell

useradd -D -s /bin/tsch

刪除用戶:userdel

userdel 命令可以用來刪除用戶,但是!它默認 只會刪除 /etc/passwd 檔案中的用戶訊息,其他相關的用呼資料都不會刪除(用戶目錄不會刪除)

如果 要刪除其他用戶資料則需添加 -r 操作

## 查看所有用戶
tail /etc/passwd

## 刪除 `account_no_options` 用戶
userdel -r account_no_options

## 再次查看是否被刪除
tail /etc/passwd

修改用戶權限、密碼

● 當用戶創建完成後,要修改用戶的設定(/etc/passwd)有以下幾種方式,每方式修改的目標也不同

A. usermod:可以修改大部分 /etc/passwd 中的設定字段,其 options 與 useradd 差不多

usermod options功能
-c備注字段
-e修改過期日期
-g修改默認群組
-l修改用戶名(username)
-p修改用戶密碼
-L鎖定帳戶
-U解除已鎖定帳戶

B. passwd(修改自己的密碼) & chpasswd(修改其他用戶密碼):


echo "Account_m:456" > test.txt

sudo chpasswd < test.txt

C. 修改特定用戶訊息 chsh (修改 shell)、chfn(修改 finger 讀取到的數據)、chage(修改帳戶有效日期)


Linux Group 群組

如果是針對單用戶來說,帳戶 (User) 權限就足以安全的控管權限,而如果需要 共享某個進程、資源,就不方便使用;所以 Linux 多了 Group 的控管概念,讓權限拓展到更廣泛的群組,讓同一個群組內的使用者可以共享資料

Group & GID 概念:主、次要群

● 每個群組都有「唯一的 GID」,該 GID 對應了一個唯一的組名 (可以透過群組名找到對應的 GID)


// 概念程式

Map<"群組名" : "GID">    // 紀錄 用戶名對應的 GID

● 新創建的使用者,沒有指定 Group 會怎樣?

這部分到不用擔心,Ubuntu 預設會為每個用戶創建各自的群組

假設你創建了 Apple 帳號,它就會幫你創建一個 Apple 群組

graph LR Shell --> 系統 -.-> |創建帳戶| Apple帳戶 系統 -.-> |創建群組| Apple群組

群組的差異:在 Linux 系統中,每個使用者都屬於一個 主群組(primary group次要群組(secondary group

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 的相關訊息,在這個文件中我們可以看到系統中的全部群組


## 輸出格式
root:x:0:

對應訊息(每個訊息之間使用 : 隔開數據)

原數據(從左到右)描述
root群組名
x加密過的 Group Passwd
GIDUID
(空)用戶列表(屬於這個群組的用戶)

root Group ID 固定是 0

● 請不要直接修改(編輯)這個 /etc/group 文件,可以用 Shell 命令來修改;像是可以用 usermod -aG 來添加用戶的群組


## 將 alien 用戶添加到 account_m 群組中    
usermod -aG account_m alien

## 將 alien 原有的群組移除,將 alien 群組設定為 account_m
usermod -G account_m alien

使用指令修改是一種安全操作

A. Group 密碼:使用 Group 密碼,可以讓非這個 Group 的成員 暫時 成為著個組的成員

B. 在 etc/group 文件中可能會發現,原本應該出現在群組的成員沒有在列表中,這是因為創建群組時,默認群組設置 不會出現在該列表中

默認群組設置可以用以下指令查看


## 查看默認設置

useradd -D

創建群組:groupadd、添加群組:usermod

groupadd 可以創建一個新群組,但是它並沒有將某個用戶加入該群組的功能,但這個操作可以透過 usermod -aG 來補足


## 創建 hello_group 群組
sudo groupadd hello_group

tail /etc/group

指定用戶並操作用戶的群組,範例如下


## 將 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

從下圖中,我們可以看到用戶 alienaccount_m 都在 hello_group 群組中

● 如果該帳戶已經被登入,並在它登入後才修改群組,那修改後的群組關係必須要 重新登入後才會作用

修改群組:groupmod

usermod -aG 命令可以用來修改(新增)使用者的群組,但如果要直接修改 /etc/group 內容可以用 groupmod 命令


tail -1 /etc/group

## 將新組名 my_group 設定給 hello_group(取代舊群組名)
sudo groupmod -n my_group hello_group

tail -1 /etc/group

usermod 命令是站在使用者的角度來操作群組,groupmod 命令是直接針對群組設定做操作


文件、資料夾權限

在 Linux 中每個文件都有所屬的 Owner, Group

文件、資料夾權限符

● 使用 ls -l 命令就可以查看到當前目錄下所有的文件,包括其權限

ls -l

權限符號就是 前面那一個字串(10 碼組成),下表會介紹常見的權限符號,由左到右來介紹這 10 碼

碼順序說明補充
0文件類型(用符號區分)- 目錄、連結、b 塊設備、c 字符設備、n 網路設備
1r針對 當前用戶,文件可讀性
2w針對 當前用戶,文件可寫性
3x針對 當前用戶,文件可執行性
4r針對 相同群組的用戶,文件可讀性
5w針對 相同群組的用戶,文件可執行性
6x針對 相同群組的用戶,文件可執行性
7r針對 其他用戶,文件可讀性
8w針對 其他用戶,文件可執行性
9x針對 其他用戶,文件可執行性

● 文件的權限是「八進制」的算法,如下表(這邊我們只看其中一組 rwx 就好,另外兩組是一樣的)

權限字符2 進制8 進制
---0000
--x0011
-w-0102
-wx0113
r--1004
r-x1015
rw-1106
rwx1117

默認文件、資料夾權限:umask

● 所謂的默認權限就是你在創建文件、資料夾時系統會默認的權限

而其中「文件」、「資料夾」默認的權限並不一樣

umask 命令:文件的默認權限可以透過 umask 命令查看;而 默認權限就是由 666(文件)、777(目錄) 減去 umask 的數值決定


umask

touch createFile

mkdir createDir

ls -laF

做 AND 掩碼運算

umask 預設值

umask 的預設值是由 PAM (Pluggable Authentication Modules) 模組所設定,而不是直接由某個文件設定

PAM 是一種通用的身份驗證架構,它可以讓系統管理員在設定身份驗證機制時更有彈性。在 Ubuntu 22 中,umask 的預設值是由 pam_umask 模組 所控制

更改 umask 數值

umask 的預設值,可以編輯 /etc/login.defs 文件,並修改其中的 UMASK 設定

也可以編輯個別使用者的 ~/.profile~/.bashrc 文件,並在其中加入 umask 命令來設定使用者的 umask 值

修改文件、資料夾權限:chmod

chmod 命令:可以透過該命令來修改文件、資料夾的權限

A. 直接指定:一般使用方式就是直接指定 8 進位權限

格式:chmod options mode file


## 修改 createFile 權限為 777

chmod 777 createFile

B. 透過符號:透過符號來操作檔案、文件權限,以下列出幾個常見的設定選項

格式:chmod [ugoa] [+-=] [rxw...]

指定目標符號說明
權限作用目標u當前用戶
gGroup 用戶
o其他用戶
a全部用戶
指定權限+添加權限
-減少權限
=指定權限
權限r可讀
w可寫
x可執行
u把權限設定為跟 User 設定相同
g把權限設定為跟 Group 設定相同
o把權限設定為跟 Other 設定相同
s運行時設定的 GID, UID (常用於共享文件

修改文件、資料夾所屬、群組:chown/chgrp

chgrp 命令:該命可以修改文件、資料夾的群組

格式:chgrp group file


ls -laF createFile

## 改變文件所群組
sudo chgrp MyNewAccount createFile

ls -laF 

chown 命令:該命令可以指定該文件、資料夾的所有者

格式:chown options owner[.group] file

可以使用 -R 遞歸設定資料夾內所有的文件


ls -laF createFile

## 改變文件所屬
sudo chown MyNewAccount createFile

ls -laF createFile

chown 命令也可以只修改文件 Group


sudo groupadd MyNewGroup

ls -laF createFile

## 修改檔案群組
sudo chown .MyNewGroup createFile

ls -laF createFile

● 一次性修改 Owner & Group,只需要在指定 Owner 時在後面加上 . 就會連同 Group 一起修改為當前登入用戶的 Group


sudo chown alien. createFile

umask 的額外訊息:創建共享文件

● 還記得 umask 其實列出了 4 個數字嘛?我們那時並沒有說明第一碼

那第一個碼(數字)就是文件的額外訊息;每個文件、目錄還儲存了 額外的 3 個額外訊息

儲存訊息說明補充
設定用戶 (SUID)當文件被使用時,程序會以 文件所屬主 (Owner) 的權限運行
設定群組 (SGID)同上,運行時程序會以 文件所屬組 (Group) 的權限運行SGID 對於 共享文件 很重要
黏著位進程結束後,文件還留存在內存中(這就是黏著)

使用命令 chmod 就可以啟用 SGID它可以強制讓該目錄下創建的文件都設定為該目錄的所屬群;其第一碼對應的八進位跟意義如下

二進位八進位說明
0000清零
0011設定黏著位
0102SGID
0113SGID + 黏著位
1004SUID
1015SUID + 黏著位
1106SUID + SGID
1117SUID + SGID + 黏著位

● 「共享文件」的概念就是 1. 將文件指定為某一群組 Group,之後,2.在該資料夾底下創建的文件都是指定 Group 的文件,藉此達到只要是該群組的成員都可以操控該資料夾的內容

創建共享文件的範例如下…


## 創建共用資料夾
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


## 在共享資料夾創建文件
touch ./share_dir/testFile

## 查看該文件的群組
ls -l ./share_dir/testFile


更多 Linux Shell 知識

探索 Debian 系統上的套件管理系統(PKMS 概念)| 套件倉庫

Linux 環境、服務:用戶、權限管理

Linux 環境、服務、管理

在這個主題中,你可以探索各種 Linux 環境、服務和管理相關的重要概念…

了解 Linux 組成:內核責任、GNU 工具、桌面環境 | 基礎版到發行版

在這裡,你將了解 Linux 系統的基本組成部分,包括內核、GNU 工具和桌面環境,並了解不同 Linux 發行版之間的差異

探索 X Window 服務與桌面環境:Linux 視窗 XWindow 服務、D-Bus 機制

這裡探討了 Linux 系統中 X Window 服務和 D-Bus 機制的工作原理,讓你深入了解桌面環境的背後運作方式

Linux 系統管理入門:安全性、用戶管理與權限設定指南

在這個指南中,你將學習如何管理 Linux 系統,包括安全性、用戶管理和權限設定,以確保系統的安全和有效運作

認識身份驗證與權限管理:UNIX UID、使用者驗證與 PAM | PAM 設定

這裡介紹了 UNIX 系統中的身份驗證機制和權限管理方式,包括 UNIX UID、使用者驗證和 PAM(Pluggable Authentication Modules)設定

Linux Shell 相關知識

Linux Shell 相關知識

這個主題涵蓋了各種與 Linux Shell 相關的知識,從基礎到進階都有…

Shell 基礎知識:包括 Shell 的基礎使用以及差異,還有變數以及計算

認識命令行:Shell 類型、命令差異 | Sub Shell 關係 | Builtin 命令

這裡介紹了命令行中不同類型的 Shell,以及各種 Shell 命令之間的區別和內建命令的用法

Shell 全局及區域變數、特殊變數及環境變數 | Shell 啟動順序 | Array 變數

學習如何在 Shell 中使用全局變數、特殊變數和環境變數,以及如何設置和管理這些變數

探索腳本與命令:Shell 腳本的必備相關知識 | 腳本的數學運算

這裡介紹了 Shell 腳本的基本知識和常用技巧,包括如何執行腳本和進行數學運算

Shell 結構化

Shell 腳本程式中的條件語句和高級特性 | Shell 結構化 & 判斷

該篇文章是介紹結構化腳本的基礎以及特殊的高級技巧,轉著於腳本中的邏輯判斷

掌握 Bash 腳本中的迴圈與循環控制技巧 | Shell 結構化 & 循環

接著是腳本中的循環與控制的技巧,它可以讓我們在 Shell 腳本中有更多的判斷與技巧

探索 Shell 函數與腳本庫 | Shell 結構化 & 函數

這裡你將會學在到結構化腳本的重要技巧「函數」,它可以讓你建立可重複利用的腳本,以節省我們之後開發的時間

Shell 掌握參數處理與用戶輸入技巧 | Shell 結構化 &輸入互動

不可互動的腳本有時候相對無趣,這篇文章有分享如何讓腳本與使用者產生交互互動,並依照使用者輸入的參數做讀取

Shell script 進階

Shell 命令輸入與輸出指南:掌握標準文件描述符與重定向 | 臨時文件

掌控 Shell、指令的輸出輸入是成為進階使用 CLI 之人必經的一課,透過這篇文章可以了解到輸出輸入、臨時文件等等資訊

探索 Linux 訊號與後台進程管理:安排定期啟動腳本 | 運行時啟動腳本

信號可以算是 Shell 腳本與 Linux 系統之間的通訊方式,透過這個文章,我們可以了解到信號與 Shell 腳本的安排時間

Linux 硬體規劃:檔案系統、分區

Linux 硬體規劃:檔案系統、分區

最後,這個主題涵蓋了 Linux 系統中硬體結構相關的重要概念…

Shell 文件和目錄操作的常用命令和技巧 | 尋找檔案

這裡介紹了 Shell 中常用的文件和目錄操作命令,包括如何尋找文件和管理文件系統

深入探索 Linux 文件系統與硬體管理 | 分區、檔案系統、邏輯卷 | inode

學習如何管理 Linux 文件系統,包括分區、文件系統和邏輯卷等相關概念,以及文件系統中的 inode 機制

理解 Unix/Linux 設備偵測、建立 | 認識與使用 udevd | SCSI 與 Linux 核心

這裡介紹了 Unix/Linux 系統中的設備偵測和管理,包括如何使用 udevd 和 SCSI 相關的 Linux 核心知識


Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

發表迴響