配置对 Harbor 的 HTTPS 访问

Posted 琦彦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了配置对 Harbor 的 HTTPS 访问相关的知识,希望对你有一定的参考价值。

配置对 Harbor 的 HTTPS 访问

默认情况下,Harbor 不附带证书。可以在没有安全性的情况下部署 Harbor,以便你可以通过 HTTP 连接到它。但是,在生产环境中,建议使用 HTTPS。如果你要使用Content Trust with Notary ,则必须使用 HTTPS。

要配置 HTTPS,你必须创建 SSL 证书。你可以使用由受信任的第三方 CA 签名的证书,也可以使用自签名证书。

本节介绍如何使用 OpenSSL创建 CA,以及如何使用你的 CA 签署服务器证书和客户端证书。你也可以使用其他 CA 提供程序,例如 Let’s Encrypt

下面的过程,假设你的 Harbor 注册中心的主机名是yourdomain.com,并且它的 DNS 记录指向你正在运行 Harbor 的主机。

SSL证书

SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socketlayer(SSL),SSL安全协议主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性,现已成为该领域中全球化的标准。由于SSL技术已建立到所有主要的浏览器和WEB服务器程序中,因此,仅需安装服务器证书就可以激活该功能了)。即通过它可以激活SSL协议,实现数据信息在客户端和服务器之间的加密传输,可以防止数据信息的泄露。保证了双方传递信息的安全性,而且用户可以通过服务器证书验证他所访问的网站是否是真实可靠。

SSL网站不同于一般的Web站点,它使用的是“HTTPS”协议,而不是普通的“HTTP”协议。因此它的URL(统一资源定位器)格式为“https://www.baidu.com”。

由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的一个数字文件, 这就是数字证书。数字证书包含证书中所标识的实体的公钥(就是说你的证书里有你的公钥),由于证书将公钥与特定的个人匹配,并且该证书的真实性由颁发机构保证(就是说可以让大家相信你的证书是真的),因此,数字证书为如何找到用户的公钥并知道它是否有效这一问题提供了解决方案。

使用数字证书能够提高用户的可信度 。数字证书中的公钥,能够与服务端的私钥配对使用,实现数据传输过程中的加密和解密 。在认证使用者身份期间,使用者的敏感个人数据并不会被传输至证书持有者的网络系统上 。

X.509:上面所说的密钥文件、申请文件、证书文件都有一套标准格式,这一套格式标准的名称就叫做X.509。

X.509证书包含三个文件:key,csr,crt。

  • key是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密
  • csr是证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名
  • crt是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息

自签名证书

自签名证书是未经公共或私有证书颁发机构签名的 SSL/TSL 证书。相反,它由创建者自己的个人或根 CA 证书签名。

对于自签名证书,这就是我们所做的。

首先要有一个CA根证书,然后用CA根证书来签发用户证书。
用户进行证书申请:一般先生成一个私钥,然后用私钥生成证书请求(证书请求里应含有公钥信息),再利用证书服务器的CA根证书来签发证书。
特别说明:
(1)自签名证书(一般用于顶级证书、根证书): 证书的名称和认证机构的名称相同.
(2)根证书:根证书是CA认证中心给自己颁发的证书,是信任链的起始点。任何安装CA根证书的服务器都意味着对这个CA认证中心是信任的。

  1. 创建我们自己的 CA 根证书和 CA 私钥(我们自己充当 CA)
  2. 创建服务器私钥以生成 CSR
  3. 使用我们的 CA根证书 和 CA 私钥创建带有 CSR 的 SSL 证书。
  4. 在浏览器或操作系统中安装 CA 证书以避免安全警告。

openssl生成证书流程

这个图有A、B、C三个部分,分别用三种颜色框选了一下

A部分是CA机构根证书的生成过程,这个过程需要先生成CA机构的私钥,再由CA机构的私钥生成CA机构证书申请文件,然后再由这两个文件生成根证书。

B部分是生成服务器私钥,然后由服务器私钥生成服务器证书申请文件。

