如何解决自托管 Harbor 的证书问题

如何解决自托管 Harbor 的证书问题

当我们在推送镜像到我们自己的 Harbor 仓库里时,有时会遇到证书问题。这可能是因为我们使用了自签名证书或者自托管的证书。在这篇文章中,我们将讨论如何解决这些问题。

问题描述

问题: x509: certificate relies on legacy Common Name field, use SANs instead

这个错误通常出现当证书未使用"主题备用名称"(SANs)而仅仅依赖于过时的"通用名称"(CN)字段时。现代的 TLS 安全性要求使用 SANs 来标识证书适用的域名或 IP 地址。

解决方案

解决这个问题的关键是生成包含 SANs 的正确证书。以下是一个详细的步骤,包括必要的 shell 脚本,以帮助你生成和配置符合现代安全标准的证书。

生成新证书

首先,我们需要在 Harbor 服务器上生成一个新的证书,这个过程涉及到创建密钥、生成证书签名请求(CSR),并最终创建包含 SANs 的证书。

脚本解析

  1. 清理旧证书文件:脚本开始先清理任何现存的证书文件,以确保不会有旧的或无效的证书干扰新证书的创建。
  2. 生成私钥和证书 :接着,使用 openssl 命令生成一个新的 4096 位 RSA 私钥和自签名证书。这一步骤还包括了生成 CSR 和处理 SANs,确保新证书满足现代 TLS 标准。
  3. 部署证书到正确的位置:生成的新证书及其私钥会被复制到 Harbor 服务器和 Docker 的相关目录中,以便正确地被服务器和客户端使用。
  4. 信任新证书:最后,脚本更新系统的 CA 信任库,并重启 Docker 服务以应用新的证书配置。
shell 复制代码
#!/bin/bash

mkdir -p /etc/ssl/private

echo "Remove old key files."

# Remove old files
sudo rm -rf /data/cert/harbor.crt
sudo rm -rf /data/cert/harbor.key
sudo rm -rf /data/cert/harbor.pem
sudo rm -rf /data/cert/harbor.cert

echo "Remove old files."

# Remove the passphrase from the private key
sudo rm -rf /etc/ssl/private/harbor.pem
sudo rm -rf /etc/ssl/private/harbor.crt
sudo rm -rf /etc/ssl/private/harbor.cert
sudo rm -rf /etc/ssl/private/harbor.key

sudo rm -rf /etc/ssl/certs/harbor.pem
sudo rm -rf /etc/ssl/certs/harbor.crt
sudo rm -rf /etc/ssl/certs/harbor.cert
sudo rm -rf /etc/ssl/certs/harbor.key

sudo rm -rf /etc/docker/certs.d/x.x.x.x/harbor.pem
sudo rm -rf /etc/docker/certs.d/x.x.x.x/harbor.key
sudo rm -rf /etc/docker/certs.d/x.x.x.x/harbor.crt
sudo rm -rf /etc/docker/certs.d/x.x.x.x/harbor.cert

sudo rm -rf /etc/pki/ca-trust/source/anchors/harbor.crt
sudo rm -rf /etc/pki/ca-trust/source/anchors/harbor.cert
sudo rm -rf /etc/pki/ca-trust/source/anchors/harbor.pem

echo "Generating a private key"

# Generate a private key
openssl genrsa -out /data/cert/harbor.key 4096

openssl req -x509 -new -nodes -sha512 -days 3650 \
 -subj "/C=CN/ST=Beijing/L=Beijing/O=GameSale/OU=Personal/CN=x.x.x.x" \
 -key /data/cert/harbor.key \
 -out /data/cert/harbor.crt

openssl req -sha512 -new \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=GameSale/OU=Personal/CN=x.x.x.x" \
    -key /data/cert/harbor.key \
    -out /data/cert/harbor.csr

cat > /data/cert/v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=x.x.x.x
IP.1=x.x.x.x
EOF

openssl x509 -req -sha512 -days 3650 \
    -extfile /data/cert/v3.ext \
    -CA /data/cert/harbor.crt -CAkey /data/cert/harbor.key -CAcreateserial \
    -in /data/cert/harbor.csr \
    -out /data/cert/harbor.crt

openssl x509 -inform PEM -in /data/cert/harbor.crt -out /data/cert/harbor.cert
openssl x509 -in /data/cert/harbor.crt -out /data/cert/harbor.pem -outform PEM

# Copy files
echo "Copy files."

sudo cp /data/cert/harbor.crt /etc/ssl/private/
sudo cp /data/cert/harbor.cert /etc/ssl/private/
sudo cp /data/cert/harbor.pem /etc/ssl/private/harbor.pem
sudo cp /data/cert/harbor.key /etc/ssl/private/

