我有一个基本的 nginx 部署和一个由 let's encrypt 通过 cert-manager 颁发的现有证书。我以为一切就绪,可以开始使用证书了,但我无法通过 https 进行连接。
连接到 LoadBalancer IP 和域有效。使用 https 连接到域无法连接。Chrome 说ERR_SSL_PROTOCOL_ERROR
,Firefox 说SSL_ERROR_RX_RECORD_TOO_LONG
,SSL Labs 说Assessment failed: No secure protocols supported
。都是同一个问题。
服务如下:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: example
labels:
app: example
spec:
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 80
selector:
app: example
这是入口:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
namespace: example
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
tls:
- hosts:
- 'example.com'
secretName: example-production-tls
rules:
- host: example.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 443
证书已填充:
kubectl describe secret
...
Data
====
tls.crt: 3574 bytes
tls.key: 1675 bytes
ca.crt: 0 bytes
并且证书资源归正确的入口所有。我已将我的域名替换为上面的“示例”。
一切似乎都已准备就绪,但我不确定为什么无法通过 https 连接。我可以运行什么来排除故障?
更新:我发现我的部署和 nginx 映像缺少一些配置。我已按照以下所有步骤操作:https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#securing-the-service
和以前一样,我可以连接到 443 和 80 上的 LoadBalancer IP,但 https 连接失败。使用 http:
curl http://<EXTERNAL-IP> -k
<html>
<h1>Hello!</h1>
<p>Stay tuned for launch!</p>
</html>
使用 https 失败:
curl https://<EXTERNAL-IP> -k
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
答案1
本例中的问题是部署和服务的组合。我在服务 yaml 中使用以下行将 https 流量路由到端口 80:
- name: https
protocol: TCP
port: 443
targetPort: 80
这无法完成 SSL 握手,而这正是问题curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
所在。
我认为这没问题,因为在之前使用 SSL 的服务上,我在 puma 上将端口 80 和 443 路由到 3000。我不确定如果在 puma 上将 443 路由到 80 会发生什么,但它肯定会破坏 nginx。更改上述服务 yaml 解决了这个问题(确保 nginx 在 443 上监听并listen 443 ssl;
在 default.conf 中启用了 SSL):
- name: https
protocol: TCP
port: 443
targetPort: 443