C部分是最后一部分,也就是生成服务器的公钥证书,服务器的公钥证书需要三部分一起来生成,A部分的CA机构的私钥,CA机构的申请证书文件,B部分的服务器证书申请文件,这三部分一起来生成服务器的公钥证书。

openssl中有如下后缀名的文件

.key格式:私有的密钥
.csr格式:证书签名请求(证书请求文件),含有公钥信息,certificate signing request的缩写
.crt格式:证书文件,certificate的缩写
.crl格式:证书吊销列表,Certificate Revocation List的缩写
.pem格式:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式

CA根证书的生成步骤

生成CA私钥(.key)–>生成CA证书请求(.csr)–>自签名得到根证书(.crt)(CA给自已颁发的证书)。

# Generate CA private key  
openssl genrsa -out ca.key 2048  

# Generate CSR  
openssl req -new -key ca.key -out ca.csr 

# Generate Self Signed certificate(CA 根证书) 
openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt 

在实际的软件开发工作中,往往服务器就采用这种自签名的方式,因为毕竟找第三方签名机构是要给钱的,也是需要花时间的。

用户证书的生成步骤

生成私钥(.key)–>生成证书请求(.csr)–>用CA根证书签名得到证书(.crt)

服务器端用户证书:

# private key 
$openssl genrsa -des3 -out server.key 1024  

# generate csr 
$openssl req -new -key server.key -out server.csr 

# generate certificate 
$openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key 

客户端用户证书:

$openssl genrsa -des3 -out client.key 1024  

$openssl req -new -key client.key -out client.csr 

$openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key 

生成pem格式证书:
有时需要用到pem格式的证书,可以用以下方式合并证书文件(crt)和私钥文件(key)来生成

$cat client.crt client.key> client.pem

$cat server.crt server.key > server.pem

结果:

服务端证书:ca.crt, server.key, server.crt, server.pem

客户端证书:ca.crt, client.key, client.crt, client.pem

总体流程:

构造证书颁发机构:

1.生成根证书私钥(pem文件)
2.生成根证书签发申请文件(csr文件)
3.自签发根证书(cer文件)

用户申请证书:

1.生成用户证书私钥(pem文件)
2.生成用户证书签发申请文件(csr文件)
3.使用跟证书签发生成用户证书(cer文件)首先,虚构一个CA认证机构出来

# 生成CA认证机构的证书密钥key
# 需要设置密码,输入两次
openssl> genrsa -des3 -out ca.key 1024

# 去除密钥里的密码(可选)
# 这里需要再输入一次原来设的密码
openssl> rsa -in ca.key -out ca.key

# 用私钥ca.key生成CA认证机构的证书ca.crt
# 其实就是相当于用私钥生成公钥,再把公钥包装成证书
openssl> req -new -x509 -key ca.key -out ca.crt -days 365
# 这个证书ca.crt有的又称为"根证书",因为可以用来认证其他证书

其次,才是生成网站的证书

用上面那个虚构出来的CA机构来认证,不收钱!

# 生成自己网站的密钥server.key
openssl> genrsa -des3 -out server.key 1024

# 生成自己网站证书的请求文件
# 如果找外面的CA机构认证,也是发个请求文件给他们
# 这个私钥就包含在请求文件中了,认证机构要用它来生成网站的公钥,然后包装成一个证书
openssl> req -new -key server.key -out server.csr

# 使用虚拟的CA认证机构的证书ca.crt,来对自己网站的证书请求文件server.csr进行处理,生成签名后的证书server.crt
# 注意设置序列号和有效期(一般都设1年)
openssl> x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -days 365

至此,私钥server.key和证书server.crt已全部生成完毕,可以放到网站源代码中去用了。

Harbor部署 SSL 认证

基础概念

签名证书与自签名证书
签名证书:由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西
自签名证书:由服务器自己颁发给自己,用于证明自己身份的东西,非权威颁发机构发布
openssl
openssl 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用

