@kiranananda

Docker registry авторизация или фильтрация по ip для push?

Здравтвуйте!

Вот уже чуток осталось, docker swarm работает, осталось добить пару вопросов с безопасностью.
Есть у меня приватный registry для моих образов. Для того что бы случайно не сделать дыру из за неверной настройки фаервола я его запускаю на конкретном хосте (mode=host), где нет доступа к внешке. И все работает хорошо, но ведь если кто то получает доступ в один из контейнеров, то без особых усилий может запушить мне в репозиторий все что угодно. И мне хотелось бы ограничить возможность для push либо паролем или еще как то...
В стандартной доке предлагают использовать ssl и прочие плюшки и это хорошо если доступ извне есть. А у меня нет никакого доступа извне, только по локальному ip адресу, да и морочиться с сертификатами, обновлениями их, получается созданием домена который должен отдавать внутренний адрес или прописывать на всех нодах в hosts, брр, что то по моему не то для такой простой задачи.
Есть вариант использовать nginx и там настроить htaccess. Но вот будет ли эта схема работать без сертификатов?
И еще один момент, docker login надо делать на каждом хосте в кластере или достаточно для всего кластера как то прописать?

Щас все это дело на nginx накрутил но толку нет, валят ошибки что надо https. Вот. Самое простое что я сейчас вижу, создавать имя в днс на внутренний ип, потом генерить самоподписаный сертификат, раскидывать его по нодам, а их щас 4 будет, больше... Хотя тогда и без днс можно обойтись в hosts прописать. Просто хотелось бы избежать этих всех телодвижений. Чем проще базовая нода в настройках тем понятнее будет поддерживать и восстанавливать...
  • Вопрос задан
  • 431 просмотр
Решения вопроса 1
@kiranananda Автор вопроса
Вообщем то решил вопрос.

Для начала мы поднимаем nginx и в нем создаем 2 секции server. Одна секция на 5000 порту, вторая на 5001.
В первой секции мы обрубаем все запросы кроме GET и HEAD, это будет порт на получение образов внутри кластера. Во второй же секции мы добавляем авторизацию. я выложу готовые конфиги вдруг кому пригодится...

user nginx;

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';
  }

#------------------------READ ONLY ACCESS-------------------------
  server {
    listen 5000;

    client_max_body_size 0;

    chunked_transfer_encoding on;

    location /v2/ {
      if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
        return 404;
      }

      #Доступ только на чтение
      if ($request_method !~* ^(GET|HEAD)$ ) {  
        return 403;
      }

      add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

      proxy_pass                          http://registry:5000;
      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;  
    }
  }


#---------------------------WRITE ACCESS-----------------------------
  server {
    listen 5001;
    client_max_body_size 0;
    chunked_transfer_encoding on;

    location /v2/ {
      if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
        return 404;
      }

      auth_basic "Registry realm";
      auth_basic_user_file /run/secrets/passwd; 

      allow 172.18.0.1;
      deny  all;

      add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

      proxy_pass                          http://registry:5000;
      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;  
    }
  }
}


И сам docker-compose.yml

version: '3.4'
services:
  nginx:
    image: nginx
    ports:
      - target: 5000
        published: 5000
        mode: host

      - target: 5001
        published: 5001
        mode: host
    configs:
      - source: nginx
        target: /etc/nginx/nginx.conf
    secrets:
      - passwd

    networks:
      registry_network:

    deploy:
        replicas: 1
        resources:
           limits:
              cpus: '0.25'
              memory: 256M
        placement:
           constraints: [node.labels.registry == true]
    logging:
        driver: syslog
        options:
            tag: registry-nginx
            syslog-address: "udp://10.92.60.151:514"

  registry:
    image: registry:2
    networks:
      registry_network:
        aliases:
          - registry
    volumes:
      - /srv/registry:/var/lib/registry   
    deploy:
          replicas: 1
          resources:
            limits:
              cpus: '0.25'
              memory: 256M
          placement:
            constraints: [node.labels.registry == true]
    logging:
        driver: syslog
        options:
            tag: registry
            syslog-address: "udp://10.92.60.151:514"

secrets:
  passwd:
    file: ./nginx/passwd

configs:
  nginx:
    file: ./nginx/nginx.conf

networks:
  registry_network:
    driver: overlay


Ну и не забываем в конфиге докера "insecure-registries" : ["10.92.60.151:5001"]

Ах да, так же удалось не использовать лишние сертификаты, в моем случае.

Для ввода пароля используем команду docker login 10.92.60.151:5001

Теперь если есть желание у 5000 порта можно убрать mode: host и в имаджах указывать 127.0.0.1:5000, в этом случае не нужно на нодах делать запись "insecure-registries" : ["10.92.60.151:5000"]
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы