์ฟ ๋ฒ๋คํฐ์ค ๋ณด์ ๊ด๋ จ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํด๋ณด๋ฉด ์๋ง ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ด๊ณ , ๊ฐ์ฅ ๋ง์ด ๋ณด์ด๋ ๊ฒ์ด ํ๋ ์์ต๋๋ค. ์๋ง ์ฟ ๋ฒ๋คํฐ์ค ๋ฟ๋ง ์๋๋ผ ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ๋ ํ๊ฒฝ์ด๋ผ๋ฉด ๋ชจ๋๊ฐ ์ ๊ฒฝ์จ์ผ ํ๋ ๋ถ๋ถ์ด์ฃ .
๋ฐ๋ก ๋ฃจํธ ๊ณ์ ๋นํ์ฑํ ์ ๋๋ค.
์ฆ, ์ปจํ ์ด๋ ๋ด ํ๋ก์ธ์ค์์ ๋ฃจํธ ๊ถํ์ ๋ชจ๋ ๋นํ์ฑํ ํ๋ ๊ฒ์ด์ฃ .
์ปจํ ์ด๋ ๋ด๋ถ์์ ์๋ฌด๋ ๋ฃจํธ ๊ถํ์ ์ฌ์ฉํ๊ฒ ํ๋ค๋ ๊ฒ์ ๋ชจ๋ฅด๋ ์ฌ๋์๊ฒ ์ง ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ ค์ฃผ๋ ๊ฒ๊ณผ ๋ค๋ฆ์ด ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ์ปจํ ์ด๋์ ์ ์ํ ํ uname -a ๋ช ๋ น์ด๋ฅผ ์ณ๋ณด๋ฉด ํธ์คํธ์ OS ๋ฒ์ ์ ๋ณผ ์ ์์ต๋๋ค.
๋ฃจํธ ๊ถํ ๋นํ์ฑํ๋ ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค ๋๋ ์ค์ ํ ์ ์๊ณ , k8s ๋ก ํ๋๋ฅผ ๋ฐฐํฌํ ๋๋ ์ค์ ํ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ ์ด๋ป๊ฒ ๋ฃจํธ ๊ณ์ ์ ๋นํ์ฑํํ๊ณ ์์ ํ ํ๋๋ฅผ ๋ง๋๋์ง ์์๋ณด๊ณ ์ ํฉ๋๋ค.
Dockerile ์ ์์ฑํ ๋ ๋ณด์ ๊ด๋ จ ์ต์ ๋ค์ ๋ฐ๋ก ์ค์ ํ์ง ์์ต๋๋ค.
์๋ฅผ ๋ค๋ฉด USER 1000
๋ ์ธ ๋๋์ฝ๋~
SecurityContext
k8s pod spec ์ผ๋ก securityContext ๋ผ๋ ํ๋๊ฐ ์์ต๋๋ค. ํ๋ ๋ด ๋ชจ๋ ๋ณด์ ์ค์ ์ ์ด ํ๋ ๋ด์์ ์ค์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ค๋ช ํ๋ ๊ฒ๋ณด๋ค ํ๋ฒ ๋ณด๋ ๊ฒ ํจ์ฌ ๋์ผ๋ ๋ฐ๋ก ํ๋ฒ ๋ณด์์ฃ .
์ด๋ฏธ์ง๋ฅผ ๋ง๋ค ๋์ ๋ณด์์ ์ ๊ฒฝ์ฐ์ง ์์ต๋๋ค
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
volumes:
- name: data-log
emptyDir: {}
containers:
- name: secure-pod
imagePullPolicy: Always
image: kingbj0429/busybox:1.28
volumeMounts:
- name: data-log
mountPath: /data/log
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
capabilities:
add: [ "NET_ADMIN", "SYS_TIME" ]
Dockerfile
FROM amd64/ubuntu:20.04
RUN apt update \
&& apt install -y sudo \
&& apt install -y libcap2-bin \
&& chmod 4755 /bin/cat \
&& useradd -s /bin/sh -u 1000 user
CMD ["/bin/sh", "-c", "sleep 1d"]
์ฐ์ Dockerfile ๋ถํฐ ํ๋ํ๋ ์์๋ณด์ฃ .
sudo ํจํค์ง๋ pod.yaml ์์ .allowPrivilegeEscalation ๋ฅผ false ์ true ์ ์ฃผ์์ ๋ ๊ฐ๊ฐ ์ด๋ป๊ฒ ๋์ํ๋ ์ง ํ์ธํ๊ธฐ ์ํจ์ ๋๋ค.
libcap2-bin ํจํค์ง๋ .capabilities[] ๋ฅผ ํ์ธํ๊ธฐ ์ํจ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ chmod 4755 /bin/cat ์ /bin/cat ๋ฐ์ด๋๋ฆฌ์ set uid ๋ฅผ ์ง์ ํจ์ผ๋ก์จ .allowPrivilegeEscalation ๊ฐ ์ด๋ป๊ฒ ๋์ํ๋ ์ง ํ์ธํ๊ธฐ ์ํจ์ ๋๋ค.
setuid ๋ ํ์ผ์ owner ๊ถํ์ ๋น๋ ค ์คํํ๋ ๊ธฐ๋ฅ์ ๋๋ค.
๋ง์ฝ ์ด๋ ํ์ผ์ ๊ถํ์ด 4755 ๋ผ๋ฉด owner ๊ฐ ์๋ ์ฌ์ฉ์๋ owner ์ ๊ถํ์ ๋น๋ ค ํ์ผ์ ์คํํ ์ ์์ต๋๋ค.
์ด์ธ setgid(2), sticky bit(1) ๋ ์กด์ฌํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก ๋ฃจํธ ๊ณ์ ๊ณผ ๋น๊ตํ๊ธฐ ์ํ uid 1000 ์ user ๊ณ์ ์ ์์ฑํฉ๋๋ค.
๊ทธ๋ผ ์ด์ pod.yaml ์ ๋ํด ์์๋ณด์ฃ .
.securityContext ์ ๋ ๋ง์ ์ต์ ์ด ๊ถ๊ธํ๋ค๋ฉด ์ฌ๊ธฐ, .securityContext ์์ฒด๊ฐ ๊ถ๊ธํ๋ค๋ฉด ์ฌ๊ธฐ!
.runAsNonRoot: true ๋ก ํ๊ฒ ๋๋ฉด, ๋ง์ฝ ๋ฃจํธ ๊ณ์ ์ผ๋ก ํ๋๋ฅผ ์คํ ์ ์๋ฌ๋ฅผ ํ ํด๋ ๋๋ค.
.runAsUser: 1000 ๋ก ํ๊ฒ ๋๋ฉด, ํ๋๋ฅผ 1000 ๊ณ์ ์ผ๋ก ์คํํฉ๋๋ค. ๋ง์ฝ 0 ์ผ๋ก ํ๊ฒ๋๋ฉด ๋ฃจํธ ๊ณ์ ์ด๋ฏ๋ก ์์ .runAsNonRoot: true ์ผ๋ก ์ธํด ํ๋ ์์ฑ์ด ์๋ฉ๋๋ค.
.runAsGroup: 1000 ๋ก ํ๊ฒ๋๋ฉด ํ๋๋ 1000 gid ๋ฅผ ๊ฐ์ง ๊ทธ๋ฃน์ ํฌํจ๋ฉ๋๋ค.
๋๋จธ์ง ์ต์ ๋ค์ ๋ํด์ ์ข ๋ ์์ธํ ์์๋ณด์ฃ .
.privileged ์ต์ ์ ํ๋๋ฅผ ์คํํ๋ ์ฌ์ฉ์์๊ฒ root ์ ๊ฐ์ ๊ถํ์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค. ์ฆ, sudo ์ ๊ฐ์ ๋ช ๋ น์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ, ๋ฃจํธ ๊ถํ์ ๊ฐ์ง ์ ์๊ฒ ๋ฉ๋๋ค.
capsh --print ๋ฅผ ํตํด ์ด๋ privileged ๊ฐ ํ ๋น๋์๋ ์ง ํ์ธํ ์ ์์ฃ .
๋ง์ฝ privileged ๊ฐ true ์ด๋ฉด, .allowPrivilegeEscalation ๊ณผ .capabilities[] ์ ์ต์ ์ ๋ฌด์๋ฏธํด์ง๋ฉฐ, .allowPrivilegeEscalation ๋ฅผ false ๋ก ์ค๋ค๋ฉด ํ๋ ์์ฑ ์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
.capabilities[] ์ต์ ์ ์ฌ์ฉ์์๊ฒ ํน์ capability ๋ฅผ ์ฃผ๋ ์ต์ ์ธ๋ฐ privileged ๊ฐ true ๋ผ๋ฉด ์ด๋ฏธ ๋ชจ๋ capability ๋ฅผ ํ ๋น๋ฐ์๊ธฐ ๋๋ฌธ์ ์๋ฏธ๊ฐ ์๊ฒ ์ฃ ?
.capabilities[] ์ [ "NET_ADMIN", "SYS_TIME" ] ์ ์ฃผ์๋ ๋ฐ ์ด๋ด ๊ฒฝ์ฐ ๋ฃจํธ ๊ณ์ ์ผ๋ก ํ๋์ Date ๋ฅผ ๋ณ๊ฒฝํ ์ ์๊ฒ ๋ฉ๋๋ค.
๋ฃจํธ๊ฐ ์๋๋ผ๋ฉด .capabilities[] ์ ์ฃผ์ด๋ capability ๋ฅผ ๊ฐ์ง๊ณ ์ด๋ ํ ์ก์ ์ ํ ์ ์์ต๋๋ค.
.allowPrivilegeEscalation
.allowPrivilegeEscalation ์ ๋ํด ์ข ๋ ์์๋ณด์ฃ . .allowPrivilegeEscalation ๊ฐ ์ฌ์ค ์ด๋ฒ ๊ธ์ ํต์ฌ์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
.allowPrivilegeEscalation ์ ๊ถํ ์์น์ ์ ํํ๋ ์ต์ ์ ๋๋ค. ๋ง์ฝ false ๋ผ๋ฉด ๊ถํ ์์น์ ํตํด ํ๋ก์ธ์ค๋ฅผ ์คํํ ์ ์์ฃ .
๊ทผ๋ฐ ์ด๋ ๊ฒ ๊ธ๋ก๋ง ๋ด์๋ ์ ์ดํด๊ฐ ์๊ฐ๋ ๋ฐ๋ก ์ค์ต์ ํด๋ณด์ฃ .
์ฐ์ .allowPrivilegeEscalation ์ true ๋ก ํด๋ณด๊ฒ ์ต๋๋ค. ์๊น ์ Dockfile ์ ๋ณด๋ฉด chmod 4755 ๋ฅผ ํตํด cat ๋ฐ์ด๋๋ฆฌ์ set uid ๋ฅผ ์ค์ ํ์ต๋๋ค. set uid ๋ฅผ ํตํด ๊ถํ ์์น์ ํ ์คํธํ ์ ์์ต๋๋ค.
cat ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ณด๋ฉด set uid ๊ฐ ์ค์ ๋์ด ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ cat /etc/shadow ๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค.
cat ๋ช ๋ น์ด๋ ๋ถ๋ชจ์ ๊ถํ์ ๋น๋ฆด ์ ์์ผ๋ฏ๋ก cat /etc/shadow ๊ฐ ์ ์์ ์ผ๋ก ์ถ๋ ฅ๋ฉ๋๋ค.
shadow ํ์ผ์ 640 ์ด๊ธฐ ๋๋ฌธ์ root ๊ฐ ์๋๊ฑฐ๋ ํด๋น๋ ๊ทธ๋ฃน์ ์๋ ์ฌ์ฉ์๊ฐ ์๋๋ผ๋ฉด ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
ํ์ง๋ง, .allowPrivilegeEscalation ์ true ๋ก ์ค์ผ๋ก์จ ๊ถํ ์์น์ ํ ์ ์๊ฒ ํด์ฃผ์๊ณ , set uid ๋ํ ์ค์ ๋์๊ธฐ ๋๋ฌธ์ root ๊ฐ ์๋์ฌ๋ ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค.
ํ์ง๋ง!
.allowPrivilegeEscalation ์ false ๋ฅผ ์ค๋ค๋ฉด, cat ๋ฐ์ด๋๋ฆฌ์ set uid ๊ฐ ์ค์ ๋์ด ์๋ค ํ ์ง๋ผ๋ cat /etc/shadow ๋ฅผ ์คํํ ์ ์์ต๋๋ค. ์๋ ๊ถํ ์์น์ ๋ง์๊ธฐ ๋๋ฌธ์ด์ฃ .
sudo ๋ํ set uid ๊ฐ ์ค์ ๋์ด์๊ณ , root ๊ถํ์ ๋น๋ฆฌ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ .allowPrivilegeEscalation ์ false ๋ก ์ค๋ค๋ฉด sudo ๋ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ด์ .allowPrivilegeEscalation ์ต์ ์ ๋ํด ๊ฐ์ด ์ค์์ฃ ?
๊ทธ๋ผ ๋ค์์ผ๋ก๋ ๋ ์ค์ํ ์ต์ ์ค ํ๋์ธ .readOnlyRootFileSystem ์ ๋ํด ์์๋ณด์ฃ .
.readOnlyRootFileSystem
์ด๋ฆ ๊ทธ๋๋ก ํ์ผ ์์คํ ์ read ๋ง ๊ฐ๋ฅํฉ๋๋ค. ๋ฐ๋ผ์ ํ์ผ๋ค์ ์ฝ์ ์ ์์ง๋ง, ์ธ ์๋ ์์ด์.
๋ณด์์ ์๊ฐํด๋ณด๋ฉด ๋น์ฐํ ํ๋ ๋ด ํ์ผ์ ์์ ํ ์ ์๊ฒ ํ๋ ๊ฒ์ด ๋ง๊ฒ ์ฃ ?
๊ทธ๋ฐ๋ฐ ํ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํด์ฃผ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ค๊ณ ๊ฐ์ ํด๋ณด์ฃ . ๋ก๊ทธ๋ /data/log ์ ์ ์ฅ๋ฉ๋๋ค.
ํ์ง๋ง .readOnlyRootFileSystem ์ true ํ๋ค๋ฉด ๋ฃจํธ๊ฐ ์๋ ์ด์ /data/log ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ธ ์ ์์ต๋๋ค.
์ฆ, touch /data/log/log.text ๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค. .runAsNonRoot ๊ฐ true ์ด๊ธฐ ๋๋ฌธ์ ๋ฃจํธ๋ก ์ ๊ทผํ ์๋ ์์ต๋๋ค.
๊ทธ๋ผ ์ด๋ด ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
๋ฐ๋ก emptyDir ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
emptyDir ์ ๊ฐ์ ํ๋ ๋ด ์กด์ฌํ๋ ์ปจํ ์ด๋๋ผ๋ฆฌ ๋ณผ๋ฅจ์ ๊ณต์ ํ ๋ ์ฌ์ฉ๋๋ ์ต์ ์ ๋๋ค. ์ฌ๊ธฐ์ ํ๊ฐ์ง ์์์ผ ํ ๊ฒ์ ์ด ๋ณผ๋ฅจ์ด ๋ง์ดํธ ๋ ๋ tmpfs ๋ก ๋ง
์ดํธ๋ ๋ค๋ ๊ฒ์ด์ฃ .
์๋ฌด๋ ์ด ๋ง์ดํธ ๊ฒฝ๋ก์๋ ์ฝ๊ฑฐ๋ ์ธ ์ ์์ต๋๋ค.
ํน๋ณํ ๊ถํ์ ์ฃผ์ง ์์๋๋ฐ 777 ๋ก ์ค์ ๋์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๋ง์ฝ busybox:1.28 ์์ ๋ก๊ทธ๋ฅผ ์ฐ๊ณ ์ถ๋ค๋ฉด /data/log ๊ฒฝ๋ก๋ฅผ .volumeMounts ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
๋ง๋ฌด๋ฆฌ
pod ๋ฅผ ๋ฐฐํฌํ ๋ ์ ๊ฒฝ์จ์ผ ํ ์์ฃผ ๊ธฐ๋ณธ์ ์ธ ๋ณด์์ ์ค์ ํด๋ณด์๋๋ฐ์. ํฌ๊ฒ ์ด๋ ต์ง ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ pod.yaml ๋ณด๋จ ์ ์ด์ ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค ๋ ๋ณด์์ ์ ๊ฒฝ์จ์ ๋ง๋๋ ๊ฒ์ด ๋ ์ผ๋ฐ์ ์ ๋๋ค.
๊ทธ๋๋ pod.yaml ์ securitContext ๋ฅผ ํตํด ๋ณด์์ ๊ฐํํ ํ๋ ๋ฐฐํฌ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ดค์ต๋๋ค.
์์ ๋์์๋ ์ต์ ๋ง๊ณ ๋ ๋ ๋ค์ํ securityContext ์ต์ ๋ค์ด ์กด์ฌํ๋ฉฐ, AppArmor ๋ Falco, Trivy, OPA GateKeeper ๋ฅผ ํตํด์ ์ฟ ๋ฒ๋คํฐ์ค ๋ณด์์ ๋ ๊ฐํํ ์ ์์ต๋๋ค.
์ด์ ๋ํด์ ๋์ค์ ์ฐจ๊ทผ์ฐจ๊ทผ ์์๋ณด๋๋ก ํ์ฃ !
๊ทธ๋ผ ์ค๋์ ์ฌ๊ธฐ๊น์ง!