當我們執行 DOCKER Container時,該流程預設是在預設名稱空間下執行,因此該流程被視為 root 使用者執行(如圖所示).如果發生 container breakout 的情況則可能會造成嚴重問題,因為攻擊者可能會獲得主機上的 root 許可權.

啟用使用者名稱空間:

1 . 編輯 /etc/systemd/system/docker.service.d/override.conf:

[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=//<user>/ . docker/server-key.pem \--userns-remap="default"\
  -H tcp://0:0:0:2376"

2 . 儲存並關閉編輯器。 3 . 接著重新載入及重啟 systemctlDOCKER : ```bash" sudo systemctl daemon-reload && sudo systemctl restart docker"

4 . 接著檢查目前正在執行中的 container 名稱為 test 的 process ID: ```bash" docker container top test"

5 . 若一切正常則應該看到類別似如下圖所示之結果:

內容解密:

  • -userns-remap=“default”: -userns-remap="default"DOCKER 必備引數之一, 它能夠讓 DOCKER Container 在非特權模式下執行.

再次執行安全稽核工具

現在我們已經成功實施了 TSL 加密以及 User Namespace 助理功能, 接下來就是再次執行安全稽核工具以確認所做出來之修改是否有效:

cd ~/docker-bench-security/
sudo ./docker-bench-security.sh -c host_configuration"

使用非特權使用者

在容器中使用非特權使用者可以防止提升許可權的攻擊。以下是具體步驟:

  1. 自定義 Docker 映像:總是重新設定並構建自己的 Docker 映像,以便根據您的需求自定義各種安全引數。
  2. 更新 Dockerfile:在構建映像之前,需要更新 Dockerfile。這可以透過向 Dockerfile 增加類別似以下命令來實作:
RUN groupadd -r <user> && useradd -r -g <group> <user>
  1. 執行容器:現在可以使用非特權使用者執行容器,而不是預設的 root 使用者。您可以使用 docker run 命令中的 -u 選項指定容器的使用者:
docker run -u <user> <IMAGE-ID>

內容解密:

  • -u: -udocker run 的選項之一, 用於指定要執行之 container 中之預設使用者.
  • groupadd: groupadd 是一個 Unix/Linux 必備工具, 用於建立新群組.
  • -r: -r 是 groupadd 的選項之一, 用於建立系統群組.

停用 Root 使用者

作為額外的安全措施,我們可以透過修改 Dockerfile 來停用容器中的 root 使用者。具體方法是將預設 Shell 從 /bin/bash 改為 /usr/sbin/nologin。這可以透過向 Dockerfile 增加以下命令來實作:

RUN chsh -s /usr/sbin/nologin root

這樣做將防止任何人存取根帳號,無論他們是否擁有根密碼。

內容解密:

  • chsh (Change Shell): chsh 是一個 Unix/Linux 必備工具, 用於讓使用者能夠變更自己的預設 shell.

防止提升許可權攻擊

建議以特定許可權執行您的容器,並確保使用者無法提升其許可權。這可以透過在執行時增加 --security-opt=no-new-privileges 標誌來實作:

docker run --security-opt=no-new-privileges <IMAGE-ID>

此標誌會阻止程式獲得任何額外的許可權。

內容解密:

  • -security-opt=no-new-privileges: --security-opt=no-new-privileges 是 docker run 的選項之一, 它能夠阻止 container 中之 process 獲得任何額外許可權.

控制 Container 資源消耗

當我們執行 Container時,我們也可透過一些引數去控制該 Container 能夠取得多少資源: 例如: CPU、記憶體、網路等…

控制資源消耗:

1 . 若想完全移除所有 kernel capabilities 則可透過以下方式: bash" docker run --cap-drop all <IMAGE-ID>" 2 . 若想增加某些 kernel capabilities 則可透過以下方式: bash" docker run --cap-drop all --cap-add NET_ADMIN -it \ --rm -u alexis c51c05657e9f /bin/bash"

控制組子系統

控制組(cgroups)是 Linux 內核的一個功能,用於隔離、限制和記錄系統上一組程式的資源使用情況。控制組用於隔離 CPU、記憶體、網路和磁碟使用情況。與名稱空間一樣,控制組是 Docker 平台及一般容器技術所必需的核心功能。

控制資源消耗

  1. 限制 CPU 使用:在執行容器時增加 --cpus 引數:
docker run -it --rm --cpus 0.25 <image name> /bin/bash
  1. 指定 CPU 核心:在執行容器時增加 --cpuset-cpus 引數:
docker run -it --rm --cpuset-cpus=0 <image name> /bin/bash

如果您的 Docker 主機有多個核心,可以指定多個核心來使用:

docker run -it --rm --cpuset-cpus=0,1 <image name> /bin/bash

或者提供一系列核心編號:

docker run -it --rm --cpuset-cpus=0-3 <image name> /bin/bash
  1. 限制記憶體消耗:在執行容器時增加 -m 引數:
docker run -it --rm -m 128m <image name> /bin/bash"

在此範例中,我們將 container 的 RAM 消耗量限製為最多可達到 128MB.

  1. 限製程式數量:在執行 container 時增加 --pids-limit 引數:
    docker run -it –-rm –-pids-limit 5 <IMAGE-ID>"
    

內容解密:

  • -–cpu: -–cpuDOCKER RUN 必備引數之一, 它能夠讓我們去設定該 Container 能夠取得之最大 CPU 資源.
  • -–memory: -–memoryDOCKER RUN 必備引數之一, 它能夠讓我們去設定該 Container 能夠取得之最大 Memory 資源.
  • -–pids-limit: -–pids-limitDOCKER RUN 必備引數之一,它能夠讓我們去設定該 Container 能夠建立之最大程式數.

AppArmor 安全模組

AppArmor(Application Armor)是一種 Linux 安全模組,用於透過自訂應用程式和容器設定來管理對作業系統資源的存取權。AppArmor 較為廣泛與可用來限制對網路以及特設定檔案路徑的存取權。

AppArmor 基本概念:

Linux 提供兩種主要形式的存取控管方式: 1 . 自主存取控管: 資源擁有者決定誰可以存取哪些資源. 例如: 檔案與目錄許可權就是屬於這型別之自主存取控管方式. 然而此型別並不適用於所有種類別之資源.

2 . 強迫性存取控管: 資源擁有者無法決定誰可以或不能進行某些動作, 而是由預先制定好的政策規範所決定. 例如: SELinux 與 AppArmor 則屬於這型別強迫性存取控管方式.

內容解密:

  • SELinux (Security Enhanced Linux): 一款開放原始碼安全架構, 用以增強 Linux 作業系統安全性。 其主要目的是透過強化授權機構來保護伺服器免受未經授權的人員或惡意軟體攻擊。 SELinux 提供了更高程度地細緻化及靈活化地安全策略, 包括角色基礎存取控管(RBAC)等功能.

確認 AppArmor 已啟用

在開始生成和使用自定義 AppArmor 設定之前,我們需要確保 AppArmor 已安裝並啟用。這可以透過執行以下命令來完成:

aa-enabled

如果 AppArmor 已啟用,您應該會收到類別似於「Yes」的回應。

安裝 Bane

Bane 是一個開放原始碼工具,可自動化生成自定義 AppArmor 設定的過程。以下是安裝步驟:

  1. 使用自動化安裝程式為 Linux 安裝 Bane:
export BANE_SHA256="69df3447cc79b028d4a435e151428bd85a816b3e26199cd010c74b7a17807a05"
sudo curl -fSL "https://github.com/genuinetools/bane/releases/download/v0.4.4/bane-linux-amd64" -o "/usr/local/bin/bane" \
&& echo "${BANE_SHA256} /usr/local/bin/bane" | sha256sum -c - \
&& sudo chmod a+x "/usr/local/bin/bane"

內容解密:

  • curl: curl 是一個 Unix/Linux 必備工具, 用於傳輸資料.
  • -fSL: -fcurl 的選項之一, 用於失敗時不顯示錯誤訊息. -Scurl 的選項之一, 用於顯示進度條. -Lcurl 的選項之一, 用於跟隨重定向.

使用 Bane 建立自定義 AppArmor 設定

建立自定義 AppArmor 設定需要對容器所需存取的資源有良好的瞭解。本僅探討如何建構一個設定以及如何在執行容器時使用它。

下載範本:

您可以從 GitHub 下載並修改此範本: Apparmor Profile Template

生成設定:

接著我們就可以透過以下方式去產出新之設定:

sudo bane <profile-name>.toml"

內容解密:

  • bane: brane 是一款開放原始碼工具, 它能夠幫助我們快速產出符合規範之 apparmor profile.

啟動 Container 與指派新之 apparmor profile:

接著我們就可以透過以下方式去啟動 container 與指派新之 apparmor profile:

docker run -d --security-opt=”apparmor:<profile-name>” <docker image>"

使用 seccomp 限制系統呼叫

為什麼要使用 seccomp?

  • 容器不需要所有可用的系統呼叫來正常執行。
  • 如果容器被入侵,攻擊者可以進行各種系統呼叫,進一步利用 Docker 主機。
  • 減少對系統呼叫的存取大大降低了容器的整體攻擊面積。

在 Docker 中使用 seccomp

Docker 使用 seccomp 濾波器來限制容器可存取的系統呼叫。Docker 預設會為 Docker 容器提供一個預設的 seccomp 設定。

建立自定義 seccomp 設定

  1. 下載設定範本: Default Seccomp Profile

  2. 編輯並儲存設定:

    {
      "defaultAction": "SCMP_ACT_ERRNO",
      "architectures": [
        "SCMP_ARCH_X86_64",
        "SCMP_ARCH_X86"
      ],
      "syscalls": [
        {
          "names": ["chmod", ...],
          ...
        }
      ]
    }
    
  3. 指定自定義 seccomp 設定:

docker run -d --security-opt=seccomp:/path/to/profile/profile.json <docker image>

內容解密:

  • secomp: 是 Linux 一款安全功能, 用於限制 process 能夠執行之 system call.
  • -–security-opt: -–security-optDOCKER RUN 必備引數之一, 它能夠讓我們去設定該 Container 能夠取得之最大 CPU 資源.

掃描 Docker 暴露漏洞

掃描 Docker 暴露漏洞是指識別在 Docker Image 中所包含之套件存在的一些安全性問題. 這樣做可以幫助我們在佈署或執行之前就先發現一些可能存在之問題, 然後再進行修補或修復以確保其安全性.

Trivy 安全掃描工具:

1 . 首先我們必須先下載 Trivy 的 docker image: ```bash" docker pull aquasec/trivy"

2 . 接著建立 cache 資料夾: ```bash" mkdir -p trivy/.cache"

3 . 接著執行以下命令即可開始進行掃描工作: bash" docker run --rm -v trivy:/path/to/cache/.cache aquasec/trivy <image-name>"

使用 Dockle 掃描 Docker 映像

Dockle 是一款開放原始碼工具,可以自動化識別 Docker 映像中的設定錯誤。以下是如何使用 Dockle 的步驟:

  1. 下載並安裝 Dockle:
VERSION=$(curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') && curl -L -o dockle.deb https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.deb
sudo dpkg -i dockle.deb && rm dockle.deb
  1. 執行掃描:
dockle <image-name>

安全最佳實踐

在構建 Docker 映像時,應遵循以下最佳實踐:

  • 使用最小基礎映像:如 Alpine Linux。
  • 指定精確的基礎映像版本:而不是使用「latest」標籤。
  • 減少或移除不必要的套件
  • 避免在 Dockerfile 中儲存密碼和秘密
  • 簽署和驗證 Docker 映像
  • 增加非特權使用者到 Docker 映像中
  • 避免使用 root 使用者

內容解密:

  • -–no-cache: -–no-cacheapk add 必備引數之一, 它能夠讓我們去設定該 Container 在執行 apk add 指令時不會將下載之套件進行快取.

構建安全的 DOCKER Image:

接著我們就可以透過以下方式去產出新之 DOCKER Image:

FROM alpine:3.13.5
RUN addgroup -S stress && adduser -S stress -G stress
CMD ["/bin/sh"]
ENV RELEASE_VERSION=1.0.4 SHELL=/bin/bash"
RUN apk add --no-cache --update bash g++ make curl \
&& cd /tmp \
&& wget https://fossies.org/linux/privat/old/stress-${RELEASE_VERSION}.tar.gz\
&& tar-xzyf./tmp/stress-${RELEASE_VERSION}.tar.gz\
&& rm /tmp/stress-${RELEASE_VERSION}.tar.gz \
&& cd /tmp/${RELEASE_VERSION}"\
&& ./configure \
&& make-j$(getconf _NPROCESSORS_ONLN) \
&& make install "
USER stress"
CMD ["/usr/local/bin/strees"]

在這篇文章中,我們探討瞭如何透過稽核和保護來增強 Docker 平台及其容器的安全性。從基本概念到實際操作,我們涵蓋了各種技術策略和最佳實踐。

首先,我們介紹了什麼是安全稽核以及為什麼它對於確保系統安全至關重要。然後,我們詳細說明瞭如何使用工具如 Docker Bench for SecurityLynis 來進行安全稽核。

接著,我們探討瞭如何透過設定 SSH 金鑰驗證、停用 root 請求以及設定 AppArmor 和 seccomp 構建更加穩固與可靠之主機環境.

最後, 本文還介紹了一些常見之漏洞掃描工具(例如: Trivy 與 Dockel),並且也提供了一些範例程式碼供大家參考學習. 希望這篇文章能夠幫助您更好地理解如何保護您的 DOCKER 平台與 Container. 若有任何問題或需要進一步協助,請隨時聯絡玄貓(BlackCat)."