OAuth2 ProxyをCloud FoundryのSidecarとしてデプロイする
前記事、"Cloud Foundryの複数Portに対するRouting"で、
また、Sidecarを使う場合も同じようにRouteをmapできます。
と書いていたので、その例としてOAuth2 Proxyをsidecarとして使う例を紹介します。
次の図のような構成を実装します。

次のバージョンで確認しました。
$ cf -v
cf version 6.50.0+4f0c3a2ce.2020-03-03
$ cf curl /v2/info | jq -r .build
2.8.6-build.15
Main Appの作成
ここではphp buildpackで作ったアプリをUpstreamのMain Appとして扱います。
Main Appは次のように作成します。
mkdir -p /tmp/demo-oauth2-proxy/htdocs
cd /tmp/demo-oauth2-proxy
echo 'Hello World!' > htdocs/index.html
このMain Appへアクセスする前にGithubで認証させるためにOAuth2 ProxyをReverse Proxとして使うことを今回の題材とします。
Main Appへ直接アクセスされることを防ぐため、デフォルトの設定である、Main App(8080ポート)へのRoutingは行いません。 代わりに同一コンテナ内にSidecarとして起動するOAuth2 Proxy(4180ポート)に対してのみRoutingします。
OAuth2 Proxyのダウンロード
次のコマンドでOAuth2 Proxyの実行可能バイナリをダウンロードしてください。
cd /tmp/demo-oauth2-proxy
curl -Ls https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v5.1.0/oauth2_proxy-v5.1.0.linux-amd64.go1.14.tar.gz | tar xzv && \
mv oauth2_proxy-*/oauth2_proxy ./ && \
rm -rf oauth2_proxy-*
Github OAuth2 Appの作成
https://github.com/settings/developersからGithub OAuth2 Appを登録します。
"New OAuth App"ボタンをクリックして、Authorization callback URLにhttps://<TARGET_SUBDOMAIN>.<APPS_DOMAIN>/oauth2/callbackを入力してください。
下図の例ではTARGET_SUBDOMAIN=demo-oauth2-proxy、APPS_DOMAIN=apps.pcfone.ioです。

Client IDとClient Secretをメモしてください。

