隨著越來越多的個人和企業採用 Docker 進行應用程式、資料函式庫和其他關鍵業務應用的容器化、佈署和代管,確保 Docker 平台的安全性變得至關重要。Docker 平台廣泛應用於各種場景,這也帶來了許多潛在的安全問題和陷阱。
當一項技術被廣泛使用時,其平台的安全性往往會受到更多關注。攻擊者不斷尋找設定錯誤和漏洞以利用系統和網路。如果未能正確設定並保護好 Docker 平台,可能會導致大規模資料洩露或系統被攻擊。
因此,我們必須認真對待 Docker 的安全問題,並制定有效的安全策略來解決平台中的各種問題。
基本要求與準備
前提條件
本專注於在 Linux 上安裝並執行最常見版本的技術——Docker 的安裝與執行環境設定。 要跟隨此中的技巧示範內容, 您需要具備以下服務已經安裝與正常執行:
- Docker
注意: 本文中的所有演示均是在 Ubuntu 20.4 伺服器上執行 DOCKER CE 的環境下進行測試, 命令是透過不同分發版之間分享, 包括套件名稱、套件管理員以及相對應初始化系統.
技術需求
- 基本知識:熟悉 DOCKER 和 DOCKER CLI 命令。
- 功能知識:熟悉 Linux 指令終端命令。
- 基本知識:熟悉 systemd 和 Linux 初始化系統。
由於個人及公司普遍採納了 DOCKER 作為 Web 應用程式、資料函式庫以及其他商業關鍵型應用程式之容器化、佈署以及主機等功能, 因此確保 DOCKER 平台之安全部份成為成功長期使用該平台之必要條件之一. 在各種使用情境下都可以看到該平台之存在, 而這些情況也帶來了許多潛在風險.
當一項技術被廣泛使用時, 人們通常會對該平台進行細緻檢查. 攻擊者不斷尋找設定錯誤或漏洞以利於攻擊系統或網路. 未能正確設定與維護好該平台可能導致大規模資料洩露或遭受攻擊.
因此我們必須重視該平台之安全部份, 建立完善與可行之政策以解決其中所出現的一些問題. 最常見的是認為「出廠即可」就足夠完成所有工作的人群. 與其他很多類別似產品一樣,Docker 需要從頭開始建立起自己的防禦體系. 另一個阻止採納與實施此專案的人群是因為它所涉及到的一些抽象概念以及複雜度高低不穩定等原因. 直到最近之前,LXC 一型別仍然不是主流替代方案之一主要原因就是因為它具有高度專業性質與難以理解. 然而,Docker 則是開發出來簡單易懂地讓更多人可以接受並加入其中去學習如何使用它, 同時也持續改進使得整體流程更加高效率. 不過即使如此,Docker 在某些方面仍然需要一些時間才能適合組織內部去學習如何去做好防禦工作.
本章旨在提供清晰明瞭地指引您如何去做好 docker platform 與 docker container 在執行期間所需做好的事前準備工作
Docker 平台概述
Docker 是一種 PaaS(平台即服務)容器化技術,利用作業系統層級的虛擬化,讓使用者能夠封裝、分發和佈署軟體、網頁應用程式以及其他可容器化的資料。與傳統的 Level 2 虛擬機器相比,Docker 直接使用主機作業系統核心,而不是為每個容器虛擬一個完整的作業系統。
以下是 Docker 平台各元件及其互連方式:
- Docker Client:透過 Unix 域通訊端或遠端 TCP 通訊端與 Docker Daemon 進行通訊。
- Docker Daemon:負責處理來自 Docker Client 的命令並管理容器。
- Containerd:負責管理容器生命週期,包括推播和提取映像以及儲存管理。它是行業標準的容器管理解決方案,也被 Kubernetes 等平台所使用。
- runc:Containerd 使用 runc 作為執行時規範來建立和管理實際的容器。
這種模組化設計使得每個元件可以單獨處理和保護,從而提高了安全性。
安全稽核
在開始保護系統之前,首先需要進行安全稽核。安全稽核會建立系統當前安全狀態的基線,指導我們後續需要採取哪些措施來加強安全性。
安全稽核是什麼?
安全稽核是對特定資訊系統進行系統性評估以檢查其設定與安全部份, 檢查專案包括最佳實踐、標準等. 在本文中,我們將使用 CIS DOCKER Benchmark 作為參考依據.
CIS DOCKER Benchmark 提供了一系列具體指引與檢查專案, 用於測試 DOCKER 平台之安全部份並建立基礎之安全部份. 有關更多詳細資料請參閱: https://www.cisecurity.org/benchmark/docker/
自動化工具:Docker Bench for Security
Docker Bench for Security 是一款開放原始碼 Bash 指令碼, 用於檢查在生產環境中佈署 DOCKER 的常見最佳實踐. 測試專案均已自動化與根據 CIS DOCKER Benchmark. 有關更多詳細資料請參閱 GitHub: https://github.com/docker/docker-bench-security
安裝與執行步驟:
- 首先在您的 Docker 主機上克隆 docker/docker-bench-security GitHub 儲存函式庫:
git clone https://github.com/docker/docker-bench-security.git
- 接著進入剛剛克隆下來之儲存函式庫:
cd docker-bench-security
- 在該目錄下找到名為
docker-bench-security.sh
的 Bash 指令碼, 執行以下命令以啟動 Docker 安全性審核:
sudo ./docker-bench-security.sh
- 執行指令碼後會自動完成所有必要之檢查工作.
安全稽核結果分析
在執行 Docker Bench for Security 後,我們會得到一個初始的安全基線評分,這個評分通常為零,表示所有檢查專案都未透過。這時候我們可以透過分析指令碼生成的結果來確定哪些部分需要加強安全性。
結果解釋
每個檢查專案都會被標記並顯示相應的狀態:
- WARN:表示該檢查專案失敗,需要進行安全加固。
- INFO:表示該檢查專案執行正常,無警告。
- PASS:表示該檢查專案成功執行。
指令碼還會提供建議清單,指出哪些元件需要進行安全加固。例如,如下圖所示,我們需要啟用 Docker Daemon 的稽核功能。
分類別與優先順序
指令碼將結果按以下類別進行排序:
- 主機設定
- 一般設定
- Docker Daemon 設定
- Docker Swarm 設定
這種分類別方式有助於區分不同元件的安全性問題,從而簡化處理流程。根據結果顯示,Docker 主機是第一個需要保護的元件。接下來我們將探討如何保護 Docker 主機並實施 Docker Bench for Security 工具推薦的安全措施。
安全主機:Linux 作業系統
由於 Docker 容器使用的是主機作業系統核心,因此主機作業系統和其容器之間存在著密切關聯. 如果您使用的是 Linux 作為您之主機作業系統, 則必須遵循以下指引:
- 選擇最小化版本之 Linux 發行版以減少攻擊面積.
- 加強及保護好您之主機作業系統.
- 持續更新您之主機作業系統至最新版本.
- 持續更新您之核心至最新版本.
- 安裝並執行最新版本 DOCKER .
- 在漏洞管理計劃中包含您之主機與容器,持續掃描漏洞以確保其安全部份.
7 .僅執行必要服務.
8 .持續關注 Linux 核心以及 DOCKER 平台上發布出現的一些漏洞資訊.
Lynis 安全稽核工具
Lynis 是一款可擴充套件與適用於多種 Unix 派生系統(包括 Linux、FreeBSD、macOS、OpenBSD 和 Solaris)上的安全部份稽核工具,它幫助系統管理員和安全部份專業人士對系統進行掃描並鑒定其防禦能力,最終達到硬化系統目的.
Lynis 安裝步驟:
Lynis 在大多數 Linux 發行版中均可直接透過套件管理器安裝:
sudo apt-get install lynis
若要顯示所有可用選項與命令:
lynis show options
在開始之前請先確認 Lynis 已經更新到最新版:
sudo lynis update info
執行 Lynis 掃描:
要對整體系統進行一次完整掃描請輸入以下命令:
sudo lynis audit system
此次掃描所產生出來的一些重要資料將會儲存在 /var/log/lynis.log
中供日後參考使用,
同時也會列出一些可能存在問題或不當設定等情況供參考修正.
Lynis 安全掃描結果
Lynis 的安全掃描結果會顯示硬化指數,這個指數是根據 100 分來評估系統當前的安全狀態。此外,Lynis 還會列出任何潛在的警告,指出嚴重的安全漏洞或設定錯誤需要修復或更新。
推薦建議
為了提高硬化指數分數,Lynis 提供了一些有用的建議,詳細說明我們需要進行哪些安全設定:
-[ Lynis 3.0.0 Results ]
Great, no warnings
Suggestions (50):
---------------------------
• This release is more than 4 months old. Consider upgrading [LYNIS]
https://cisofy.com/lynis/controls/LYNIS/
• Set a password on GRUB boot loader to prevent altering boot configuration [BOOT-5122]
https://cisofy.com/Lynis/controls/BOOT-5122/
• Consider hardening system services [BOOT-5264]
Details : Run ‘/usr/bin/systend-analyze security SERVICE’ for each service
https://cisofy.com/Lynts/controls/BOOT-5264/
• If not required, consider explicit disabling of core dump in /etc/security/limits.conf
https://cisofy.com/Lynis/controls/KRNL-5820/
• Check PAM configuration, add rounds if applicable and expire passwords to encrypt
https://ctsofy.com/Lynis/controls/AUTH-9229/
建立使用者帳戶
接下來我們將開始保護主機作業系統:
- 建立並設定必要的使用者帳戶:首先要做的是在系統上新增並設定必要之使用者帳號。
- 接著我們需要設定各種群組以分配特定角色之許可權給不同使用者。
- 在最後一步中我們將開始指設定檔案許可權以及分配特設定檔案與目錄之擁有權.
Linux 支援多使用者模式,因此多個使用者可以同時存取該系統. 從安全部份角度來看這既是優點也是缺點:因為多個帳號提供了更多攻擊向量, 所以增加了整體伺服器風險.
建立 Linux 使用者帳號:
以下是如何在 Linux 上建立一個新使用者帳號:
useradd -c "First Name Last Name" -m -s /bin/bash <username>
其中 -c
是用於包含關於該帳號的一些文字字串(例如: 使用者名稱), -m
則表示要建立該新使用者之家目錄,
-s
則表示要設定預設登入 Shell (例如: /bin/bash
).
指定密碼:
接著我們需要為此新帳號設定密碼:
passwd <username>
然後您會被要求輸入密碼,請務必遵循您組織內部所制定出來之安全政策規範.
設定 sudo 許可權
在 Linux 主機上設定存取時,有些人可能需要 sudo 許可權以執行一些管理任務如更新套件或安裝軟體等. 預設情況下所有使用者都沒有 sudo 許可權,因此無法執行這類別管理任務.
增加到 sudo 群組:
若想讓某位已經存在之使用者擁有 sudo 許可權則可以透過以下命令將其增加至 sudo
或 wheel
群組中:
usermod -aG sudo <username>
增加到 Docker 群組
Docker 對 Docker Daemon 的存取控制是透過具有特殊許可權的 Linux 機構實作。只有授權與需存取的人才應被增加到此群組。
增加自訂使用者到 Docker 群組:
若想讓某位已經存在之使用者能夠與 Docker Daemon 請求互動則可以透過以下命令將其增加至 docker
群組中:
usermod -aG docker <username>
停止 root 帳號登入
第一步就是停止 root 帳號登入功能。完成此步驟後可防止任何未經授權或未經授權的人員取得root帳號並進行惡意操作。
停用 root 登入
root 使用者的許可權可以被濫用來執行任何命令(無論是惡意還是非惡意),包括修改系統上其他使用者的密碼,從而將他們鎖定在外。常見的 Linux 安全實踐建議停用 root 登入並建立一個單獨的管理員帳號,該帳號可以分配 sudo 許可權以執行需要 root 許可權的命令。這樣做可以減少對 root 帳號的威脅並降低主機的整體攻擊面。
方法一:更改預設 Shell
我們可以透過將 root 使用者的預設 Shell 從 /bin/bash
或 /bin/sh
改為 /usr/sbin/nologin
來停用 root 登入。這可以使用 Linux 的 chsh
工具來完成:
- 執行以下命令:
sudo chsh -s /usr/sbin/nologin root
- 接著嘗試登入到根帳號,您會看到「This account is currently not available」訊息,表示無法登入到根帳號。
方法二:鎖定密碼
另一種防止根登入方式就是使用 passwd
工具鎖定根賬戶之密碼:
sudo passwd -l root
若想解除某位特定賬戶之密碼則可透過以下指令:
sudo passwd -u <username>
SSH 安全設定
如果您未停止允許 Root 帳號進行遠端連線, 則攻擊者可能會嘗試透過暴力破解 SSH 嘗試取得 Root 許可權. 因此即使已經停止允許 Root 帳號進行遠端連線, 您仍然應該考慮禁止此型別操作.
防止 SSH 中之 Root 請求:
- 編輯 OpenSSH Server 設定案:
/etc/ssh/sshd_config
- 在檔案中找到
#Authentication:
標題下方之PermitRootLogin yes
,並將其更改為PermitRootLogin no
- 儲存後重新啟動 sshd service:
sudo systemctl restart sshd
接著我們再次嘗試透過 SSH 命令去連線至伺服器,如下圖所示我們會收到 Permission Denied 錯誤訊息, 這代表我們成功地阻擋了所有透過 SSH 去請求 Root 資源之要求.
內容解密:
- chsh: Change Shell (變更 shell) 是一個 Unix/Linux 命令, 用於讓使用者能夠變更自己的預設 shell。
- nologin: nologin 是一個特殊 shell, 主要目的是拒絕任何人進入系統。
- passwd: passwd 是一個 Unix/Linux 命令, 用於設定或更新使用者密碼。
- -l:
-l
是 passwd 的選項之一, 用於鎖定指定使用者賬戶. - -u:
-u
是 passwd 的選項之一, 用於解除指定使用者賬戶上的鎖定狀態. - systemctl restart sshd: systemctl 是 Systemd 初始化系統中的工具之一, 它提供了一些管理系統服務和守護程式的一些功能. restart 指的是重新啟動某項服務(例如: sshd).
設定 SSH 金鑰驗證
金鑰驗證利用非對稱加密生成兩個金鑰,分別用於資料的加密和解密。這兩個金鑰分別稱為公鑰和私鑰。公鑰可以公開分享,而私鑰必須保持機密。
生成 SSH 金鑰對
我們可以使用 ssh-keygen
工具在客戶端生成 SSH 金鑰對:
ssh-keygen -t rsa
這將生成一組 RSA 公私金鑰對,並提示您指定要儲存金鑰的目錄以及為該金鑰對設定口令碼(可選)。
上載公共金錢至伺服器
接著我們需要將公共金錢上載到伺服器:
ssh-copy-id <username@SERVER-IP>
停用密碼驗證
現在我們已經能夠使用私人秘匙登入, 接下來就是完全停止允許透過 SSH 做遠端連線之功能.
- 編輯 OpenSSH Server 設定案:
/etc/ssh/sshd_config
- 在檔案中找到
#Authentication:
標題下方之PasswordAuthentication yes
,並將其更改為PasswordAuthentication no
- 儲存後重新啟動 sshd service:
sudo systemctl restart sshd
內容解密:
- ssh-keygen: 是一個 Unix/Linux 必備工具, 用於產生、管理及轉換認證所需之公開與私有秘匙.
- -t rsa:
-t
是 ssh-keygen 的選項之一, 用於指定要產出的秘匙型別(例如: RSA). - ~/.ssh/id_rsa: 預設情況下, ssh-keygen 會在當前使用者家目錄中的
.ssh
資料夾中產出名為 id_rsa 的私有秘匙, 同時也會產出名為 id_rsa.pub 的公開秘匙. - passphrase: passphrase 是一種額外安全措施, 用於保護您的私有秘匙不被未經授權的人員取得.
執行 Lynis 安全掃描
完成所有建議後,我們可以再次執行 Lynis 安全掃描以確認變更是否成功應用:
sudo lynis audit system
如圖所示,硬化指數應該會因遵循安全建議而增加。
Docker 檔案稽核規則設定
在初次進行 Docker 安全稽核時,我們發現需要針對特定 Docker 檔案設定稽核規則。這些檔案包括設定、二進位檔以及 systemd 服務檔等。
執行 Docker Bench for Security 工具:
再次執行此工具並限制結果僅顯示主機設定部分:
sudo ./docker-bench-security.sh -c host_configuration
內容解密:
- Docker Bench for Security : 一款開放原始碼 Bash 指令碼, 用於自動化測試 DOCKER 平台佈署時的一些最佳實踐. 它根據 CIS DOCKER Benchmark 作為參考依據.
Linux Audit 框架概述
Linux Audit 框架用來設定及設定一些像是 DOCKER 一樣之使用者空間程式之監控政策。 以下圖表說明瞭 Linux Audit Framework 各元件如何互相作用:
安裝 Auditd
Auditd 在大多數 Linux 發行版中都預先安裝,但如果需要手動安裝,可以使用您的發行版套件管理器。在 Ubuntu 和根據 Debian 的發行版中,可以透過以下命令安裝 Auditd:
sudo apt-get install auditd
為 Docker 檔案建立稽核規則
我們之前使用 Docker Bench for Security 工具進行的主機設定安全稽核提供了一些需要進行稽核的 Docker 檔案列表。我們可以透過執行以下 auditctl
命令來為這些檔案建立稽核規則:
sudo auditctl -w <path to artifact> -k docker
其中 -w
用於指定要監控的檔案或服務,-k
用於指定篩選鍵(filter key),這是一個簡短的文字字元串。同一個鍵可以應用到多個不同的稽核規則上,從而方便分析和搜尋日誌。
建立所有必要的稽核規則
根據之前 Docker Bench for Security 報告中的警告資訊,我們需要為每個警告建立相應的稽核規則。例如:
- 對於
/etc/docker
目錄:
sudo auditctl -w /etc/docker -k docker
- 對於其他目錄和檔案也類別似地建立相應的稽核規則。
檢視已建立的所有稽核規則
完成後, 我們可透過以下命令檢視已經生成之所有稽核規則:
sudo auditctl -l
內容解密:
- auditctl: 是一款 Unix/Linux 必備工具, 用來管理及控制 Linux Audit 框架.
- -w:
-w
是auditctl
的選項之一, 用來指定要監視之檔案或服務. - -k:
-k
是auditctl
的選項之一, 用來指定篩選鍵(Filter Key). 篩選鍵是一種簡短文字字元串, 它能夠將不同之稽核規則群組化.
永久儲存並重啟 Auditd
接著將這些新增之稽核規則寫入 /etc/audit/rules.d/audit.rules
,然後重新啟動 auditd
:
- 編輯
/etc/audit/rules.d/audit.rules
- 增加剛才生成之所有稽核規則:
-w /usr/bin/dockerd -p rwxa -k docker ...
- 儲存並關閉編輯器。
- 接著重新啟動
auditd
:
sudo systemctl restart auditd
- 最後再次執行 Docker Bench for Security 工具以確認所設定出來之稽核規則已經成功啟用:
cd ~/docker-bench-security/
sudo ./docker-bench-security.sh -c host_configuration"
內容解密:
- systemctl restart : systemcti 是 SystemD 初始化系統中的工具之一, 它提供了一些管理系統服務和守護程式的一些功能. restart 指的是重新啟動某項服務(例如: ssh).
安全 DOCKER Daemon
現在我們已經擁有一個安全與穩固運作中的 DOCKER 主機環境了, 接下來就是開始對 DOCKER Daemon 本身進行一些安全性加強工作.
實施 TLS 加密
Docker Client 與 Docker Daemon 之間的通訊可以透過 Unix 域通訊端本地進行,也可以透過 TCP 通訊端遠端進行。然而,這些通訊在預設情況下是不加密的,因此攻擊者可能會進行中間人攻擊(MITM),攔截從 Docker Client 傳送到 Docker Daemon 的命令。
生成 TLS 憑證
我們將使用自動化 Bash 指令碼來生成 TLS 憑證。以下是步驟:
- 下載並執行指令碼:
cd ~
wget https://raw.githubusercontent.com/AlexisAhmed/DockerSecurityEssentials/main/Docker-TLS-Authentication/secure-docker-daemon.sh
chmod u+x secure-docker-daemon.sh
./secure-docker-daemon.sh
- 指令碼會提示您輸入 Docker Server IP 地址,然後自動在
.docker/
目錄中建立客戶端和伺服器憑證。
內容解密:
- TLS (Transport Layer Security): 是一種安全協定, 用於保護網路通訊.
- Unix 域通訊端: 是一種 IPC (Inter-Process Communication)機制, 用於允許不同程式之間進行通訊.
- TCP (Transmission Control Protocol): 是一種網路協定, 提供可靠的資料傳輸.
設定 Docker Daemon
生成 TLS 憑證後,我們需要為 Docker Daemon 建立自定義 systemd 設定檔案以啟用 TLS 和指定 TLS 憑證。
- 建立並編輯設定檔案:
sudo mkdir /etc/systemd/system/docker.service.d/
sudo vim /etc/systemd/system/docker.service.d/override.conf
- 在檔案中增加以下設定(請將
<user>
替換為您的使用者名稱):
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -D -H unix:///var/run/docker.sock --tlsverify --tlscert=/home/<user>/.docker/server-cert.pem --tlscacert=/home/<user>/.docker/ca.pem --tlskey=/home/<user>/.docker/server-key.pem -H tcp://0.0.0.0:2376"
- 儲存並重新啟動 Docker Service:
sudo systemctl restart docker"
- 接著將客戶端 TLS 憑證複製到遠端 DOCKER Client 上以完成認證工作.
內容解密:
- systemd: 是 Linux 中的一個初始化系統與系統管理守護程式, 它提供了一些管理系統服務和守護程式的一些功能. daemon-reload 指的是重新載入所有已更改之 service unit file. restart 指的是重新啟動某項服務(例如: ssh).