关于docker使用OpenSSL的自签发证书创建TLS仓库
docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
[docker@docker_server ca]$ tree docker.testdomain.com/
docker.testdomain.com/
├── docker-compose.yml
└── registry
├── auth
│ └── nginx.htpasswd
├── config.yml
└── ssl
├── docker.testdomain.com.crt
└── docker.testdomain.com.key
3 directories, 5 files
docker.testdomain.com/ssl 为证书存放目录
docker.testdomain.com/auth/nginx.htpasswd 为registry的用户名/密码文件
docker.testdomain.com/config.yml 为registry配置文件
第一步创建 CA 私钥
openssl genrsa -out "root-ca.key" 4096
定义变量
#国家
COUNTRY=CN
#省份
PROVINCE=HLJ
#城市
CITY=HRB
#组织名
ORGANIZE=SELF
#通用名
_CN='docker.testdomain.com'
IP=192.168.122.105
第二步利用私钥创建 CA 根证书请求文件
openssl req -new -key "root-ca.key" -out "root-ca.csr" -sha256 -subj "/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$ORGANIZE/CN=$_CN"
第三步配置 CA 根证书
cat > root-ca.cnf << EOF
[root_ca]
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
subjectKeyIdentifier=hash
EOF
第四步签发根证书
openssl x509 -req -days 3650 -in "root-ca.csr" -signkey "root-ca.key" -sha256 -out "root-ca.crt" -extfile "root-ca.cnf" -extensions root_ca
第五步生成站点 SSL 私钥.
openssl genrsa -out "${_CN}.key" 4096
第六步使用私钥生成证书请求文件。
openssl req -new -key "${_CN}.key" -out "site.csr" -sha256 -subj "/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$ORGANIZE/CN=$_CN"
第七步配置证书,新建 site.cnf 文件
cat > site.cnf << EOF
[server]
authorityKeyIdentifier=keyid,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage=serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = DNS:${_CN}, IP:${IP}
subjectKeyIdentifier=hash
EOF
第八步签署站点 SSL 证书。
openssl x509 -req -days 750 -in "site.csr" -sha256 -CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial -out "${_CN}.crt" -extfile "site.cnf" -extensions server
把生成的站点证书复制到ssl目录中
生成registry认证文件,替换username/password
docker run --rm \
--entrypoint htpasswd \
registry \
-Bbn username password > auth/nginx.htpasswd
docker.testdomain.com/config.yml
cat > ${_CN}/config.yml << EOF
version: 0.1
log:
accesslog:
disabled: true
level: debug
formatter: text
fields:
service: registry
environment: staging
storage:
delete:
enabled: true
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
auth:
htpasswd:
realm: basic-realm
path: /etc/docker/registry/auth/nginx.htpasswd
http:
addr: :443
host: https://docker.testdomain.com
headers:
X-Content-Type-Options: [nosniff]
http2:
disabled: false
tls:
certificate: /etc/docker/registry/ssl/docker.testdomain.com.crt
key: /etc/docker/registry/ssl/docker.testdomain.com.key
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
EOF
docker-compose.yml配置
cat > ${_CN}/docker-compose.yml << EOF
version: '3'
services:
registry:
container_name: registry
image: registry
ports:
- "443:443"
volumes:
- ./registry:/etc/docker/registry
- /var/lib/registry:/var/lib/registry
volumes:
registry-data:
EOF
修改 hosts
docker.testdomain.com 127.0.0.1
启动registry
docker-compose up -d
Creating registry ... done
登陆
[docker@docker_server docker.testdomain.com]$ docker login docker.testdomain.com
Username: username
Password:
WARNING! Your password will be stored unencrypted in /home/docker/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
build一个镜像
[docker@docker_server myubuntu]$ cat Dockerfile
FROM ubuntu:16.04
RUN apt-get update \
&&apt-get -y install net-tools \
&&apt-get -y install iputils-ping
[docker@docker_server myubuntu]$
[docker@docker_server myubuntu]$docker build -t docker.testdomain.com -f Dockerfile .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM ubuntu:16.04
---> b9e15a5d1e1a
Step 2/2 : RUN apt-get update &&apt-get -y install net-tools &&apt-get -y install iputils-ping
...
Successfully built 38876fa3f3fe
Successfully tagged docker.testdomain.com/username/ubuntu:net-tools
[docker@docker_server myubuntu]$
push测试成功
[docker@docker_server myubuntu]$ docker push docker.testdomain.com/username/ubuntu:net-tools
The push refers to repository [docker.testdomain.com/username/ubuntu]
fa0810c2ddcd: Pushed
75b79e19929c: Layer already exists
4775b2f378bb: Layer already exists
883eafdbe580: Layer already exists
19d043c86cbc: Layer already exists
8823818c4748: Layer already exists
net-tools: digest: sha256:0fa8d7d38435ae43a1dacd72c4881a97bed76fa9ed7c62466a4e7e9a60c79c24 size: 1569
[docker@docker_server myubuntu]$
TIPS
测试在非本机login的时候会报错
[docker@docker_server-2 ~]$ docker login docker.testdomain.com
Username: username
Password:
Error response from daemon: Get https://docker.testdomain.com/v2/: x509: certificate signed by unknown authority
[docker@docker_server-2 ~]$
服务端报错
2018/10/15 04:21:04 http: TLS handshake error from 192.168.122.106:44626: remote error: tls: bad certificate
最后查阅了别人的文章后发现openssl自签发的证书需要拷贝到客户端安装
把证书复制到客户端
放到下面的路径中
[root@docker_server-2 docker.testdomain.com]# pwd
/etc/docker/certs.d/docker.testdomain.com
[root@docker_server-2 docker.testdomain.com]# ls
docker.testdomain.com.crt
[root@docker_server-2 docker.testdomain.com]#
再次登录成功
[docker@docker_server-2 ~]$ docker login docker.testdomain.com
Username: username
Password:
WARNING! Your password will be stored unencrypted in /home/docker/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[docker@docker_server-2 ~]$
[docker@docker_server-2 ~]$ docker pull docker.testdomain.com/username/ubuntu:net-tools
net-tools: Pulling from username/ubuntu
3b37166ec614: Already exists
504facff238f: Already exists
ebbcacd28e10: Already exists
c7fb3351ecad: Already exists
2e3debadcbf7: Already exists
f576a46c0046: Pull complete
Digest: sha256:0fa8d7d38435ae43a1dacd72c4881a97bed76fa9ed7c62466a4e7e9a60c79c24
Status: Downloaded newer image for docker.testdomain.com/username/ubuntu:net-tools
[docker@docker_server-2 ~]$
[root@docker_server-2 ~]# curl -k https://username:password@docker.testdomain.com/v2/_catalog
{"repositories":["nginx","ubuntu","username/nginx","username/ubuntu"]}