如何使用 oauth2_proxy 保护 GitHub 登录后的私有 Kubernetes 服务
简介
Kubernetesingresses可以轻松地将 Web 服务公开到 Internet。但是,当涉及到私人服务时,您可能希望限制谁可以访问它们。oauth2_proxy可以作为公共互联网和私人服务之间的屏障。 oauth2_proxy 是一个反向代理和服务器,它使用不同的提供商(例如 GitHub)提供身份验证,并通过用户的电子邮件地址或其他属性验证用户。
在本教程中,您将使用 oauth2_proxy 和 GitHub 来保护您的服务。完成后,您将拥有一个如下图所示的授权系统:

先决条件
要完成本教程,您需要:
-
一个 Kubernetes 集群,有两个 Web 服务,运行一个 Nginx 入口和 Let's Encrypt。本教程基于How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes。为了完成本教程,请务必遵循它。
-
GitHub帐户。
-
Python 安装在您的本地计算机上。如果您没有安装它,请按照您的操作系统](https://www.digitalocean.com/community/tags/python?type=tutorials#install-and-configure-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:
回声_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 应用程序。
在您帐户的开发人员设置](https://github.com/settings/developers)页面的[OAuth 应用程序选项卡中,单击 New OAuth App 按钮。
Application name 和 Homepage URL 字段可以是您想要的任何内容。在 Authorization callback 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
将这两个附加注释添加到文件中以要求身份验证:
回声_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 的文档。
更多推荐

所有评论(0)