Новости Санкции бьют по IT: Docker Hub блокирует пользователей из России

Специальный корреспондент
Собака

Собака

Пресс-служба
Команда форума
Private Club
Регистрация
13/10/15
Сообщения
54.789
Репутация
62.390
Реакции
276.952
RUB
0
Многие проекты теперь могут столкнуться с серьезными проблемами в работе.

image



В ночь на 30 мая 2024 года сервис ограничил доступ для пользователей из России. При попытке зайти на сайт сервиса из России появляется заглушка, что Docker является американской компанией и должна соблюдать правила экспортного контроля США

mvlp7s4c0w7kcglegigdm71gbggkbt0z.png


Уведомление также гласит, что компания блокирует все IP-адреса, расположенные на Кубе, в Иране, Северной Корее, Республике Крым, Судане и Сирии. Как показало , в России блокировка затронула не только Крым, но и другие города, включая Москву, Воронеж, Волгоград и Иркутск. При использовании VPN сайт открывается, но со скачиванием образов возникают сложности.
Docker Hub является крупнейшим репозиторием для хранения контейнеров, созданных с помощью Docker – сервиса автоматизации развертывания и управления приложениями в средах с поддержкой контейнеризации. Docker Hub использовался множеством российских программистов и компаний для разработки и управления приложениями.






 
zvskkafvotia3ana94b2giebmki.png

Главной новостью этой недели стала блокировка пользователей из России ресурсом Docker Hub. Она осуществляется по Geo IP.

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

В статье три проверенных мною способа, как получить доступ к ресурсу.


Знакомо?

~> docker pull alpine:3.17
Error response from daemon: pull access denied for alpine, repository does not exist or may require 'docker login': denied: <html><body><h1>403 Forbidden</h1>
Since Docker is a US company, we must comply with US export control regulations. In an effort to comply with these, we now block all IP addresses that are located in Cuba, Iran, North Korea, Republic of Crimea, Sudan, and Syria. If you are not in one of these cities, countries, or regions and are blocked, please reach out to
</body></html>

Такой ответ сейчас получают пользователи из России. Что можно с этим сделать?

1. Зеркала​

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

Публичные зеркала​

Сейчас все пишут про публичные зеркала. Некоторые люди предлагают использовать ноунейм и правительственные зеркала. Но я не советую этого делать. В какой-то момент в образ может добавиться слой с каким-нибудь вредоносом.

Если хотите использовать публичные зеркала, то используйте от компаний, которым важна репутация. Сейчас это:

  • - Гугл. Он и так знает уже всё, что можно было о вас знать. Теперь ещё узнает, что вы используйте полный образ debian, а не slim версию.
  • - Зеркало от TimeWeb. Компания не маленькая и не новая.
Думаю, скоро подобное поднимут многие компании.

Своё зеркало​

Это в первую очередь актуально для компаний и команд разработки. Компания Docker уже очень давно предоставляет образ registry, с помощью которого любой желающий может поднять своё зеркало.

Мы вас заблокировали. Ну зеркало там поднимите, если что. Вот образ.
Логика простая:

Вам нужен образ, например, alpine:3.17, вы просите его у зеркала, зеркало проверяет свой кэш. Если образ у него уже есть, отдаёт вам, если нет - качает и потом отдаёт вам.

Соответственно, чтоб зеркало могло само качать образы, его IP-адрес не должен быть в списках бана у Docker. Скорее всего, ему нужно находиться вне РФ, но не всегда. Проверить, что образы будут выкачиваться на виртуалке без установленного докера:

curl -I

403 - VPS не подходит

200 - подходит

Опишу самый простой вариант поднятия зеркала через compose.

Без аутентификации​

Своё "публичное" зеркало. Публичное зеркало могут использовать другие люди, если узнают о его существовании. В результате будет лишняя нагрузка на канал и занятое место на диске. Но плюс в том, что без аутентификации использовать зеркало намного проще.

А ограничить можно, например, на уровне firewall по подсетям.

Для подтягивания сертификатов Let’s Encrypt предлагаю traefik, весь его конфиг помещается в compose файл. Вся конфигурация registry хранится в одном файле и легко перетаскивается в случае чего.

$DOMAIN - домен для вашего зеркала. Не используйте IP-адрес. Без шифрования таскать образы через магистраль идея плохая. И ещё придётся подкручивать докер, чтоб не ругался.

$EMAIL - Для Let’s Encrypt. Отправляет письма с предупреждениями, не особо полезные.

