OAuth2Proxyは便利だよって話

こんにちは、インフラグループ Kubernetesチームの福田です。

突然ですが、Webアプリケーションでユーザの認証にOIDCを使うことはよくあると思います。
弊社でも様々な箇所でOIDCが利用されてます。
自社で開発しているWebアプリケーションや最近のログイン機能を持つOSSの多くは、OIDC Providerさえ用意すればOIDCを利用することができます。
しかし、現実的にはログイン機能を持たないOSSのWebアプリケーションでOIDC認証を使いたいケースや自前で開発したWebアプリケーションにおいてもわざわざOIDCのクライアント機能を追加実装するのが面倒なケースがあります。
そんな時に使えるのがOAuth2Proxyです。

OAuth2Proxyはリバースプロキシとして動作しながら、OIDCの認証をしてくれます。
具体的にはクライアントからのアクセスに対してOIDCの認証を行い、認証されたクライアントからのアクセスのみをバックエンドに通過させるといったことが可能です。

サンプル構成の構築

サンプル構成を通してKubernetes上での構築方法を紹介していきます。

サンプル構成ではOAuth2Proxyのバックエンドにnginxを利用し、OIDCプロバイダにはoktaを使いたいと思います。

okta(OIDC Provider)の設定

oktaのApplicationを作成します。

  1. Sign-in methodはOIDCを選択し、Application typeとしてWebを選択します。
  2. Grant typeではAuthorization CodeRefresh Tokenを選択します。
  3. Login Redirect URIsはお使いの環境に合わせて設定してください。(ここではhttps://corp.example.com/oauth2/callbackとしておきます。)
  4. また、作成後に生成されたClient IDClient Secretをメモしておきます。
  5. 最後にユーザのアクセス許可設定をします。

シークレット情報の作成

シークレット情報をSecretとして保存します。

kind: Secret
apiVersion: v1
metadata:
  name: my-credential
type: Opaque
data:
  client_id: **********
  client_secret: **********
  cookie_secret: **********

client_idclient_secretは"okta(OIDC Provider)の設定"のところでメモした値を使います。
cookie_secretにはランダムな値を使います。

Podの作成

OAuth2Proxyとnginxを構築します。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: sample
  name: sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample
  template:
    metadata:
      labels:
        app: sample
    spec:
      containers:
      - name: redis
        image: redis
        volumeMounts:
        - name: cache
          mountPath: /data
      - name: nginx
        image: nginx
      - name: oauth2-proxy
        image: bitnami/oauth2-proxy
        ports:
        - name: oauth-proxy
          containerPort: 80
        args:
        - --http-address
        - 0.0.0.0:80
        env:
        - name: OAUTH2_PROXY_UPSTREAMS
          value: http://localhost/
        - name: OAUTH2_PROXY_PROVIDER_DISPLAY_NAME
          value: okta
        - name: OAUTH2_PROXY_PROVIDER
          value: oidc
        - name: OAUTH2_PROXY_OIDC_ISSUER_URL
          value: https://sample.okta.com/oauth2/default
        - name: OAUTH2_PROXY_CLIENT_ID
          valueFrom:
            secretKeyRef:
              name: my-credential
              key: client_id
        - name: OAUTH2_PROXY_CLIENT_SECRET
          valueFrom:
            secretKeyRef:
              name: my-credential
              key: client_secret
        - name: OAUTH2_PROXY_PASS_ACCESS_TOKEN
          value: 'true'
        - name: OAUTH2_PROXY_EMAIL_DOMAINS
          value: '*'
        - name: OAUTH2_PROXY_REDIRECT_URL
          value: https://corp.example.com/oauth2/callback
        - name: OAUTH2_PROXY_COOKIE_SECURE
          value: 'false'
        - name: OAUTH2_PROXY_COOKIE_SECRET
          valueFrom:
            secretKeyRef:
              name: my-credential
              key: cookie_secret
        - name: OAUTH2_PROXY_SKIP_PROVIDER_BUTTON
          value: 'true'
        - name: OAUTH2_PROXY_COOKIE_NAME
          value: SESSION
        - name: OAUTH2_PROXY_COOKIE_SAMESITE
          value: lax
        - name: OAUTH2_PROXY_SESSION_STORE_TYPE
          value: redis
        - name: OAUTH2_PROXY_REDIS_CONNECTION_URL
          value: redis://localhost
        startupProbe:
          initialDelaySeconds: 5
          periodSeconds: 5
          tcpSocket:
            port: 6379
      volumes:
      - name: cache
        emptyDir: {}

nginxのPodに対してサイドカーとしてOAuth2Proxyコンテナを差し込んでいます。
redisコンテナがありますが、これはOIDCプロバイダーへのアクセスを減らすためのセッション情報のキャッシュとして使ってます。

サンプル構成の完了

IngressやServiceなどのリソース作成の説明は省略しますが、これで構築は完了です。
対象のURL(この記事の場合はhttps://corp.example.com)にアクセスするとoktaのサインイン画面が表示されます。

そして、サインインして認証をPASSするとnginxにアクセスできます。

参考リンク

まとめ

今回はOAuth2Proxyについて紹介させていただきました。
本記事を通して構築がとても簡単であることが分かったと思います。

OAuth2Proxyのようなツールを自前で社内開発しているところも多いのではないでしょうか。
メンテナンスコストの理由からそういった社内開発のアプリをOSSへ移行することを検討している場合はOAuth2Proxyは選択肢の1つとしてありかと思います。


株式会社エニグモ すべての求人一覧

hrmos.co