distroless/static ベースの OAuth2 Proxy コンテナイメージを作成した
Louketo に EOL notice として下記の記載があります。 Sunsetting Louketo Project にも同様の記載があります。
Louketo Proxy reached end of line in November 21, 2020. This means that we no longer support, or update it. The details are available here.
FAQ に下記の記載もあります。
Are there any alternatives I should use instead?
OAuth2 Proxy is very close in a set of capabilities to Louketo Proxy and we highly suggest you investigate it as a replacement.
上述の通り、OAuth2 Proxy が代替候補として記載されています。 OAuth2 Proxy は golang で書かれており、シングルバイナリで動作する為、デプロイも簡単です。 OAuth2 Proxy は公式にも docker コンテナイメージが配布されているのですが、distroless/static ベースなイメージを作成したのでメモしておきます。
OAuth2 Proxy 公式の Docker コンテナイメージ
OAuth2 Proxy は Dockerfile も公開されていますし、quay.io/oauth2-proxy/oauth2-proxy でコンテナイメージも公開されています。 OAuth2 Proxy の GitHub ページで公開されている Dockerfile はマルチステージビルドになっており、最終的に作成されるイメージのベースは alpine:3.15 になっていました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 | # All builds should be done using the platform native to the build node to allow
# cache sharing of the go mod download step.
# Go cross compilation is also faster than emulation the go compilation across
# multiple platforms.
FROM --platform=${BUILDPLATFORM} golang:1.17-buster AS builder
# Copy sources
WORKDIR $GOPATH/src/github.com/oauth2-proxy/oauth2-proxy
# Fetch dependencies
COPY go.mod go.sum ./
RUN go mod download
# Now pull in our code
COPY . .
# Arguments go here so that the previous steps can be cached if no external
# sources have changed.
ARG VERSION
ARG TARGETPLATFORM
ARG BUILDPLATFORM
# Build binary and make sure there is at least an empty key file.
# This is useful for GCP App Engine custom runtime builds, because
# you cannot use multiline variables in their app.yaml, so you have to
# build the key into the container and then tell it where it is
# by setting OAUTH2_PROXY_JWT_KEY_FILE=/etc/ssl/private/jwt_signing_key.pem
# in app.yaml instead.
# Set the cross compilation arguments based on the TARGETPLATFORM which is
# automatically set by the docker engine.
RUN case ${TARGETPLATFORM} in \
"linux/amd64") GOARCH=amd64 ;; \
"linux/arm64") GOARCH=arm64 ;; \
"linux/arm/v6") GOARCH=arm GOARM=6 ;; \
esac && \
printf "Building OAuth2 Proxy for arch ${GOARCH}\n" && \
GOARCH=${GOARCH} VERSION=${VERSION} make build && touch jwt_signing_key.pem
# Copy binary to alpine
FROM alpine:3.15
COPY nsswitch.conf /etc/nsswitch.conf
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /go/src/github.com/oauth2-proxy/oauth2-proxy/oauth2-proxy /bin/oauth2-proxy
COPY --from=builder /go/src/github.com/oauth2-proxy/oauth2-proxy/jwt_signing_key.pem /etc/ssl/private/jwt_signing_key.pem
USER 2000:2000
ENTRYPOINT ["/bin/oauth2-proxy"]
|
このイメージを Trivy でチェックしたところ、以下の結果でした。 ベースになっている alpine:15 が Total: 0
と非常に優秀です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | # trivy image quay.io/oauth2-proxy/oauth2-proxy
2022-01-02T10:40:00.093+0900 INFO Detected OS: alpine
2022-01-02T10:40:00.093+0900 INFO Detecting Alpine vulnerabilities...
2022-01-02T10:40:00.095+0900 INFO Number of language-specific files: 1
2022-01-02T10:40:00.095+0900 INFO Detecting gobinary vulnerabilities...
quay.io/oauth2-proxy/oauth2-proxy (alpine 3.15.0)
=================================================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
bin/oauth2-proxy (gobinary)
===========================
Total: 1 (UNKNOWN: 1, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
+-------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+-------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| golang.org/x/text | CVE-2021-38561 | UNKNOWN | v0.3.3 | 0.3.7 | -->avd.aquasec.com/nvd/cve-2021-38561 |
+-------------------+------------------+----------+-------------------+---------------+---------------------------------------+
|
イメージサイズは以下でした。 OAuth2 Proxy のバイナリが 20MB 程度あるのですが、alpine のベースイメージが 5.6MB 程度しか無い為、結果的に 28MB 程度とコンパクトです。
| # docker images quay.io/oauth2-proxy/oauth2-proxy
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/oauth2-proxy/oauth2-proxy latest 3ff33e0bddcf 10 days ago 28.5MB
|
distroless ベースで自作した Docker コンテナイメージ
勉強がてら、distroless ベースで Docker コンテナイメージを作成してみました。
Trivy でチェックすると CVE-2021-45046 のみ、検出されていました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | # trivy image sig9/oauth2-proxy
2022-01-02T12:10:57.050+0900 INFO Detected OS: debian
2022-01-02T12:10:57.050+0900 INFO Detecting Debian vulnerabilities...
2022-01-02T12:10:57.051+0900 INFO Number of language-specific files: 1
2022-01-02T12:10:57.051+0900 INFO Detecting gobinary vulnerabilities...
sig9/oauth2-proxy (debian 11.2)
===============================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
app/oauth2-proxy (gobinary)
===========================
Total: 1 (UNKNOWN: 1, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
+-------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+-------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| golang.org/x/text | CVE-2021-38561 | UNKNOWN | v0.3.3 | 0.3.7 | -->avd.aquasec.com/nvd/cve-2021-38561 |
+-------------------+------------------+----------+-------------------+---------------+---------------------------------------+
|
イメージサイズは以下でした。 OAuth2 Proxy のバイナリが 20MB 程度、distroless/static のサイズが 3MB 程度、合計で 25MB 程度になっています。
| # docker images sig9/oauth2-proxy
REPOSITORY TAG IMAGE ID CREATED SIZE
sig9/oauth2-proxy latest 7347c593447e 2 minutes ago 25.1MB
|
OAuth2 Proxy コンテナ用の docker-compose.yaml ファイル
OAuth2 Proxy は設定ファイルを指定することも出来ますが、docker コンテナとして起動する場合は設定を環境変数として指定するのも簡単です。 ただ、毎回 docker の起動オプションに環境変数を指定するのはやや手間なので必要なパラメータを定義した docker-compose.yaml
を用意しておきます。 主に以下の項目について値を検討します。
項目 |
値 |
OAUTH2_PROXY_COOKIE_SECRET |
openssl rand -base64 32 \| tr -- '+/' '-_' で生成する |
OAUTH2_PROXY_UPSTREAMS |
環境に合わせて調整 |
OAUTH2_PROXY_OIDC_ISSUER_URL |
Realm の Endpoint Configuration から取得 |
OAUTH2_PROXY_CLIENT_ID |
Realm で作成した Client ID |
OAUTH2_PROXY_CLIENT_SECRET |
Realm で作成した Client の Credential 情報から取得 |
OAUTH2_PROXY_REDIRECT_URL |
http://OAUTH2-PROXY/oauth2/callback を指定 |
docker-compose.yaml
の具体例は以下の通りです。 同じ docker-compose.yaml
中で Nginx を起動し、それを OAUTH2_PROXY_UPSTREAMS
に Upstream として指定しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | version: "3"
services:
nginx:
image: sig9/nginx
oauth2-proxy:
image: sig9/oauth2-proxy
environment:
OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180
OAUTH2_PROXY_COOKIE_SECRET: CIqqMvs7n9hOXQ2YRpzcDlD2kmWzSnkD2Hc_nJpBVn4=
OAUTH2_PROXY_COOKIE_SECURE: "false"
OAUTH2_PROXY_COOKIE_NAME: "oauth2_proxy"
OAUTH2_PROXY_EMAIL_DOMAINS: "*"
OAUTH2_PROXY_UPSTREAMS: http://nginx/
OAUTH2_PROXY_PROVIDER: oidc
OAUTH2_PROXY_OIDC_ISSUER_URL: http://10.0.0.1:8080/auth/realms/realm1
OAUTH2_PROXY_CLIENT_ID: nginx
OAUTH2_PROXY_CLIENT_SECRET: BOXBGE8a3pPMCy7ZsHWIMDUX9h5QqQRB
OAUTH2_PROXY_REDIRECT_URL: http://10.0.0.1/oauth2/callback
OAUTH2_PROXY_SCOPE: openid email profile
OAUTH2_PROXY_PASS_ACCESS_TOKEN: "true"
OAUTH2_PROXY_PASS_USER_HEADERS: "true"
OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER: "true"
OAUTH2_PROXY_SKIP_PROVIDER_BUTTON: "true"
OAUTH2_PROXY_INSECURE_OIDC_ALLOW_UNVERIFIED_EMAIL: "true"
ports:
- 80:4180
|
実際に docker-compose で起動する例は以下の通りです。