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

介绍

Kubernetes ingresses使网络服务容易暴露在互联网上. 然而,当涉及到私人服务时,你可能会想要限制谁可以访问它们。 oauth2_proxy可以作为公共互联网和私人服务之间的屏障。

在本教程中,您将使用 oauth2_proxy 与 GitHub 来保护您的服务. 完成后,您将有一个权限系统,看起来像下图中的一个:

A diagram of a request flow end-result

前提条件

要完成本教程,您将需要:

步骤 1 - 配置您的域名

在遵循前提部分链接的教程后,您将有两个在您的集群上运行的Web服务:echo1和echo2 你还将有一个入口,将echo1.your_domain和echo2.your_domain与其相应的服务地图。

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

*所有私人服务都将属于.int.your_domain子域,如service.int.your_domain。在一个子域内组合私人服务是理想的,因为认证cookie将在所有*.int.your_domain子域中共享。

<$>[注] 注: 请确保在本教程中显示的任何地方用自己的域名替换 your_domain

首先,更新现有的 ingress 定义以将echo1echo2服务移动到.int.your_domain

1nano echo_ingress.yaml

重命名echo1.your_domain的所有实例为echo1.int.your_domain,并将echo2.your_domain的所有实例替换为echo2.int.your_domain:

 1[label echo_ingress.yaml]
 2apiVersion: extensions/v1beta1
 3kind: Ingress
 4metadata:
 5  name: echo-ingress
 6  annotations:  
 7    kubernetes.io/ingress.class: nginx
 8    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
 9spec:
10  tls:
11  - hosts:
12    - echo1.int.your_domain
13    - echo2.int.your_domain
14    secretName: letsencrypt-prod
15  rules:
16  - host: echo1.int.your_domain
17    http:
18      paths:
19      - backend:
20          serviceName: echo1
21          servicePort: 80
22  - host: echo2.int.your_domain
23    http:
24      paths:
25      - backend:
26          serviceName: echo2
27          servicePort: 80

保存文件并应用更改:

1kubectl apply -f echo_ingress.yaml

这将更新您的echo1echo2服务的TLS证书。

现在更新您的 DNS 配置以反映您所做的更改. 首先,通过运行以下命令来查找您的 Nginx 入口的 IP 地址,以打印其详细信息:

1kubectl get svc --namespace=ingress-nginx

您将在输出中看到EXTERNAL-IP下的IP地址:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)                      AGE
3ingress-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 App。

在您的帐户的 OAuth 应用程序的开发者设置页面上,单击 新 OAuth 应用程序按钮。

您可以选择应用程序名称主页 URL的域名。在授权回调 URL域中,请输入https://auth.int.your_domain/oauth2/callback

註冊申請後,您將收到一個客戶 ID 和秘密. 記住兩個,因為您將需要他們在下一步。

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

步骤三:设置登录门户

首先,您将创建一个 Kubernetes 秘密,以保留 GitHub 应用程序的客户 ID 和秘密,以及由 oauth2_proxy 设置的浏览器 Cookie 的加密秘密。

运行以下命令来生成安全的 Cookie 秘密:

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

将结果复制到您的Clipboard

然后,创建Kubernetes秘密,取代您的Cookie秘密、GitHub客户端ID和GitHub秘密密密钥的突出值:

1kubectl -n default create secret generic oauth2-proxy-creds \
2--from-literal=cookie-secret=YOUR_COOKIE_SECRET \
3--from-literal=client-id=YOUR_GITHUB_CLIENT_ID \
4--from-literal=client-secret=YOUR_GITHUB_SECRET

您将看到以下输出:

1[secondary_label Output]
2secret/oauth2-proxy-creds created

接下来,创建一个名为「oauth2-proxy-config.yaml」的新文件,其中包含对「oauth2_proxy」的配置:

1nano oauth2-proxy-config.yaml

您将在此文件中设置的值将取代 Helm 图表的默认值。

 1[label oauth2-proxy-config.yaml]
 2config:
 3  existingSecret: oauth2-proxy-creds
 4
 5extraArgs:
 6  whitelist-domain: .int.your_domain
 7  cookie-domain: .int.your_domain
 8  provider: github
 9
10authenticatedEmailsFile:
11  enabled: true
12  restricted_access: |-
13    [email protected]
14    [email protected]    
15
16ingress:
17  enabled: true
18  path: /
19  hosts:
20    - auth.int.your_domain
21  annotations:
22    kubernetes.io/ingress.class: nginx
23    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
24  tls:
25    - secretName: oauth2-proxy-https-cert
26      hosts:
27        - auth.int.your_domain

这个代码是这样做的:

  1. 指示 oauth2_proxy 使用您创建的秘密.
  2. 设置域名和提供商类型.
  3. 设置允许的电子邮件地址列表. 如果 GitHub 帐户与这些电子邮件地址之一相关联,则将允许访问私人服务。
  4. 配置将服务于登录门户在 auth.int.your_domain上的入口,使用 Let's Encrypt 的 TLS 证书。

现在你已经准备好了秘密和配置文件,你可以安装oauth2_proxy

1helm repo update \
2&& helm upgrade oauth2-proxy --install stable/oauth2-proxy \
3--reuse-values \
4--values oauth2-proxy-config.yaml

Let's Encrypt 证书发行和安装可能需要几分钟。

要測試部署是否成功,請瀏覽「https://auth.int.your_domain」。

随着 oauth2_proxy 设置和运行,剩下的只是在您的服务上要求身份验证。

第四步:保护私人服务

为了保护服务,配置其 Nginx 入口以通过 oauth2_proxy 执行身份验证。 Nginx 和 nginx-ingress 支持此配置,所以您只需要为入口定义添加几个注释。

让我们保护您在前提教程中设置的echo1echo2服务,在您的编辑器中打开echo_ingress.yaml:

1nano echo_ingress.yaml

将这两个额外的注释添加到文件中以要求验证:

1[label echo_ingress.yaml]
2   annotations:
3     kubernetes.io/ingress.class: nginx
4     certmanager.k8s.io/cluster-issuer: letsencrypt-prod
5     nginx.ingress.kubernetes.io/auth-url: "https://auth.int.your_domain/oauth2/auth"
6     nginx.ingress.kubernetes.io/auth-signin: "https://auth.int.your_domain/oauth2/start?rd=https%3A%2F%2F$host$request_uri"

保存文件并应用更改:

1kubectl apply -f echo_ingress.yaml

现在,当你浏览到https://echo1.int.your_domain,你将被要求使用GitHub登录以访问它. 使用有效的帐户登录后,你将被重定向回echo1服务。

结论

在本教程中,您在Kubernetes集群上设置了outh2_proxy,并保护了GitHub登录背后的私人服务。

oauth2_proxy 支持 GitHub 以外的许多不同的提供商. 有关不同提供商的更多信息,请参阅 官方文档

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

Published At
Categories with 技术
comments powered by Disqus