oauth2_proxyを使用してGitHubログインの背後にあるプライベートKubernetesサービスを保護する方法

前書き

Kubernetesingressesを使用すると、Webサービスをインターネットに簡単に公開できます。 ただし、プライベートサービスに関しては、アクセスできるユーザーを制限する必要があります。 oauth2_proxyは、パブリックインターネットとプライベートサービスの間のバリアとして機能します。 oauth2_proxyは、GitHubなどのさまざまなプロバイダーを使用して認証を提供するリバースプロキシおよびサーバーであり、電子メールアドレスまたはその他のプロパティによってユーザーを検証します。

このチュートリアルでは、GitHubでoauth2_proxyを使用してサービスを保護します。 完了すると、次の図のような承認システムが作成されます。

A diagram of a request flow end-result

前提条件

このチュートリアルを完了するには、次のものが必要です。

[[step-1 -—- configuring-your-domains]] ==ステップ1—ドメインの構成

「前提条件」セクションにリンクされているチュートリアルに従うと、クラスターで2つのWebサービス(echo1echo2)が実行されます。 また、echo1.your_domainecho2.your_domainを対応するサービスにマップする1つの入力があります。

このチュートリアルでは、次の規則を使用します。

  • すべてのプライベートサービスは、service.int.your_domainのように.int.your_domainサブドメインに分類されます。 認証Cookieはすべての*.int.your_domainサブドメイン間で共有されるため、プライベートサービスを1つのサブドメインにグループ化するのが理想的です。

  • ログインポータルはauth.int.your_domainで提供されます。

[.note]#Note:このチュートリアルに表示されている場所では、必ず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管理サービスを参照し、その外部IPアドレスを指すecho1-2.your_domainAレコードを見つけます。 DigitalOceanを使用してDNSレコードを管理している場合、手順についてはHow to Manage DNS Recordsを参照してください。

echo1およびecho2のレコードを削除します。 ホスト名*.int.your_domainの新しいAレコードを追加し、それを入力の外部IPアドレスにポイントします。

これで、*.int.your_domainの下のサブドメインへのリクエストはすべて、Nginx入力にルーティングされるため、クラスター内でこれらのサブドメインを使用できます。

次に、GitHubをログインプロバイダーとして構成します。

[[step-2 -—- creating-a-github-oauth-application]] ==ステップ2— GitHubOAuthアプリケーションの作成

oauth2_proxyは、さまざまなログインプロバイダーをサポートします。 このチュートリアルでは、GitHubプロバイダーを使用します。 開始するには、新しいGitHub OAuthアプリを作成します。

アカウントのOAuth Apps tab of the Developer settingsページで、New OAuth Appボタンをクリックします。

Application nameフィールドとHomepage URLフィールドは、任意の値にすることができます。 [Authorization callback URL]フィールドにhttps://auth.int.your_domain/oauth2/callbackと入力します。

アプリケーションの登録後、クライアントIDとシークレットを受け取ります。 次のステップで必要になるため、この2つに注意してください。

GitHub OAuthアプリケーションを作成したので、oauth2_proxyをインストールして構成できます。

[[step-3 -–- setting-up-the-login-portal]] ==ステップ3–ログインポータルの設定

Helmを使用してoauth2proxy onto the cluster. First, you’ll create a Kubernetes secret to hold the GitHub application’s Client ID and Secret, as well as an encryption secret for browser cookies set by oauth2proxyをインストールします。

次のコマンドを実行して、安全なCookieシークレットを生成します。

python -c 'import os,base64; print base64.b64encode(os.urandom(16))'

結果をクリップボードにコピーします

次に、Cookieシークレット、GitHubクライアントID、およびGitHubシークレットキーの強調表示された値を置き換えて、Kubernetesシークレットを作成します。

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

このコードは次のことを行います。

  1. 作成したシークレットを使用するようにoauth2_proxyに指示します。

  2. ドメイン名とプロバイダータイプを設定します。

  3. 許可されたメールアドレスのリストを設定します。 GitHubアカウントがこれらのメールアドレスのいずれかに関連付けられている場合、プライベートサービスへのアクセスが許可されます。

  4. 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をセットアップして実行すると、サービスで認証を要求するだけです。

[[step-4 -—- protecting-the-private-services]] ==ステップ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を使用してログインするように求められます。 有効なアカウントでログインすると、echo1サービスにリダイレクトされます。 同じことがecho2にも当てはまります。

結論

このチュートリアルでは、Kubernetesクラスターでoauth2_proxyを設定し、GitHubログインの背後にあるプライベートサービスを保護しました。 保護する必要のある他のサービスについては、ステップ4で説明されている手順に従ってください。

oauth2_proxyは、GitHub以外のさまざまなプロバイダーをサポートしています。 さまざまなプロバイダーの詳細については、the official documentationを参照してください。

さらに、多くの構成パラメーターを調整する必要がありますが、デフォルトはほとんどのニーズに適合します。 パラメータのリストについては、the Helm chart’s documentationおよびoauth2_proxy’s documentationを参照してください。