tl;dr
- OAuth2 Proxyは既存サービスに変更を加えずにOAuth2認証を追加できるOSSで、Goole認証も追加できるよ
- GCP(Google Cloud Platform)でOAuth2の設定をして、kubernetesのPodの中にoauth2-proxyを追加したら簡単にGoogle認証を追加できたよ
OAuth2 Proxy とは
プロキシとして動作して、OAuth2認証を追加できるOSSです。
アーキテクチャ図を見ると、一度通信をoauth2-proxyが受けて、OAuth2認証を行い、認証の通った通信のみを、バックエンドのサービスに繋ぐ様になっていることがしれます。
やってみたのアーキテクチャ
自宅サーバ(OrangePi5+、ラズパイのようなもの)で自分が使うWebサービスを公開しているのですが、これを使うことで簡単にGoogle認証を組み込めないかやってみました。
なお、自宅サーバは以下のようなものです。
- マシン: OrangePi5+ ARM64 Memory16GB
- SSLのフロント: nginx
- コンテナオーケストレーションツール: k3s
構成は以下の通りです。フロントにSSLを処理するためのnginxが入っていますが、今回は本題ではないので説明を省略します。アプリケーションのnamespaceの方をみてください。Podの中に、oauth2-proxyコンテナと、保護対象のコンテナの2つがある構成とします。
Google認証の準備
Google側の設定は、GCPコンソール上で設定できました。詳細は、OAuth2 Proxyのドキュメントにあります。
GCPの「APIとサービス」のメニューの認証情報から、認証情報の作成を行います。
https://chatgpt.74th.tech というURLでサービスをすると以下のように設定します。
- アプリケーション種類: Webアプリケーション
- 名前: 任意
- 承認済みのJavaScript生成元:
https://chatgpt.74th.tech
- 承認済みのリダイレクトURI:
https://chatgpt.74th.tech/oauth2/callback
これで client_id と client_secret がコピーできるため、それをメモします。
これでGCP側の設定は完了です。
OAuth2 Proxyの設定ファイルを作る
OAuth2 Proxyは設定ファイルが必要です。Google認証の場合、以下のようになります。
http_address = "0.0.0.0:3001"
redirect_url = "https://chatgpt.74th.tech/oauth2/callback"
upstreams = ["http://localhost:3000/"]
client_id = "<GCPからコピーしたclient_id>"
client_secret = "<GCPからコピーしたclient_secret>"
oidc_issuer_url = "https://chatgpt.74th.tech"
provider = "google"
cookie_secret = "<作成したcookie_secret>"
- http_address: oauth2-proxyのプログラムがリスンするホストとポート
- redirect_url:
https://chatgpt.74th.tech/oauth2/callback
- upstreams: oauth2-proxyから保護対象のコンテナへのアクセス
- client_id、client_secret: GCPで設定後得た値
- oidc_issuer_url:
https://chatgpt.74th.tech
- provider:
google
- cookie_secret: 後述
cookie_secretはただの乱数値でよく、公式サイトにもPythonでの生成例が掲載されています。
https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview
python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())'
許可するユーザは、いくつか設定方法がありますが、メールアドレスのリストファイルを作る方法があります。
fugafuga@gmail.com
hogehoge@gmail.com
Kubernetesマニフェストを作る
設定ファイルをマウントしたいため、KustomizeのConfigmap Generatorの機能を使います。
resources:
- deploy.yaml
- service.yaml
configMapGenerator:
- name: oauth2-proxy-config
files:
- oauth2-proxy-config/oauth2-proxy.cfg
- oauth2-proxy-config/authenticated-emails.txt
Deploymentは以下のように記述しました。
- containersに、アプリケーションと、oauth2-proxyと目的のアプリの2つのコンテナを設定する。
- OAuth2 Proxyの設定ファイルをマウントするように設定する。
- OAuth2 Proxyのコンテナの、プログラムの引数に設定ファイルを指すように設定する。
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
spec:
replicas: 1
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
containers:
# 目的のアプリ
- name: server
image: gcr.io/gcp-project/chatgpt-app:latest
ports:
- containerPort: 3000
# OAuth2 zproxy
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0-arm64
ports:
- containerPort: 3001
args:
- --config=/etc/oauth2-proxy-config/oauth2-proxy.cfg
- --authenticated-emails-file=/etc/oauth2-proxy-config/authenticated-emails.txt
volumeMounts:
- mountPath: /etc/oauth2-proxy-config
name: oauth2-proxy-config
volumes:
- name: oauth2-proxy-config
configMap:
name: oauth2-proxy-config
特に紹介すべきことはないですが、Serviceのマニフェストです。
apiVersion: v1
kind: Service
metadata:
name: server
namespace: chatgpt
labels:
run: server
spec:
ports:
- name: http
port: 3001
targetPort: 3001
nodePort: 30310
selector:
app: server
type: NodePort
アクセスすると
OAuth2 Proxyのページが最初に表示され、Google認証に進むことができました。
終わりに
簡単に自宅サーバ上のKubernetesで動かすアプリに、Google認証を追加することができました。
ユーザ管理を必要としないアプリケーションであれば簡単に設定できるため、便利に感じます。
Proxyであることで、バックエンドのアプリケーションの脆弱性を気にする必要がない(Cookieハイジャックはありますが)のも、非常にありがたいです。