Harbor镜像仓库以及Docker如何拉取私有仓库镜像和漏洞和连接错误问题

前言:实战中碰到了harbor,需要拖取一些镜像到本地,这边的话简单记录下如何使用docker拉取harbor镜像笔记

参考文章:https://goharbor.io/docs/2.9.0/install-config/download-installer/
参考文章:https://goharbor.io/docs/2.9.0/install-config/configure-yml-file/
参考文章:https://goharbor.io/docs/2.9.0/install-config/run-installer-script/
参考文章:https://goharbor.io/docs/2.9.0/install-config/reconfigure-manage-lifecycle/
参考文章:https://goharbor.io/docs/2.9.0/install-config/configure-https/
参考文章:https://distribution.github.io/distribution/spec/auth/token/
参考文章:https://mp.weixin.qq.com/s/V8Ecqq_DPOQhH5q9UBWkXg
参考文章:https://zhuanlan.zhihu.com/p/435267429

关于harbor镜像仓库

Harbor是VMware公司开源的企业级Docker Registry项目,其目标是帮助用户迅速搭建一个企业级的Docker Registry服务。虽然Docker官方提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署企业自己的私有镜像仓库也是非常必要的。

Harbor以docker公司开源的registry为基础(docker自身也有一个原生的registry注册库),提供了管理UI,基于角色的访问控制(Role Based Access Control),AD/LDAP集成,以及审计日志(Auditlogging)等企业用户需求的功能,同时原生支持中文。

Harbor的每个组件都是以Docker容器的形式构建的,使用docker-compose来对它进行部署;用于部署Harbor的docker-compose模板位于/usr/local/bin/harbor/docker-compose.yml(自定义),Docker harbor有可视化的web管理界面,可以方便管理Docker镜像,又提供了多个项目的镜像权限管理及控制功能。

关于harbor架构图

harbor有很多服务,因为实战中碰到了关于认证的问题,所以这边主要学习的还是它是如何进行认证的

harbor认证

参考文章:https://distribution.github.io/distribution/spec/auth/token/

执行tcp命令来抓取docker与harbor之间的http请求交互

tcpdump -i eth0 -s 0 -A 'tcp dst port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x3C21444F and host 222.222.222.222'

然后通过docker login xxx.com,下面会抓到三个包,如下所示

第一个包

尝试使用注册表开始推/拉操作,如果认证服务器配置了权限认证的话则需要授权,它将返回401 Unauthorized HTTP响应。

其中401响应包含有关如何进行身份验证的信息,通知Docker Client在特定的请求中需要带上一个合法的token,而认证的逻辑地址则指向上述架构图中的Core Services。

IP 10.0.4.2.57206 > 222.222.222.222
GET /v2/ HTTP/1.1
Host: 222.222.222.222
User-Agent: docker/20.10.12 go/go1.16.2 git-commit/20.10.12-0ubuntu2~20.04.1 kernel/5.4.0-96-generic os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.12 \(linux\))
Accept-Encoding: gzip
Connection: close
222.222.222.222.http > 10.0.4.2.57206
HTTP/1.1 401 Unauthorized
Server: nginx
Date: Thu, 16 Nov 2023 14:39:50 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 76
Connection: close
Docker-Distribution-Api-Version: registry/2.0
Set-Cookie: sid=acffec268e2515273191f89cdb23902d; Path=/; HttpOnly
Www-Authenticate: Bearer realm="http://222.222.222.222/service/token",service="harbor-registry"
X-Request-Id: 994e7d11-758e-47b3-90b6-0464e836f4d4
{"errors":[{"code":"UNAUTHORIZED","message":"unauthorized: unauthorized"}]}

第二个包

客户端Docker Client向授权服务器发送Basic Auth凭证信息来请求承载令牌

当nginx服务器(harbor)收到请求之后,nginx会根据配置的认证地址将带有用户名和密码的请求发送到Core Service服务中

