oauth2_proxyを使用してGitHubログインの背後にあるプライベートKubernetesサービスを保護する方法
序章
Kubernetes ingresses を使用すると、Webサービスをインターネットに簡単に公開できます。 ただし、プライベートサービスに関しては、アクセスできるユーザーを制限することをお勧めします。 oauth2_proxy は、パブリックインターネットとプライベートサービスの間のバリアとして機能します。 oauth2_proxyは、GitHubなどのさまざまなプロバイダーを使用して認証を提供し、ユーザーの電子メールアドレスまたはその他のプロパティによってユーザーを検証するリバースプロキシおよびサーバーです。
このチュートリアルでは、GitHubでoauth2_proxyを使用して、サービスを保護します。 完了すると、次の図のような認証システムが作成されます。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Nginx入力とLet’sEncryptで実行される2つのWebサービスを備えたKubernetesクラスター。 このチュートリアルは、 DigitalOceanKubernetesでCert-Managerを使用してNginxIngressを設定する方法に基づいています。 このチュートリアルを完了するには、必ず最後まで実行してください。
- GitHubアカウント。
- ローカルマシンにインストールされたPython。 インストールされていない場合は、オペレーティングシステムのインストール手順に従ってください。
ステップ1—ドメインの構成
前提条件のセクションにリンクされているチュートリアルに従うと、クラスター上でecho1
とecho2
の2つのWebサービスが実行されます。 また、echo1.your_domain
およびecho2.your_domain
を対応するサービスにマップする1つの入力があります。
このチュートリアルでは、次の規則を使用します。
- すべてのプライベートサービスは、
service.int.your_domain
のように、.int.your_domain
サブドメインに分類されます。 認証Cookieはすべての*.int.your_domain
サブドメイン間で共有されるため、プライベートサービスを1つのサブドメインにグループ化するのが理想的です。 - ログインポータルは
auth.int.your_domain
で提供されます。
注:このチュートリアルに表示されている場所では、必ずyour_domain
を独自のドメイン名に置き換えてください。
開始するには、既存の入力定義を更新して、echo1
およびecho2
サービスを.int.your_domain
の下に移動します。 ドメインを変更できるように、テキストエディタでecho_ingress.yaml
を開きます。
- nano echo_ingress.yaml
echo1.your_domain
のすべてのインスタンスの名前をecho1.int.your_domain
に変更し、echo2.your_domain
のすべてのインスタンスをecho2.int.your_domain
に置き換えます。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: echo-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- echo1.int.your_domain
- echo2.int.your_domain
secretName: letsencrypt-prod
rules:
- host: echo1.int.your_domain
http:
paths:
- backend:
serviceName: echo1
servicePort: 80
- host: echo2.int.your_domain
http:
paths:
- backend:
serviceName: echo2
servicePort: 80
ファイルを保存し、変更を適用します。
- kubectl apply -f echo_ingress.yaml
これにより、echo1
およびecho2
サービスのTLS証明書も更新されます。
次に、行った変更を反映するようにDNS構成を更新します。 まず、次のコマンドを実行して詳細を出力することにより、Nginx入力のIPアドレスを検索します。
- kubectl get svc --namespace=ingress-nginx
出力のEXTERNAL-IP
の下にIPアドレスが表示されます。
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx LoadBalancer 10.245.247.67 203.0.113.0 80:32486/TCP,443:32096/TCP 20h
外部IPアドレスをクリップボードにコピーします。 DNS管理サービスを参照し、echo1-2.your_domain
のA レコードを見つけて、その外部IPアドレスを指します。 DigitalOceanを使用してDNSレコードを管理している場合、手順についてはDNSレコードの管理方法を参照してください。
echo1
およびecho2
のレコードを削除します。 ホスト名*.int.your_domain
の新しいA
レコードを追加し、それを入力の外部IPアドレスにポイントします。
これで、*.int.your_domain
の下のサブドメインへのリクエストはすべて、Nginx入力にルーティングされるため、クラスター内でこれらのサブドメインを使用できます。
次に、GitHubをログインプロバイダーとして構成します。
ステップ2—GitHubOAuthアプリケーションを作成する
oauth2_proxyは、さまざまなログインプロバイダーをサポートしています。 このチュートリアルでは、GitHubプロバイダーを使用します。 開始するには、新しいGitHubOAuthアプリを作成します。
アカウントの開発者設定ページのOAuthアプリタブで、新しいOAuthアプリボタンをクリックします。
アプリケーション名およびホームページURLフィールドは、任意のフィールドにすることができます。 認証コールバックURLフィールドに、https://auth.int.your_domain/oauth2/callback
と入力します。
アプリケーションを登録すると、クライアントIDとシークレットを受け取ります。 次のステップで必要になるため、2つに注意してください。
GitHub OAuthアプリケーションを作成したので、oauth2_proxyをインストールして構成できます。
ステップ3–ログインポータルの設定
Helmを使用して、oauth2_proxyをクラスターにインストールします。 まず、GitHubアプリケーションのクライアントIDとシークレットを保持するKubernetesシークレットと、oauth2_proxyによって設定されたブラウザーCookieの暗号化シークレットを作成します。
次のコマンドを実行して、安全なCookieシークレットを生成します。
- python -c 'import os,base64; print base64.b64encode(os.urandom(16))'
結果をクリップボードにコピーします
次に、Kubernetesシークレットを作成し、強調表示された値をCookieシークレット、GitHubクライアントID、およびGitHubシークレットキーに置き換えます。
- kubectl -n default create secret generic oauth2-proxy-creds \
- --from-literal=cookie-secret=YOUR_COOKIE_SECRET \
- --from-literal=client-id=YOUR_GITHUB_CLIENT_ID \
- --from-literal=client-secret=YOUR_GITHUB_SECRET
次の出力が表示されます。
Outputsecret/oauth2-proxy-creds created
次に、oauth2_proxy
の構成を含むoauth2-proxy-config.yaml
という名前の新しいファイルを作成します。
- nano oauth2-proxy-config.yaml
このファイルに設定する値は、ヘルムチャートのデフォルトを上書きします。 次のコードをファイルに追加します。
config:
existingSecret: oauth2-proxy-creds
extraArgs:
whitelist-domain: .int.your_domain
cookie-domain: .int.your_domain
provider: github
authenticatedEmailsFile:
enabled: true
restricted_access: |-
[email protected]
[email protected]
ingress:
enabled: true
path: /
hosts:
- auth.int.your_domain
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
tls:
- secretName: oauth2-proxy-https-cert
hosts:
- auth.int.your_domain
このコードは次のことを行います。
- 作成したシークレットを使用するようにoauth2_proxyに指示します。
- ドメイン名とプロバイダータイプを設定します。
- 許可されるメールアドレスのリストを設定します。 GitHubアカウントがこれらのメールアドレスのいずれかに関連付けられている場合、プライベートサービスへのアクセスが許可されます。
- Let’s EncryptからのTLS証明書を使用して、
auth.int.your_domain
のログインポータルにサービスを提供する入力を構成します。
シークレットと構成ファイルの準備ができたので、oauth2_proxy
をインストールできます。 次のコマンドを実行します。
- helm repo update \
- && helm upgrade oauth2-proxy --install stable/oauth2-proxy \
- --reuse-values \
- --values oauth2-proxy-config.yaml
Let’s Encrypt証明書が発行され、インストールされるまでに数分かかる場合があります。
展開が成功したことをテストするには、https://auth.int.your_domain
を参照します。 GitHubでログインするように求めるページが表示されます。
oauth2_proxyを設定して実行すると、あとはサービスで認証を要求するだけです。
ステップ4—プライベートサービスの保護
サービスを保護するには、oauth2_proxyを介して認証を実施するようにNginx入力を構成します。 Nginxとnginx-ingressはこの構成をネイティブにサポートしているため、入力定義にいくつかのアノテーションを追加するだけで済みます。
前提条件のチュートリアルで設定したecho1
およびecho2
サービスを保護しましょう。 エディタでecho_ingress.yaml
を開きます。
- nano echo_ingress.yaml
認証を要求するには、次の2つの注釈をファイルに追加します。
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/auth-url: "https://auth.int.your_domain/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.int.your_domain/oauth2/start?rd=https%3A%2F%2F$host$request_uri"
ファイルを保存し、変更を適用します。
- kubectl apply -f echo_ingress.yaml
https://echo1.int.your_domain
を参照すると、GitHubにアクセスするためにGitHubを使用してログインするように求められます。 有効なアカウントでログインすると、echo1
サービスにリダイレクトされます。 echo2
についても同様です。
結論
このチュートリアルでは、Kubernetesクラスターにoauth2_proxyを設定し、GitHubログインの背後にあるプライベートサービスを保護しました。 保護する必要のあるその他のサービスについては、手順4で概説されている手順に従ってください。
oauth2_proxyは、GitHub以外のさまざまなプロバイダーをサポートしています。 さまざまなプロバイダーの詳細については、公式ドキュメントを参照してください。
さらに、デフォルトはほとんどのニーズに適合しますが、調整が必要になる可能性のある多くの構成パラメーターがあります。 パラメータのリストについては、ヘルムチャートのドキュメントおよびoauth2_proxyのドキュメントを参照してください。