天天看點

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目錄中

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

【建立證書】

上面已經介紹建立證書需要哪些步驟,接下來就實際操作一下。

一、建立根證書key以及根證書

    1、建立根證書key

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

    說明1:可以指定des3加密算法,但是有一個不友善的地方就是每次重新開機服務nginx需要輸入密碼。

 說明2:如果1024秘鑰長度不長,可以指定2048或者4096,我們隻是試驗,是以1024長度就行了。

   2、建立根證書

[[email protected] demoCA]# 
[[email protected] 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]
[[email protected] demoCA]# 
[[email protected] demoCA]# 
           

說明1:-x509一般用于根證書,在生成服務端證書時不需要此參數。

說明2:Common Name一般是域名。這個地方應該也可以是ip位址。由于我們是區域網路而且也沒有域名,這個地方随便寫一個域名,後面需要設定hosts檔案。

二、建立服務端key以及證書

[email protected] myauth]# 
[[email protected] myauth]# openssl genrsa -out nginx.key 1024
Generating RSA private key, 1024 bit long modulus
....++++++
..........................++++++
e is 65537 (0x10001)
[[email protected] myauth]# 
[[email protected] myauth]# 
[[email protected] 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 []:
[[email protected] myauth]# 
           

說明1:Common Name與根證書中的CommonName保持一緻。

三、簽名服務端證書

[[email protected] myauth]# 
[[email protected] 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
[[email protected] myauth]# 
[[email protected] 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_certificate,ssl_certificate_key指定服務端證書以及key。

說明2:為了增加安全性,需要為nginx指定使用者名和密碼。通過配置auth_basic、auth_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即可,無需參數,下面校驗的結果:

Nginx反向代理Docker Registry

【Docker通路Registry】

以上基本完成docker registry服務搭建了,那麼如果在另外一台機器上通路這個registry應該設定什麼?如何通路呢?

一、修改hosts檔案(另外一台linux ubuntu系統)

由于我們在生成根證書的時候,指定的是域名,而且在區域網路内沒有域名伺服器,是以需要設定本機的hosts檔案。在/etc/hosts檔案中增加:10.85.160.126   mydocker.registry.io

二、添加根證書

注意:這個地方隻需要把根證書拷貝到本機即可。

這個地方有一個坑:要把根證書拷貝到什麼目錄中呢?我的docker版本是1.13版本,之前的版本如何設定,不清楚。

1、在/etc/docker目錄中建立如下目錄:

[email protected]:/etc/docker/# mkdir -p certs.d/mydocker.registry.io
           

然後把根證書拷貝到目錄mydocker.registry.io,此目錄名應該與證書中的Common Name保持一緻。

2、根證書名字需是ca.crt,需要重命名。

3、重新開機docker: systemctl restart docker

三、驗證

[email protected]:~#
[email protected]:~#
[email protected]:~#docker login -u admin -p admin  https://mydocker.registry.io/v2/ 
Login Succeeded
[email protected]:~# 
[email protected]:~#
[email protected]:~#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
[email protected]:~#
           

以上内容就是全部内容,這個是一步一步設定Docker Registry私服。這個registry是無界面的管理方式,若需要界面可安裝nexus3(未實踐),若有任何疑問可留言!!

繼續閱讀