如何使用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 服务:echo1
和 echo2
。 您还将拥有一个将 echo1.your_domain
和 echo2.your_domain
映射到其相应服务的入口。
在本教程中,我们将使用以下约定:
- 所有私有服务都将属于
.int.your_domain
子域,如service.int.your_domain
。 将私有服务分组在一个子域下是理想的,因为身份验证 cookie 将在所有*.int.your_domain
子域之间共享。 - 登录门户将在
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 步 — 创建 GitHub OAuth 应用程序
oauth2_proxy 支持各种登录提供程序。 在本教程中,您将使用 GitHub 提供程序。 首先,创建一个新的 GitHub OAuth 应用程序。
在您帐户的开发者设置页面的OAuth Apps选项卡中,单击New OAuth App按钮。
Application name 和 Homepage 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
此代码执行以下操作:
- 指示 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 步 — 保护私人服务
为了保护服务,将其 Nginx 入口配置为通过 oauth2_proxy 强制进行身份验证。 Nginx 和 nginx-ingress 原生支持此配置,因此您只需在入口定义中添加几个注释即可。
让我们保护您在先决条件教程中设置的 echo1
和 echo2
服务。 在编辑器中打开 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 的文档 。