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,这边看下手册,但是也没看出啥,就只能这样放着了,如果以后知道再来补充
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源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 实现:二维数组的成绩统计