services:
mirror:
container_name: "mirror"
image: registry:2.8.3
volumes:
- ./data/:/var/lib/registry
environment:
- REGISTRY_PROXY_REMOTEURL=
- REGISTRY_HTTP_ADDR=0.0.0.0:80
- REGISTRY_STORAGE_DELETE_ENABLED=true
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.mirror.rule=Host($DOMAIN)"
- "traefik.http.routers.mirror.entrypoints=websecure"
- "traefik.http.routers.mirror.tls.certresolver=myresolver"
- "traefik.http.services.mirror.loadbalancer.server.port=80"

traefik:
image: "traefik:v2.11.3"
container_name: "traefik"
command:
# - "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=с"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
restart: always

Прописываете А-запись для IP-адреса, помещаете compose-файл куда-нибудь на сервере. Затем docker compose up -d и всё, у вас есть своё "публичное" зеркало.

С аутентификацией​

То же самое, но используем Basic Auth. Аутентификация для зеркала таит свой подводный камень, про него будет далее в клиентах.

Registry сам умеет в Basic auth, но там нужно создавать htpasswd файл и, соответственно, отдельный bind/volume под него. Описываю самый простой вариант, поэтому за аутентификацию будет также отвечать traefik.

У traefik свой прикол: символы $ в хэше нужно экранировать ещё одним $.

Хэш для пароля генерируется стандартно

htpasswd -bBn user password

Либо

echo $(htpasswd -bBn user password) | sed -e s/\\$/\\$\\$/g

Полученный hash вставляется в label traefik.http.middlewares.mirror-auth.basicauth.users.
Можно задать несколько юзеров через запятую

services:
mirror:
container_name: "mirror"
image: registry:2.8.3
volumes:
- ./data:/var/lib/registry
- ./auth/:/auth
environment:
- REGISTRY_PROXY_REMOTEURL=
- REGISTRY_HTTP_ADDR=0.0.0.0:80
- REGISTRY_STORAGE_DELETE_ENABLED=true
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.mirror.rule=Host($DOMAIN)"
- "traefik.http.routers.mirror.entrypoints=websecure"
- "traefik.http.routers.mirror.tls.certresolver=myresolver"
- "traefik.http.services.mirror.loadbalancer.server.port=80"
- "traefik.http.routers.mirror.middlewares=mirror-auth"
- "traefik.http.middlewares.mirror-auth.basicauth.users=user:$$2y$$05$$D/a0AJqMRN/18eu9hD2Oxe5b9BJDgUvYaXQYSH.aQpjqhhYqswXPO"

traefik:
image: "traefik:v2.11.3"
container_name: "traefik"
command:
# - "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=$EMAIL"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
restart: always

Получили "приватное" зеркало на минималках.

Не забудьте, что место на диске рано или поздно может закончиться.

Периодически чистить слои без тегов можно так

docker exec mirror bin/registry garbage-collect /etc/docker/registry/config.yml -m

Использование зеркал на "клиентах"​

Если вы раньше не использовали зеркала, приготовьтесь к тому, что что-то может не заработать сразу или вообще не заработать. По моему опыту, не всегда всё получается с первого раза.

Linux​

Опять же простой сервер с докером. Без этих ваших кубернетусов.

Используем публичное зеркало​

Добавляете в файл ~/.docker/config.json. Возможно, его будет нужно создать.

"registry-mirrors": [
"https://$DOMAIN"
]

Если там ничего, нет кроме зеркала, то выглядит так:

{
"registry-mirrors": [
"https://$DOMAIN"
]
}

Рестарт докера

systemctl restart docker.service

Проверка, что зеркало подцепилось

docker info

В конце должно быть

Registry Mirrors:


Теперь при docker pull alpine сервис docker будет ходить в зеркало. Это можно отследить в логах поднятого ранее registry mirror.

На сервере зеркала можно также добавить в /etc/docker/daemon.json. Возможно, его будет нужно создать.

Используем приватное зеркало​

У зеркалом с аутентификацией всё немного (много) по-другому.

docker login $DOMAIN

Вводите логин и пароль. И он сам создаёт запись в ~/.docker/config.json.

Но при docker pull alpine качать он будет не с зеркала. Ха-ха. Думали всё так просто?

Но зато, если явно указать путь через зеркало docker pull my-mirror.com/library/alpine, он пойдёт просить образ у зеркала.

Проблема давняя, вот .

Есть workround, на ваш страх и риск. .

После

docker login mirror-example.com

в ~/.docker/config.json получаете такой json:

{
"auths": {
"mirror-example.com": {
"auth": "dXNlcjp1c2Vy"
}
}
}

Преобразуем. Нужно добавить ещё один registry с url и таким же паролем:

{
"auths": {
"mirror-example.com": {
"auth": "dXNlcjp1c2Vy"
},
" ": {
"auth": "dXNlcjp1c2Vy"
}
}
}

Docker Desktop. Windows, MacOS​

У Docker Desktop зеркало можно добавить через Settings - Docker engine. Синтаксис такой же.
Пример с публичным зеркалом:

{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"registry-mirrors": [
" "
]
}

registry-mirrors добавлено после существующих настроек.

На винде можно, не лазя в GUI, поправить файл C:\Users\$USER\.docker\daemon.json.

В MacOS вроде в ~/.docker/daemon.json.

Но нужны ли зеркала в Docker Desktop? Скорее нет, чем да.

2. Прокси​

Зеркала позволяют только пулить через себя. Просмотр образов, push и прочее через зеркало не сделаешь.

Но докер умеет ходить к своему же hub через прокси. Компания Docker продолжает:

Не осилил mirror? Пушить ещё надо? Ну вот через прокси тогда сходи, вот настройка. И пушить заодно сможешь ещё.

Linux​

Тут есть некоторая путаница. Для того чтобы пулить образы через прокси, нужно делать systemd службу, а не править ~/.docker/daemon.json.

Переменные в daemon.json применяются при сборке и в запущенных контейнерах. Они не используются для docker cli. В это прописано:

These settings are used to configure proxy environment variables for containers only, and not used as proxy settings for the Docker CLI or the Docker Engine itself.
Вам потребуется рабочий HTTP или SOCKS прокси. Продублирую :

Создаём каталог

sudo mkdir -p /etc/systemd/system/docker.service.d

Открываем /etc/systemd/system/docker.service.d/http-proxy.conf
и вставляем

[Service]
Environment="HTTP_PROXY= "
Environment="HTTPS_PROXY= "

Заставляем systemd найти новый сервис и рестартуем docker

sudo systemctl daemon-reload
sudo systemctl restart docker

Проверяем, что применилось. Должны показаться Environments

~> sudo systemctl show --property=Environment docker

Environment=HTTP_PROXY= HTTPS_PROXY=

Теперь docker pull выкачивает образ через прокси

~> docker pull alpine:3.16
3.16: Pulling from library/alpine
a88dc8b54e91: Pull complete
Digest: sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4
Status: Downloaded newer image for alpine:3.16
docker.io/library/alpine:3.16

Docker desktop​

Тут всё совсем просто.
Идём в Settings - Resourses - Proxies

m-zynlmlfjiwrkdpet6rwewblgi.png

И в HTTP и в HTTPS вставляем одно и то же значение.



Теперь и поиск работает

cthxfjmxkxiwruf2sr3shuyayqq.png

Откуда взять прокси​

Это уже другая тема, вкратце с чем у меня успешно завелось:

  1. от :
docker run --rm \
-p "3128:3128/tcp" \
-p "1080:1080/tcp" \
ghcr.io/tarampampam/3proxy:latest

Самый простой пример для тестов без аутентификации. Использовать недолго и с осторожностью.

  1. Прикручиваем логин и пароль, помещаем в compose
services:
3proxy:
image: "ghcr.io/tarampampam/3proxy:1.9.1"
container_name: "3proxy"
ports:
- "3128:3128"
- "1080:1080"
environment:
- PROXY_LOGIN=user
- PROXY_PASSWORD=password
restart: always

Теперь есть свои простые HTTP (3128 порт) и SOCKS (1080 порт) прокси.

С паролем переменные выглядят так

[Service]
Environment="HTTP_PROXY= "
Environment="HTTPS_PROXY= "

  1. Приложение Nekobox подключенное к серверу по Shadowsocks2022 (либо любые другие из семейства Xray). Обычный режим прокси, без tun и "системного прокси". По дефолту слушает порт 2080.
Вбиваем везде



gtluqfeerksmjli6kbhzmlzn81i.png

3. Роутеры, роутеры, роутеры​

Docker Hub не первый и не последний. Самое удобное для дома/офиса - это маршрутизация в туннель/прокси по доменам на роутере. Никаких клиентов на девайсах, всем занимается роутер.







 

Docker Hub убрал геоблокировку для российских пользователей.


Репозиторий Docker Hub убрал геоблокировку для пользователей из России. Как убедился «Ъ», по состоянию на 14:43 сайт по адресу открывается из России и полностью доступен.

KMO_178047_00018_1_t222_145815.jpg


Ранее репозиторий доступ для российских пользователей. Тогда при попытке зайти на сайт появлялось уведомление о том, что Docker является американской компанией и она должна подчиняться решениям властей страны. С такими же проблемами столкнулись и белорусские пользователи.

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


 
Сверху Снизу