配置 Harbor 的 HTTPS 访问

默认情况下,Harbor 不附带证书。可以在没有安全性的情况下部署 Harbor,以便可以通过 HTTP 连接到它。但是,使用 HTTP 仅在与外部互联网断开连接的气隙测试或开发环境中是可以接受的。在非气隙环境中使用 HTTP 会使您容易受到中间人攻击。在生产环境中,始终使用 HTTPS。

要配置 HTTPS,您必须创建 SSL 证书。您可以使用由受信任的第三方 CA 签名的证书,也可以使用自签名证书。本节介绍如何使用 OpenSSL 创建 CA,以及如何使用您的 CA 签名服务器证书和客户端证书。您可以使用其他 CA 提供商,例如 Let’s Encrypt

以下步骤假设您的 Harbor 注册表的主机名是 yourdomain.com,并且其 DNS 记录指向您正在运行 Harbor 的主机。

生成证书颁发机构证书

在生产环境中,您应该从 CA 获取证书。在测试或开发环境中,您可以生成自己的 CA。要生成 CA 证书,请运行以下命令。

  1. 生成 CA 证书私钥。

    openssl genrsa -out ca.key 4096
    
  2. 生成 CA 证书。

    调整 -subj 选项中的值以反映您的组织。如果您使用 FQDN 连接您的 Harbor 主机,则必须将其指定为通用名称 (CN) 属性。

    openssl req -x509 -new -nodes -sha512 -days 3650 \
     -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=MyPersonal Root CA" \
     -key ca.key \
     -out ca.crt
    

生成服务器证书

证书通常包含 .crt 文件和 .key 文件,例如,yourdomain.com.crtyourdomain.com.key

  1. 生成私钥。

    openssl genrsa -out yourdomain.com.key 4096
    
  2. 生成证书签名请求 (CSR)。

    调整 -subj 选项中的值以反映您的组织。如果您使用 FQDN 连接您的 Harbor 主机,则必须将其指定为通用名称 (CN) 属性并在密钥和 CSR 文件名中使用它。

    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 扩展文件。

    无论您是使用 FQDN 还是 IP 地址连接到您的 Harbor 主机,您都必须创建此文件,以便您可以为您的 Harbor 主机生成符合主题备用名称 (SAN) 和 x509 v3 扩展要求的证书。替换 DNS 条目以反映您的域名。

    cat > v3.ext <<-EOF
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1=yourdomain.com
    DNS.2=yourdomain
    DNS.3=hostname
    EOF
    
  4. 使用 v3.ext 文件为您的 Harbor 主机生成证书。

    将 CSR 和 CRT 文件名中的 yourdomain.com 替换为 Harbor 主机名。

    openssl x509 -req -sha512 -days 3650 \
        -extfile v3.ext \
        -CA ca.crt -CAkey ca.key -CAcreateserial \
        -in yourdomain.com.csr \
        -out yourdomain.com.crt
    

向 Harbor 和 Docker 提供证书

生成 ca.crtyourdomain.com.crtyourdomain.com.key 文件后,您必须将它们提供给 Harbor 和 Docker,并重新配置 Harbor 以使用它们。

  1. 将服务器证书和密钥复制到 Harbor 主机上的证书文件夹中。

    cp yourdomain.com.crt /data/cert/
    cp yourdomain.com.key /data/cert/
    
  2. yourdomain.com.crt 转换为 yourdomain.com.cert,供 Docker 使用。

    Docker 守护程序将 .crt 文件解释为 CA 证书,将 .cert 文件解释为客户端证书。

    openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert
    
  3. 将服务器证书、密钥和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中。您必须首先创建相应的文件夹。

    cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
    cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
    cp ca.crt /etc/docker/certs.d/yourdomain.com/
    

    如果您将默认的 nginx 端口 443 映射到不同的端口,请创建文件夹 /etc/docker/certs.d/yourdomain.com:端口,或 /etc/docker/certs.d/harbor_IP:端口

  4. 重启 Docker Engine。

    systemctl restart docker
    

您可能还需要在操作系统级别信任该证书。有关更多信息,请参阅 Harbor 安装问题排查

以下示例说明了使用自定义证书的配置。

/etc/docker/certs.d/
    └── yourdomain.com:port
       ├── yourdomain.com.cert  <-- Server certificate signed by CA
       ├── yourdomain.com.key   <-- Server key signed by CA
       └── ca.crt               <-- Certificate authority that signed the registry certificate

部署或重新配置 Harbor

如果您尚未部署 Harbor,请参阅 配置 Harbor YML 文件,了解有关如何通过在 harbor.yml 中指定 hostnamehttps 属性来配置 Harbor 以使用证书的信息。

如果您已使用 HTTP 部署 Harbor 并想要重新配置它以使用 HTTPS,请执行以下步骤。

  1. 运行 prepare 脚本以启用 HTTPS。

    Harbor 使用 nginx 实例作为所有服务的反向代理。您可以使用 prepare 脚本配置 nginx 以使用 HTTPS。prepare 位于 Harbor 安装程序捆绑包中,与 install.sh 脚本位于同一级别。

    ./prepare
    
  2. 如果 Harbor 正在运行,请停止并删除现有实例。

    您的镜像数据保留在文件系统中,因此不会丢失任何数据。

    docker compose down -v
    
  3. 重启 Harbor

    docker compose up -d
    

验证 HTTPS 连接

为 Harbor 设置 HTTPS 后,您可以通过执行以下步骤来验证 HTTPS 连接。

  • 打开浏览器并输入 https://yourdomain.com。它应该显示 Harbor 界面。

    某些浏览器可能会显示警告,指出证书颁发机构 (CA) 未知。当使用来自不受信任的第三方 CA 的自签名 CA 时,会发生这种情况。您可以将 CA 导入到浏览器以消除警告。

  • 在运行 Docker 守护程序的机器上,检查 /etc/docker/daemon.json 文件,以确保未为 https://yourdomain.com 设置 -insecure-registry 选项。

  • 从 Docker 客户端登录到 Harbor。

    docker login yourdomain.com
    

    如果您已将 nginx 443 端口映射到不同的端口,请在 login 命令中添加端口。

    docker login yourdomain.com:port
    

后续操作