iT邦幫忙

2021 iThome 鐵人賽

DAY 27
2
Security

從以卵擊石到堅若磐石之 Web API 安全性全攻略系列 第 27

Day27-保護鯨魚人人有責(二)

前言

昨天已經介紹了幾個寫 Dockerfile 時該注意的地方,但其實需要注意的地方非常非常多,所以今天會再補充兩個,話不多說馬上開始吧!

只 COPY 需要的東西

平常在寫 Dockerfile 時,有些人為了一時方便,會直接用 COPY . /app 把整個專案資料夾複製到 container 的 /app 資料夾內。這樣不用動太多腦筋,在 container 裡面也可以直接存取到所有檔案,但這樣的做法可以說是糟透了

FROM node:14
WORKDIR /app

# Very BAD
COPY . .

RUN npm install
RUN npm run test
CMD ["node", "index.js"]

首先是這樣會讓 image 變得很肥(連 node_modules 都進去了能不肥嗎XD),而且一不小心就會把 .envrc 這類敏感資料一起放進去,如果哪天這個 image 被駭客拿到,裡面的 AWS 憑證、資料庫密碼等等超機密資料就會直接外洩出去,哪天突然被刪庫也是有可能的

為了避免這種事情發生,在 build image 時應該只把需要的東西複製進去,譬如說你馬上就要跑 npm install,這才把 package.jsonpackage-lock.json 放進去,而程式碼也是把真的會跑到的那些放進去就好

FROM node:14
WORKDIR /app

# Good
COPY package.json package-lock.json ./
RUN npm install

# Good
COPY src/ index.js ./
RUN npm run test
CMD ["node", "index.js"]

而且這樣還有另外一個好處,就是如果你改了 src 裡面的程式碼,但沒有安裝新的 package(開發時大部分都是這樣吧~),因為 Docker 會自動做 cache,所以就不需要重新跑一次 npm install,會直接從第 10 行的 npm run test 開始跑,因此可以大幅縮減需要等待的時間

用 multi-stage build 捨棄不需要的檔案

這跟上一點有點類似,簡單來說就是不要留任何不需要的東西在 image 裡面(沒用的東西都給我滾),即便那是 build image 過程中產生的東西也是一樣

譬如說原本 Go API server 的 Dockerfile 可能長這樣,因為要在 build image 時編譯出執行檔,所以第 5 行的 COPY *.go 是一定要的,沒有他們就無法進行編譯

FROM golang:1.17
WORKDIR /app

COPY *.go go.mod go.sum ./
RUN go build -o main
CMD ["./main"]

但說真的一旦編譯出執行檔之後,那些 Go 程式碼就用不到了,所以應該來個爽快的過河拆橋,用 multi-stage build 把編譯完的執行檔保留下來就好,程式碼什麼的就直接拜拜

像下面這個這個 Dockerfile 經過 multi-stage build 後 image 裡面就只有 /app/main這個編譯好的執行檔,沒有任何程式碼以及 Go 的編譯器,非常的存粹

# compile stage
FROM golang:1.17 as compile-env
WORKDIR /app
COPY *.go go.mod go.sum ./
RUN go build -o main

# final stage
FROM gcr.io/distroless/base
COPY --from=compile-env /app/main /app
CMD ["/app/main"]

那這樣有什麼好處呢?除了 image 可以變小很多之外,即便 image 被駭客拿到了,程式碼也不會外流出去(有很多攻擊都是拿到程式碼後從裡面找到漏洞),因此只保留執行檔可以提高安全性

除此之外,因為環境越複雜就越可能有沒發現的漏洞,而把 base image 從原本的 golang:1.17 換成 Google 提供的 distroless image 剛好可以大幅減少環境的複雜度(distroless 幾乎沒裝什麼東西,連 shell 都沒有),也就可以提高安全性

小結

這兩天介紹了一些在寫 Dockerfile 時的注意事項,雖然很多都是小地方,但畢竟魔鬼藏在細節裡,想要讓你的 Docker image 更安全,那就連這些小細節都不能放過哦~


上一篇
Day26-保護鯨魚人人有責(一)
下一篇
Day28-保護鯨魚人人有責(三)
系列文
從以卵擊石到堅若磐石之 Web API 安全性全攻略30

尚未有邦友留言

立即登入留言