介绍
Kubernetes ingresses使网络服务容易暴露在互联网上. 然而,当涉及到私人服务时,你可能会想要限制谁可以访问它们。 oauth2_proxy可以作为公共互联网和私人服务之间的屏障。
在本教程中,您将使用 oauth2_proxy 与 GitHub 来保护您的服务. 完成后,您将有一个权限系统,看起来像下图中的一个:
前提条件
要完成本教程,您将需要:
- 一个 Kubernetes 集群有两个 Web 服务运行 Nginx ingress 和 Let's Encrypt. 这个教程是建立在 如何在 DigitalOcean Kubernetes 上使用 Cert-Manager 设置 Nginx Ingress上。 请确保遵循到最后,以完成本教程。
- A GitHub帐户.
- Python 安装在您的本地机器上. 如果您没有安装,请遵循 操作系统的安装说明。
步骤 1 - 配置您的域名
在遵循前提部分链接的教程后,您将有两个在您的集群上运行的Web服务:echo1和echo2 你还将有一个入口,将echo1.your_domain和echo2.your_domain与其相应的服务地图。
在本教程中,我们将使用以下公约:
*所有私人服务都将属于.int.your_domain
子域,如service.int.your_domain
。在一个子域内组合私人服务是理想的,因为认证cookie将在所有*.int.your_domain
子域中共享。
<$>[注]
注: 请确保在本教程中显示的任何地方用自己的域名替换 your_domain
。
首先,更新现有的 ingress 定义以将echo1
和echo2
服务移动到.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
这将更新您的echo1
和echo2
服务的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_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 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
这个代码是这样做的:
- 指示 oauth2_proxy 使用您创建的秘密.
- 设置域名和提供商类型.
- 设置允许的电子邮件地址列表. 如果 GitHub 帐户与这些电子邮件地址之一相关联,则将允许访问私人服务。
- 配置将服务于登录门户在
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 支持此配置,所以您只需要为入口定义添加几个注释。
让我们保护您在前提教程中设置的echo1
和echo2
服务,在您的编辑器中打开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 的文档。