Nginx反向代理Docker Registry

上一篇介绍如何搭建Registry私服。

虽然上一篇的私服已经能够正常使用,但是存在一些问题,例如

1)不安全。直接将端口暴露出来,容易被攻击 -- 采用nginx做https反向代理。

2)单点故障,导致服务不能使用 -- 启动多个Registry服务,用nginx做负载均衡。

今天介绍利用nginx做反向代理。比较惭愧,原先对openssl一直不太了解,大概花了三周的时间才把Registry搞定,希望通过此篇,能够帮助像我一样,对ssl是小白的。

若让Regisry和Nginx能够正常运行,生成ssl证书是必须的,主要分成以下三个步骤:
       1、生成根证书以及key
       2、生成服务端证书以及key
       3、用根证书签名服务端证书

【前提】
 Registry私服采用上一篇部署的私服,私服在生成证书之前还需要做以下修改:
 一、修改openssl.cnf文件,具体修改内容如下(Centos系统):
    1、vi /etc/pki/tls/openssl.cnf, 修改dir指向目录

 [ CA_default ]
    #dir            = /etc/pki/CA               # Where everything is kept
    dir             = /etc/pki/demoCA               # Where everything is kept
    certs           = $dir/certs            # Where the issued certs are kept
    crl_dir         = $dir/crl              # Where the issued crl are kept
    database        = $dir/index.txt        # database index file.
    #unique_subject = no                    # Set to 'no' to allow creation of
                                           # several ctificates with same subject.
    new_certs_dir   = $dir/newcerts         # default place for new certs.

    certificate     = $dir/cacert.pem       # The CA certificate
    serial          = $dir/serial           # The current serial number
    crlnumber       = $dir/crlnumber        # the current crl number
                                           # must be commented out to leave a V1 CRL
    crl             = $dir/crl.pem          # The current CRL
    private_key     = $dir/private/cakey.pem# The private key
    RANDFILE        = $dir/private/.rand    # private random number file
   
    x509_extensions = usr_cert              # The extentions to add to the cert
   2、x509扩展属性( 这个地方是一个大坑,就是这个坑,坑了我三周
        如果不修改x509扩展属性,则在访问registry的时候会报这个错误:
Error response from daemon: Get https://10.85.160.126/v1/users/: x509: cannot validate certificate for 10.85.160.126 because it doesn't contain any IP SANs
   这个错误在网上搜一下,也会出现相关内容,但是大部分都是针对v3_req标签的修改。 我也参照类似的修改,结果就陷入大坑--修改v3_req根本不生效。原因是:我的扩展属性是用的x509_extensions = usr_cert,并非v3_req。
   下面只显示修改内容,追加subjectAltName属性以及alt_names。
   [ usr_cert ]
   ...
   subjectAltName = @alt_names
   ...
   
   [alt_names]

   IP.1 = 10.85.160.126

   说明:alt_names可以有多,如果设置多个则IP.2,IP.3,IP.4等。这个ip地址是Host主机的ip地址。

二、创建目录以及相关文件
  进入/etc/pki目录中

  [root@localhost pki]# mkdir -p ./demoCA/{private,newcerts}
  [root@localhost pki]# touch ./demoCA/index.txt
  [root@localhost pki]# echo 01 > ./demoCA/serial

【创建证书】

上面已经介绍创建证书需要哪些步骤,接下来就实际操作一下。

一、创建根证书key以及根证书

    1、创建根证书key

  [root@localhost pki]# cd demoCA
  [root@localhost demoCA]# 
  [root@localhost demoCA]# openssl genrsa -out private/myCA.key 1024
  Generating RSA private key, 1024 bit long modulus
  ......++++++
  ......................++++++
  e is 65537 (0x10001)
  [root@localhost demoCA]# 

    说明1可以指定des3加密算法,但是有一个不方便的地方就是每次重启服务nginx需要输入密码。

 说明2:如果1024秘钥长度不长,可以指定2048或者4096,我们只是试验,因此1024长度就行了。

   2、创建根证书

[root@localhost demoCA]# 
[root@localhost demoCA]# openssl req -new -x509 -key private/myCA.key -out certs/myCA.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:myname
Organizational Unit Name (eg, section) []:myname
Common Name (eg, your name or your server's hostname) []:mydocker.registry.io
Email Address []:[email protected]
[root@localhost demoCA]# 
[root@localhost demoCA]# 

说明1-x509一般用于根证书,在生成服务端证书时不需要此参数。

说明2Common Name一般是域名。这个地方应该也可以是ip地址。由于我们是局域网而且也没有域名,这个地方随便写一个域名,后面需要设置hosts文件。

二、创建服务端key以及证书

root@localhost myauth]# 
[root@localhost myauth]# openssl genrsa -out nginx.key 1024
Generating RSA private key, 1024 bit long modulus
....++++++
..........................++++++
e is 65537 (0x10001)
[root@localhost myauth]# 
[root@localhost myauth]# 
[root@localhost myauth]# openssl req -new -key nginx.key -out nginx.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:myname
Organizational Unit Name (eg, section) []:myname
Common Name (eg, your name or your server's hostname) []:mydocker.registry.io
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost myauth]# 

说明1Common Name与根证书中的CommonName保持一致。

三、签名服务端证书

[root@localhost myauth]# 
[root@localhost myauth]# openssl ca -in nginx.csr -keyfile /etc/pki/demoCA/private/myCA.key -cert /etc/pki/demoCA/certs/myCA.crt -out nginx.crt
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jan 22 15:28:53 2018 GMT
            Not After : Jan 22 15:28:53 2019 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BeiJing
            organizationName          = myname
            organizationalUnitName    = myname
            commonName                = mydocker.registry.io
            emailAddress              = [email protected]
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                4D:83:A5:27:98:A4:31:27:17:CA:C9:03:45:AB:7D:1F:91:94:20:8E
            X509v3 Authority Key Identifier: 
                keyid:AB:20:2A:E9:9A:B0:BF:1D:61:50:8D:47:B4:B6:96:53:E5:98:51:41

            X509v3 Subject Alternative Name: 
                IP Address:10.85.160.126
Certificate is to be certified until Jan 22 15:28:53 2019 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@localhost myauth]# 
[root@localhost myauth]# 

