Istio 1.17中访问Ingress Gateway出现SEC_E_UNTRUSTED_ROOT证书信任错误的解决方法
首先咱们先把问题根源理清楚:你遇到的SEC_E_UNTRUSTED_ROOT错误,本质是因为你用的是自签名SSL证书,而你的curl客户端(或者任何访问的客户端)的信任列表里根本不认这个证书的签发机构,所以直接判定证书不可信。下面给你分场景讲解决办法,还有几个配置细节要注意:
一、临时测试用的快速解决法
如果只是想验证服务能不能正常通,不想折腾证书信任的话,可以在curl命令里加-k参数跳过证书校验:
curl -k https://abb936882d5594ab0b76d7c059cf64f6-1086964687.us-west-2.elb.amazonaws.com:9443
⚠️ 注意:这个方法只适合测试环境,生产环境绝对不能用,跳过证书校验会带来安全风险。
二、生产/正式环境的正确解决思路
要让客户端真正信任你的证书,需要把签发这个自签名证书的根CA证书导入到客户端的信任存储里:
- Windows系统:打开「证书管理器」,找到「受信任的根证书颁发机构」,导入你的CA证书并设置为信任
- Linux系统:把CA证书复制到
/etc/pki/ca-trust/source/anchors/目录,然后执行update-ca-trust命令更新信任列表 - macOS系统:用「钥匙串访问」工具导入CA证书,右键证书选择「显示简介」,在「信任」选项里设置为「始终信任」
- 浏览器访问:在浏览器的证书管理设置里导入CA证书,不同浏览器操作略有不同,比如Chrome在「设置-隐私和安全-安全-管理证书」里操作
三、检查并修正你的Istio配置细节
除了证书信任问题,你的配置里还有两个小坑需要修正:
1. Gateway的Hosts配置错误
看你提供的gateway.yaml,前两个server的hosts字段写的是- '',这会导致Gateway无法正确匹配请求,应该改成和第三个server一样的- '*',修改后的servers部分如下:
servers: - port: number: 9443 name: http protocol: HTTPS tls: mode: SIMPLE credentialName: mysuperdomain-certs hosts: - '*' - port: number: 7443 name: http-two protocol: HTTPS tls: mode: SIMPLE credentialName: mysuperdomain-certs hosts: - '*' - port: number: 6443 name: http-three protocol: HTTPS tls: mode: SIMPLE credentialName: mysuperdomain-certs hosts: - '*'
修改后执行命令应用配置:
kubectl apply -f gateway.yaml -n istio-system
2. Secret创建时参数顺序搞反了
你创建Secret的命令里,--key和--cert的参数写反了!正确的应该是--key指定私钥文件(一般是key.pem),--cert指定证书文件(一般是cert.pem),你之前的命令把两者搞混了,可能导致Gateway加载证书异常。
先删掉错误的Secret,再重新创建:
kubectl delete secret mysuperdomain-certs -n istio-system kubectl create secret tls mysuperdomain-certs -n istio-system --key cert/key.pem --cert cert/cert.pem
然后重启Ingress Gateway的Pod让配置生效:
kubectl rollout restart deployment istio-ingressgateway -n istio-system
总结
先修正你的Gateway和Secret配置,确保证书能被Istio正确加载;然后根据环境选择是用-k临时测试,还是把CA证书导入客户端信任列表。如果是生产环境,更推荐使用权威CA机构签发的证书,这样就不需要手动配置客户端信任了。
备注:内容来源于stack exchange,提问作者Sridharan r.g

