iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Security

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

Day26-保護鯨魚人人有責(一)

前言

自從進入大容器時代後,Docker、K8s 已經逐漸成為開發、測試及部署時不可或缺的工具,但也因為這樣跟容器有關的攻擊越來越普遍

而想要從零開始建出一個容器,第一步就是要寫 Dockerfile 把你的應用包裝成 Docker image。關於怎麼產生出盡量小的 image 已經很多人寫過了,所以這兩天要來說說想要寫出一個安全的 Dockerfile,有哪些該注意的地方

使用 stable 或 LTS 的 base image

很多人在寫 Dockerfile 並不會特別指定 base image 的版本(就懶啊,我懂 XD),譬如說想要包一個 Node API server,就直接寫 FROM node 或是 FROM node:latest

# Bad
FROM node

WORKDIR /app
COPY . .
RUN npm install
RUN npm run test

但這樣可能會在哪次 build image 時就意外從 Node 14 升到 Node 16,導致部分功能直接壞掉。而且最新版本的 Node 可能有一些不為人知的 bug,需要有一些勇者去幫忙踩坑,所以除非是自己的 Side Project 想要玩玩看最新的 feature,否則直接把最新版本的 Node 用在 production 並不是個好作法

比較好的方式是先看看 Node 的 LTS(Long-Term Support) 版本是多少,像我在寫文章的當下是 v14.17.5,那就選擇 node:14 或是 node:14.17 作為 base image

# Good
FROM node:14

WORKDIR /app
COPY . .
RUN npm install
RUN npm run test

安裝套件時要指定版本

這點跟上面提到的不要用 latest image 有些類似,不管你是用 apt-get install 安裝 CLI 工具、用 npm install 裝函式庫、還是用 curl/wget 把東西下載回來編譯,都要盡量確保每次下載到的東西是一樣的

譬如在用 apt-get 安裝 nginx 時就可以透過 apt-get install nginx=1.14.0 來下載指定版本(有點麻煩對吧,我也覺得XD),而 npm、pip 這類的語言套件管理工具則是看官方推薦什麼方法,像 npm 就是用 package-lock.json 來鎖定套件的版本、pip 的話則是先跑 pip freeze > requirements.txt 把套件的版本凍起來,等要安裝時再跑 pip install -r requirements.txt 把原本的套件裝回來

# Good
FROM ubuntu:20.04

RUN apt-get update
RUN apt-get install nginx=1.14.0 python=2.7.15 nodejs=12.18.2

雖然把套件版本的鎖定之後可以省下很多麻煩,但也不能一直鎖在那都不更新,所以記得偶爾去檢查一下版本是不是太舊了,如果太舊再手動把版號升上去就好了~

不要把敏感資料 hardcode 在 Dockerfile 裡面

我想這已經是常識等級的安全知識了,因為直接把敏感資料用 ENV 寫在 Dockerfile 裡會讓駭客輕易拿到(只要拿到 image 就可以了),所以絕對不要想不開把資料庫或任何的帳號密碼寫在裡面,ENV 頂多用來設定時區或是 NODE_ENV 這種被看光也不會出事的變數就好,不然哪天資料被偷走真的會哭出來

FROM node:14

ENV TZ=Asia/Taipei
ENV NODE_ENV=production

# Very Bad
ENV PG_HOST=test.postgresql.com
ENV PG_USER=thisIsmyUserName
ENV PG_PASS=mySecretPa55w0rd
ENV PG_DBNAME=projectName

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

如果說 ENV 不能放敏感資料,那這些資料究竟要怎麼被加進環境變數呢?

答案就是在 docker run 時加上 --env 或是 --env-file 把環境變數塞進去;如果是用 docker-compose 的話,則是把那些資料寫進 docker-compose.yml 的 environment 裡面這樣 container 啟動時就會讀到這些變數,而且即便 image 被偷走也不用擔心資料外洩

小結

今天簡單介紹了三個寫 Dockerfile 時該注意的地方,但因為除了這幾個之外其實還有很多,所以明天會再補充幾個

如果對於今天的內容有什麼問題都歡迎在下方劉言提問,沒問題的話那就明天見囉~


上一篇
Day25-你的資料安全嗎(三)
下一篇
Day27-保護鯨魚人人有責(二)
系列文
從以卵擊石到堅若磐石之 Web API 安全性全攻略30

尚未有邦友留言

立即登入留言