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—ドメインの構成
前提条件のセクションにリンクされているチュートリアルに従うと、クラスターで2つのWebサービスecho1
とecho2
が実行されます。 また、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
に置き換えます。
echo_ingress.yaml
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
このファイルに設定する値は、ヘルムチャートのデフォルトを上書きします。 次のコードをファイルに追加します。
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つの注釈をファイルに追加します。
echo_ingress.yaml
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のドキュメントを参照してください。