この値をUser Provider ServiceまたはCredHub Service Brokerに登録します。
User Provided Serviceの場合
cf create-user-provided-service github-oauth2-app -p '{"client_id": "3210067a78235e54fa17", "client_secret":"24c06ed8c2d6d7146c28e4cd72c4d18b63ef5bef"}'
CredHub Service Brokerの場合
cf create-service credhub default github-oauth2-app -c '{"client_id": "3210067a78235e54fa17", "client_secret":"24c06ed8c2d6d7146c28e4cd72c4d18b63ef5bef"}'
Main App及びSidecarのデプロイ
次のmanifest.ymlを作成してください。OAUTH2_PROXY_EMAIL_DOMAINS、OAUTH2_PROXY_COOKIE_SECRET、OAUTH2_PROXY_GITHUB_ORGは自分の環境に合わせて変更してください。
applications:
- name: demo-oauth2-proxy
buildpacks:
- php_buildpack
memory: 64M
services:
- github-oauth2-app
env:
# Configurationの詳細は https://oauth2-proxy.github.io/oauth2-proxy/configuration
OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180
OAUTH2_PROXY_EMAIL_DOMAINS: .pivotal.io,.vmware.com
OAUTH2_PROXY_COOKIE_SECURE: true
# 次のコマンドで生成。 python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(16)).decode())'
OAUTH2_PROXY_COOKIE_SECRET: 1pNTxc6qvV1rZBYobr0FUQ==
OAUTH2_PROXY_UPSTREAMS: http://localhost:8080
OAUTH2_PROXY_PROVIDER: github
OAUTH2_PROXY_GITHUB_ORG: pivotal
sidecars:
- name: oauth2-proxy
process_types:
- web
command: |
echo ${VCAP_SERVICES} | grep credhub
if [ "$?" = "0" ];then
CREDS=$(echo ${VCAP_SERVICES} | jq '.["credhub"][0].credentials')
else
CREDS=$(echo ${VCAP_SERVICES} | jq '.["user-provided"][0].credentials')
fi
export OAUTH2_PROXY_CLIENT_ID=$(echo ${CREDS} | jq -r .client_id)
export OAUTH2_PROXY_CLIENT_SECRET=$(echo ${CREDS} | jq -r .client_secret)
/home/vcap/app/oauth2_proxy
次のコマンドでデプロイしてください。
APP_NAME=demo-oauth2-proxy
TARGET_SUBDOMAIN=${APP_NAME}
APPS_DOMAIN=$(cf curl "/v2/shared_domains" | jq -r ".resources[0].entity.name")
CURRENT_SPACE=$(cat ~/.cf/config.json | jq -r ".SpaceFields.Name")
# 1.
cf v3-create-app ${APP_NAME}
APP_GUID=$(cf app ${APP_NAME} --guid)
# 2.
cf curl "/v2/apps/${APP_GUID}" -X PUT -d "{\"ports\": [8080, 4180]}"
cf create-route ${CURRENT_SPACE} ${APPS_DOMAIN} --hostname ${TARGET_SUBDOMAIN}
ROUTE_GUID=$(cf curl "/v2/routes?q=host:${TARGET_SUBDOMAIN}" | jq -r ".resources[0].metadata.guid")
# 3.
cf curl "/v2/route_mappings" -X POST -d "{\"app_guid\": \"${APP_GUID}\", \"route_guid\": \"${ROUTE_GUID}\", \"app_port\": 4180}"
# 4.
cf v3-apply-manifest -f manifest.yml
cf v3-push ${APP_NAME}
- Sidecarを含むmanifestを使ってデプロイする場合は、先にappを作成する必要があります。[Doc]
- このコンテナが
8080と4180をListenしていることを設定します。ここで設定したポートでヘルスチェックが行われます。通常Main Appはここで指定した一つ目のポートを使用するので、先頭を8080にするのが無難です。 - 作成したRouteにアクセスした場合に、このコンテナ内の4180ポートにマッピングされるように設定します。
- Sidecarを含むmanifestを適用します。
cf logs ${APP_NAME}を確認すると、次のようなログが出力されます。
2020-04-11T23:51:16.84+0900 [API/1] OUT Starting app with guid 5a8769b7-4891-4f57-b6aa-0157f3e945dc
2020-04-11T23:51:17.06+0900 [CELL/0] OUT Cell eda33d0c-120e-4025-991c-fd5f1c7d1e68 creating container for instance 291d8c06-72f4-4fbc-68ce-59be
2020-04-11T23:51:17.79+0900 [CELL/0] OUT Cell eda33d0c-120e-4025-991c-fd5f1c7d1e68 successfully created container for instance 291d8c06-72f4-4fbc-68ce-59be
2020-04-11T23:51:18.06+0900 [CELL/0] OUT Downloading droplet...
2020-04-11T23:51:22.75+0900 [CELL/0] OUT Downloaded droplet (90.7M)
2020-04-11T23:51:23.08+0900 [CELL/0] OUT Starting health monitoring of container
2020-04-11T23:51:24.60+0900 [APP/PROC/WEB/SIDECAR/OAUTH2-PROXY/0] ERR [2020/04/11 14:51:24] [oauthproxy.go:215] mapping path "/" => upstream "http://localhost:8080/"
2020-04-11T23:51:24.60+0900 [APP/PROC/WEB/SIDECAR/OAUTH2-PROXY/0] ERR [2020/04/11 14:51:24] [http.go:92] HTTP: listening on 0.0.0.0:4180
2020-04-11T23:51:24.69+0900 [APP/PROC/WEB/0] OUT 14:51:24 httpd | [Sat Apr 11 14:51:24.685558 2020] [mpm_event:notice] [pid 168:tid 140340045219712] AH00489: Apache/2.4.41 (Unix) configured -- resuming normal operations
2020-04-11T23:51:24.69+0900 [APP/PROC/WEB/0] OUT 14:51:24 httpd | [Sat Apr 11 14:51:24.685696 2020] [mpm_event:info] [pid 168:tid 140340045219712] AH00490: Server built: Jan 7 2020 15:08:24
2020-04-11T23:51:24.69+0900 [APP/PROC/WEB/0] OUT 14:51:24 httpd | [Sat Apr 11 14:51:24.685704 2020] [core:notice] [pid 168:tid 140340045219712] AH00094: Command line: '/app/httpd/bin/httpd -f /home/vcap/app/httpd/conf/httpd.conf -D FOREGROUND'
2020-04-11T23:51:24.75+0900 [APP/PROC/WEB/0] OUT 14:51:24 php-fpm | [11-Apr-2020 14:51:24] NOTICE: fpm is running, pid 170
2020-04-11T23:51:24.75+0900 [APP/PROC/WEB/0] OUT 14:51:24 php-fpm | [11-Apr-2020 14:51:24] NOTICE: ready to handle connections
2020-04-11T23:51:26.69+0900 [CELL/0] OUT Container became healthy
デプロイが成功したらhttps://${TARGET_SUBDOMAIN}.${APPS_DOMAIN}にアクセスしてください。
未ログイン状態では次のようにOAuth2 Proxyの画面が表示されます。

"Sign in with GitHub"をクリックして、GitHubにログインしてください。

"Authorize"をクリック。

これでMain AppのHello World!が出力されます。

SidecarとRoute Mappingの応用を使ってReverse Proxyを同一コンテナ内に立てる方法を紹介しました。色々応用が効くと思います。