docker registry nginx 安全访问控制

系统环境准备

centos7 

[root@docker-130 etc]# docker -v

Docker version 1.9.1, build a34a1d5

nginx 版本需要1.7.5以后的,因为需要一个add_header功能,我这里用的1.9

registry 2.1.1

安装部署

192.168.10.130 

192.168.10.128

nginx 和 registry都是跑在容器里面 宿主机为 192.168.10.130

首先启动一个registry容器,保证registry功能正常,

docker run -d --restart=always --name registry -p 5000:5000  -v /data/registry/data:/var/lib/registry registry:2.1.1

修改docker配置文件 /etc/sysconfig/docker 在需要从registry服务器下载image的客户端

添加参数

OPTIONS= '--insecure-registry 192.168.10.130:5000',这个参数后面的client试验中可加可不加,服务器需要加

docker pull 和push没有问题,在看后面的

然后启动一个nginx容器,

docker run -d --name nginx --link registry:registry -p 443:443 -v /data/etc:/tmp nginx:1.9

这里使用-v的原因是从官网下载的镜像所起的容器是不让修改内容的,所以可以把需要修改的文件移动到/tmp中,修改好后再cp回去,这里也可以使用docker cp命令

如果不准备为此花钱去购买一个SSL密钥,可以使用自己授权的 SSL key让registry支持HTTPS加密访问。
生成SSL证书只要两行命令,将signdomain的值换成实际域名即可

在nginx容器中执行

signdomain=registry.example.com

openssl req -nodes \

-subj "/C=CN/ST=BeiJing/L=Dongcheng/CN=$signdomain" \

-newkey rsa:4096 -keyout $signdomain.key -out $signdomain.csr

然后再执行

openssl x509 -req -days 3650 -in $signdomain.csr -signkey $signdomain.key -out $signdomain.crt

把生成的key和crt文件配给nginx就可以提供https访问了,只是因为是没有权威认证的自签名证书

创建授权用户,第一次需要加-c参数

#htpasswd -c /etc/nginx/docker-registry.htpasswd sun

New password:
Re-type new password:
Adding password for user sun

修改nginx.conf

添加

upstream docker-registry {

    server 192.168.10.130:5000;

}

修改vhost里的default.conf

server {
 listen 443;
 server_name registry.example.com; ##这里如果要用域名,就得在/etc/hosts中添加相应的解析
 ssl on;
 ssl_certificate /etc/ssl/certs/registry.example.com.crt;
 ssl_certificate_key /etc/ssl/private/registry.example.com.key;
 proxy_set_header Host       $http_host;   # required for Docker client sake
 proxy_set_header X-Real-IP  $remote_addr; # pass on real client IP
 client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
 # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
 chunked_transfer_encoding on;
 add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always; 
 location / {
     # let Nginx know about our auth file
     auth_basic              "Restricted";
     auth_basic_user_file    docker-registry.htpasswd;
     proxy_pass http://docker-registry;
     proxy_set_header  Host              $http_host;   # required for docker client's sake
     proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
     proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
     proxy_set_header  X-Forwarded-Proto $scheme;
     proxy_read_timeout                  900;
}
 location /_ping {
     auth_basic off;
     proxy_pass http://docker-registry;
 }
 location /v2/_ping {
     auth_basic off;
     proxy_pass http://docker-registry;
 }
}

修改好后记得重启nginx服务

此时我们在192.168.10.128去访问

curl -i -k https://sun:[email protected]:443/v2/_catalog

HTTP/1.1 200 OK

Server: nginx/1.9.4

Date: Wed, 02 Dec 2015 09:18:36 GMT

Content-Type: application/json; charset=utf-8

Content-Length: 46

Connection: keep-alive

Docker-Distribution-Api-Version: registry/2.0

Docker-Distribution-Api-Version: registry/2.0


{"repositories":["lashou/centos","v2/swarm"]}

然后我们去登录

因为没有权威认证的自签名证书,使用docker longin 访问时会提示下面的错误:

docker pull docker.webmaster.me/centos:centos6
Error: Invalid registry endpoint https://docker.webmaster.me/v1/: Get https://docker.webmaster.me/v1/_ping: x509: certificate signed by unknown authority. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry docker.webmaster.me` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/docker.webmaster.me/ca.crt

根据提示把我们之前生的.crt 文件放在/etc/docker/certs.d/docker.webmaster.me/ 下,这里的路径要根据提示写

如果还没有解决这个问题

那我们就需要执行  cat $signdomain.crt >> /etc/pki/tls/certs/ca-bundle.crt

 Error response from daemon: Login: 404 page not found
 (Code: 404; Headers: map[Server:[nginx/1.8.0] Date:[Thu, 03 Dec 2015 10:52:03 GMT] Content-Type:[text/plain; charset=utf-8] Content-Length:[19] Connection:[keep-alive] Docker-Distribution-Api-Version:[registry/2.0]])

如果报这个错,就需要在nginx配置文件里加上add-header 

这是正确登录后的返回信息
[root@docker-128 ~]# docker login registry.example.com:443
Username (sun): sun
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded

在config.json文件中记载了登录用户的信息

到这里我们做的加密认证功能已经实现了,可是有一个问题,那就是我们还可以通过原来的方式访问registry仓库

这里需要做iptables设置,但是后来我咨询别人,说不需要这样,所以我也没有加。目前先这样


猜你喜欢

转载自my.oschina.net/u/1775013/blog/538475