LoginSignup
2

More than 3 years have passed since last update.

posted at

GKE で oauth2_proxy を使って任意のサービスに Google アカウント認証を追加する

はじめに

  • GKE で Google アカウント認証を導入する場合 Cloud IAP を使うのが簡単。
  • Cloud IAP は手軽ではあるが、アクセスを許可するメールアドレスなどの設定がプロジェクト単位になるため場合によっては要件とマッチしないことがある。
  • そこで oauth2_proxy を使って Google アカウント認証プロキシを立てることで、任意のサービスで任意のアカウントやグループを対象にアクセスを制御することができるようになる。
  • この記事では Nginx サーバーの前に oauth2_proxy を立ち上げてアクセスコントロールを行う設定手順を記載する。

基本的な流れ

  • GCP コンソールで OAuth クライアントを作成する
  • (必要であれば)サービスアカウントを作成し設定する
  • Google アカウント認証を行う Nginx サービスを起動する

GKE クラスタの作成

  • 任意のプロジェクトで任意の設定で GKE クラスタを作成し、クラスタに接続しておく。

OAuth クライアントの作成

  • https://console.cloud.google.com にログイン
  • プロジェクトの作成または選択
  • "API とサービス" > "認証情報"
  • "認証情報を作成" > "OAuth クライアント ID"
  • "クライアント ID" と "クライアントシークレット" をシークレットに登録する
echo -n "クライアント ID" > clientid
echo -n "クライアントシークレット" > clientsecret
kubectl create secret generic oauth-setting --from-file=./clientid --from-file=./clientsecret

アクセスを許可するメールアドレスやグループを指定するための設定

  • oauth2_proxy では通常の OAuth 認証のあとにホワイトリストに記載されたメールアドレスやグループに所属するユーザーだけアクセスを許可する機能がある。
  • この検証のために内部ではサービスアカウントを利用しているので、メールアドレスやグループを指定してアクセスコントロールを行いたい場合はこの節の設定が必要になる。

サービスアカウントの作成

  • https://console.cloud.google.com にログイン
  • "IAM と管理" > "サービスアカウント"
  • "サービスアカウントの作成"
  • "新しい秘密鍵の提供" にチェックをして "JSON" でダウンロード

API の有効化

  • GCP コンソールメニューで "API とサービス" > "ライブラリ"
  • "Admin SDK" を検索して有効化する

サービスアカウントの設定

サービスアカウントの鍵ファイルをシークレットに入れる

  • サービスアカウント作成時にダウンロードした鍵の入った JSON ファイルを Kubernetes の Secret に追加します。
kubectl create secret generic sa-setting --from-file=./KEY_FILE.json

SSL 証明書の作成

  • OAuth 認証のためのページでは SSL を利用する必要がある。
  • 検証のために Ingress で自己認証証明書を使って SSL 通信を提供する。
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
kubectl create secret tls tls-secret --key tls.key --cert tls.crt

Docker image の作成

  • oauth2_proxy を実行するための Docker image を作成し Google Container Registry にアップロードする
FROM golang:1.10

ADD https://github.com/bitly/oauth2_proxy/releases/download/v2.2/oauth2_proxy-2.2.0.linux-amd64.go1.8.1.tar.gz /tmp
RUN tar -xf /tmp/oauth2_proxy-2.2.0.linux-amd64.go1.8.1.tar.gz -C ./bin --strip-components=1 && rm /tmp/*.tar.gz
docker build -t oauth2-proxy:v1.0 .
docker tag oauth2-proxy:v1.0 gcr.io/PROJECT_NAME/oauth2-proxy
gcloud docker -- push gcr.io/PROJECT_NAME/oauth2-proxy

Google 認証をする Nginx コンテナを立ち上げる

Deployment の作成

  • Nginx コンテナと oauth2_proxy コンテナを持つ Pod を Deployment から立ち上げる。
  • oauth2_proxy の args の -google-group-google-service-account-json はメールアドレスやグループ単位でアクセス制御を行いたい場合のみ指定する。
    • サービスアカウントの鍵ファイルのマウントも同様に必要であれば行う。
deployment.yml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      # Nginx コンテナ
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
      # oauth2_proxy コンテナ
      - name: oauth2-proxy
        image: gcr.io/PROJECT_NAME/oauth2-proxy
        ports:
        - containerPort: 4180
        command: ["/go/bin/oauth2_proxy"]
        args:
        - "-upstream=http://0.0.0.0:80/" # 認証成功時に提供するコンテンツの URL
        - "-http-address=0.0.0.0:4180" # oauth2_proxy が可動する URL
        - "-email-domain=*" # アクセスを許可するドメイン名
        - "-google-service-account-json=/etc/sa-setting/projectname-random.json" # サービスアカウントの鍵ファイルのパス
        - "-google-group=groupname@yourcompany.com" # アクセスを許可するグループのメールアドレス(複数回指定可)(サービスアカウント設定もする必要がある)
        - "-cookie-secret=5E3899D7-969C-449F-9EA7-41A21E690387" # クッキー名の seed 文字列
        - "-google-admin-email=chiba@kakapoapps.com" # Google の管理者アカウントのメールアドレス. サービスアカウントでのリクエスト送信時に利用する
        env:
        - name: OAUTH2_PROXY_CLIENT_ID
          valueFrom:
            secretKeyRef:
              name: oauth-setting
              key: clientid
        - name: OAUTH2_PROXY_CLIENT_SECRET
          valueFrom:
            secretKeyRef:
              name: oauth-setting
              key: clientsecret
        volumeMounts:
        # サービスアカウントの鍵ファイルをマウントする
        - name: sa-setting
          mountPath: "/etc/sa-setting"
          readOnly: true
        # Ingress のヘルスチェック用に設定. oauth2_proxy では /ping で疎通確認を行うことができる.
        readinessProbe:
          httpGet:
            path: /ping
            port: 4180
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      # サービスアカウントの鍵ファイルの Secret をマウントできるようにボリュームとして設定する
      - name: sa-setting
        secret:
          secretName: sa-setting

Service の作成

  • TCP/80 で受けて oauth2_proxy の TCP/4180 に転送するサービスを作成する.
service.yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx-service
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 4180
    protocol: TCP
    name: http
  selector:
    app: nginx

Ingress の作成

ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  tls:
    - hosts:
      - www.example.com # 任意のドメイン名を指定
      secretName: tls-secret # 作成した SSL 証明書の Secret を指定
  rules:
    - host: www.example.com
      http:
        paths:
        - path: /*
          backend:
            serviceName: nginx-service
            servicePort: 80

動作確認

  • kubectl get ingress で Ingress の IP アドレスを確認したら /etc/hosts などに指定したドメイン名と IP アドレスの設定を行いブラウザで動作確認を行う。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2