Core Services获取用户名和密码以后对用户信息进行认证,如果成功则返回认证成功的信息和授权令牌

IP 10.0.4.2.57208 > 222.222.222.222
GET /service/token?account=admin&client_id=docker&offline_token=true&service=harbor-registry HTTP/1.1
Host: 222.222.222.222
User-Agent: docker/20.10.12 go/go1.16.2 git-commit/20.10.12-0ubuntu2~20.04.1 kernel/5.4.0-96-generic os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.12 \(linux\))
Authorization: Basic YWRtaW46SGFyYm9yMTIzNDU=
Accept-Encoding: gzip
Connection: close
IP 222.222.222.222.http > 10.0.4.2.57208
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 16 Nov 2023 14:39:50 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 889
Connection: close
Content-Encoding: gzip
Set-Cookie: sid=6171c37cd393b65cea59875bc3e5e617; Path=/; HttpOnly
X-Request-Id: 935a8f70-525f-42aa-8516-8db974258ca6
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
...................wa.v. ..1 AH.....(a.(...u........~q?\..ma..Q;.;. ...g.j@.]p.y^.....=

第三个包

客户端Docker Client使用嵌入在请求的Authorization标头中的Bearer令牌重试原始请求

Harbor服务器通过验证Bearer令牌和嵌入其中的声明集来授权客户端,并照常开始推/拉会话

IP 10.0.4.2.57210 > 222.222.222.222
GET /v2/ HTTP/1.1
Host: 222.222.222.222
User-Agent: docker/20.10.12 go/go1.16.2 git-commit/20.10.12-0ubuntu2~20.04.1 kernel/5.4.0-96-generic os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.12 \(linux\))
Authorization: Bearer eyJhbGciOiJSUzI1Nxxxxxxxxxxxxxxxxxxxx0uSz_j_B03fxUTM
Accept-Encoding: gzip
Connection: close
IP 222.222.222.222.http > 10.0.4.2.57210
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 16 Nov 2023 14:39:50 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2
Connection: close
Docker-Distribution-Api-Version: registry/2.0
Set-Cookie: sid=2f26025cf2a272a75509b4882a962a00; Path=/; HttpOnly
X-Request-Id: d492afc9-9a22-441b-bfce-c5fc9fa89591
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'

Harbor环境搭建

参考文章:https://goharbor.io/docs/2.9.0/install-config/configure-yml-file/
参考文章:https://goharbor.io/docs/2.9.0/install-config/download-installer/
参考文章:https://goharbor.io/docs/2.9.0/install-config/run-installer-script/
参考文章:https://goharbor.io/docs/2.9.0/install-config/reconfigure-manage-lifecycle/

然后这边在 https://github.com/goharbor/harbor/releases 下载的harbor环境,机器环境是ubuntu 20.04,这边下载的环境是v2.5.5,这边将harbor.yml.tmpl模板配置文件复制一份为harbor.yml

这边的话首先要修改hostname为机器地址,这边设置的就是外网地址

然后这边访问使用的是http,所以https部分需要注掉

数据库就保持默认,默认的数据库账号密码为root123,如下图所示

确保docker和docker-compose都安装完了之后,再执行./install.sh脚本搭建harbor

Harbor仓库登录

遇到如下的问题,这边解决方式是进入/etc/docker/daemon.json,添加如下内容,允许docker守护程序使用HTTP方式进行连接到注册表

{
"registry-mirrors":[
"http://hub-mirror.c.163.com/",
"https://docker.mirrors.ustc.edu.cn"
],
"insecure-registries": [
"192.168.59.218"
]
}

如果是Docker Desktop的话可以在设置中进行修改配置项,如下图所示

这边设置完记得重启docker服务systemctl restart docker,这样docker的配置文件才能生效,如下图所示

这边登录到实际搭建的环境docker login xxx.xxx.xxx.xxxx,输入对应的web管理员账号密码即可登录成功,如下图所示

Harbor镜像推送

先列出当前已经有的镜像,如下图所示

