Аутентифицируйте прокси с помощью nginx

Эта страница содержит информацию о размещении вашего собственного реестра с помощью реестр Docker с открытым исходным кодом. Для получения информации о Docker Hub, который предлагает размещенный реестр с дополнительными функциями, такими как группы, организации, веб-перехватчики, автоматические сборки и т.д., см. статью Docker Hub.

Опция использования

Люди, уже полагающиеся на прокси-сервер nginx для аутентификации своих пользователей в других службах, могут захотеть использовать его и туннелировать обмен данными реестра через тот же конвейер.

Обычно это включает в себя корпоративные настройки с использованием LDAP/AD на серверной части и механизм SSO, выходящий на их внутренний http-портал.

Альтернативы

Если вам просто нужна аутентификация для вашего реестра и вы довольны отдельным доступом пользователей, вам действительно стоит подумать о том, чтобы придерживаться собственного базовая функция реестра аутентификации.

Решение

С помощью представленного здесь метода вы реализуете базовую аутентификацию для механизмов докеров в обратном прокси-сервере, который находится перед вашим реестром.

Хотя мы используем простой файл htpasswd в качестве примера, любой другой сервер аутентификации nginx должен быть довольно легко реализован после того, как вы закончите с примером.

Мы также реализуем push-ограничение (для ограниченной группы пользователей) для примера. Опять же, вы должны изменяет это, чтобы соответствовать вашему пробегу.

Попался

Хотя эта модель предоставляет вам возможность использовать любой механизм проверки подлинности, который вы хотите, с помощью вторичного механизма проверки подлинности, реализованного внутри вашего прокси-сервера, она также требует, чтобы вы перенесли завершение TLS из реестра в сам прокси-сервер.

Примечание

Docker не рекомендует привязывать ваш реестр к localhost:5000 без аутентификации. Это создаёт потенциальную лазейку в безопасности вашего реестра Docker. В результате любой, кто может войти на сервер, на котором работает ваш реестр Docker, может отправлять образы без аутентификации.

Кроме того, введение дополнительного уровня http в ваш конвейер связи усложняет его развертывание, обслуживание и отладку. Убедиться, что требуется дополнительная сложность.

Например, Amazon Elastic Load Balancer (ELB) в режиме HTTPS уже устанавливает следующий заголовок клиента:

X-Real-IP
X-Forwarded-For
X-Forwarded-Proto

Поэтому, если за ним стоит экземпляр Nginx, удаляет данные строки из приведенного далее примера конфигурации:

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;

В противном случае Nginx сбрасывает значения ELB, и запросы не маршрутизируются должным образом. Дополнительные сведения см. в статье #970.

Настройка вещей

Просмотрите требования, затем выполняет следующие действия.

  1. Создаёт необходимые каталоги

    $ mkdir -p auth data
    
  2. Создаёт основную конфигурацию nginx. Вставляет данный блок кода в новый файл с именем auth/nginx.conf:

    events {
        worker_connections  1024;
    }
    
    http {
    
      upstream docker-registry {
        server registry:5000;
      }
    
      ## Set a variable to help us decide if we need to add the
      ## 'Docker-Distribution-Api-Version' header.
      ## The registry always sets this header.
      ## In the case of nginx performing auth, the header is unset
      ## since nginx is auth-ing before proxying.
      map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
        '' 'registry/2.0';
      }
    
      server {
        listen 443 ssl;
        server_name myregistrydomain.com;
    
        # SSL
        ssl_certificate /etc/nginx/conf.d/domain.crt;
        ssl_certificate_key /etc/nginx/conf.d/domain.key;
    
        # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
        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;
    
        # disable any limits to avoid HTTP 413 for large image uploads
        client_max_body_size 0;
    
        # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
        chunked_transfer_encoding on;
    
        location /v2/ {
          # Do not allow connections from docker 1.5 and earlier
          # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
          if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
            return 404;
          }
    
          # To add basic authentication to v2 use auth_basic setting.
          auth_basic "Registry realm";
          auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
    
          ## If $docker_distribution_api_version is empty, the header is not added.
          ## See the map directive above where this variable is defined.
          add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
    
          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;
        }
      }
    }
    
  3. Создаёт файл паролей auth/nginx.htpasswd для «testuser» и «testpassword».

    $ docker run --rm --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/nginx.htpasswd
    

    Примечание

    Если вы не хотите использовать bcrypt, вы можете пропустить параметр -B.

  4. Копирует файлы сертификатов в каталог auth/.

    $ cp domain.crt auth
    $ cp domain.key auth
    
  5. Создаёт файл compose. Вставляет следующий YAML в новый файл с именем docker-compose.yml.

    nginx:
      # Note : Only nginx:alpine supports bcrypt.
      # If you don't need to use bcrypt, you can use a different tag.
      # Ref. https://github.com/nginxinc/docker-nginx/issues/29
      image: "nginx:alpine"
      ports:
        - 5043:443
      links:
        - registry:registry
      volumes:
        - ./auth:/etc/nginx/conf.d
        - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro
    
    registry:
      image: registry:2
      volumes:
        - ./data:/var/lib/registry
    

Запуск и остановка

Теперь выполните свой стек:

docker-compose up -d

Войти в систему с авторизованным пользователем «push» (используя testuser и testpassword), затем пометьте и отправить свое первое образ:

docker login -u=testuser -p=testpassword -e=root@example.ch myregistrydomain.com:5043
docker tag ubuntu myregistrydomain.com:5043/test
docker push myregistrydomain.com:5043/test
docker pull myregistrydomain.com:5043/test