虽然上一篇的私服已经能够正常使用,但是存在一些问题,例如
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 []:rootca@abc.com
[root@localhost demoCA]#
[root@localhost demoCA]#
说明1:-x509一般用于根证书,在生成服务端证书时不需要此参数。
说明2:Common 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 []:abc@abc.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost myauth]#
说明1:Common 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 = abc@abc.com
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_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即可,无需参数,下面校验的结果:
【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、重启docker: systemctl 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(未实践),若有任何疑问可留言!!