NSS: client certificate not found (nickname not specified)

博客记录了在使用curl进行接口联调时遇到的NSS错误:clientcertificatenotfound(nicknamenotspecified)。最初问题表现为证书未被信任,解决方法是将自签名证书的CA加入信任。但之后问题转变为找不到客户端证书,最终解决方案是获取并使用客户端证书(p12),通过openssl转换为.pem格式,并在curl命令中指定--cert和--key参数,或者合并为all.pem后使用。问题成功解决。

NSS: client certificate not found (nickname not specified)报错排查及解决

curl: (35) NSS: client certificate not found (nickname not specified)

排查好久,这里记录下这个坑。

初始

这是第三方的一个接口,测试联调时,curl https://xxx.com.cn发现提示证书未信任,

curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

看到熟悉的报错,我知道将对方自签名证书的CA加入信任即可。一通操作之后却还是不行,但是报错变成了新的.

curl: (35) NSS: client certificate not found (nickname not specified)

-vvv也还是没发现什么新的有用信息。
curl -vvv https://xxxxx 时总是报错

* About to connect() to xxx.com.cn port 8912 (#0)
*   Trying 111.122.224.223...
* Connected to gwtest.ccic-net.com.cn (111.122.224.223) port 8912 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS: client certificate not found (nickname not specified)
* NSS error -12227 (SSL_ERROR_HANDSHAKE_FAILURE_ALERT)
* SSL peer was unable to negotiate an acceptable set of security parameters.
* Closing connection 0
curl: (35) NSS: client certificate not found (nickname not specified)

原因

其实报错提示很明显,client certificate not found,开始没想到是双向认证,一直以为是CA根证书信任没弄好,结果一直无法解决。

解决

找第三方拿到客户端证书jks证书(p12)。

openssl pkcs12 -in xxx.p12 -out client.pem -nokeys       #客户端个人证书的公钥
openssl pkcs12 -in xxx.p12 -out key.pem -nocerts -nodes     #客户端个人证书的私钥
也可以转换为公钥与私钥合二为一的文件;
openssl pkcs12 -in xxx.p12 -out all.pem -nodes                                   #客户端公钥与私钥,一起存在all.pem中

使用client.pem+key.pem

curl --cert client.pem --key key.pem https://www.xxxx.com

或使用all.pem

curl --cert all.pem  https://www.xxxx.com

问题解决~

<think>好的,我现在需要帮助用户解决通过curl访问Kubernetes节点的cadvisor metrics接口时出现401 Unauthorized错误的问题。首先,我要回想一下关于Kubernetes中cadvisor的metrics接口的相关知识。 用户提到使用curl访问时返回401 Unauthorized,这可能涉及到认证和授权的问题。cadvisor通常集成在kubelet中,而kubelet的metrics接口默认可能启用了身份验证。我需要考虑几个可能的原因: 1. **端口和认证机制**:Kubernetes的kubelet有两个端口,10250和10255。其中10250是安全端口,使用HTTPS和认证;而10255是非安全端口,HTTP且可能不需要认证。用户可能访问的是10250端口但未提供有效凭证,或者集群配置禁用了非安全端口。 2. **RBAC权限**:即使端口正确,用户或服务账户可能没有足够的权限访问metrics接口,需要检查相关的ClusterRole和RoleBinding。 3. **kubelet配置**:可能kubelet的配置中关闭了匿名访问或非安全端口,导致必须通过认证才能访问。 接下来,我需要参考用户提供的引用。例如,引用[1]提到metrics-server连接10255端口被拒绝,这可能是因为Kubernetes版本升级后默认关闭了非安全端口,导致需要改用10250端口并携带证书或token认证。引用[3]中的curl报错Unauthorized,用户可能没有正确设置认证头。 解决方案步骤可能包括: - **确认访问的端口**:检查是否使用10255(可能已弃用)还是10250,并确保使用HTTPS。 - **获取认证token**:从ServiceAccount中获取token,并在curl请求中添加Authorization头。 - **配置RBAC**:创建或更新ClusterRoleBinding,授予访问metrics的权限。 - **检查kubelet配置**:确认是否启用匿名访问或调整认证参数,但这可能涉及修改kubelet启动参数,需谨慎操作。 需要注意,直接关闭认证可能存在安全风险,应优先考虑正确配置认证和RBAC。另外,用户可能运行的是较新版本的Kubernetes,其中非安全端口默认关闭,因此必须使用安全端口和认证信息。</think>### 解决方案:Kubernetes cAdvisor Metrics接口401 Unauthorized错误 #### 1. **确认访问端口和协议** cAdvisor的Metrics接口默认通过kubelet提供,Kubernetes中kubelet的Metrics接口分为以下两种: - **安全端口**:`10250`(HTTPS,需认证) - **非安全端口**:`10255`(HTTP,部分版本默认关闭[^1]) 若返回401错误,可能因访问了安全端口但未携带认证信息,或非安全端口被禁用。 **验证命令**: ```bash # 尝试访问非安全端口(HTTP) curl http://<节点IP>:10255/metrics/cadvisor # 尝试访问安全端口(HTTPS) curl https://<节点IP>:10250/metrics/cadvisor --insecure ``` #### 2. **携带认证信息访问安全端口** 若需访问安全端口(10250),需在请求中添加有效的Bearer Token或客户端证书。 ##### **方法1:使用ServiceAccount Token** 1. 获取默认ServiceAccount的Token: ```bash TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode) ``` 2. 通过curl访问: ```bash curl -k -H "Authorization: Bearer $TOKEN" https://<节点IP>:10250/metrics/cadvisor ``` ##### **方法2:使用客户端证书** 若集群配置了客户端证书认证,需指定证书路径: ```bash curl --cert /path/to/client.crt --key /path/to/client.key --cacert /path/to/ca.crt https://<节点IP>:10250/metrics/cadvisor ``` #### 3. **配置RBAC权限** 若Token无权限访问metrics接口,需绑定以下ClusterRole: 1. 创建ClusterRole: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: metrics-reader rules: - nonResourceURLs: ["/metrics/*", "/stats/*"] verbs: ["get"] ``` 2. 绑定到ServiceAccount: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: allow-metrics-access subjects: - kind: ServiceAccount name: default namespace: default roleRef: kind: ClusterRole name: metrics-reader apiGroup: rbac.authorization.k8s.io ``` #### 4. **检查kubelet配置** 若需启用非安全端口(**不推荐生产环境**): 1. 修改kubelet启动参数: ```bash --anonymous-auth=true \ --authentication-token-webhook=false \ --authorization-mode=AlwaysAllow ``` 2. 重启kubelet服务(谨慎操作)[^1]。 #### 5. **验证网络策略** 确保请求来源IP未被防火墙或NetworkPolicy拦截: ```bash kubectl get networkpolicy -A ``` ### 关键原因总结 | 原因 | 解决方案 | |-------------------|----------------------------------| | 使用未认证的安全端口 | 添加Bearer Token或客户端证书 | | RBAC权限不足 | 绑定metrics-reader ClusterRole | | 非安全端口关闭 | 改用安全端口或调整kubelet配置 | ### 注意事项 - **安全风险**:开放非安全端口或禁用认证会暴露节点数据,仅在测试环境使用。 - **Kubernetes版本差异**:1.18+版本默认关闭非安全端口[^1]。 - **Pod内访问**:在Pod内通过`https://<节点名称>:10250`访问时需验证证书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MicePro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值