Docker私有注册表使用自签名证书

时间:2015-12-15 11:44:29

标签: docker self-signed docker-registry

我想运行一个广泛使用的私有docker注册表。 所以我将能够从其他服务器推送和提取图像。

我遵循本教程:doc1& doc2

我执行了3个步骤: 首先,我创建了我的证书和密钥(作为CNAME,我填写了我的ec2主机名)

mkdir -p certs && openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
  -x509 -days 365 -out certs/domain.crt

我使用此密钥创建了我的docker注册表。

docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

比我将domain.crt的内容复制到/etc/docker/certs.d/ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/ca.crt 我重启了码头工具:sudo service docker restart 当我尝试推送图像时,出现以下错误:

unable to ping registry endpoint https://ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/v0/
v2 ping attempt failed with error: Get https://ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/v2/: net/http: TLS handshake timeout
 v1 ping attempt failed with error: Get https://ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/v1/_ping: net/http: TLS handshake timeout

我真的不知道自己错过了什么或做错了什么。有人可以帮帮我吗。感谢

3 个答案:

答案 0 :(得分:0)

我不确定你是否直接复制/粘贴你的pwd ...但是文件路径应该是/etc/docker/certs.d

您目前有etc / docker / cert.d /registry.ip:5000/domain.crt

答案 1 :(得分:0)

错误消息显示“TLS握手超时”。这表示没有进程正在侦听端口5000(使用netstat检查),或者端口是从您尝试推送映像的位置(AWS安全组中的开放端口)关闭的。

答案 2 :(得分:0)

从我所见,与浏览器相比,泊坞窗登录对精心制作的自签名证书更敏感+我会在最底层指出一个有趣的陷阱,因此请通读全文。

根据此网站: https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html

  

Bash#openssl x509 -noout -text -in ca.crt   
X509v3基本限制:严重   
CA:TRUE

^您应该看到类似这样的内容,即您已正确配置了证书。

在网上遵循随机操作指南的同时,我能够生成ca.crt和website.crt
当我运行上述命令时,我没有看到该输出,但我注意到:
如果我将证书导入为Mac或Win中受信任的证书,我的浏览器会很高兴并说是有效的证书,但是RHEL7上的docker登录会发出类似这样的消息

  

x509:证书由未知授权机构签名

我尝试了以下与使用相关的指示:
/etc/docker/certs.d/mydockerrepo.lan:5000/ca.crt
https://docs.docker.com/engine/security/certificates/
它给了我更好的错误消息(这使我首先找到了上述站点)

  

x509:未知授权机构签署的证书(可能是由于   “ x509:无效签名:父证书无法对这种类型的签名   证书”,同时尝试验证候选人授权证书

经过两天的混乱,我发现了:
当我学习编程时,我被教导了一个简短的独立示例的概念,因此,为了在这里尝试使用ansible,并利用openssl内置模块,我正在运行最新的ansible 2.9,但是理论上应该适用于ansible 2.5 ++:


简短的自包含示例:

#Name this file generatecertificates.playbook.yml
#Run using Bash# ansible-playbook generatecertificates.playbook.yml
#
#What to Expect:
#Run Self Contained Stand Alone Ansible Playbook --Get--> 
# currentworkingdir/certs/
#                         ca.crt
#                         ca.key
#                         mydockerrepo.private.crt
#                         mydockerrepo.private.key
#
#PreReq Ansible 2.5++
#PreReq Bash# pip3 install cryptograph >= 1.6 or PyOpenSSL > 0.15 (if using selfsigned provider)
---
- hosts: localhost
  connection: local
  gather_facts: no
  vars:
  - caencryptionpassword: "myrootcaencryptionpassword"
  - dockerepodns: "mydockerrepo.private"
  - rootcaname: "My Root CA"



  tasks:
  - name: get current working directory
    shell: pwd
    register: pathvar
  - debug: var=pathvar.stdout



  - name: Make sub directory
    file:
      path: "{{pathvar.stdout}}/certs"
      state: directory
    register: certsoutputdir
  - debug: var=certsoutputdir.path



  - name: "Generate Root CA's Encrypted Private Key"
    openssl_privatekey: 
      size: 4096
      path: "{{certsoutputdir.path}}/ca.key" 
      cipher: auto 
      passphrase: "{{caencryptionpassword}}"
  - name: "Generate Root CA's Self Signed Certificate Signing Request"
    openssl_csr: 
      path: "{{certsoutputdir.path}}/ca.csr"
      privatekey_path: "{{certsoutputdir.path}}/ca.key"
      privatekey_passphrase: "{{caencryptionpassword}}"
      common_name: "{{rootcaname}}" 
      basic_constraints_critical: yes
      basic_constraints: ['CA:TRUE']
  - name: "Generate Root CA's Self Signed Certificate"
    openssl_certificate: 
      path: "{{certsoutputdir.path}}/ca.crt" 
      csr_path: "{{certsoutputdir.path}}/ca.csr"
      provider: selfsigned
      selfsigned_not_after: "+3650d" #Note: Mac won't trust by default due to https://support.apple.com/en-us/HT210176, but you can explitly trust to make it work.
      privatekey_path: "{{certsoutputdir.path}}/ca.key"
      privatekey_passphrase: "{{caencryptionpassword}}"
    register: cert
  - debug: var=cert



  - name: "Generate Docker Repo's Private Key"
    openssl_privatekey: 
      size: 4096
      path: "{{certsoutputdir.path}}/{{dockerepodns}}.key"
  - name: "Generate Docker Repo's Certificate Signing Request"
    openssl_csr: 
      path: "{{certsoutputdir.path}}/{{dockerepodns}}.csr"
      privatekey_path: "{{certsoutputdir.path}}/{{dockerepodns}}.key"
      common_name: "{{dockerepodns}}"
      subject_alt_name: 'DNS:{{dockerepodns}},DNS:localhost,IP:127.0.0.1'
  - name: "Generate Docker Repo's Cert, signed by Root CA"
    openssl_certificate: 
      path: "{{certsoutputdir.path}}/{{dockerepodns}}.crt"
      csr_path: "{{certsoutputdir.path}}/{{dockerepodns}}.csr"
      provider: ownca
      ownca_not_after: "+365d" #Cert valid 1 year
      ownca_path: "{{certsoutputdir.path}}/ca.crt"
      ownca_privatekey_path: "{{certsoutputdir.path}}/ca.key"
      ownca_privatekey_passphrase: "{{caencryptionpassword}}"
    register: cert
  - debug: var=cert

有趣的陷阱/最终步骤:

  

RHEL7Bash#sudo cp ca.crt /etc/pki/ca-trust/source/anchors/ca.crt   
RHEL7Bash#sudo update-ca-trust   
RHEL7Bash#sudo systemctl重新启动docker

棘手的是,您必须重新启动docker,以便docker登录才能识别对新添加到系统的CA的更新。