KEY与CSR的区别
Key通常用来存放一个公钥或者私钥,并非X.509证书,编码同样的,可能是PEM,也可能是DER。证书自身拥有一个密钥对(即一个公钥和一个私钥),由公钥(Public Key)与私钥(Private Key)是通过一种算法得到,公钥是密钥对中公开的部分,私钥则是非公开的部分。

一般公钥和密钥的关系为:1,公钥和私钥成对出现、2,公开的密钥叫公钥,只有自己知道的叫私钥、3,用公钥加密的数据只有对应的私钥可以解密、4,用私钥加密的数据只有对应的公钥可以解密、5,如果可以用公钥解密,则必然是对应的私钥加的密、6,如果可以用私钥解密,则必然是对应的公钥加的密

CSR文件必须在申请和购买SSL证书之前创建。

也就是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件,证书申请 者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书

Harbor自签名证书方式

1. 生成CA根证书

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

生成 CA 证书私钥

openssl genrsa -out ca.key 4096

生成 CA 证书

假如你使用类似于yourdomain.com的FQDN(Fully Qualified Domain Name)方式来连接registry主机,则你必须使用yourdomain.com来作为CN(Common Name)。

否则,假如你使用IP地址来连接你的registry主机的话,CN可以指定为任何值。

公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。
 
例1:打算为“chinassl.net”申请SSL证 书,那这个公用名(Common Name)就要填写“chinassl.net”,而不能填写 “www.chinassl.net”,因为在申请SSL证书时发证机构认为“www.yourdomain.com”和 “yourdomain.com”是不同的两个域名;
 
例2:如将要为bill.chinassl.net申请SSL证书,那么这里公用名(Common Name)就 要填写“bill.chinassl.net”而不能填写“chinassl.net”或“www.chinassl.net”
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
 
 #  req  产生证书签发申请命令
 # -x509 签发X.509格式证书命令。X.509是最通用的一种签名证书格式。
 # -new  生成证书请求
 # -key  指定私钥文件
 # -nodes 表示私钥不加密
 # -out   输出
 # -subj 指定用户信息
 # -days 有效期

2. 生成Harbor服务器证书

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

生成私钥

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
     

生成 x509 v3 扩展文件。

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

替换DNS条目以反映你的域。

# 域名方式访问
# 需要替换下方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=registry.harbor.com
DNS.2=registry.harbor
DNS.3=harbor
EOF


# IP方式访问
# 需要替换下方IP地址
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:192.168.93.9
EOF


# 示例
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

使用v3.ext文件为你的 Harbor 主机生成证书。

将CRS 和 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
    
# x509  签发X.509格式证书命令。
# -req   表示证书输入请求。
# -days  表示有效天数
# -extensions 表示按OpenSSL配置文件v3_req项添加扩展。
# -CA   表示CA证书,这里为ca.crt
# -CAkey  表示CA证书密钥,这里为ca.key
# -CAcreateserial 表示创建CA证书序列号
# -extfile  指定文件    

3. 签发Harbor 证书

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

cp yourdomain.com.crt /data/cert/
cp yourdomain.com.key /data/cert/

4. 签发Docker 证书

**目的:**使用证书验证镜像仓库客户端

从Docker 1.13开始,在Linux上,所有根证书颁发机构都与系统默认值合并,包括作为主机的根CA设置。

在早期版本的Docker和适用于Windows Server的Docker Enterprise Edition上,仅当未配置自定义根证书时才使用系统默认证书。

如果存在多个证书,则按字母顺序尝试每个证书。如果出现4xx级或5xx级身份验证错误,则Docker继续尝试使用下一个证书。

转换yourdomain.com.crtyourdomain.com.cert, 供 Docker 使用。

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

openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert

拷贝证书

将服务器证书、密钥和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中

# 如果如下目录不存在,请创建,如果有域名请按此格式依次创建
# ip方式
mkdir -p /etc/docker/certs.d/harbor_IP
# 域名方式
mkdir -p /etc/docker/certs.d/yourdomain.com

