文章作者:夢家
個人站點:dreamhomes.top
原文地址:https://dreamhomes.github.io/posts/202006041113.html
公衆號ID:DreamHub
問題引入
默認情況下,容器中的進程以 root
用戶執行,並且這個 root
用戶和宿主機中的 root
是同一個用戶,這意味着:
- 容器中運行的進程,在合適的機會下,有權限控制宿主機中的一切;
- 容器中運行的進程,以
root
用戶執行,外界很難追溯到真實的用戶; - 容器進程生成的文件,是
root
用戶所有,普通用戶沒有權限讀取修改。
可知,以 root
權限執行是很不方便且很不安全的。
解決方法
- 在容器內創建用戶並且切換用戶;
- 增加一個新用戶,名爲
user
; - 讓這個用戶有
root
權限; - 置其密碼爲
password
; - Container啓動後以
user
登錄,並且直接到user
的home
目錄下;
將下面代碼片段放到Dockerfile
裏面。
RUN useradd --create-home --no-log-init --shell /bin/bash user \
&& RUN adduser user sudo \
&& RUN echo 'user:password' | chpasswd
USER user
WORKDIR /home/user
-
使用
fixuid
修改容器中非root
用戶的uid
和gid
;用上面的代碼新建非 root 用戶後,該用戶的
uid
和gid
一般是1000:1000
。docker 和宿主機共享一套內核,內核控制的
uid
和gid
則仍然只有一套。換句話說,我們在容器裏以新建的 docker 用戶(uid 1000)
執行進程,宿主機會認爲該進程是宿主機上uid
爲1000
的用戶執行的,而這個用戶不一定是我們的賬戶,相當於我們冒名頂替了別人的用戶,這樣難以追溯到真實用戶。要解決這個問題可以在添加用戶時指定
uid
爲用戶的uid
,例如1002
;RUN addgroup --gid 1002 docker && \ adduser --uid 1002 --ingroup docker --home /home/docker --shell /bin/sh --gecos "" docker
但是其它人用這個鏡像的時候,
uid
可能又不一樣,這樣寫死很不方便,所以更好的解決方法是用 fixuid來在容器啓動的時候切換uid
:# 新建用戶代碼和上面一樣 RUN useradd --create-home --no-log-init --shell /bin/bash user\ && adduser user sudo \ && echo 'user:password' | chpasswd # 安裝配置 fixuid RUN USER=user && \ GROUP=docker && \ curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.4.1/fixuid-0.4.1-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - && \ chown root:root /usr/local/bin/fixuid && \ chmod 4755 /usr/local/bin/fixuid && \ mkdir -p /etc/fixuid && \ printf "user: $USER\ngroup: $GROUP\n" > /etc/fixuid/config.yml USER user:docker ENTRYPOINT ["fixuid"]
此時啓動容器時需要指定
uid
和gid
,命令如下:docker run --rm -it -u $(id -u):$(id -g) image-name bash