Pomeriumを導入してアクセスコントロールを行えるようにした話
こんにちは,ICTSCのインフラチームの竹村です.
普段は監視基盤の構築や運用を行っています.
ICTSCのインフラチームでは,使用しているサービスに対してアクセス制御を行うためにPomeriumと呼ばれるID認識型プロキシを使用しています. 本記事ではICTSCがPomeriumを導入した経緯とPomeriumの構築手順,最後に正常に構築できているかを確認します.
Pomeriumについて
Pomeriumは,内部のアプリケーションの前段にプロキシとして存在し,
外部のIDプロバイダーを用いてユーザを識別します.識別したユーザやユーザが所属するグループごとにポリシーを適用して,アクセスコントロールを行うことができます.
他のID認証型プロキシとしては,GoogleのIdentity-Aware ProxyやAkamaiのEnterprise Application Accessがあります.
公式の動画を見てもらえると,大体のイメージをつかんでもらえると思います.
今までのアクセスコントロール方法について
今までのアプリケーションへのアクセスコントロールの方針としては,認証が組み込まれていないアプリケーションはBasic認証を使用していました.例えばインフラチームでは,監視に使っているPrometheusに認証の仕組みがないため,Basic認証を使用していました.
認証が組み込まれているアプリケーションではadminアカウントを作成し,そのアカウントをチーム内で共有して運用を行っていました.
一方で,各アプリケーションごとに作成された管理用のユーザのパスワードを探す必要があるという問題や管理用のアカウントを複数人で共有しているためアクセスコントロールができないという問題がありました.
Pomeriumの導入
今までのアクセスコントロールの問題を解決するために,Pomeriumを導入しました.また,ICTSCではGitHub Organizationを使用しています.GitHub Organizationでのチームやメンバーに関しては,Terraformを使って管理しています.Pomeriumでは,IDプロバイダーとしてGitHubを使用することができます.また,GitHubのチームごとにアクセスコントロールの設定を簡単に行うことができます.
Pomeriumの構築手順
Pomeriumの構築手順を示します.インフラチームでは,HelmfileとArgo CDを使いデプロイの自動化を行っています.ここでは,Helmfileを使用したPomeriumの構築方法を示します.
Helmfileの書き方や使い方に関しては,以下のスライドに詳しくまとめられています.
Kubernetes Dashboard | Pomerium
Helm/Helmfileについて
以下のバージョンのソフトウェアを使用しています.
- Helm v3.4.1
- Helmfile v0.135.0
- Kubernetes v1.19.3
- Pomerium v0.12.1
IDプロバイダーとしては,GitHubを利用しています.
NGINX Ingress ControllerとCert-managerの構築とPomeriumでアクセスコントロールを行いたい内部のアプリケーションの用意が終わっていることが前提となります.今回の例では,内部のアプリケーションとして,Prometheusを使用しています.
次に,Pomeriumの構築を行っていきます.
まず,helmfile.yaml を用意します.
environments:
workspace:
values:
- environment/workspace/values.yaml
develop:
values:
- environment/develop/values.yaml
production:
values:
- environment/production/values.yaml
repositories:
- name: pomerium
url: https://helm.pomerium.io
releases:
- name: helm-pomerium
namespace: monitoring
chart: pomerium/pomerium
values:
- environment/{{ .Environment.Name}}/values.yaml
次に,各enviromentに対応したvalues.yamlのファイルを用意します.
authenticate:
idp:
provider: "github"
clientID: GitHub_CLIENT_ID
clientSecret: GitHub_CLIENT_SECRET
serviceAccount: "ewogICJ1c2VybmFtZSI6ICJZT1VSX0dJVEhVQl9VU0VSTkFNRSIsCiAgInBlcnNvbmFsX2FjY2Vzc190b2tlbiI6ICJHRU5FUkFURURfR0lUSFVCX0FDQ0VTU19UT0tFTiIKfQo="
forwardAuth:
enabled: true
config:
sharedSecret: YOUR_SHARED_SECRET
cookieSecret: YOUR_COOKIE_SECRET
rootDomain: dev.example.com
policy:
- from: https://dashboard-proxied.dev.example.com
to: http://prometheus.monitoring.svc.cluster.local:9090
allowed_groups: ["ictsc_infra"]
tls_skip_verify: true
- from: https://kibana.dev.example.com
to: http://kibana.monitoring.svc.cluster.local:5601
allowed_groups: ["ictsc_infra"]
tls_skip_verify: true
ingress:
hosts:
- dashboard-proxied.dev.example.com
- kibana.dev.example.com
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod" # see `le.issuer.yaml`
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
secretName: pomerium-ingress-tls
IDプロバイダーがGitHubの場合は,clientIDとclientSecret,serviceAccountの3つのトークンが必要になります.
これらのトークンの取得方法は,この後に説明します.
rootDomainを定義することにより,rootDomainを起点としてPrometheusの各コンポーネントのIngressが作成されます.
policyでは,該当するURLに対してアクセスしてきたユーザを識別しポリシーにマッチした場合,どのアプリケーションにルーティングするかを定義します.
policyの1つ目の例だと,ictsc_infraという名前のチームに所属しているユーザを http://dashboar-proxied.dev.example.com
から,内部のサービスのPrometheusにルーティングされます.
次に,GitHubでOAuth2を行うためのアプリケーションを作成します.
[Settings] →[Developer settings] → [New OAuth App]の順番にボタンを押し,新しくOAuthアプリケーションを作成します.
HomepageURLには,Pomeriumと統合するアプリケーションのホームページURLを入力します.Authorization callback URLにはPomeriumのauthenticate_service_urlを入力します.先ほどのvalues.yamlの例だと, https://authenticate.dev.example.com/oauth2/callback
になります.
Client IDとClient Secretsが作成されるので,その値を values.yaml
のclientIDとclientSecretに貼り付けます.
最後に,policyでallowed_groupを使用するために,サービスアカウントを設定します.GitHubのサービスアカウントは,github.com/settings/tokens/new から新しく取得できます.
取得したアクセストークンを以下のJSONに貼り付け,base64でエンコードします.
エンコードした結果を,values.yamlに貼り付けます.
{
"username": "YOUR_GITHUB_USERNAME",
"personal_access_token": "GENERATED_GITHUB_ACCESS_TOKEN"
}
$ base64 service_account.json
ewogICJ1c2VybmFtZSI6ICJZT1VSX0dJVEhVQl9VU0VSTkFNRSIsCiAgInBlcnNvbmFsX2FjY2Vzc190b2tlbiI6ICJHRU5FUkFURURfR0lUSFVCX0FDQ0VTU19UT0tFTiIKfQo=
あとは,設定をもとにPomeriumを立ち上げます.
以下のコマンドを実行します.
$ helmfile -e develop apply
サービスが起動しているを確認するために,以下のコマンドを実行します.
$ helm ls -n monitoring
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
helm-pomerium monitoring 2 2021-02-22 09:08:06.869077288 +0900 JST deployed pomerium-15.0.0 0.12.1
$ kubectl -n monitoring get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
helm-pomerium <none> dashboard-proxied.dev.example.com,kibana.dev.example.com,forwardauth.dev.example.com + 1 more... 80, 443 28h
Ingressのhostに定義したドメインにアクセスをすると,GitHubのログイン画面にリダイレクトされます.今回はICTSC Pomerium(dev)という名前のOAtuh アプリケーションで認可を行っています.
GitHubのユーザでログインを行います.policyのallowed_groupsで設定したチームに所属するユーザが,内部のサービスにアクセスできれば成功です.下の図では,内部サービスのPrometheusにアクセスできています.
最後に
インフラチームでPomeriumを利用することにより,GitHubのチームに基づいてアプリケーションのアクセスコントロールをできるようになりました.
後日にインフラチームが運用しているKubernetesの記事も公開されるので,楽しみにしてください!