在Docker中遇到x509: certificate relies on legacy Common Name field, use SANs instead问题的解决
近期在给公司内部安装KubeSphere
新环境和维护原有KubeSphere
环境的过程中,频繁遇到x509: certificate relies on legacy Common Name field, use SANs instead
,此问题会影响正常功能的使用,简要介绍其解决方案。
问题描述
本操作过程基于KubeSphere离线安装一文来操作的。
-
执行下述命令生成自己的证书
mkdir -p certs openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 36500 -out certs/domain.crt
-
在生成证书的过程中按照文档要求将
Common Name
的值设置为dockerhub.kubekey.local
-
在
/etc/hosts
中将dockerhub.kubekey.local
映射到当前服务器IP地址192.168.0.2 dockerhub.kubekey.local
-
让
Docker
信任刚生成的证书mkdir -p /etc/docker/certs.d/dockerhub.kubekey.local cp certs/domain.crt /etc/docker/certs.d/dockerhub.kubekey.local/ca.crt
-
执行下述命令启动
Docker
仓库docker run -d \ --restart=always \ --name registry \ -v "$(pwd)"/certs:/certs \ -v /mnt/registry:/var/lib/registry \ -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ -p 443:443 \ registry:2
-
在终端执行
docker pull dockerhub.kubekey.local/nginx
,运行结果如下,提示原证书的配置方式过期,不能正常使用,问题出现!
分析与解决
-
在https://go.dev/doc/go1.15#commonname中找到如下一段说明
The deprecated, legacy behavior of treating the
CommonName
field on X.509 certificates as a host name when no Subject Alternative Names are present is now disabled by default. It can be temporarily re-enabled by adding the valuex509ignoreCN=0
to theGODEBUG
environment variable.Note that if the
CommonName
is an invalid host name, it’s always ignored, regardless ofGODEBUG
settings. Invalid names include those with any characters other than letters, digits, hyphens and underscores, and those with empty labels or trailing dots从中可知在
Go10.15
之后Common Name
这个字段已经废弃,可在GODEBUG
中通过配置x509ignoreCN=0
来重新启用此字段,不过我们是基于Go
的Docker
应用环境,而非Go
开发环境,显然此种方式不大可行。 -
继续搜索,找到这篇文章how-do-i-use-sans-with-openssl-instead-of-common-name,其中提供了一个解决思路
-
对原有生成证书的步骤改进如下,然后重新执行生成证书
openssl req -addext "subjectAltName = DNS:dockerhub.kubekey.local" -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 36500 -out certs/domain.crt
-
重新执行
docker pull dockerhub.kubekey.local/nginx
可发现证书问题已经解决 -
前述执行结果任然报错的原因为镜像不存在,切换为一个已经存在的镜像重新执行即可