iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0

虛擬化-相信 IT 界的人員應該都不會覺得這個名詞很陌生,因為虛擬化技術帶給企業前所未有的便利,也節省了不少成本。

2013 年,影響力極大的 Docker 橫空出世,讓許多開發人員開始採用容器技術。Docker 是什麼呢?為了後續的主題,我們先來談談虛擬化技術的名人-容器(Container)。

虛擬化技術的介紹

用下面這張圖來跟大家介紹虛擬化技術:
lab-01

  • 傳統主機:就是大家想像中的一台實體主機上面跑著固定的服務;在維運成本上,除了軟體的維護更新,還要負擔硬體設備的維護。
  • 虛擬機器:常見的例子就是 VMware、VirtualBox,透過把主機的硬體資源獨立切割出來,建立一個新的 OS 區塊。
  • 容器:透過跟主機共享 Kernel 建立起來的虛擬化環境;因為共享 Kernel,所以不用安裝 OS,使用起來更輕便快速。

Docker 使用的虛擬化就是以容器的形式出現,那什麼是容器?簡單來說,Linux 容器裡的應用,仍然是執行在 Host 上的程序,由 Host 的核心管理。容器透過 Namespace 等機制,讓這些程序擁有不同的資源視圖,再搭配權限與資源限制,形成相對隔離的執行環境。我們用下面的範例跟各位介紹:
lab-02

可以發現我用 ps aux 的時候其實找得到建立起來的 Container,我用 kill -9 <PID> 的時候我建立起來的 Container 就接著消失了。這邊也直接的證明所謂的容器說穿了只是一個 Process,雖然說很方便部署速度也很快,但是穩定性沒有一定的保證。

根據以上的內容我們可以得到以下結論:

  1. 方便性:容器>虛擬機>傳統主機。
  2. 生命週期存活度:傳統主機>虛擬機>容器。
  3. 隔離性:傳統主機>虛擬機>容器。
  4. 部署速度:容器>虛擬機>傳統主機。

單看虛擬化的比較會發現,容器目前還沒辦法完全取代虛擬機,兩者現在是相輔相成的好夥伴。常見的架構,是在一台實體主機上跑多個虛擬機,每個虛擬機裡再同時跑好幾個 Container。

談談 Docker 的基本特性

雖然說 Container 的隔離性比虛擬機差,但……它的隔離程度究竟是什麼樣子?接下來用實作的方式讓大家了解。首先輸入這個指令建立一個容器:

程序隔離

docker run -d --name lab12-box ubuntu:22.04 sleep infinity

這個指令的意思是:用 ubuntu:22.04 這個 Image 建立一個名稱叫 lab12-box 的容器並在背景持續執行,容器啟動後跑的第一個指令是 sleep infinity。

執行完後我們用 docker ps 來看看是否建立成功:
lab-04

接著使用這個指令進入容器內部:

docker exec -it lab12-box bash

lab-05

下面對照 Container 與 Host 的指令結果(左邊為 Container、右邊為 Host)。先執行以下指令,檢查身分以及看得到的程序有哪些:

id
ps aux
cat /proc/1/comm

lab-06
lab-07

我們可以看到 Host 可以觀察到容器內的程序,但容器內透過 ps 看到的程序範圍較小。搭配後面 PID Namespace 編號不同的結果,可以看出兩者使用不同的 PID Namespace。另外,容器內同時出現 sleep、bash 與 ps,也說明一個容器可以執行多個程序。具體隔離哪些資源,我們可以用下面這個指令做初步查看:

ls -l /proc/self/ns/
readlink /proc/self/ns/{pid,mnt,net,uts,ipc,user}

lab-08

  • ls -l /proc/self/ns/:看目錄裡有哪些 Namespace 項目。
  • readlink /proc/self/ns/{pid,mnt,net,uts,ipc,user}:直接讀出指定 Namespace 的 symlink 指向哪個 inode。

可以看到 Namespace 的資源被獨立分開出來,跟 Host 讀到的資源不一樣。唯一一樣的只有 user 這個資源,這也間接證明 Docker 預設是使用 root 的身分建立容器。

關於 Namespace 各項資源的說明,可以參考 Linux 官方文件。
參考連結:namespaces(7) — Linux manual page

核心共享

在介紹虛擬機技術的差異時,我們看到容器跟主機共享同一個核心,這一點可以透過以下指令查證:

uname -r
cat /proc/version

lab-09

權限限制

在前面我們剛剛證明了容器的身分跟 Host 一樣都是 root 想必嚇了大家一跳,這樣不是很危險嗎?但其實 Docker 有限制了容器內的 root 權限,我們可以透過以下指令查證:

capsh --print 2>/dev/null || grep Cap /proc/self/status

lab-10
為了安全,Docker 預設丟掉了一票危險的 capabilities(如 CAP_SYS_ADMIN、CAP_SYS_MODULE),甚至額外加了一些限制。從這個結果可以確認,Docker 預設給容器的 root 權限並不完整。

掛載檔案系統的不同

最後我們用一個比較簡單的指令,查看兩者之間的檔案系統會不會一樣?

ls -l /root

lab-11

從結果可以看到,在本次預設設定下,容器內的 /root 與 Host 的 /root 顯示不同內容。這是因為容器使用自己的根檔案系統,因此即使同樣以 root 身分查看 /root,看到的也不是 Host 的 /root 目錄。

今天透過以上幾個實驗了解了容器的特性;明天,我們將更進一步看看錯誤的容器設定會造成什麼樣的風險。

感謝大家的收看,我們明天見!


上一篇
Day 11|從 sudo 到 SSH:回顧提權的成因與成立條件
下一篇
Day 13|拿到 Container Shell 之後,攻擊者下一步會找什麼?
系列文
我以前被社會打穿,現在輪到我研究怎麼把系統打穿:資安工程師的 30 天紅隊轉職實驗 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言