从外部客户端到 Kubernetes 集群内服务器的 TLS 握手失败。这是关于理解原因。
我已将 Istio 入口网关配置为通过端口 15433 上收到的 TLS,并将其路由到端口 433 上的服务器。
入口网关日志显示客户端尝试 TLS 握手时的活动,但不显示服务器日志,也不显示 istio-proxy 日志。
TLS客户端:
openssl s_client \
-connect [redacted]-[redacted].us-west-2.elb.amazonaws.com:15443 \
-servername myservice.mynamespace \
-CAfile /path/to/ca.cert \
-cert /path/to/cert.pem \
-key /path/to/cert.key <<< "Q"
logs
CONNECTED(00000006)
140090868934296:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 298 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1600987862
Timeout : 300 (sec)
Verify return code: 0 (ok)
Istio 入口网关日志:
"- - -" 0 - "-" "-" 298 0 1069 - "-" "-" "-" "-" "192.168.101.136:443" outbound|443||myservice.mynamespace.svc.cluster.local 192.168.115.141:42350 192.168.115.141:15443 192.168.125.206:23298 myservice.mynamespace -
其中 192.168.101.136 是 myservice pod 的 IP,192.168.115.141 是 ingressgateway pod 的 IP。
根据 IP,这意味着客户端连接到达了网关,网关似乎已应用虚拟服务路由并记录它正在将其转发到 Pod。看起来很正常,除了 Pod 上的 istio-proxy 没有显示任何活动,服务器日志也没有显示(尽管服务器不记录传输层发生的事情)。
AFAIK 服务器已正确配置 TLS,因为以下端口转发的 TLS 握手成功:
kubectl port-forward -n mynamespace service/myservice 4430:443 &
openssl s_client \
-connect localhost:4430 \
-CAfile /path/to/ca.cert \
-cert /path/to/cert.pem \
-key /path/to/cert.key <<< "Q"
# I get back a TLS session ID, looks good.
所以这指向istio网关和虚拟服务配置的问题。
Gatway:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
namespace: mynamespace
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 15443
name: tls-passthrough
protocol: TLS
tls:
mode: PASSTHROUGH
hosts:
- "*"
虚拟服务:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myservice
namespace: mynamespace
spec:
hosts:
- "*"
gateways:
- mygateway
tls:
- match:
- port: 15443
sniHosts:
- myservice.mynamespace
route:
- destination:
host: myservice
port:
number: 443
库伯内特服务:
apiVersion: v1
kind: Service
metadata:
name: myservice
namespace: mynamespace
labels:
app: myservice
spec:
selector:
app: myservice
ports:
- protocol: TCP
port: 443
targetPort: 443
name: grpc-svc
UPDATE:实际上,来自客户端的 TLS 流量确实到达了服务器 Pod,我已经通过这样做确认了这一点tcpdump port 443
在服务器 Pod 上运行 openssl s_client 命令时看到数据包。不清楚为什么 pod 上的 istio-proxy 没有显示这一点,这并不能解释握手失败的原因。
我注意到了别的事情。通过-msg
标记为openssl s_client
,我没有看到任何返回,在“>>>”之后没有“