美文网首页Linux运维进阶-Python,Docker,ShellDocker容器运维驿站
nginx反向代理+http user 认证访问 私有regis

nginx反向代理+http user 认证访问 私有regis

作者: My熊猫眼 | 来源:发表于2019-10-03 21:53 被阅读0次

    上一篇讲述了如何搭建ssl支持的registry容器, 但是,更多的情况可能是:利用nginx做反向代理,从而实现对registry的访问;而nginx作为反向代理来使用在实际情况中非常多见,并且还支持基本的用户权限认证。
    本节讲述如何用nginx 的反向代理实现对registry的访问(https访问),同时用nginx提供基本的用户认证功能:

    1. 首先下载nginx image, 然后run nginx 容器. 我们需要这个容器run起来,然后把配置文件从容器中copy到宿主机中. 在随后会将 localhost下的 /root/docker_study/nginx/ , mapping到容器的/etc/nginx; 理解这一点很重要. 因为nginx的配置文件中不能用localhost的路径,而要用在container中的路径;
    #docker pull nginx的过程忽略. 以下的nginx是官方的nginx image.
    [root@localhost ~]# docker image ls nginx
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    docker.io/nginx     latest              f949e7d76d63        8 days ago          126 MB
    [root@localhost ~]#
    #把nginx 容器运行起来;
    [root@localhost ~]# docker run -d -p 8080:80 --rm --name official_nginx nginx
    03b95be10b94d47e5f92dd9b139c230633cce5db3c7c4863582d2f9cf35d2127
    [root@localhost ~]# curl -I http://192.168.0.110:8080/
    HTTP/1.1 200 OK
    Server: nginx/1.17.4
    ...
    [root@localhost ~]#
    #容器中nginx的配置文件在 /etc/nginx , copy配置文件到localhost的当前目录下
    [root@localhost docker_study]# docker cp official_nginx:/etc/nginx  . 
    [root@localhost docker_study]# ls
    nginx  
    [root@localhost docker_study]#
    
    1. 编辑nginx的配置文件:
      A. 因为要配置ssl支持,所以需要在配置文件中打开ssl支持,并指定证书以及key的路径;
      B. 因为做反向代理,所以需要指定后端registry的IP以及端口信息;
    #这里依然使用之前的证书,一共用到的是如下的2个文件;
    #首先copy证书到nginx的cert.d目录下
    [root@localhost nginx]# pwd
    /root/docker_study/nginx
    [root@localhost nginx]# mkdir cert.d
    [root@localhost nginx]# cp /root/cert_test/{my.crt,myprivate.key}  ./cert.d
    [root@localhost nginx]# ls cert.d/
    my.crt  myprivate.key
    

    我们有了证书 (nginx/cert.d/目录下)后,就可以修改nginx的配置了,这里主要分为两步来完成:
    A. 添加ssl相关的配置:
    参照docker官方文档的说明 https://docs.docker.com/registry/recipes/nginx/ ,在nginx的conf.d/default.conf中的server 配置节中添加如下内容:

        listen       443 ssl;      #修改原来的80端口为443端口,并指出用ssl连接;        
        server_name  www.my.com;  #修改server name 为 www.my.com ,需要和证书my.crt中的设定相一致,这个名字就是nginx对外提供服务器名字;
        #添加ssl相关的配置,指定cert以及key的路径,此处的路径为在container中的路径;
        ssl_certificate /etc/nginx/cert.d/my.crt;
        ssl_certificate_key /etc/nginx/cert.d/myprivate.key;
        #ssl安全相关的其他配置,直接copy官方的参数:
        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
    

    B. 进行nginx 反向代理的配置:
    配置反向代理之前,我们需要考虑nginx 和 registry容器的通信问题, 因为nginx和registry容器的ip在每次退出重启后都会变化,所以nginx 如何知道后端registry的ip呢?
    这里采用的方法是:让两个容器使用同一个网络栈,从而对另一个容器的访问就变成了对localhost的访问,这样就避免了ip变化带来的通信上的困扰;理解了这一点,我们在配置nginx反向代理的时候,后端的registry 就是localhost了

    在nginx的主配置文件nginx.conf中的http节,添加内容如下:

    #添加proxy相关的配置,
      upstream my_registry {         #定义uptream的名称,后面server 节的proxy_pass参数会使用这个名称;
        server localhost:5000;          #后端的registry服务器就是localhost, 因为nginx 和registry 会使用同一个网络栈,所以指定localhost就可以了;
      }
    

    在default.conf中已经存在的server节中添加如下内容, 并注释掉原有的local / {...} 部分:

          location /v2/ {
           #如下的配置是nginx proxy相关的配置;
          proxy_pass                          http://my_registry; #这个名称要和上面指定的upstream的名称一致;
    #这里的proxy不能够写为: http://my_registry/, 如果后面有字符“/”, 那么匹配部分的v2 在pass到后端的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;
          }
    
    1. 启动nginx, my_registry容器,进行初步的验证:
      在启动nginx的时候,用--network="container:<CONTAINER-ID>"的模式,从而确保nginx和registry使用的是同一个网络栈;
    [root@localhost nginx]# docker run -d  -p 443:443 -v /root/docker_study/nginx/:/etc/nginx  --rm --name nginx_for_registry nginx 
    d1a492516aab9456813603430356606a7ddce8b821436439d468910c0cabb538
    [root@localhost nginx]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                          NAMES
    d1a492516aab        nginx               "nginx -g 'daemon ..."   5 seconds ago       Up 4 seconds        80/tcp, 0.0.0.0:443->443/tcp   nginx_for_registry
    [root@localhost nginx]# docker run -d -v /var/my_registry/:/var/lib/registry --network="container:d1a492516aab" --rm my_registry
    c5fe1c808c2a6a26ab419f080227ae3c98fd12ba7c3ca727195ad5b525b0080c
    [root@localhost nginx]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                          NAMES
    c5fe1c808c2a        my_registry         "/my_entry.sh /etc..."   5 seconds ago       Up 4 seconds                                       kind_albattani
    d1a492516aab        nginx               "nginx -g 'daemon ..."   2 minutes ago       Up About a minute   80/tcp, 0.0.0.0:443->443/tcp   nginx_for_registry
    [root@localhost nginx]# 
    [root@localhost conf.d]# curl  -XGET https://www.my.com/v2/_catalog   #可以正常访问到数据;
    {"repositories":["panda/my_baseimage","panda/my_registry"]}
    [root@localhost conf.d]# 
    

    至此,已经成功完成利用"nginx作为反向代理”实现对registry的访问;
    下面,我们将进一步学习如何配置http user的访问认证.

    1. 添加http user 访问认证:
      我们这里使用htpasswd这个工具来进行密码认证,htpasswd是apache的http 密码生成工具,用起来比较简单,可以做基本的认证功能;
      a). 首先是用htpasswd来生成密码文件nginxpwd,并放到目录nginx/auth/下:
    [root@localhost nginx]# htpasswd -Bb -c  nginxpwd testuser1 testpwd1 #首次生成要加-c参数
    Adding password for user testuser1
    [root@localhost nginx]# htpasswd -Bb nginxpwd testuser2 testpwd2
    Adding password for user testuser2
    [root@localhost nginx]# cat nginxpwd    #一共生成了两ID以及对应密码
    testuser1:$2y$05$pzs.lZ9KyaAbLnrnZYIMwO8ibZKsELkXG8bPRpu3fp6QK.fvOFPvC
    testuser2:$2y$05$XMpbB2deNcQPjo.qRDSwsu9kU3k8RP.LGoMmbb.8L/q/./WycKy3a
    [root@localhost nginx]# mkdir -p auth
    [root@localhost nginx]# mv nginxpwd  auth/
    [root@localhost nginx]# 
    

    b). 更新nginx的配置,在conf.d/default.conf下的server节添加如下内容:

    auth_basic "Restricted Access";           #指定认证方式;
    auth_basic_user_file /etc/nginx/auth/nginxpwd;  #指定用于认证的文件路径
    

    c). 重新按照上面步骤启动nginx和registry容器,然后进行访问:
    报错了,报错了,报错了......什么原因呢?

    [root@localhost nginx]# docker login www.my.com
    Username: testuser1
    Password: 
    Error response from daemon: login attempt to https://www.my.com/v2/ failed with status: 500 Internal Server Error
    [root@localhost nginx]# 
    

    经过排查(用docker logs CONTAINER-ID ),看错误logs, 是因为加密问题;再进一步查找原因,是因为nginx的auth_basic认证并不支持bcrypt加密方式,而 htpasswd 的-B 是 bcrypt加密方式,所以导致问题,重新用默认加密方式生成密码,再次验证:

    [root@localhost auth]# docker login www.my.com
    Username: testuser1
    Password: 
    Login Succeeded
    [root@localhost auth]# docker pull -a www.my.com/panda/my_registry
    Trying to pull repository www.my.com/panda/my_registry ... 
    v1: Pulling from www.my.com/panda/my_registry
    Digest: sha256:7022fc0185a773a8b7a75f624ef91b8b6fb03fafd9bf667cb90af95691129d00
    Status: Downloaded newer image for www.my.com/panda/my_registry
    [root@localhost auth]# 
    

    通过以上步骤,完成基本的nginx 反向代理配置,以及通过nginx实现简单的认证;从而提供对私有registry的认证访问;
    还有一些参数是需要加入的,请参考 : https://docs.docker.com/registry/recipes/nginx/ 获取更多指南;

    本文原创,转载注明出处

    相关文章

      网友评论

        本文标题:nginx反向代理+http user 认证访问 私有regis

        本文链接:https://www.haomeiwen.com/subject/bfedpctx.html