sudo cp /data/cert/harbor.crt /etc/ssl/certs/
sudo cp /data/cert/harbor.cert /etc/ssl/certs/
sudo cp /data/cert/harbor.pem /etc/ssl/certs/harbor.pem
sudo cp /data/cert/harbor.key /etc/ssl/certs/

sudo cp /data/cert/harbor.crt /etc/docker/certs.d/x.x.x.x/
sudo cp /data/cert/harbor.cert /etc/docker/certs.d/x.x.x.x/
sudo cp /data/cert/harbor.pem /etc/docker/certs.d/x.x.x.x/harbor.pem
sudo cp /data/cert/harbor.key /etc/docker/certs.d/x.x.x.x/

sudo cp /data/cert/harbor.crt /etc/pki/ca-trust/source/anchors/
sudo cp /data/cert/harbor.cert /etc/pki/ca-trust/source/anchors/
sudo cp /data/cert/harbor.pem /etc/pki/ca-trust/source/anchors/harbor.pem

echo "Generating a private key successfully."

echo "restart"

sudo update-ca-trust

systemctl restart docker
sudo systemctl restart docker.service

cd /opt/harbor
./prepare

# docker-compose down -v
# docker-compose up -d


echo "end."

客户端配置

在服务器端配置完毕后,我们还需要确保客户端信任新的自签名证书。对于不同的操作系统,这可能涉及到不同的步餤。下面以 CentOS 为例,描述如何将新证书添加到客户端的信任列表中。

脚本解析

  1. 添加证书到信任列表:通过将证书复制到系统指定的证书存储位置,然后运行系统命令来更新证书库,使系统信任新的 Harbor 证书。
  2. 登录并推送镜像到 Harbor:一旦证书被信任,接下来的步骤展示了如何登录到 Harbor,并推送一个 Docker 镜像到仓库。
yaml 复制代码
- name: Trust self-signed certificate
  run: |
    echo "${{ env.CERTIFICATE }}" > harbor.crt
    sudo mkdir -p /usr/local/share/ca-certificates/harbor
    sudo mkdir -p /etc/docker/certs.d/${{ env.HARBOR_URL }}
    sudo mkdir -p /usr/local/share/ca-certificates/extra
    sudo mkdir -p /etc/ssl/certs
    sudo cp harbor.crt /usr/local/share/ca-certificates/harbor/harbor.crt
    sudo cp harbor.crt /etc/docker/certs.d/${{ env.HARBOR_URL }}/ca.crt
    sudo cp harbor.crt /usr/local/share/ca-certificates/extra/harbor.crt
    sudo cp harbor.crt /etc/ssl/certs/harbor.crt
    sudo update-ca-certificates
    sudo systemctl restart docker

- name: Login to Harbor
    run: |
        echo $HARBOR_PASSWORD | docker login $HARBOR_URL --username $HARBOR_USERNAME --password-stdin
        docker build -t $HARBOR_URL/$IMAGE_NAME:$VERSION .
        docker push $HARBOR_URL/$IMAGE_NAME:$VERSION
    env:
        HARBOR_USERNAME: ${{ env.HARBOR_USERNAME }}
        HARBOR_PASSWORD: ${{ env.HARBOR_PASSWORD }}
        HARBOR_URL: ${{ env.HARBOR_URL }}
        IMAGE_NAME: ${{ env.APP_NAME }}
        VERSION: ${{ env.VERSION }}
相关推荐
GraduationDesign19 分钟前
基于SpringBoot的蜗牛兼职网的设计与实现
java·spring boot·后端
颜淡慕潇30 分钟前
【K8S问题系列 | 20 】K8S如何删除异常对象(Pod、Namespace、PV、PVC)
后端·云原生·容器·kubernetes
customer0834 分钟前
【开源免费】基于SpringBoot+Vue.JS安康旅游网站(JAVA毕业设计)
java·vue.js·spring boot·后端·kafka·开源·旅游
搬码后生仔2 小时前
将 ASP.NET Core 应用程序的日志保存到 D 盘的文件中 (如 Serilog)
后端·asp.net
Suwg2092 小时前
《手写Mybatis渐进式源码实践》实践笔记(第七章 SQL执行器的创建和使用)
java·数据库·笔记·后端·sql·mybatis·模板方法模式
凡人的AI工具箱3 小时前
每天40分玩转Django:Django文件上传
开发语言·数据库·后端·python·django
spcodhu3 小时前
在 Ubuntu 上搭建 MinIO 服务器
linux·后端·minio
小码编匠3 小时前
2024 年各编程语言运行百万并发任务需多少内存?
java·后端·python
小码编匠3 小时前
C# 实现多线程启动停止暂停继续
后端·c#·.net
sin22014 小时前
springboot测试类里注入不成功且运行报错
spring boot·后端·sqlserver