在以 root 用戶身份運行 Docker 會帶來一些潛在的危害和安全風險,這些風險包括:
1.容器逃逸:如果一個容器以 root 權限運行,并且它包含了漏洞或者被攻擊者濫用,那么攻擊者可能會成功逃出容器,并在宿主系統上執行惡意操作。這會導致宿主系統的安全性受到威脅。
2.特權升級:在以 root 用戶身份運行 Docker 的情況下,容器內的進程可能會嘗試特權升級,獲取宿主系統的 root 權限。這可能會導致嚴重的安全問題,因為攻擊者可能會利用這些權限來控制宿主系統。
3.文件系統訪問:以 root 用戶身份運行的容器可以訪問宿主系統上的文件系統,這可能會導致機密文件的泄漏或文件的損壞。
4.網絡權限:容器以 root 權限運行時,可能會濫用網絡權限,例如進行端口掃描、DDoS 攻擊等惡意行為。
為了減少這些風險,推薦采取以下做法:
?以非root用戶身份運行容器:最佳實踐是在容器中以非root用戶的身份運行應用程序。這可以通過在容器中指定普通用戶來實現,并避免使用USER指令將容器進程切換到 root 用戶。
?限制容器的權限:使用 Docker 的安全配置選項,如--security-opt,可以限制容器的能力,例如禁止容器訪問宿主系統的特定目錄、文件和設備。
?更新和監控容器:定期更新容器的基礎鏡像和應用程序,以確保安全漏洞得到修復。同時,使用容器監控和審計工具來檢測不尋常的活動。
?限制容器能力:使用 Docker 的能力(capabilities)設置來限制容器的權限,僅提供所需的最小權限來運行應用程序。
什么東西看似Rootless ,實則不然
?docker run --user foo:它允許你以非 root 身份在容器中執行進程。值得注意的是,你無法執行包安裝等特權活動。runc、containerd 等仍以 root 身份運行。
?usermod -aG docker foo:允許非root用戶連接到docker套接字。相當于允許用戶以 root 身份運行。
?sudo docker和chmod +s dockerd: 無需解釋
?dockerd --userns-remap:它允許你以非 root 身份運行容器。runc、containerd 等仍然以 root 身份運行。
Docker Rootless 基本概念
Docker Rootless 是一種在非特權模式下運行 Docker 的方式,允許以非root用戶身份來管理 Docker 守護進程和容器,以降低潛在的安全漏洞風險。在這種模式下,即使在 Docker 安裝期間,也無需使用root權限。這有助于提高容器的安全性,因為以非特權用戶身份運行容器可以限制容器內部的特權操作。對于特權模式的 Docker 容器,攻擊者可能會利用宿主機文件讀寫權限等漏洞來逃逸,因此非特權模式更為安全。
同時,在 Docker 中,容器可以選擇是否以特權模式運行,通過設置--privileged=false可以將容器切換為非特權模式。總的來說,Docker Rootless 模式提供了一種更加安全的方式來運行 Docker 容器,降低了潛在的安全風險,特別是在多租戶環境中或需要更嚴格的容器隔離時,這種模式非常有用。
Rootless 模式允許以非 root 用戶身份運行 Docker 守護進程(dockerd)和容器,以緩解 Docker 守護進程和容器運行時中潛在的漏洞。
Rootless 模式是在 Docker v19.03 版本作為實驗性功能引入的,在 Docker v20.10 版本 GA。
Rootless 模式如何運作
Rootless 模式利用 user namespaces 將容器中的 root 用戶和 Docker 守護進程(dockerd)用戶映射到宿主機的非特權用戶范圍內。Docker 此前已經提供了--userns-remap標志支持了相關能力,提升了容器的安全隔離性。Rootless 模式在此之上,讓 Docker 守護進程也運行在重映射的用戶名空間中。
用戶命名空間自 Linux 內核 v3.8 以來就已存在,因此該功能在 Docker 中已經存在很長時間了 。
img
Rootless 模式在用戶名稱空間內執行Docker守護程序和容器。這與userns-remapmode非常相似,除了模式之外,userns-remap守護進程本身以root特權運行,而在Rootless 模式下,守護程序和容器都在沒有root特權的情況下運行。
Rootless 模式不使用具有SETUID位或文件功能的二進制文件,除了newuidmap和newgidmap,它們是允許在用戶名稱空間中使用多個UID / GID所必需的。
Rootless 模式已知限制
?僅支持以下存儲驅動程序:
?overlay2(僅在以5.11或更高版本的內核,Ubuntu風格的內核或Debian風格的內核運行時)
?fuse-overlayfs(僅在與內核4.18或更高版本一起運行且fuse-overlayfs已安裝的情況下)
?btrfs(僅在使用內核4.18或更高版本運行,或~/.local/share/docker通過user_subvol_rm_allowedmount選項安裝時)
?vfs
?僅當與cgroup v2和systemd一起運行時,才支持Cgroup。請參閱限制資源。
?不支持以下功能:
?AppArmor
?檢查站
?疊加網絡
?暴露SCTP端口
?要使用該ping命令,請參閱路由ping數據包。
?要公開特權TCP / UDP端口(<1024),請參閱公開特權端口。
?IPAddress顯示在中,docker inspect并在RootlessKit的網絡名稱空間中命名。這意味著如果不nsenter進入網絡名稱空間,則無法從主機訪問IP地址。
?主機網絡(docker run --net=host)。
Rootless 模式實踐
實踐環境
本文使用 Centos 7.5 操作系統的虛擬機進行實驗。
$cat/etc/redhat-release CentOSLinuxrelease7.5.1804(Core)
創建普通用戶
$useraddrootless $echo123456|passwdrootless--stdin
安裝依賴
Rootless 模式可以在沒有 root 權限的情況下運行 Docker 守護進程和容器, 但是需要安裝newuidmap和newgidmap工具,以便在用戶命名空間下創建從屬(subordinate)用戶和組的映射(remapping)。通過以下命令安裝newuidmap和newgidmap工具。
cat</etc/sysctl.conf user.max_user_namespaces=28633 EOT sysctl--system EOF
注意事項
CentOS 7
?添加user.max_user_namespaces=28633到/etc/sysctl.conf(或/etc/sysctl.d)并運行sudo sysctl --system。
?systemctl --user默認情況下不起作用。dockerd-rootless.sh不使用systemd直接運行。
CentOS 8 / Fedora
?fuse-overlayfs建議安裝。運行sudo dnf install -y fuse-overlayfs。
?你可能需要sudo dnf install -y iptables。
?啟用SELinux后,你可能會遇到can't open lock file /run/xtables.lock: Permission denied錯誤。解決此問題的方法是sudo dnf install -y policycoreutils-python-utils && sudo semanage permissive -a iptables_t。此問題已在moby / moby#41230中進行了跟蹤。
?已知可在CentOS 8和Fedora 33上工作。
Ubuntu
?無需準備。
?overlay2默認情況下啟用存儲驅動程序(特定于Ubuntu的內核補丁)。
?已知可在Ubuntu 16.04、18.04和20.04上運行
UID/GID 映射配置
從屬用戶和組的映射由兩個配置文件來控制,分別是/etc/subuid和/etc/subgid。使用以下命令為 rootless 用戶設置 65536 個從屬用戶和組的映射。
echo"rootless65536"|tee/etc/subuid echo"rootless65536"|tee/etc/subgid
對于 subuid,這一行記錄的含義為:用戶 rootless,在當前的 user namespace 中具有 65536 個從屬用戶,用戶 ID 為 100000-165535,在一個子 user namespace 中,這些從屬用戶被映射成 ID 為 0-65535 的用戶。subgid 的含義和 subuid 相同。
比如說用戶 rootless 在宿主機上只是一個具有普通權限的用戶。我們可以把他的一個從屬 ID (比如 100000 )分配給容器所屬的 user namespace,并把 ID 100000 映射到該 user namespace 中的 uid 0。此時即便容器中的進程具有 root 權限,但也僅僅是在容器所在的 user namespace 中,一旦到了宿主機中,頂多也就有 rootless 用戶的權限而已。
安裝 Rootless Docker
切換到 rootless 用戶。
su-rootless
執行以下命令安裝 Rootless Docker。
curl-fsSLhttps://get.docker.com/rootless|sh
安裝成功后顯示如下內容。
$curl-fsSLhttps://get.docker.com/rootless|sh #Installingstableversion24.0.5 #Executingdockerrootlessinstallscript,commit:b9139c0 %Total%Received%XferdAverageSpeedTimeTimeTimeCurrent DloadUploadTotalSpentLeftSpeed 10066.5M10066.5M001235k0055055----1373k %Total%Received%XferdAverageSpeedTimeTimeTimeCurrent DloadUploadTotalSpentLeftSpeed 10019.4M10019.4M001096k0018018----1233k +PATH=/home/rootless/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/rootless/.local/bin:/home/rootless/bin +/home/rootless/bin/dockerd-rootless-setuptool.shinstall [INFO]systemdnotdetected,dockerd-rootless.shneedstobestartedmanually: PATH=/home/rootless/bin:/sbin:/usr/sbin:$PATHdockerd-rootless.sh [INFO]CreatingCLIcontext"rootless" Successfullycreatedcontext"rootless" [INFO]UsingCLIcontext"rootless" Currentcontextisnow"rootless" [INFO]Makesurethefollowingenvironmentvariable(s)areset(oraddthemto~/.bashrc): #WARNING:systemdnotfound.YouhavetoremoveXDG_RUNTIME_DIRmanuallyoneverylogout. exportXDG_RUNTIME_DIR=/home/rootless/.docker/run exportPATH=/home/rootless/bin:$PATH [INFO]Someapplicationsmayrequirethefollowingenvironmentvariabletoo: exportDOCKER_HOST=unix:///home/rootless/.docker/run/docker.sock
將以下內容添加到 ~/.bashrc 文件中,添加完以后使用source ~/.bashrc命令使環境變量生效。
exportXDG_RUNTIME_DIR=/home/rootless/.docker/run exportPATH=/home/rootless/bin:$PATH exportDOCKER_HOST=unix:///home/rootless/.docker/run/docker.sock
啟動 Docker 守護進程
方式1:帶systemd(強烈推薦)
systemd文件默認位置為~/.config/systemd/user/docker.service。
使用systemctl --user管理守護程序的生命周期:
$systemctl--userstartdocker
要在系統啟動時啟動守護程序,請啟用systemd服務并持續進行以下操作:
$systemctl--userenabledocker $sudologinctlenable-linger$(whoami)
即使使用User=指令,也不支持將Rootless Docker作為全系統范圍的服務(/etc/systemd/system/docker.service)啟動。
關于目錄路徑的說明:
?套接字默認路徑為$XDG_RUNTIME_DIR/docker.sock。$XDG_RUNTIME_DIR通常設置為/run/user/$UID。
?數據目錄默認設置為~/.local/share/docker。數據目錄不應位于NFS上。
?守護程序配置目錄默認設置為~/.config/docker。此目錄~/.docker與客戶端使用的目錄不同。
sudo loginctl enable-linger $(whoami)解釋
這個命令是用于啟用用戶的 linger(保持)設置,讓用戶的會話在用戶注銷后繼續運行。讓我詳細解釋一下這個命令的各個部分:
1.sudo:sudo是一個用于以超級用戶權限執行命令的工具。在這里,它用于確保我們有足夠的權限來執行后續的命令。
2.loginctl:loginctl是一個用于管理 Linux 登錄會話和用戶登錄狀態的工具。它可以用于查看、控制和管理用戶登錄會話。
3.enable-linger: 這是loginctl的一個子命令,用于啟用用戶的 linger 設置。Linger 是一個控制登錄會話是否在用戶注銷后繼續運行的機制。啟用 linger 后,用戶注銷后,其登錄會話將繼續運行,直到手動停止。
4.$(whoami): 這部分是一個命令替換,它會被當前登錄用戶的用戶名所替代。whoami命令用于獲取當前登錄用戶的用戶名。
因此,整個命令的目的是以超級用戶權限啟用當前登錄用戶的 linger 設置,使其登錄會話在用戶注銷后繼續運行。這在某些情況下可能會很有用,例如,如果你希望在用戶注銷后繼續運行某些后臺任務或服務。請謹慎使用這個命令,因為它可能會導致系統資源被占用,特別是在多用戶環境中。
方式2:沒有systemd
dockerd-rootless.sh
必須設置以下環境變量:
?$HOME:用戶目錄
?$XDG_RUNTIME_DIR:臨時目錄,只有預期的用戶可以訪問,例如~/.docker/run。該目錄應在每次主機關閉時刪除。該目錄可以位于tmpfs上,但是不應位于之/tmp下。在此/tmp目錄下,可能容易受到TOCTOU攻擊。
客戶端
需要明確指定套接字路徑或CLI上下文。
要指定套接字路徑,請使用$DOCKER_HOST:
$exportDOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock $dockerrun-d-p8080:80nginx
要指定CLI上下文,請使用docker context:
$dockercontextuserootless rootless Currentcontextisnow"rootless" $dockerrun-d-p8080:80nginx
運行容器
使用以下命令啟動一個 nginx 容器,并將 80 端口映射到宿主機的 8080 端口。
dockerrun-d-p8080:80nginx
查看容器。
[rootless@demo~]$dockerps CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES f3b204c97a84nginx"/docker-entrypoint.…"9minutesagoUp9minutes0.0.0.0:8080->80/tcp,:::8080->80/tcpbold_stonebraker
訪問容器。
$curlhttp://localhost:8080 #返回結果Nginx歡迎界面Welcometonginx! Welcometonginx!
Ifyouseethispage,thenginxwebserverissuccessfullyinstalledand working.Furtherconfigurationisrequired.
Foronlinedocumentationandsupportpleasereferto nginx.org.
Commercialsupportisavailableat nginx.com.Thankyouforusingnginx.
Rootless 模式調試技巧
進入dockerd名稱空間
dockerd-rootless.sh腳本,會在其自己的user,mount和network 名稱空間中執行dockerd。
為了進行調試,你可以通過以下明立進入名稱空間Rootless 模式
nsenter-U--preserve-credentials-n-m-t$(cat$XDG_RUNTIME_DIR/docker.pid)
Rootless 模式卸載
要刪除Docker守護程序的systemd服務,請運行dockerd-rootless-setuptool.sh uninstall:
dockerd-rootless-setuptool.sh默認位置:/home/rootless/bin/dockerd-rootless-setuptool.sh
$dockerd-rootless-setuptool.shuninstall +systemctl--userstopdocker.service +systemctl--userdisabledocker.service Removed/home/testuser/.config/systemd/user/default.target.wants/docker.service. [INFO]Uninstalleddocker.service [INFO]ThisuninstallationtooldoesNOTremoveDockerbinariesanddata. [INFO]Toremovedata,run:`/usr/bin/rootlesskitrm-rf/home/testuser/.local/share/docker`
要刪除數據目錄,請運行rootlesskit rm -rf ~/.local/share/docker。
要刪除二進制文件,docker-ce-rootless-extras請在軟件包管理器中安裝了Docker的情況下刪除軟件包。如果你使用https://get.docker.com/rootless安裝了Docker,請刪除以下二進制文件`~/bin`:
$cd~/bin $rm-fcontainerdcontainerd-shimcontainerd-shim-runc-v2ctrdockerdocker-initdocker-proxydockerddockerd-rootless-setuptool.shdockerd-rootless.shrootlesskitrootlesskit-docker-proxyruncvpnkit
Rootless Docker 與 Podman
RedHat Inc 的 Podman 是另一種流行的容器引擎,用于運行和管理容器。它被譽為以Rootless 運行是其相對于 docker 引擎的功能之一。通過Rootless Docker ,彌合了差距,現在它們具有幾乎相同的功能和幾乎相同的性能。他們之間還使用大量相同的代碼。
Rootless Docker 不支持指定docker run --net=host 。但如果你確實需要使用docker run --net=host,Podman 可能是你更好的選擇。
總結
Docker Rootless模式是官方提供的一種安全解決方案,可以讓Docker守護進程以普通用戶身份運行,從而避免容器應用利用Docker漏洞獲得宿主機root權限的風險。
另外,要注意的是因為Docker作為容器本身需要利用很多系統高級特性,因此Docker守護進程以非Root身份運行實際上也會導致一些功能受限。這點可以參與官方文檔詳細了解。
審核編輯:湯梓紅
-
內核
+關注
關注
3文章
1363瀏覽量
40228 -
Linux
+關注
關注
87文章
11230瀏覽量
208931 -
容器
+關注
關注
0文章
494瀏覽量
22045 -
root
+關注
關注
1文章
85瀏覽量
21376 -
Docker
+關注
關注
0文章
454瀏覽量
11815
原文標題:容器快了,卻不安全了,Rootless 安排上
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論