Moby: режим docker swarm: порты на 127.0.0.1 доступны для 0.0.0.0

Созданный на 2 апр. 2017  ·  53Комментарии  ·  Источник: moby/moby

Описание

В режиме docker swarm привязка порта к 127.0.0.1 приводит к тому, что порт также открывается на 0.0.0.0. Это может быть серьезной проблемой безопасности и должно быть объяснено в документации.

Шаги по воспроизведению проблемы:

  1. Создайте службу, например MongoDB, в файле docker-compose.swarm.yml и опубликуйте порт 27017 на localhost:
  mongodb:
    image: mongo:3.2
    volumes:
      - ./persistent-data/mongodb:/data
      - ./persistent-data/mongodb/db:/data/db
    networks:
      data:
        aliases:
          - mongo.docker
    logging:
      driver: syslog
      options:
        syslog-address: "udp://10.129.26.80:5514"
        tag: "docker[mongodb]"
    ports:
      - "127.0.0.1:27017:27017"
    deploy:
      placement:
        constraints: [node.labels.purpose == main-data]
  1. Разверните свой рой
  2. Проверьте, открыт ли порт извне вашего роя с помощью netcat

Опишите полученные результаты:

nc -vz PUBLIC_NODE_IP 27017
found 0 associations
found 1 connections:
[...]
Connection to PUBLIC_NODE_IP port 27017 [tcp/*] succeeded!

Опишите ожидаемые результаты:
Порт доступен только на 127.0.0.1, по крайней мере, на узлах роя, на которых запущена эта служба.

Дополнительная информация, которую вы считаете важной (например, проблема возникает только иногда):

Вывод docker version :

Docker version 17.03.1-ce, build c6d412e

Вывод docker info :

информация о докере для менеджера роя:

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 17.03.1-ce
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 3
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: active
 NodeID: pk7ulemi0z0chgtsg0azfrjz5
 Is Manager: true
 ClusterID: 27etomlyjvtmygrm6rcdgr2ni
 Managers: 1
 Nodes: 6
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Number of Old Snapshots to Retain: 0
  Heartbeat Tick: 1
  Election Tick: 3
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
 Node Address: 10.129.26.165
 Manager Addresses:
  10.129.26.165:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 4ab9917febca54791c5f071a9d1f404867857fcc
runc version: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe
init version: 949e6fa
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.4.0-64-generic
Operating System: Ubuntu 16.04.2 LTS
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 992.4 MiB
Name: <HIDDEN>
ID: IMOK:QIR7:WU5Y:WTPP:EPRQ:F77G:ULGE:WOG4:O7S7:6AFE:V7QG:2XEK
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: <HIDDEN>
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

Дополнительные сведения о среде (AWS, VirtualBox, физическая и т. Д.):
Протестировано на каплях Digital Ocean.

areswarm kinbug

Самый полезный комментарий

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

Все 53 Комментарий

Да, это должно привести к ошибке; службы (по умолчанию) «публикуют», используя «входящую» сеть, и не поддерживают указание IP-адреса, так как невозможно предсказать, на каком _node_ они окажутся (таким образом, неизвестно, какие IP-адреса доступны, хотя 127.0 .0.1 может быть возможно). Эта проблема связана с отслеживанием этой функции https://github.com/docker/docker/issues/26696 (и этот «эпический» трек отслеживает другие параметры, которые (пока) не поддерживаются службами https://github.com/docker/docker/issues / 25303)

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

version: "3.2"
services:
  mongodb:
    image: nginx:alpine
    ports:
      - "127.0.0.1:27017:80"

пинг @dnephin @vdemeester

@ fer2d2 В режиме роя, если вы публикуете что-либо ( ports для stack deploy ), оно публикуется в сети ingress и, следовательно, становится общедоступным. Есть несколько способов обойти это ограничение, но добавление kind/bug к этому, потому что мы должны по крайней мере предупреждать людей об этом при выполнении stack deploy с портами, имеющими эту нотацию (например, host:port:port ).

Чтобы обойти это, есть несколько способов:

  • Во-первых, вы должны публиковать порты mongo только в том случае, если хотите, чтобы они были общедоступными , в противном случае он доступен через пакет обнаружения имен в докере (другой контейнер / служба в той же сети сможет получить доступ к нему через mongo имя
  • Если вы хотите опубликовать его на хосте, а не в ingress (то есть не в рое публично, а только на хосте, на котором он запущен, так же, как и без режима роя), вам необходимо использовать расширенный синтаксис портов .
    ports:
      - mode: host
        target: 80
        published: 9005

Он будет делать то же самое, что и docker run -p 80:9005 … поэтому он привяжет его к 0.0.0.0 , но ограничен узлом.

Но, как сказал @thaJeztah : «Ошибка в том, что докер должен выдавать ошибку, вместо того, чтобы молча игнорировать этот параметр» 👼

/ cc @mavenugo @aboch, чтобы узнать, есть ли способ привязать его к конкретному IP-адресу? (действительно сложно добиться, потому что IP-адрес узла будет другим, поэтому ..)

@vdemeester Могу ли я указать localhost в качестве целевого хоста, используя эту нотацию?

    ports:
      - mode: host
        target: 127.0.0.1:80
        published: 9005

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

заранее спасибо

Кажется, что и целевой, и опубликованный используются как целочисленный тип в длинном синтаксисе

Я думаю, что это нежелательное поведение, если вы подключаетесь к некоторым службам через туннели SSH. Например, если вы хотите иметь сервер MySQL или MongoDB на 127.0.0.1 и подключаться через туннель SSH, с Docker Swarm вы должны открыть порт базы данных на 0.0.0.0 или создать собственный контейнер базы данных с SSH, работающим внутри (и оба варианта очень небезопасны).

Существует множество клиентов баз данных, использующих туннели SSH, например SQL Workbench или Robomongo, которые нельзя использовать из-за этого ограничения (специфическая привязка интерфейса).

У нас в компании та же проблема, что и у @ fer2d2 , при попытке подключить Mongobooster к рою докеров через туннель ssh. Единственное решение, которое мы нашли, - открыть порт 27017 и защитить базу данных с помощью пользователя и пароля.

Любые новости?

+1

+1

Другой вариант использования для разрешения пары ip_address : port для сопоставления портов длинной формы - для адресов anycast или любых других адресов, которые могут быть связаны с loopback. Они будут похожи на адрес 127.0.0.1 в том смысле, что они видны только в кольцевой сети. Служба, ограниченная узлами с этим свойством, может захотеть открыть порт только на произвольном адресе, чтобы избежать конфликтов портов, избегая правил iptables для трансляции портов.

Может ли это быть вариантом, если вы укажете:

placement:
        constraints:
          - node.id ==

Ура

+1

+1

+1

для себя я решил эту проблему так:

iptables -I DOCKER-USER -i eth0 -j DROP
iptables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT

Докер эти правила не трогает. просто добавляет свой
-A DOCKER-USER -j RETURN
В результате, хотя порт прослушивает 0.0.0.0, но недоступен из внешнего интерфейса eth0

Такое поведение нарушает «безопасность по умолчанию», и добавления заметки в документах будет недостаточно. А пока это должно вызвать ошибку.

Это также связано с режимом: ingress / host (эти два вопроса, кажется, путают в обсуждении). В режиме входа нет ничего, что могло бы помешать привязке службы к локальным адресам на всех узлах, но не к внешним адресам. Следовательно, 127.xxx должно быть разрешено. (в режиме без роя (с использованием docker run) я привязываюсь к 127.0.0.2:80 и 127.0.0.3:80 и т. д. Для тестирования нескольких серверов локально в разработке.).

Другая проблема заключается в том, что по умолчанию используется входной режим. Это неожиданно и также приводит к проблемам с безопасностью. Я просто попытался запустить службу на узле, который должен находиться в частной части сети, с портом, привязанным к 127.0.0.3:80. Затем он также был привязан к общедоступному интерфейсу общедоступного узла. (То есть молча игнорирует IP-адрес и молча использует входной режим, и мои данные становятся общедоступными).

Случаи использования

  • Примеры использования, которые меня впечатлили (определенно реальные)

    • 1 Привязать к порту определенного узла, потому что порт используется на других узлах. Вы можете использовать для этого режим хоста, но значение по умолчанию - сюрприз.

    • 2 Привязать к порту определенного узла, потому что другие узлы имеют общедоступные интерфейсы. Вы можете использовать для этого режим хоста, но по умолчанию это нарушает «безопасный по умолчанию» .

    • 3 Свяжите локально, потому что вы не хотите, чтобы он был видимым для других хостов, по умолчанию нарушается «безопасный по умолчанию»

    • 4 Выполните привязку к 127.0.0.3, потому что на вашей машине разработки много чего, и 127.0.0.1 используется этим портом. И используйте /etc/hosts , чтобы каждое доменное имя отправлялось в другой контейнер. Это работает с docker run , но не с compose.

  • Другие варианты использования

    • Привяжите к определенному интерфейсу, например 192.168.0.x, потому что это внутренняя сеть. по умолчанию нарушает «безопасность по умолчанию»

    • Привязать к конкретному конкретному узлу, но не ограничивать выполнение службы на этом узле. Это тот же вариант использования, что и 1 или 2, но без использования ограничений. Трафик будет проходить через рой.

Итак, в итоге

  • Игнорирование IP-адреса и привязка к 0.0.0.0, а также входящий режим по умолчанию являются нарушением «безопасности по умолчанию». Ошибки должны выдаваться, если IP-адрес указан, а документы обновлены. Ошибка должна быть выдана, если режим не указан (не по умолчанию) и документы обновлены. (это решает проблему режима и предотвращает неожиданные проблемы с безопасностью.)
  • Затем можно добавить поддержку IP-адресов в режиме хоста.
  • Можно добавить поддержку IP-адресов во входящем режиме, который ограничен локальными адресами 127.xxx. (разные локальные адреса, например 127.0.0.2 и 127.0.0.3, должны рассматриваться как разные (только что переданные в ОС)).

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

@ richard-delorenzi Moby в настоящее время даже не принимает IP-адрес хоста. Таким образом, вне запроса функции это звучит как проблема на стороне клиента ... в частности, как compose yaml переводится в Docker CLI.

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

+1

+1

+1

У меня есть своего рода обходной путь, который я использую. Я запускаю автономные контейнеры и подключаю их к сети с именем core, которая используется всеми нашими внутренними службами (mongo, elasticsearch, infxdb и т. Д.), Которые работают внутри роя.

Я не вижу, как это сделать в файле набора, поэтому мы просто запускаем автономные контейнеры, например:

docker run --name kibana --rm -d -v /var/lib/kibana:/usr/share/kibana/config -p 127.0.0.1:5601:5601 --network core docker.elastic.co/kibana/kibana:6.1.2

docker run --name chronograf --rm -d -v /var/lib/chronograf:/var/lib/chronograf -p 127.0.0.1:8888:8888 --network core chronograf:1.4 chronograf --influxdb-url=http://influxdb:8086

После их запуска docker ps показывает, что новые контейнеры привязаны к 127.0.0.1. Аминь. Затем я могу подключиться к хосту докеров с моей локальной рабочей станции для безопасного доступа, например:

ssh -i my_ssh_key.pem [email protected]  -L 8888:localhost:8888  -L 5601:localhost:5601 -N

Затем из моего браузера я могу подключиться к http: // localhost : 8888 или http: // localhost : 5601

Работает на меня.

В случае, если сокет UNIX может заменить сокет 127.0.0.1 TCP / IP, возможный обходной путь, который я реализовал для fluent-bit, доступен здесь

Может быть, добавление еще одной опции в mode может помочь. Что-то вроде local в дополнение к host и ingress .

Удалите формулировку «Полезная безопасность: Moby обеспечивает безопасные настройки по умолчанию без ущерба для удобства использования». в файле readme moby . Это определенно ложная реклама, см. Комментарий @ richard-delorenzi.

По умолчанию службы не публикуют порты, поэтому будут недоступны, если вы не укажете, что они должны публиковать порт. Привязка к конкретному IP-адресу в настоящее время не поддерживается; если ваша служба не должна быть доступна, не публикуйте порты и подключайтесь к службе через внутреннюю (оверлейную) сеть.

Добавление поддержки привязки к IP-адресу обсуждается в https://github.com/moby/moby/issues/26696 , но нетривиально реализовать (с учетом IP-адресов, отличных от "localhost")

Добавлено предупреждение при развертывании стека;

docker stack deploy -c- test <<'EOF'
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "127.0.0.1:8080:80"
EOF

WARN[0000] ignoring IP-address (127.0.0.1:8080:80/tcp) service will listen on '0.0.0.0' 
Creating network test_default
Creating service test_web

А при попытке развернуть сервис с указанным IP-адресом он не будет развернут с ошибкой;

docker service create -p 127.0.0.1:9090:80 nginx:alpine
invalid argument "127.0.0.1:9090:80" for "-p, --publish" flag: hostip is not supported
See 'docker service create --help'.

@dalu, если ваша система

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

@ cpuguy83

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

Нет. Почему он должен быть общедоступным, если кто-то привяжет его к непубличному ip, например 127.0.0.1 или 10.0.0.0? Собственно, это правильный ответ:

Привязка к конкретному IP-адресу в настоящее время не поддерживается

@dalu

Но он должен быть доступен, но не публично. И в этом все дело.
По умолчанию вы небезопасны и избегаете исправления с помощью семантики.
Вопрос не решен уже почти 2 года.

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

@Bessonv Он

Проблема в том, что формат compose разработан для dev envs и был продвинут для поддержки развертывания кластера. "docker stack" должен просто выйти из строя, но тогда люди хотят иметь возможность использовать один составной файл, чтобы управлять ими всеми, и вот здесь беспорядок.

@ cpuguy83
Я не уверен, что меня устраивает это описание. В конце формат компоновки - это просто описание желаемого состояния. Совершенно нормально иметь некоторые различия между одной машиной (составить) и кластером (роем). С моей точки зрения, вообще нет смысла поддерживать compose. Тем более, что активировать режим роя так просто. Но это требует исправления роя.

Проблема вовсе не в рое и 100% в формате compose + реализация в docker cli.
Обратите внимание, что в настоящее время стеки на 100% являются реализацией на стороне клиента.

Мы обнаружили, что внутри стека вам не нужно явно открывать какие-либо порты для внутренних служб, таких как база данных, redis и т. Д. Просто пропустите конфигурацию ports внутренней службы и ссылку по имени отлично работает .

Пример службы БД внутри стека

services:
  db:
    image: postgres:11-alpine
  networks:
    - backend

... может использоваться службой Django app по умолчанию следующим образом:

DATABASES = {
    'default': env.db(default='postgres://user:pass<strong i="13">@db</strong>:5432/catalog'),
}

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

Проблема вовсе не в рое и 100% в формате compose + реализация в docker cli.
Обратите внимание, что в настоящее время стеки на 100% являются реализацией на стороне клиента.

Как бы то ни было: я перестал использовать стек (из-за этой проблемы), и мне все равно. Винить библиотеку, винить докера, винить мою кошку.

Я не видел этой проблемы при прямом использовании docker или при использовании compose.

Похоже, этот подход может помочь (должен выполняться на каждом узле в рое):

  1. покинуть рой
  2. удалить сеть docker_gwbridge
  3. воссоздать сеть docker_gwbridge с дополнительной опцией com.docker.network.bridge.host_binding_ipv4 = IP
  4. присоединиться к рой назад
    Работает для портов, опубликованных в режиме "host". Без режима «хост» входящая сеть используется с другим драйвером и областью «рой».

Ужасное решение:

$ mv /usr/bin/docker-proxy /usr/bin/docker-proxy-original
$ cat << 'EOF' > /usr/bin/docker-proxy
#!/bin/sh
exec /usr/bin/docker-proxy-original `echo $* | sed s/0.0.0.0/127.0.0.1/g`
EOF
$ chmod 755 /usr/bin/docker-proxy
$ service docker restart

@jsmouret Я даже не могу найти докер-прокси в последней версии докера. Это какое-то наследие? Или название другое?

Похоже, это зависит ...

$ apt-file search docker-proxy
docker-ce: /usr/bin/docker-proxy
docker.io: /usr/sbin/docker-proxy

Это поведение должно быть как-то задокументировано в документации .
В настоящее время он просто игнорирует хост из краткого сопоставления портов. И тихо не работает.

Еще одна странность заключается в том, что вы не можете установить хост в длинной синтаксической схеме.

Это поведение следует как-то задокументировать в документации.

Я согласен; Я думал, что это упоминалось где-то на той странице, но не могу найти; не стесняйтесь открывать вопрос в репозитории документации; https://github.com/docker/docker.github.io/issues

В настоящее время он просто игнорирует хост из краткого сопоставления портов. И тихо не работает.

какую версию докера вы используете? он должен вывести предупреждение (при использовании docker stack deploy ) или _error_ (при использовании docker service create ); см. https://github.com/moby/moby/issues/32299#issuecomment -472793444

какую версию докера вы используете? он должен распечатать предупреждение (при использовании docker stack deploy) или ошибку (при использовании docker service create);

Ух, похоже, это моя вина. Это действительно так, когда я пытался развернуть стек с консоли.
Раньше я делал это через пользовательский интерфейс portainer, и он не отображал никаких ошибок или предупреждений.

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

Работоспособное, чистое решение - это запуск SSH-сервера во втором контейнере, который подключен к той же сети докеров, что и ваша база данных. Затем порт SSH может быть опубликован на хосте (конечно, на порт, отличный от 22), так что вы можете перенаправить через контейнер SSH в свою базу данных.

@nartamonov Я не понимаю, как это можно сделать безопасно от входа, если сам протокол не является безопасным.
Безопасный доступ к нему будет через плоскость зашифрованных данных ( --opt encrypted для чрезмерных сетей) и развернуть контейнер с любыми инструментами, которые вам нужны, подключенными к этой сети.

Это, вероятно, имеет другие побочные эффекты, не связанные с этим, но установка "iptables": false в /etc/docker/daemon.json дает обходной путь. Менее радикальное решение - добавить только настраиваемое правило, подобное предложению @helldweller .

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

Похоже, этот подход может помочь (должен выполняться на каждом узле в рое):

1. leave swarm

2. remove network docker_gwbridge

3. recreate network docker_gwbridge with additional option com.docker.network.bridge.host_binding_ipv4=IP

4. join swarm back
   Works for ports published in mode "host". Without mode "host" ingress network is used with other driver and scope "swarm".

@ienovytskyi
Если я не ошибаюсь, при этом все опубликованные порты привязываются к заданному адресу по умолчанию IP ? Чтобы быть ясным, это не годный обходной путь, если вы хотите ограничить привязанный интерфейс только для некоторых портов некоторых служб.

Я хочу сообщить о своем обходном пути.

Пример использования:
Некоторые службы в рое должны прослушивать все интерфейсы или, по крайней мере, общедоступный интерфейс - этот контейнер в моем примере является обратным прокси.
В этих узлах роя также есть экземпляр базы данных на каждом узле, они используют сеть роя, определенную как:

docker network create --scope swarm NETWORK_NAME --attachable -d overlay

Веб-сервисы, которым нужны соединения с базой данных, конечно, должны быть присоединены к этому NETWORK_NAME

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

Решение:
Только сервисы, которые должны быть доступны во всех сетях (обратные прокси в моем примере), могут иметь ports: ['SOMEPORT:ANOTHERPORT'] в определении своих сервисов.

Все остальные службы должны иметь на хосте парный докер-контейнер без роя.
Этот контейнер без роя соединит порт, присутствующий на NETWORK_NAME/nodeXYZ:port с localhost

Пример с mongodb:

docker run --rm -it --net=NETWORK_NAME -d --name expose-mongo -p 127.0.0.1:27017:47017 alpine/socat tcp-listen:47017,fork,reuseaddr tcp-connect:mongo01:27017

Оборотная сторона: для каждого узла роя должен быть контейнер без роя, поэтому со многими нодами это действительно скучно, если не использовать ansible / тяжелые скрипты

Мое решение проблемы «если вы подключаетесь к некоторым службам через туннели SSH», о которой упоминал

FROM alpine

RUN apk add --no-cache openssh
RUN mkdir ~/.ssh
RUN ssh-keygen -A
RUN echo "root:root" | chpasswd
RUN echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config
RUN echo 'Port 22' >> /etc/ssh/sshd_config
RUN echo -e " \
Match User root \n\
  AllowTcpForwarding yes\n\
  X11Forwarding no\n\
  AllowAgentForwarding no\n\
  ForceCommand /bin/false\n\
" >> /etc/ssh/sshd_config

EXPOSE 22
CMD /usr/sbin/sshd -D -e "$@"

Затем в docker-compose.yml:

...
  db:
    image: mysql:5.6
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?err}
      MYSQL_ROOT_HOST: '%'
    volumes:
      - "./mysql:/var/lib/mysql"
    deploy:
      placement:
        constraints: [node.role == manager]

  sshd:
    image: maxisme/sshd:latest
    volumes:
      - "~/.ssh:/root/.ssh"
    ports:
      - "2223:22"
    deploy:
      placement:
        constraints: [node.role == manager]

что позволяет мне добавить мои authorized_keys в папку ~/.ssh а затем прокси-сервер ssh перескочит через порт 2223 в мою базу данных, используя имя хоста db .

Работоспособное, чистое решение - это запуск SSH-сервера во втором контейнере, который подключен к той же сети докеров, что и ваша база данных. Затем порт SSH может быть опубликован на хосте (конечно, на порт, отличный от 22), так что вы можете перенаправить через контейнер SSH в свою базу данных.

действительный

еще один пример, почему эта функция важна.
У меня есть сервер с установленным plesk, у plesk уже есть его конфигурации, но я могу добавить еще одну конфигурацию, чтобы указать на службу docker swarm. Этот сервер plesk является узлом роя.
Я хочу использовать plesk для proxy_pass на порт. Этот порт следует опубликовать, потому что контейнер находится в оверлейной сети, но ему нужен внешний порт для связи с миром.

Таким образом, proxypass должен указывать на локальный интерфейс, например 127.0.0.1: someport
а контейнер в рое должен публиковать порт только для localhost.

Таким образом, порт контейнера доступен только прокси-серверу, а не напрямую из мира.

Мне нравится ваш обходной путь @maxisme , но как вы управляете владением authorized_keys ? В OS X это работает для меня (монтирование принадлежит root ), но на производственной машине Linux я получаю:

Authentication refused: bad ownership or modes for file /root/.ssh/authorized_keys
Connection closed by authenticating user root 85.145.195.174 port 60535 [preauth]

Том принадлежит UID пользователя хоста, который не равен root и SSHD отказывается с ним работать. Обходной путь поверх вашего обходного пути 😬 - использовать configs , например:

services:
  sshd:
    image: [...]/sshd:${version}
    configs:
      # FIXME: It would be much better to use a bind volume for this, as it
      # would always be in sync with the host configuration. So revoking a key
      # in the host machine would automatically revoke it in the container. But
      # I can't figure out how to give the volume right ownership. It keeps UID
      # from the host which doesn't align with the container user.
      - source: authorized_keys
        target: /root/.ssh/authorized_keys
        mode: 0600

configs:
  authorized_keys:
    file: ~/.ssh/authorized_keys

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

Однако часто хосты имеют, например, северные и южные интерфейсы. Вы можете захотеть, чтобы порты роя связывались только с интерфейсами северного направления на всех хостах роя.

Если имена интерфейсов для всех интерфейсов, к которым вы хотите привязать службу, одинаковы (например, eth0), можно было бы предложить возможность указать имя интерфейса для привязки портов роя (в разделе портов службы).

    nginx:
      image: nvbeta/swarm_nginx
      networks:
        - demonet1
      ports:
        - "eth0:8088:80"

Когда eth0 недоступен на узле роя, указанный порт не будет привязан ни к какому интерфейсу.

@ tad-lispy У вас должна быть возможность изменить uid и gid пользователя контейнера, чтобы они совпадали с владельцем тома на хосте.
Образ linuxserver поддерживает это путем установки переменных среды (см. Https://hub.docker.com/r/linuxserver/openssh-server, User / Group Identifiers ),

Была ли эта страница полезной?
0 / 5 - 0 рейтинги