distrolessのnonrootイメージを使おう

この記事は はてなエンジニア Advent Calendar 2021 11日目の記事です。

コンテナのベースイメージとしてdistrolessを選択肢にするということがここ最近増えてきました。

そんなdistrolessを非rootユーザで使おうとしたらとても簡単だったのでその紹介です。

どのくらい簡単かというと、Goのアプリケーションであれば以下のように変えるだけで対応できます。(コメントアウト部分は元々のrootユーザで動かしていた場合のもの)

FROM golang:1.17 as builder

WORKDIR /go/src
COPY go.mod go.sum .
RUN go mod download
COPY . .
RUN go build -o /out/myapp .

# FROM gcr.io/distroless/static:latest
FROM gcr.io/distroless/static:nonroot

# COPY --from=builder /out/myapp /usr/local/bin/
COPY --from=builder --chown=nonroot:nonroot /out/myapp /usr/local/bin/

distrolessでは2019年にマージされた以下のプルリクエストで非rootユーザである nonroot ユーザ及びそれを利用するための :nonroot というイメージタグが導入されました。

github.com

:nonroot のタグはstaticに限らずdistrolessの全イメージで使うことができ、簡単には :latest はrootユーザで :nonroot はnonrootユーザという区別がされています。

なので非rootユーザ対応は基本的には :nonroot にするだけで良いですが、マルチステージビルドの場合はbuilderステージで作成されたものはユーザを指定していない限りrootで作成されて実行できなくなってしまうのでCOPY時にchownオプション*1nonroot:nonroot を指定してあげる必要があります。

ちなみにnonrootというユーザは :nonroot イメージに限らずどのイメージでも作成されているのでDockerfileに USER nonroot と書くという方法でも冗長だけど一応実現は可能です。

cohalz@co ~ % docker run -it --rm gcr.io/distroless/static:debug
/ # cat /etc/passwd
root:x:0:0:root:/root:/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/sbin/nologin
nonroot:x:65532:65532:nonroot:/home/nonroot:/sbin/nologin

ちなみにdistrolessはnonroot以外にもbusybox入りのdebugイメージやアーキテクチャも指定することができますが、全部使いたい場合は順番としてはdebug-nonroot-arm64 といった順番で指定するという感じになっています。

この :nonroot イメージは少しずつ利用が広がっており、google/koも2020年10月に出たv0.6.0からデフォルトではこのnonrootイメージを使うようになっています。

cloud.google.com

セキュリティ対策をちゃんとしようという流れがある中、コンテナイメージの非root化をまだ全然やれてない人は数行変えるだけで試せるdistrolessからやってみてはどうでしょうかという記事でした。

明日のアドベントカレンダーの担当は id:papix さんです。