# 如果端口为443,则不需要指定。如果为自定义端口,请指定端口
# 域名方式
/etc/docker/certs.d/yourdomain.com:port
# ip方式
/etc/docker/certs.d/harbor_IP:port

# 复制证书
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/

# 以下示例说明了使用自定义证书的配置。
/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

重启 Docker Engine

systemctl restart docker

你可能还需要在操作系统级别信任证书。有关更多信息,请参阅 Harbour 安装故障排除。

4. 部署或重新配置 Harbor

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

# 拷贝模板配置文件
# cp harbor.yml.tmpl harbor.yml
# 进入文件
# vim harbor.yml


hostname: yourdomain.com

# harbor.yml
https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /data/cert/harbor.crt
  private_key: /data/cert/harbor.key

重新生成配置文件并重启,请执行以下步骤。

# 方式1: 重新按照
./install.sh

# 方式2 : 
./prepare
docker-compose -f /opt/harbor/docker-compose.yml up  -d --force-recreate

5. 验证 HTTPS 连接

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

方式一:浏览器

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

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

方式二:docker命令

非Harbor主机所在服务器,可以在/etc/docker/daemon.json文件中的-insecure-registry选项中,添加https://yourdomain.com。然后从 Docker 客户端登录到 Harbor。

docker login yourdomain.com

注册Harbor 为系统服务

添加 Harbor 系统服务,以便 Harbor 在服务器或者docker重启时自动启动。

进入cd /etc/systemd/system添加 Harbor 服务文件,名字是harbor.service

#cd /etc/systemd/system
#vi harbor.service
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml up -d --force-recreate
ExecStop=/usr/local/bin/docker-compose -f /opt/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target

保存文件并启用 Harbor 服务:

#chmod 644 harbor.service
#systemctl daemon-reload
#systemctl enable harbor

要检查 Harbor 的状态,请运行:

systemctl status harbor

Harbor配置Https异常问题

Docker

Docker守护程序将.crt文件作为CA证书,并将.cert文件作为客户端证书。如果一个CA证书被意外赋予扩展名.cert而不是正确的.crt扩展名,则Docker守护程序会记录以下错误消息:

Missing key KEY_NAME for client certificate CERT_NAME. CA certificates should use the extension .crt.

如果Docker镜像仓库没有端口号,请不要将端口添加到目录名称中。

下面显示了默认443端口上镜像像库的配置,非443端口则需要在目录名称中添加端口号:

    /etc/docker/certs.d/
    └── my-https.registry.example.com          <-- Hostname without port
       ├── client.cert
       ├── client.key
       └── ca.crt

相关信息

参考链接

https://docs.vmware.com/en/VMware-Telco-Cloud-Automation/1.9.5/com.vmware.tca.userguide/GUID-F36AFBB9-81B6-42B4-923A-5511B502E25C.html

Missing key KEY_NAME for client certificate CERT_NAME. CA certificates should use the extension .crt.


如果Docker镜像仓库没有端口号,请不要将端口添加到目录名称中。

下面显示了默认443端口上镜像像库的配置,非443端口则需要在目录名称中添加端口号:

```bash
    /etc/docker/certs.d/
    └── my-https.registry.example.com          <-- Hostname without port
       ├── client.cert
       ├── client.key
       └── ca.crt

相关信息

参考链接

https://docs.vmware.com/en/VMware-Telco-Cloud-Automation/1.9.5/com.vmware.tca.userguide/GUID-F36AFBB9-81B6-42B4-923A-5511B502E25C.html

https://docs.docker.com.zh.xy2401.com/engine/security/certificates/

以上是关于配置对 Harbor 的 HTTPS 访问的主要内容,如果未能解决你的问题,请参考以下文章

配置对港口的HTTPS访问

docker 镜像仓库Harbor https访问

Docker以https访问Harbor私有仓库

基于https的harbor部署与升级

基于https的harbor部署与升级

基于https的harbor部署与升级