use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

问题:

最近在golang 1.15+版本上,用 gRPC通过TLS实现数据传输加密时,遇到了一个问题:

 

原文:

2021/02/02 16:17:04 Call Route err: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication  field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0"

造成的原因是因为我用的证书,并没有开启SAN扩展(默认是没有开启SAN扩展)所生成的,所以在导致客户端和服务端无法建立连接, 所以我们要根据提示来解决这个问题:

按照提示所示,有2种方案可以解决:

方案一:设置 GODEBUG 为 x509ignoreCN=0

      将go的 环境变量 GODEBUG 为 x509ignoreCN=0,但是我设置了,还是未成功,你们可以自己试下,是否能成功。

方案二:使用开启扩展SAN的证书

   1. 什么是 SAN

SAN(Subject Alternative Name) 是 SSL 标准 x509 中定义的一个扩展。使用了 SAN 字段的 SSL 证书,可以扩展此证书支持的域名,使得一个证书可以支持多个不同域名的解析。

   2.如何生成含有SAN的证书

<think>我们面对的问题:Docker守护进程因TLS证书验证失败导致的连接错误,具体错误信息为: Error response from daemon: Get "https://harbor.x.com/v2/": tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead 根据错误信息,问题在于Docker客户端(或守护进程)使用的Go语言TLS验证机制不再支持仅使用Common Name(CN)的证书,而要求使用Subject Alternative Names(SANs)。在较新版本的Go中,默认行为是忽略CN,只检查SANs扩展。因此,如果证书没有设置SANs,就会报错。 解决方案有两个方向: 1. 重新生成证书,包含SANs扩展(推荐长期解决方案)。 2. 临时调整Docker客户端的行为,使其兼容旧证书(临时解决方案)。 ### 解决方案一:重新生成证书(推荐) 步骤: 1. 生成CA私钥和自签名证书(如果还没有CA): ```bash openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -sha512 -days 3650 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \ -key ca.key \ -out ca.crt ``` 2. 生成服务器私钥和证书签名请求(CSR): ```bash openssl genrsa -out yourdomain.com.key 4096 openssl req -sha512 -new \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \ -key yourdomain.com.key \ -out yourdomain.com.csr ``` 3. 创建x509 v3扩展配置文件(`v3.ext`),包含SANs: ``` authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1=yourdomain.com DNS.2=hostname IP.1=192.168.1.10 # 如果有IP访问,需要添加 ``` 4. 使用CA和扩展配置文件生成服务器证书: ```bash openssl x509 -req -sha512 -days 3650 \ -extfile v3.ext \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -in yourdomain.com.csr \ -out yourdomain.com.crt ``` 5. 将生成的服务器证书(`yourdomain.com.crt`)和私钥(`yourdomain.com.key`)部署到Harbor服务器,并配置Harbor使用该证书。 6. 将CA证书(`ca.crt`)复制到Docker客户端所在主机的证书信任目录: ```bash sudo mkdir -p /etc/docker/certs.d/yourdomain.com sudo cp ca.crt /etc/docker/certs.d/yourdomain.com/ca.crt ``` 7. 重启Docker守护进程: ```bash sudo systemctl restart docker ``` ### 解决方案二:临时解决方案(不推荐,仅用于测试环境) 在Docker客户端设置环境变量`GODEBUG=x509ignoreCN=0`,使Go忽略对CN的检查,从而允许使用仅包含CN的证书。 1. 临时设置(仅对当前shell有效): ```bash export GODEBUG=x509ignoreCN=0 docker login yourdomain.com ``` 2. 永久设置(修改Docker服务启动配置): - 编辑Docker服务配置文件(通常为`/etc/systemd/system/docker.service.d/override.conf`,如果没有则创建): ```ini [Service] Environment="GODEBUG=x509ignoreCN=0" ``` - 重新加载配置并重启Docker: ```bash sudo systemctl daemon-reload sudo systemctl restart docker ``` 注意:此方法会降低安全性,因为忽略CN检查可能会使中间人攻击更容易。因此,仅建议在测试环境中使用。 ### 总结 推荐使用解决方案一(重新生成包含SANs的证书)以符合安全标准。如果只是临时测试,可以使用解决方案二。 ### 相关问题 1. 如何为Harbor生成自签名证书? 2. 如何配置Docker客户端信任自签名证书? 3. 除了SANs问题,还有哪些常见的Docker证书错误?</think>### Docker TLS证书验证失败问题分析 您遇到的错误 `x509: certificate relies on legacy Common Name field, use SANs instead` 是由于 Docker 客户端使用的 Go 语言运行时(1.15+ 版本)加强了 TLS 证书验证机制所致。新版本 Go 不再接受仅依赖 `Common Name`(CN)字段的证书,而要求证书必须包含 `Subject Alternative Names`(SANs)扩展字段。 #### 错误原因详解 1. **证书规范变化**: - 旧证书:仅使用 `Common Name` 标识域名(如 `CN=harbor.example.com`) - 新要求:证书必须包含 `SANs` 扩展(如 `DNS:harbor.example.com, IP:192.168.1.100`) - 数学表达:若证书 $C$ 满足 $C_{\text{SANs}} = \emptyset$(SANs 为空),则验证失败 2. **Docker/Go 兼容性**: - Docker 客户端基于 Go 编写,Go 1.15+ 默认禁用 CN 验证 - 错误提示中的 `legacy Common Name field` 明确指出了问题根源 --- ### 解决方案(两种方法) #### ✅ 方法一:重新生成合规证书(推荐) ```bash # 1. 创建证书配置文件(san.cnf) cat > san.cnf <<EOF [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = CN ST = Beijing L = Beijing O = MyOrg OU = DevOps CN = harbor.example.com # 您的仓库域名 [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = harbor.example.com # 必须包含的域名 IP.1 = 192.168.1.100 # 访问仓库的IP(如有) EOF # 2. 生成新证书 openssl req -x509 -sha256 -nodes -days 3650 \ -newkey rsa:2048 -keyout harbor.key -out harbor.crt \ -config san.cnf -extensions 'v3_req' # 3. 将证书部署到Harbor服务器 # (参考Harbor文档更新证书) # 4. 在Docker客户端信任证书 sudo mkdir -p /etc/docker/certs.d/harbor.example.com sudo cp harbor.crt /etc/docker/certs.d/harbor.example.com/ca.crt ``` #### ⚠️ 方法二:临时降级验证(仅测试环境) ```bash # 方案1:单次执行(临时生效) export GODEBUG=x509ignoreCN=0 docker login harbor.example.com # 方案2:修改Docker系统配置(永久生效) sudo mkdir -p /etc/systemd/system/docker.service.d sudo tee /etc/systemd/system/docker.service.d/override.conf <<EOF [Service] Environment="GODEBUG=x509ignoreCN=0" EOF # 重启Docker sudo systemctl daemon-reload sudo systemctl restart docker ``` > **警告**:此方法会降低安全性,不建议在生产环境使用[^1][^2][^3][^4]。 --- ### 验证步骤 1. 检查证书 SANs 字段: ```bash openssl x509 -in harbor.crt -text -noout | grep -A1 "Subject Alternative Name" # 应显示:DNS:harbor.example.com, IP:192.168.1.100 ``` 2. 测试 Docker 连接: ```bash docker login harbor.example.com # 成功提示:Login Succeeded ``` --- ### 相关问题 1. 如何为 Docker 仓库生成多域名 SANs 证书? 2. 除了 SANs 问题,还有哪些常见 Docker 证书错误需要排查? 3. 如何将自签名证书批量部署到 Kubernetes 集群中的节点? > 引用说明: > [^1]: Docker拉取镜像报错解决参考 > [^2]: Docker登录失败x509证书问题参考 > [^3]: Docker连接Harbor报错及解决方案 > [^4]: 私有仓库登录报错排查流程
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值