雑記帳

整理しない情報集

更新情報

OAuth2-Proxyをk8s/k3s+Traefikに乗せてみる

公開日:

カテゴリ: ソフトウェア

OAuth2-Proxyをk8s/k3s+Traefikに乗せるのに地味に手間取ったのでメモ書きです。構成は以前Dockerに構築したときと同じリダイレクト方式です。

OAuth2-Proxyのデプロイ

以前と同じ要領で普通にOAuth2-ProxyをセットアップすればOKです。特段の対応は不要です。

コンフィグファイルは以前とほぼ変わらないため省略します。下の例ではComfigMapとしてマウントしています。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: oauth2-proxy-ingress
  namespace: oauth2-proxy
spec:
  ingressClassName: traefik
  rules:
  - host: oauth2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: oauth2-proxy-service
            port:
              number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: oauth2-proxy-service
  namespace: oauth2-proxy
spec:
  type: ClusterIP
  selector:
    app: oauth2-proxy
  ports:
  - port: 80
    targetPort: 4180
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: oauth2-proxy
  namespace: oauth2-proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: oauth2-proxy
  template:
    metadata:
      labels:
        app: oauth2-proxy
    spec:
      containers:
      - name: oauth2-proxy
        image: quay.io/oauth2-proxy/oauth2-proxy:latest
        ports:
        - containerPort: 4180
          protocol: TCP
        volumeMounts:
        - name: config-volume
          mountPath: /etc/oauth2-proxy.cfg
          subPath: oauth2-proxy.cfg
        args: ["--config=/etc/oauth2-proxy.cfg"]
      volumes:
      - name: config-volume
        configMap:
          name: config

ミドルウェアの作成

このあたりがk8s/k3s+Traefikで実装する場合の肝となります。以下2つのミドルウェアを作成します。

  • 認証プロキシ
  • エラーリダイレクト

認証プロキシ

認証確認を実施するミドルウェアを作成します。

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oauth2-proxy-auth
  namespace: oauth2-proxy
spec:
  forwardAuth:
    address: https://oauth2-proxy-service.oauth2-proxy/oauth2/auth
    trustForwardHeader: true
    authResponseHeaders:
    - "X-Auth-Request-User"
    - "X-Auth-Request-Email"

spec.forwardAuth.addressにOAuth2-Proxyの認証確認の/oauth2/authエンドポイントを指定します。k8s/k3sの内部用に独自ドメインをTraefikに対して名前解決できるようにしている場合は、そのアドレスの指定でOKです(例: https://oauth2.example.com/oauth2/auth)。

アプリ側で認証ヘッダが必要な場合はtrustForwardHeaderauthResponseHeadersも設定します。

エラーリダイレクト

認証に失敗した場合に、認証画面にリダイレクトするためのミドルウェアを作成します。

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oauth2-proxy-redirect
  namespace: oauth2-proxy
spec:
  errors:
    status:
    - "401"
    service:
      name: oauth2-proxy-service
      port: 80
    query: "/oauth2/start?rd={url}"
    statusRewrites:
      401: 302

HTTPステータスコードが401の場合にoauth2-proxy-serviceサービスの/oauth2/startエンドポイントへリダイレクトします(HTTPステータスコードは401から302へ書き換え)。

クエリの{url}はリクエストURLに置換される(エスケープも自動)ためrd={url}を指定することで、開いたURLへ認証後にリダイレクトします。

ミドルウェアの適用

あとは認証プロキシを使いたいアプリのIngressのアノテーションに作成したミドルウェアを追加すると、認証プロキシが適用されます。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  namespace: myapp
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: oauth2-proxy-oauth2-proxy-redirect@kubernetescrd,oauth2-proxy-oauth2-proxy-auth@kubernetescrd
spec:
  ingressClassName: traefik
  rules:
    # 略

traefik.ingress.kubernetes.io/router.middlewaresという長いアノテーションのキー名は固定です。

ミドルウェアの指定方法は名前空間名-ミドルウェア名@kubernetescrdです。複数指定する場合はカンマ区切りです。名前空間名とミドルウェア名はハイフンでつなぐため、例のようにミドルウェアの名前空間名やミドルウェア名にハイフンが入っていると見づらいかもしれません。

カテゴリ: ソフトウェア