这边将要推送的镜像打一个标签,这边测试推送一个docker版本的wpscan进行测试

docker tag wpscanteam/wpscan:latest 139.196.127.88:8002/testproject/wpscan:1.0

接着将该wpscan:1.0进行推送到harbor上,如下图所示

docker push 139.196.127.88:8002/testproject/wpscan:1.0

Harbor镜像拉取

这边测试拉取上面上传的wpscan镜像,如下图所示

这边执行pull操作docker pull 139.xxx.xxx.88:8002/testproject/wpscan@sha256:34688ff71a3c04442116e04c43f26800e8f0f89178ef7eeef06cdf0a52fdedba

关于Harbor的未授权访问

参考文章:https://mp.weixin.qq.com/s/V8Ecqq_DPOQhH5q9UBWkXg

实际上只是一个伪漏洞,看大家是如何认为的了,这边的话可以搜索公开的项目,通过遍历所有数字和字母即可整合所有的公开项目,如下图所示

配置https访问

参考文章:https://goharbor.io/docs/2.9.0/install-config/configure-https/

打开harbor.yml改写来https配置项,如下图所示

创建对应的文件夹/data/cert/

生成CA证书

Generate a CA certificate private key.

openssl genrsa -out ca.key 4096

Generate the CA certificate.

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

生成服务器端证书

Generate a private key

openssl genrsa -out 139.196.127.88.key 4096

Generate a certificate signing request (CSR)

openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=139.xxx.xxx.88" \
-key 139.xxx.xxx.88.key \
-out 139.xxx.xxx.88.csr

Generate an x509 v3 extension file

cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=139.xxx.xxx.88
EOF

Use the v3.ext file to generate a certificate for your Harbor host

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

然后将当前的/data/cert的crt文件和csr文件更改为server.crt和server.csr

刷新配置,重启docker harbor服务

./prepare
docker-compose up -d

拉取https镜像的情况

在客户端的docker中把insecure-registries配置项去掉,如下图所示

此时再次登录的时候就提示需要提供一个有效的validate certificate证书了

这边的话把上面配置好的harbor中的证书在客户端中进行配置,先在客户端的docker中配置好证书,certs.d下的每个文件夹对应的就是客户端的地址,我这边的话就是ip,那直接创建ip的文件夹即可,然后将ca.crt文件放入到certs.d/139.xxx.xxx.88里面

mkdir /etc/docker/certs.d/139.xxx.xxx.88

测试连接发现出现如下情况

解决方法如下所示

生成的方式还是跟上面一样,唯一不同的就是v3.ext文件,内容为如下,多加了一个subjectAltName指定ip

cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:139.xxx.xxx.88
[alt_names]
DNS.1=139.xxx.xxx.88
EOF

这个问题没有解决,最后还是无法成功登录,不知道什么原因,后面再看

docker login 出现502的情况

多看下是不是代理的问题,我这边关掉就能正常连接

docker login 出现503情况

参考文章:https://zhuanlan.zhihu.com/p/435267429

查阅文章的时候发现自己的情况和上面的情况一样,但是并不是代理的问题,如下图所示

我一开始看到这篇文章:https://blog.csdn.net/oscarun/article/details/121616615

但是我默认代理实际是关闭的,如下图所示

实战中发现目标内网主机要docker拉取harbor的主机都在/etc/hosts配置了harbor.com,于是本地也配置了harbor.com,再次执行发现成功了

目标环境的harbor版本是v1.10.10-322972dc,这边看下手册,但是也没看出啥,就只能这样放着了,如果以后知道再来补充

posted @   zpchcbd  阅读(1381)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2019-11-12 实现:通讯录管理系统
2019-11-12 实现:结构体案例
2019-11-12 学习:结构体
2019-11-12 实现:指针和冒泡函数和数组
2019-11-12 学习:指针
2019-11-12 学习:函数的分文件编写
2019-11-12 实现:二维数组的成绩统计
点击右上角即可分享
微信分享提示