SSL终止Nginx入口控制器

时间:2018-06-06 00:49:56

标签: ssl nginx kubernetes kubernetes-ingress

我无法在我的kubernetes集群上的nginx入口控制器上获得TLS终止。

我的入口规则如下所示:

Christophers-MacBook-Pro-2:acme-microservice cjaime$ kubectl describe ing myapp-ingress-1
Name:             myapp-ingress-1
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<none>)
TLS:
 acme-io terminates myapp-default.acme.io
Rules:
 Host                            Path  Backends
 ----                            ----  --------
 myapp-default.acme.io  
                                 /   myapp:80 (<none>)
Annotations:
 ingress.kubernetes.io/ssl-redirect:  true
 kubernetes.io/ingress.class:         nginx
Events:
 Type    Reason  Age               From                      Message
 ----    ------  ----              ----                      -------
 Normal  UPDATE  53m (x2 over 1h)  nginx-ingress-controller  Ingress default/myapp-ingress-1
 Normal  UPDATE  53m (x2 over 1h)  nginx-ingress-controller  Ingress default/myapp-ingress-1
 Normal  UPDATE  53m (x2 over 1h)  nginx-ingress-controller  Ingress default/myapp-ingress-1
 Normal  UPDATE  53m (x2 over 1h)  nginx-ingress-controller  Ingress default/myapp-ingress-1

每当我尝试从浏览器访问它时,我都会得到以下服务器证书

Server certificate
subject=/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate
issuer=/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate

这阻止我创建有效的SSL连接。我知道我的秘密是正确的,因为当使用openssl时,我得到一个有效的连接如下

openssl s_client -servername myapp-default.acme.io -connect us1a-k8s-4.acme.io:31443 -showcerts
CONNECTED(00000003)

<content omitted>

   Start Time: 1528241749
   Timeout   : 300 (sec)
   Verify return code: 0 (ok)
---

但是如果我在省略servername的情况下运行相同的命令,我会得到相同的假证书和连接错误

openssl s_client  -connect us1a-k8s-4.acme.io:31443 -showcerts
CONNECTED(00000003)
depth=0 O = Acme Co, CN = Kubernetes Ingress Controller Fake Certificate
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 O = Acme Co, CN = Kubernetes Ingress Controller Fake Certificate
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate
  i:/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate

<content omitted>

   Start Time: 1528241957
   Timeout   : 300 (sec)
   Verify return code: 21 (unable to verify the first certificate)

2 个答案:

答案 0 :(得分:2)

使用openssl进行的测试正确执行,并且当通过SNI在请求中提供主机名时,它们显示nginx确实为 myapp-default.acme.io 提供了有效证书。这与您在Ingress中配置的内容一致。

对于没有主机名的其他主机名或请求,将发送默认证书。该证书将存储在Secret中,并通过命令行参数配置到入口控制器(--default-ssl-certificate=$(POD_NAMESPACE)/tls-ingress)。

您的浏览器警告可能是因为您的浏览器中的主机名或缓存的假证书不匹配。我建议您查看如何在b浏览器中刷新证书缓存和/或使用curl重做测试:

curl -v https://myapp-default.acme.io

如果仍然无法正常工作,您可能会受到#1954的影响 - 更新nginx-ingress-controller。

答案 1 :(得分:0)

现在如下工作:

在入口控制器终止SSL之前, 来自浏览器的成功http请求是带有主机头集的入口控制器:

Chrome Browser

http://us1a-k8s-4.acme.io:31443/index.html
Host : myapp-default.acme.io

*us1a-k8s-4.acme.io is the node where nginx ingress controller 
lives.*

更新入口定义以使用证书后,我们开始使用

curl --resolve myapp-default.acme.io:31443:172.31.0.18 https://myapp- 
default.acme.io:31443/index.html

*where 172.31.0.18 would be the IP for us1a-k8s-4.acme.io*  

但是从浏览器,使用主机头我们之前使用它的方式对于http请求不起作用。

然而,当我们在/ etc / hosts文件中输入如下内容时

172.31.0.18     myapp-default.acme.io

并通过浏览器点击以下网址:

http://myapp-default.acme.io:31443/index.html

它工作了!

似乎nginx不知道主机头,它使用URL来查找正确的证书。

选中此https://www.claudiokuenzler.com/blog/693/curious-case-of-curl-ssl-tls-sni-http-host-header