github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/docs/apache.md (about)

     1  <!--[metadata]>
     2  +++
     3  title = "Authenticating proxy with apache"
     4  description = "Restricting access to your registry using an apache proxy"
     5  keywords = ["registry, on-prem, images, tags, repository, distribution, authentication, proxy, apache, httpd, TLS, recipe, advanced"]
     6  +++
     7  <![end-metadata]-->
     8  
     9  # Authenticating proxy with apache
    10  
    11  ## Use-case
    12  
    13  People already relying on an apache proxy to authenticate their users to other services might want to leverage it and have Registry communications tunneled through the same pipeline.
    14  
    15  Usually, that includes enterprise setups using LDAP/AD on the backend and a SSO mechanism fronting their internal http portal.
    16  
    17  ### Alternatives
    18  
    19  If you just want authentication for your registry, and are happy maintaining users access separately, you should really consider sticking with the native [basic auth registry feature](deploying.md#native-basic-auth). 
    20  
    21  ### Solution
    22  
    23  With the method presented here, you implement basic authentication for docker engines in a reverse proxy that sits in front of your registry.
    24  
    25  While we use a simple htpasswd file as an example, any other apache authentication backend should be fairly easy to implement once you are done with the exemple.
    26  
    27  We also implement push restriction (to a limited user group) for the sake of the exemple. Again, you should modify this to fit your mileage. 
    28  
    29  ### Gotchas
    30  
    31  While this model gives you the ability to use whatever authentication backend you want through the secondary authentication mechanism implemented inside your proxy, it also requires that you move TLS termination from the Registry to the proxy itself.
    32  
    33  Furthermore, introducing an extra http layer in your communication pipeline will make it more complex to deploy, maintain, and debug, and will possibly create issues.
    34  
    35  ## Setting things up
    36  
    37  Read again [the requirements](recipes.md#requirements).
    38  
    39  Ready?
    40  
    41  Run the following script:
    42  
    43  ```
    44  mkdir -p auth
    45  mkdir -p data
    46  
    47  # This is the main apache configuration you will use
    48  cat <<EOF > auth/httpd.conf
    49  LoadModule headers_module modules/mod_headers.so
    50  
    51  LoadModule authn_file_module modules/mod_authn_file.so
    52  LoadModule authn_core_module modules/mod_authn_core.so
    53  LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
    54  LoadModule authz_user_module modules/mod_authz_user.so
    55  LoadModule authz_core_module modules/mod_authz_core.so
    56  LoadModule auth_basic_module modules/mod_auth_basic.so
    57  LoadModule access_compat_module modules/mod_access_compat.so
    58  
    59  LoadModule log_config_module modules/mod_log_config.so
    60  
    61  LoadModule ssl_module modules/mod_ssl.so
    62  
    63  LoadModule proxy_module modules/mod_proxy.so
    64  LoadModule proxy_http_module modules/mod_proxy_http.so
    65  
    66  LoadModule unixd_module modules/mod_unixd.so
    67  
    68  <IfModule ssl_module>
    69      SSLRandomSeed startup builtin
    70      SSLRandomSeed connect builtin
    71  </IfModule>
    72  
    73  <IfModule unixd_module>
    74      User daemon
    75      Group daemon
    76  </IfModule>
    77  
    78  ServerAdmin you@example.com
    79  
    80  ErrorLog /proc/self/fd/2
    81  
    82  LogLevel warn
    83  
    84  <IfModule log_config_module>
    85      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    86      LogFormat "%h %l %u %t \"%r\" %>s %b" common
    87  
    88      <IfModule logio_module>
    89        LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    90      </IfModule>
    91  
    92      CustomLog /proc/self/fd/1 common
    93  </IfModule>
    94  
    95  ServerRoot "/usr/local/apache2"
    96  
    97  Listen 5043
    98  
    99  <Directory />
   100      AllowOverride none
   101      Require all denied
   102  </Directory>
   103  
   104  <VirtualHost *:5043>
   105  
   106    ServerName myregistrydomain.com
   107  
   108    SSLEngine on
   109    SSLCertificateFile /usr/local/apache2/conf/domain.crt
   110    SSLCertificateKeyFile /usr/local/apache2/conf/domain.key
   111  
   112    ## SSL settings recommandation from: https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html
   113    # Anti CRIME
   114    SSLCompression off
   115  
   116    # POODLE and other stuff
   117    SSLProtocol all -SSLv2 -SSLv3 -TLSv1
   118  
   119    # Secure cypher suites
   120    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
   121    SSLHonorCipherOrder on
   122  
   123    Header always set "Docker-Distribution-Api-Version" "registry/2.0"
   124    Header onsuccess set "Docker-Distribution-Api-Version" "registry/2.0"
   125    RequestHeader set X-Forwarded-Proto "https"
   126  
   127    ProxyRequests     off
   128    ProxyPreserveHost on
   129  
   130    # no proxy for /error/ (Apache HTTPd errors messages)
   131    ProxyPass /error/ !
   132  
   133    ProxyPass        /v2 http://registry:5000/v2
   134    ProxyPassReverse /v2 http://registry:5000/v2
   135  
   136    <Location /v2>
   137      Order deny,allow
   138      Allow from all
   139      AuthName "Registry Authentication"
   140      AuthType basic
   141      AuthUserFile "/usr/local/apache2/conf/httpd.htpasswd"
   142      AuthGroupFile "/usr/local/apache2/conf/httpd.groups"
   143  
   144      # Read access to authentified users
   145      <Limit GET HEAD>
   146        Require valid-user
   147      </Limit>
   148  
   149      # Write access to docker-deployer only
   150      <Limit POST PUT DELETE PATCH>
   151        Require group pusher
   152      </Limit>
   153  
   154    </Location>
   155  
   156  </VirtualHost>
   157  EOF
   158  
   159  # Now, create a password file for "testuser" and "testpassword"
   160  docker run --entrypoint htpasswd httpd:2.4 -Bbn testuser testpassword > auth/httpd.htpasswd
   161  # Create another one for "testuserpush" and "testpasswordpush"
   162  docker run --entrypoint htpasswd httpd:2.4 -Bbn testuserpush testpasswordpush >> auth/httpd.htpasswd
   163  
   164  # Create your group file
   165  echo "pusher: testuserpush" > auth/httpd.groups
   166  
   167  # Copy over your certificate files
   168  cp domain.crt auth
   169  cp domain.key auth
   170  
   171  # Now create your compose file
   172  
   173  cat <<EOF > docker-compose.yml
   174  apache:
   175    image: "httpd:2.4"
   176    hostname: myregistrydomain.com
   177    ports:
   178      - 5043:5043
   179    links:
   180      - registry:registry
   181    volumes:
   182      - `pwd`/auth:/usr/local/apache2/conf
   183  
   184  registry:
   185    image: registry:2
   186    ports:
   187      - 127.0.0.1:5000:5000
   188    volumes:
   189      - `pwd`/data:/var/lib/registry
   190  
   191  EOF
   192  ```
   193  
   194  ## Starting and stopping
   195  
   196  Now, start your stack:
   197  
   198      docker-compose up -d
   199  
   200  Login with a "push" authorized user (using `testuserpush` and `testpasswordpush`), then tag and push your first image: 
   201  
   202      docker login myregistrydomain.com:5043
   203      docker tag ubuntu myregistrydomain.com:5043/test
   204      docker push myregistrydomain.com:5043/test
   205  
   206  Now, login with a "pull-only" user (using `testuser` and `testpassword`), then pull back the image:
   207  
   208      docker login myregistrydomain.com:5043
   209      docker pull myregistrydomain.com:5043/test
   210  
   211  Verify that the "pull-only" can NOT push:
   212  
   213      docker push myregistrydomain.com:5043/test