(转)为 Ingress-nginx 配置双向认证(mtls)

mtls

首先什么是 mtls (双向认证)?它是一个过程,在这个过程中,客户机和服务器都通过证书颁发机构彼此验证身份。
相信 tls 大家都比较熟悉,就是 server 端提供一个授信证书,当我们使用 https 协议访问server端时,client 会向 server 端索取证书并认证(浏览器会与自己的授信域匹配或弹出不安全的页面)。
mtls 则是由同一个 root ca 生成两套证书,即客户端证书和服务端证书。客户端使用 https 访问服务端时,双方会交换证书,并进行认证,认证通过方可通信。

证书生成

证书格式类型

证书主要的格式有以下几种

  • .DER .CER,文件是二进制格式,只保存证书,不保存私钥。
  • .PEM,一般是文本格式,可保存证书,可保存私钥。
  • .CRT,可以是二进制格式,可以是文本格式,与 .DER 格式相同,不保存私钥。
  • .PFX .P12,二进制格式,同时包含证书和私钥,一般有密码保护。
  • .JKS,二进制格式,同时包含证书和私钥,一般有密码保护。

DER

该格式是二进制文件内容,Java 和 Windows 服务器偏向于使用这种编码格式。

转换为 PEM:

openssl x509 -in cert.crt -inform der -outform pem -out cert.pem

PEM

Privacy Enhanced Mail,一般为文本格式,以 —–BEGIN… 开头,以 —–END… 结尾。中间的内容是 BASE64 编码。这种格式可以保存证书和私钥,有时我们也把PEM 格式的私钥的后缀改为 .key 以区别证书与私钥。具体你可以看文件的内容。

这种格式常用于 Apache 和 Nginx 服务器。

转换为 DER:

openssl x509 -in cert.crt -outform der -out cert.der

CRT

Certificate 的简称,有可能是 PEM 编码格式,也有可能是 DER 编码格式。

转为 PEM

openssl x509 -in mycert.crt -out mycert.pem -outform PE

转为 P12

openssl pkcs12 -export -clcerts -inkey client.key -in client.crt -out client.p12 -name "client"

PFX

Predecessor of PKCS#12,这种格式是二进制格式,且证书和私钥存在一个 PFX 文件中。一般用于 Windows 上的 IIS 服务器。改格式的文件一般会有一个密码用于保证私钥的安全。

转换为 PEM:

openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes

JKS

Java Key Storage,很容易知道这是 JAVA 的专属格式,利用 JAVA 的一个叫 keytool 的工具可以进行格式转换。一般用于 Tomcat 服务器。

生成根证书(ROOT CA)

此根证书用于自签名,会被浏览器认为是不可信,若在生产环境中,需要通过CA机构签发服务端/客户端证书。

openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=My Cert Authority'
# CommonName(CN):标识与证书关联的主机名或所有者,这里通常是发行人的名称。

生成 server 端证书

这里的CN是服务器的主机名。 仅当服务器证书安装在主机名与CN匹配的服务器上时,服务器证书才有效。

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 端证书

这里CN通常是客户端/用户的名称。

# 这里生成 crt 类型的证书
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

浏览器一般需要 p12 类型的证书,生成如下

openssl pkcs12 -export -clcerts -inkey client.key -in client.crt -out client.p12 -name "client"
参考官网  k8s ingress prerequestes

ingress 配置

这里默认使用 K8s 的 ingress-nginx。
首先我们需要在ingress 所在的 namespace 下创建对应的 secret

kubectl create secret generic ca-secret --from-file=ca.crt=ca.crt
kubectl create secret generic tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key

创建ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-nginx
  annotations:
    kubernetes.io/ingress.class: nginx
    # 开启客户端认证
    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
    # 指定root ca 的 secret
    nginx.ingress.kubernetes.io/auth-tls-secret: "<namespace>/ca-secret"
    # 指定验证证书链的深度
    nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
    # 指定url,将验证失败的请求重定向到该url
    nginx.ingress.kubernetes.io/auth-tls-error-page: "http://www.mysite.com/error-cert.html"
    # 是否将证书传递给后端的服务
    nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-nginx
          servicePort: 80
  tls:
  - secretName: tls-secret

验证

这里我们随便起一个 nginx 的服务:

kubectl run my-nginx --image=nginx --replicas=2 --port=80
kubectl expose deployment my-nginx --type=NodePort --port=80 --target-port=80

按照上述配置,创建 secret、ingress。

通过 curl 访问我们的服务 curl -k https://x.x.x.x/,会发现返回了一个 400 的response

[root@my ~]# curl -k https://10.48.51.222/
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>

这就说明服务端认为我们是不可信的,因为没有携带证书。当我们携带证书去访问,

curl -k --cert client.pem --key key.pem https://x.x.x.x/

则会返回正常页面。

阿里云官方也有一篇不错的文档,不过双证书相关的配置,官方可视化操作没找到,需要使用命令进行

什么是HTTPS双向认证(MutualTLSauthentication)_API 网关-阿里云帮助中心

如果已经有https域名,新增加ingress rule 修改同名空间,不同的名称即可完成隔离

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值