说明1:输入命令行后,会有打印证书相关内容,只需要保证有X509v3 Subject Alternative Name,即可。

Nginx配置】

证书完成后,开始搭建nginx环境:

一、nginx官网下载源码,目前下载版本是nginx-1.12.2.tar.gz,编译过程如下:

./configure --with-http_ssl_module --with-http_auth_request_module
make && make install
二、 修改 nginx 配置文件

修改/usr/local/nginx/conf/nginx.conf文件,修改主要内容

server {
        listen       443 ssl;
        server_name  localhost;

        #ssl_certificate      cert.pem;
        #ssl_certificate_key  cert.key;
        ssl_certificate      /usr/local/nginx/conf/myauth/nginx.crt; 
        ssl_certificate_key  /usr/local/nginx/conf/myauth/nginx.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {//设置反向代理服务--即后台真正服务
            #root   html;
            #index  index.html index.htm;
            # To add basic authentication to v2 use auth_basic setting.
            auth_basic "Registry realm";
            auth_basic_user_file /usr/local/nginx/conf/myauth/nginx.htpasswd;
            proxy_pass  http://localhost:5000; //这个地方很重要!!
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_redirect http:// $scheme://; #做https跳转
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

说明1:通过属性ssl_certificatessl_certificate_key指定服务端证书以及key

说明2:为了增加安全性,需要为nginx指定用户名和密码。通过配置auth_basicauth_basic_user_file

说明3:由于我们启动docker registry的时候,声明了端口映射。如果docker服务与nginx不在同一台机器上,我们可以指定另外ip地址形式。若docker容器自身有ip地址,可以直接指定docker容器的ip

说明4:nginx.htpasswd文件生成方式如下,执行完如下命令行就会生成文件nginx.htpasswd

htpasswd -bc nginx.htpasswd admin admin

三、启动nginx并验证

Nginx启动非常简单直接运行nginx即可,无需参数,下面校验的结果:


【Docker访问Registry】

以上基本完成docker registry服务搭建了,那么如果在另外一台机器上访问这个registry应该设置什么?如何访问呢?

一、修改hosts文件(另外一台linux ubuntu系统)

由于我们在生成根证书的时候,指定的是域名,而且在局域网内没有域名服务器,因此需要设置本机的hosts文件。在/etc/hosts文件中增加:10.85.160.126   mydocker.registry.io

二、添加根证书

注意:这个地方只需要把根证书拷贝到本机即可。

这个地方有一个坑:要把根证书拷贝到什么目录中呢?我的docker版本是1.13版本,之前的版本如何设置,不清楚。

1、在/etc/docker目录中创建如下目录:

root@ubuntu-server:/etc/docker/# mkdir -p certs.d/mydocker.registry.io

然后把根证书拷贝到目录mydocker.registry.io,此目录名应该与证书中的Common Name保持一致。

2、根证书名字需是ca.crt,需要重命名。

3、重启dockersystemctl restart docker

三、验证

root@ubuntu-server:~#
root@ubuntu-server:~#
root@ubuntu-server:~#docker login -u admin -p admin  https://mydocker.registry.io/v2/ 
Login Succeeded
root@ubuntu-server:~# 
root@ubuntu-server:~#
root@ubuntu-server:~#docker pull mydocker.registry.io/my/centos-base:v1.0
v1.0: Pulling from my/centos-base
e280bd282c7f: Pull complete 
ab3e77d42621: Pull complete 
Digest: sha256:339bab8951add5e07894a42de5fef63fc2506cf9ca145f9322edb6c4ddfc848d
Status: Downloaded newer image for mydocker.registry.io/my/centos-base:v1.0
root@ubuntu-server:~#

以上内容就是全部内容,这个是一步一步设置Docker Registry私服。这个registry是无界面的管理方式,若需要界面可安装nexus3(未实践),若有任何疑问可留言!!


猜你喜欢

转载自blog.csdn.net/xxb249/article/details/79138370
今日推荐