Skip to content

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 程度とコンパクトです。

1
2
3
# 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 程度になっています。

1
2
3
# 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 で起動する例は以下の通りです。

1
docker compose up -d