Linux 系統的 /proc 檔案系統包含大量的行程資訊,雖然方便管理,但也可能成為資安漏洞。駭客能利用這些資訊進行攻擊,因此保護 /proc 的安全至關重要。本文介紹如何透過 hidepid 選項隱藏 /proc 中的敏感資訊,並搭配 cgroups 和 namespace 技術,限制行程資源和建立隔離環境,有效強化系統安全。這些設定能避免未授權使用者存取敏感資訊,並限制惡意程式碼的影響範圍,提升系統的整體安全性。
加強Linux系統安全:隱藏proc檔案系統與行程隔離
在Linux系統中,/proc 檔案系統提供了豐富的行程資訊,這對於系統管理員來說非常有用。然而,這些資訊也可能被駭客利用來規劃攻擊。因此,適當地組態 /proc 檔案系統的安全性是非常重要的。
隱藏proc檔案系統
預設情況下,任何使用者都可以檢視 /proc 檔案系統中的行程資訊。為了提高安全性,可以透過 hidepid 選項來限制對 /proc 的存取。在大多數Linux發行版中,可以透過修改 /etc/fstab 檔案來實作這一點。
設定hidepid選項
- 編輯
/etc/fstab檔案並加入以下行:proc /proc proc hidepid=2 0 0 - 重新掛載
/proc檔案系統:sudo mount -o remount proc
hidepid 選項有三個值:
- 0:預設值,允許所有使用者檢視彼此的行程。
- 1:允許使用者檢視其他使用者的行程目錄,但無法
cd到這些目錄,也無法使用ps或top檢視其他使用者的行程資訊。 - 2:隱藏所有其他使用者的行程資訊,包括
/proc中的行程目錄。
程式碼範例與說明
# 編輯/etc/fstab檔案
sudo nano /etc/fstab
# 加入以下行
proc /proc proc hidepid=2 0 0
# 儲存並離開編輯器後,重新掛載/proc檔案系統
sudo mount -o remount proc
內容解密:
- 編輯
/etc/fstab檔案是為了在系統啟動時自動掛載/proc檔案系統並設定hidepid=2,以隱藏其他使用者的行程資訊。 sudo mount -o remount proc命令用於重新掛載/proc檔案系統,使設定立即生效。
行程隔離
行程隔離是另一個重要的安全機制,旨在防止駭客透過許可權提升來進行攻擊。Linux核心提供了多種功能來實作行程隔離,其中包括 Control Groups (cgroups)。
Control Groups (cgroups)
cgroups 是 Linux核心的一個功能,用於將行程分組並對這些組設定資源限制。自 systemd 引入以來,cgroups 成為 Linux 系統的一部分,每個行程預設執行在自己的 cgroup 中。
使用cgroups設定資源限制
- 安裝Apache Web伺服器:
sudo dnf install httpd sudo systemctl enable --now httpd - 為Apache服務開啟資源計費功能:
sudo systemctl set-property httpd.service MemoryAccounting=1 CPUAccounting=1 BlockIOAccounting=1
程式碼範例與說明
# 安裝httpd並啟用服務
sudo dnf install httpd
sudo systemctl enable --now httpd
# 設定httpd服務的資源計費功能
sudo systemctl set-property httpd.service MemoryAccounting=1 CPUAccounting=1 BlockIOAccounting=1
內容解密:
sudo dnf install httpd用於安裝Apache Web伺服器。sudo systemctl enable --now httpd用於啟用並立即啟動httpd服務。sudo systemctl set-property httpd.service MemoryAccounting=1 CPUAccounting=1 BlockIOAccounting=1用於為httpd服務開啟記憶體、CPU和I/O的計費功能,這些設定將寫入/etc/systemd/system.control/httpd.service.d/目錄下的組態檔案中。
管理系統資源與安全性增強:cgroups 與 namespace 隔離詳解
在現代 Linux 系統中,資源管理和安全性增強是至關重要的議題。cgroups(控制群組)和 namespace 隔離是 Linux 核心提供的兩項關鍵功能,它們能夠顯著提升系統的安全性和資源利用效率。本文將探討這兩項技術的工作原理、應用場景以及如何在實際環境中佈署。
cgroups:資源限制與管理
cgroups 是 Linux 核心的一個功能,用於對一組行程進行資源限制、優先順序設定、資源會計和資源隔離。透過 cgroups,管理員可以精確控制行程的資源使用,如 CPU、記憶體、磁碟 I/O 等,從而防止某個行程耗盡系統資源,導致服務品質下降或系統當機。
啟用 cgroups 並設定資源限制
首先,我們需要在系統上啟用某個服務的 cgroups 功能。以 Apache HTTP Server(httpd.service)為例,我們可以透過 systemctl set-property 命令啟用 CPU 和記憶體的會計功能,並設定相應的資源限制。
sudo systemctl set-property httpd.service CPUAccounting=yes MemoryAccounting=yes
sudo systemctl set-property httpd.service CPUQuota=40% MemoryLimit=500M
上述命令會在 /etc/systemd/system.control/httpd.service.d/ 目錄下建立相關的設定檔,用於定義資源限制。
設定檔解析
檢視 50-CPUQuota.conf 檔案內容,可以看到如下設定:
# This is a drop-in unit file extension, created via "systemctl set-property"
# or an equivalent operation. Do not edit.
[Service]
CPUQuota=40%
內容解密:
CPUQuota=40%表示將 Apache HTTP Server 的 CPU 使用率限制在 40% 以內,防止其佔用過多 CPU 資源,影響其他服務的正常運作。- 這種設定方式確保了系統資源的合理分配,避免單一服務壟斷資源。
namespace 隔離:增強安全性與隔離性
namespace 是 Linux 核心提供的另一項重要安全功能,用於實作行程之間的隔離。透過 namespace,不同的行程可以擁有獨立的系統資源檢視,如檔案系統、網路疊件、PID 空間等,從而增強系統的安全性和隔離性。
namespace 的型別
目前,Linux 支援多種 namespace 型別,包括:
- Mount (mnt) namespace:允許每個行程擁有自己的檔案系統掛載點,防止不同行程間的檔案系統操作相互幹擾。
- UTS namespace:允許每個行程擁有獨立的主機名和 NIS 網域名稱。
- PID namespace:為每個行程提供獨立的 PID 空間,使得不同 namespace 中的行程不會分享相同的 PID。
- Network (net) namespace:允許每個行程擁有獨立的網路疊件,包括網路介面、路由表和防火牆規則等。
- Interprocess Communication (ipc) namespace:防止不同 namespace 中的行程透過 IPC 機制相互通訊,增強系統安全性。
- Control group (cgroup) namespace:隱藏行程所屬的 cgroup 資訊,提供額外的隔離層。
- User namespace:允許在不同的 namespace 中使用不同的使用者和組 ID,實作許可權的細粒度控制。
檢視 namespace
可以透過 /proc 檔案系統檢視行程所屬的 namespace。例如:
$ pwd
/proc/7669/ns
$ sudo ls -l
total 0
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 net -> 'net:[4026531992]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 pid -> 'pid:[4026531836]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 user -> 'user:[4026531837]'
lrwxrwxrwx. 1 donnie donnie 0 Oct 30 16:16 uts -> 'uts:[4026531838]'
圖表翻譯:
此圖示展示了行程與不同型別 namespace 之間的隸屬關係。每個 namespace 提供了一種特定的隔離機制,共同構成了 Linux 系統安全性與隔離性的基礎。
深入理解 Linux 名稱空間與核心能力
名稱空間的進階應用
在前面的討論中,我們已經初步瞭解了 Linux 名稱空間的基本概念。現在,讓我們進一步探討名稱空間在實際應用中的重要性。仔細觀察系統中的某個目錄時,你可能會發現一個特殊的專案 pid_for_children,它負責追蹤子名稱空間中的程式 ID。雖然大多數使用者不太可能直接建立自己的名稱空間,但許多現代軟體和工具已經內建了名稱空間技術。
例如,某些現代網頁瀏覽器利用名稱空間為每個開啟的分頁建立沙盒環境,而 Docker 則使用名稱空間來隔離容器之間的環境及其與主機作業系統的互動。這種技術大大增強了系統的安全性和資源管理的靈活性。
核心能力的基本原理
在執行 ps aux 命令時,你可能會注意到許多由 root 使用者擁有的程式。這是因為這些程式需要存取某些普通使用者無法存取的系統資源。然而,讓服務以完全的 root 許可權執行可能會帶來安全風險。幸運的是,Linux 提供了核心能力(kernel capabilities)來減輕這種風險。
核心能力允許將 root 使用者的許可權劃分為不同的單元。例如,像 Apache 或 Nginx 這樣的網頁伺服器服務需要以 root 許可權啟動,以便繫結到特權埠(如 80 和 443)。但一旦啟動,它們通常會放棄 root 許可權,或產生屬於非特權使用者的子程式。
程式碼範例:檢視 Apache 程式
[donnie@centos7-tm1 ~]$ ps aux | grep http
root 1015 0.0 0.5 230420 5192 ? Ss 15:36 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1066 0.0 0.2 230420 3000 ? S 15:36 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1067 0.0 0.2 230420 3000 ? S 15:36 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1068 0.0 0.2 230420 3000 ? S 15:36 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1069 0.0 0.2 230420 3000 ? S 15:36 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1070 0.0 0.2 230420 3000 ? S 15:36 0:00 /usr/sbin/httpd -DFOREGROUND
donnie 1323 0.0 0.0 112712 964 pts/0 R+ 15:38 0:00 grep --color=auto http
#### 內容解密:
此命令用於檢視與 http 相關的程式。可以看到,主 Apache 程式以 root 使用者執行,而子程式則以非特權的 apache 使用者執行。這種設計有效地降低了安全風險。
使用核心能力提升安全性
對於某些無法放棄 root 許可權的程式,可以透過賦予其特定的核心能力來降低安全風險。例如,若某個自定義程式需要存取特權網路埠,可以賦予其 CAP_NET_BIND_SERVICE 能力,而無需以 root 身份執行該程式。
程式碼範例:為 Python 設定核心能力
首先,檢查 Python 可執行檔的位置:
[donnie@localhost ~]$ which python2
/usr/bin/python2
[donnie@localhost ~]$ ls -l /usr/bin/python2
lrwxrwxrwx. 1 root root 9 Oct 8 17:08 /usr/bin/python2 -> python2.7
接著,檢視並設定核心能力:
[donnie@localhost ~]$ getcap /usr/bin/python2.7
[donnie@localhost ~]$ sudo setcap 'CAP_NET_BIND_SERVICE+ep' /usr/bin/python2.7
[donnie@localhost ~]$ getcap /usr/bin/python2.7
/usr/bin/python2.7 = cap_net_bind_service+ep
#### 內容解密:
getcap用於檢查檔案是否已設定核心能力。setcap用於為檔案設定特定的核心能力。在此例中,我們為python2.7賦予了CAP_NET_BIND_SERVICE功能,使其能夠繫結到特權埠(如埠80),而無需以 root 身份執行。
圖表說明:核心能力的使用流程
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Linux系統安全強化Proc與行程隔離
package "安全架構" {
package "網路安全" {
component [防火牆] as firewall
component [WAF] as waf
component [DDoS 防護] as ddos
}
package "身份認證" {
component [OAuth 2.0] as oauth
component [JWT Token] as jwt
component [MFA] as mfa
}
package "資料安全" {
component [加密傳輸 TLS] as tls
component [資料加密] as encrypt
component [金鑰管理] as kms
}
package "監控審計" {
component [日誌收集] as log
component [威脅偵測] as threat
component [合規審計] as audit
}
}
firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成
@enduml
圖表翻譯: 此圖展示了為可執行檔設定核心能力的流程,包括檢查檔案、檢視和設定核心能力,以及驗證結果和測試功能。
瞭解 Linux 系統中的能力(Capabilities)與安全機制
設定能力(Capabilities)並非萬能解方
在 Linux 系統中,設定特定的能力(Capabilities)有時仍無法滿足程式執行的需求。某些情況下,即使賦予特定能力,程式仍可能無法在沒有 root 許可權的情況下正常運作。此外,系統更新可能會覆寫已設定能力的執行檔。
實作:為 Python 網頁伺服器設定能力
本實驗將示範如何允許一般使用者執行 Python 網頁伺服器,需使用 Python 2,在 AlmaLinux 8 虛擬機器上進行:
- 停止 Apache 服務(若已安裝):
sudo systemctl stop httpd - 安裝 Python 2:
sudo dnf install python2 - 嘗試以一般使用者啟動 Python SimpleHTTPServer,並記錄錯誤訊息:
python2 -m SimpleHTTPServer 80 - 檢查 Python 執行檔的能力設定:
getcap /usr/bin/python2.7 - 為 Python 執行檔設定
CAP_NET_BIND_SERVICE能力:sudo setcap 'CAP_NET_BIND_SERVICE+ep' /usr/bin/python2.7 - 重複步驟 3 和 4,此時應能成功執行。
- 確保虛擬機器防火牆已開放 80 連線埠,並使用主機的網頁瀏覽器存取伺服器。
- 使用
Ctrl + C關閉網頁伺服器。 - 檢視
ping執行檔的能力設定:getcap /usr/bin/ping
理解 SECCOMP 與系統呼叫(Syscalls)
Linux 核心包含約 330 個系統呼叫(Syscalls),用於執行特權操作,如檔案操作、許可權變更等。Secure Computing (SECCOMP) 允許限制或停用特定程式的系統呼叫,提升安全性。
使用 strace 命令觀察系統呼叫
strace -c -f -S name ls 2>&1 1>/dev/null | tail -n +3 | head -n -2 | awk '{print $NF}' | sort -u
SECCOMP 的應用
SECCOMP 最初為 Google Chrome 瀏覽器開發,現廣泛用於限制程式的系統呼叫,確保安全性。
使用 Docker 容器進行程式隔離
Docker 容器技術利用核心能力(Kernel Capabilities)、cgroups、namespaces 和 SECCOMP 等技術實作容器間及容器與主機間的隔離。預設情況下,Docker 容器執行於受限的能力和系統呼叫下,可進一步增強安全性。
Docker 安全性的考量
儘管 Docker 提供多層隔離,但仍存在安全風險。例如,非特權的 docker 群組成員可掛載主機的根檔案系統於自建容器中。
程式碼解析:
以下為 Python SimpleHTTPServer 的範例程式碼:
# SimpleHTTPServer.py
from http.server import HTTPServer, BaseHTTPRequestHandler
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"Hello, world!")
def run(server_class=HTTPServer, handler_class=RequestHandler):
server_address = ('', 80)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
if __name__ == "__main__":
run()
內容解密:
此範例程式碼展示了一個簡單的 HTTP 伺服器,使用 Python 的 http.server 模組實作。主要功能包括:
- 處理 GET 請求:當接收到 GET 請求時,回傳 “Hello, world!"。
- 繫結連線埠:預設使用 80 連線埠,需具備
CAP_NET_BIND_SERVICE能力。 - 持續執行:伺服器啟動後持續執行,監聽請求。
此範例說明瞭如何使用 Python 建立基本網頁伺服器,並透過設定能力來允許非 root 使用者繫結特權連線埠(如 80)。