前端双向认证配置
平台部署后默认打开了 TLS 服务端(单向)认证,本文介绍如何在已有服务端认证的情况下,开启客户端验证(双向)认证。 整个云平台运行在 Kubernetes 之上,前端服务通过 ingress 暴露出来,我们使用了开源的traefik组件来负责 ingress 的实现,所以在 traefik 上设置客户端认证。 生成证书 下面使用生成自签名证书的方式来配置,如果已经有证书机构签发的服务端和客户端
平台部署后默认打开了 TLS 服务端(单向)认证,本文介绍如何在已有服务端认证的情况下,开启客户端验证(双向)认证。
整个云平台运行在 Kubernetes 之上,前端服务通过 ingress 暴露出来,我们使用了开源的 traefik 组件来负责 ingress 的实现,所以在 traefik 上设置客户端认证。
生成证书
下面使用生成自签名证书的方式来配置,如果已经有证书机构签发的服务端和客户端证书,可以忽略这个步骤。
生成 CA
$ openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=My Cert Authority'
生成 Server 服务端证书
基于上面生成的 CA 签发 server 证书:
$ openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=mydomain.com'
$ openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
生成 Client 客户端证书
基于上面生成的 CA 签发 client 证书:
$ openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=My Client'
$ openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
上传证书到 Kubernetes
# 上传 ca 到 kube-system 命令空间
$ kubectl -n kube-system create secret generic ca-secret --from-file=ca.crt=ca.crt
# 上传 server 证书到 onecloud 命名空间
$ kubectl -n onecloud create secret generic tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key
修改前端 default-web ingress
前端是通过 onecloud 命令空间里面的 default-web ingress 访问的,把前端使用的 tls 证书换成 tls-secret 。
$ kubectl edit ingress -n onecloud default-web
...
tls:
# 修改这个 secretName 为 tls-secret
- secretName: tls-secret
...
修改 traefik 配置
修改 traefik configmap
traefik 的配置在 kube-system 命名空间的 traefik-ingress-lb config 里面,开启客户端验证主要是配置 entryPoints.https.tls.ClientCA 。
$ kubectl edit configmaps -n kube-system traefik-ingress-lb
...
[entryPoints.https]
address = ":443"
# 添加如下的 ClientCA 配置
[entryPoints.https.tls]
[entryPoints.https.tls.ClientCA]
files = ["/tests/ca.crt"]
optional = false
...
修改 traefik daemonset
然后修改 kube-system 命令空间里面的 traefik-ingress-controller daemonset ,主要是把刚才创建的 ca-secret 挂载到配置的 /tests/ca.crt 目录。
$ kubectl edit daemonsets -n kube-system traefik-ingress-controller
...
volumeMounts:
- mountPath: /config
name: config
# 添加这个 volume mount,名称为 ca
- mountPath: /tests
name: ca
...
volumes:
- configMap:
defaultMode: 420
name: traefik-ingress-lb
name: config
- name: ca
secret:
defaultMode: 420
# 这里引用之前创建的 ca-secret
secretName: ca-secret
...
重启 traefik 服务
$ kubectl get pods -n kube-system | grep traefik | awk '{print $1}' | xargs kubectl delete pods -n kube-system
等待 traefik 容器变成 Running。
$ kubectl get pods -n kube-system | grep traefik
traefik-ingress-controller-fk54h 1/1 Running 0 9s
使用 curl 进行测试
假设部署的前端访问地址是 https://192.168.121.21 ,下面验证客户端认证是否开启:
# 不使用 client 证书访问失败,符合预期
$ curl -k https://192.168.121.21
curl: (58) NSS: client certificate not found (nickname not specified)
# 使用 client 证书访问成功
$ curl -k --cert ./client.crt --key ./client.key https://192.168.121.21
<!DOCTYPE html><html lang=en translate=no><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><meta name=google content=notranslate><link rel=icon href=/favicon.ico><title>云联壹云</title><link href=/js/chunk-2d216214.5f7b7e0c.js rel=prefetch><link href=/js/chunk-39bb5eb4.8512e62d.js rel=prefetch><link href=/css/app.fb52a32e.css rel=preload as=style><link href=/css/chunk-vendors.09e9c25d.css rel=preload as=style><link href=/js/app.74cda7af.js rel=preload as=script><link href=/js/chunk-vendors.a7b5c015.js rel=preload as=script><link href=/css/chunk-vendors.09e9c25d.css rel=stylesheet><link href=/css/app.fb52a32e.css rel=stylesheet></head><body><noscript><strong>We're sorry but OneCloud doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/vendor.b82688a471b737ceddd1.js></script><script src=/js/chunk-vendors.a7b5c015.js></script><script src=/js/app.74cda7af.js></script></body></html>
浏览器配置
通过以上的配置,发现客户端配置已经成功,但通过浏览器访问,还需要把客户端的证书放到浏览器里面,否则访问就会出现下面的界面:
下面以 Chrome 浏览器为例, 需要把之前生成的 client.crt 和 client.key 装换成 pfx/pkcs12 格式,就能导入浏览器,命令如下:
# 把 client.crt 和 client.key 组合到一起
$ cat client.crt client.key > pkcs12.pem
# 转换成 pkcs12 格式
$ openssl pkcs12 -in pkcs12.pem -export -out pkcs12.p12
把 pkcs12.p12 导入到浏览器:
选择刚才生成的 pkcs12.p12 证书:
导入后再刷新访问前端,就可以成功访问界面。
更多推荐
所有评论(0)