如何使用oauth2 proxy保护GitHub登录后的私有Kubernetes服务

来自菜鸟教程
跳转至:导航、​搜索

介绍

Kubernetes ingresses 可以轻松地将 Web 服务公开到 Internet。 但是,当涉及到私人服务时,您可能希望限制谁可以访问它们。 oauth2_proxy 可以作为公共互联网和私人服务之间的屏障。 oauth2_proxy 是一个反向代理和服务器,它使用不同的提供商(例如 GitHub)提供身份验证,并通过用户的电子邮件地址或其他属性验证用户。

在本教程中,您将使用 oauth2_proxy 和 GitHub 来保护您的服务。 完成后,您将拥有一个如下图所示的授权系统:

先决条件

要完成本教程,您需要:

  • 一个 Kubernetes 集群,其中包含两个使用 Nginx 入口和 Let's Encrypt 运行的 Web 服务。 本教程基于 如何在 DigitalOcean Kubernetes 上使用 Cert-Manager 设置 Nginx 入口。 为了完成本教程,请务必遵循它。
  • 一个 GitHub 帐户。
  • Python 安装在本地机器上。 如果您没有安装它,请按照您的操作系统 安装说明进行操作。

第 1 步 — 配置您的域

按照先决条件部分中链接的教程进行操作后,您将在集群上运行两个 Web 服务:echo1echo2。 您还将拥有一个将 echo1.your_domainecho2.your_domain 映射到其相应服务的入口。

在本教程中,我们将使用以下约定:

  • 所有私有服务都将属于 .int.your_domain 子域,如 service.int.your_domain。 将私有服务分组在一个子域下是理想的,因为身份验证 cookie 将在所有 *.int.your_domain 子域之间共享。
  • 登录门户将在 auth.int.your_domain 上提供。

注意:请务必将your_domain替换为您自己的域名,无论它出现在本教程中的任何位置。


首先,更新现有的入口定义以将 echo1echo2 服务移动到 .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

这也将更新您的 echo1echo2 服务的 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_domainA 记录以指向该外部 IP 地址。 如果您使用 DigitalOcean 管理您的 DNS 记录,请参阅 如何管理 DNS 记录 以获取说明。

删除 echo1echo2 的记录。 为主机名 *.int.your_domain 添加一个新的 A 记录,并将其指向入口的外部 IP 地址。

现在,对 *.int.your_domain 下任何子域的任何请求都将被路由到 Nginx 入口,因此您可以在集群中使用这些子域。

接下来,您将 GitHub 配置为您的登录提供程序。

第 2 步 — 创建 GitHub OAuth 应用程序

oauth2_proxy 支持各种登录提供程序。 在本教程中,您将使用 GitHub 提供程序。 首先,创建一个新的 GitHub OAuth 应用程序。

在您帐户的开发者设置页面的OAuth Apps选项卡中,单击New OAuth App按钮。

Application nameHomepage URL 字段可以是任何你想要的。 在 授权回调 URL 字段中,输入 https://auth.int.your_domain/oauth2/callback

注册应用程序后,您将收到一个 Client ID 和 Secret。 请注意这两个,因为您将在下一步中需要它们。

现在您已经创建了一个 GitHub OAuth 应用程序,您可以安装和配置 oauth2_proxy。

第 3 步 - 设置登录门户

您将使用 Helm 将 oauth2_proxy 安装到集群上。 首先,您将创建一个 Kubernetes 机密来保存 GitHub 应用程序的客户端 ID 和机密,以及由 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-config.yaml 的新文件,其中将包含 oauth2_proxy 的配置:

nano oauth2-proxy-config.yaml

您将在此文件中设置的值将覆盖 Helm 图表的默认值。 将以下代码添加到文件中:

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: |-
    allowed@user1.com
    allowed@user2.com

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 设置并运行后,剩下的就是要求对您的服务进行身份验证。

第 4 步 — 保护私人服务

为了保护服务,将其 Nginx 入口配置为通过 oauth2_proxy 强制进行身份验证。 Nginx 和 nginx-ingress 原生支持此配置,因此您只需在入口定义中添加几个注释即可。

让我们保护您在先决条件教程中设置的 echo1echo2 服务。 在编辑器中打开 echo_ingress.yaml

nano echo_ingress.yaml

将这两个附加注释添加到文件中以要求身份验证:

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 之外的许多不同的提供程序。 要了解更多关于不同提供程序的信息,请参阅官方文档

此外,您可能需要调整许多配置参数,尽管默认值将适合大多数需求。 有关参数列表,请参阅 Helm 图表的文档oauth2_proxy 的文档