Для подключения к корпоративной сети мы используем CiscoAnyConnect , работает хорошо, но не с докером.
Как только докер пытается поднять свою сеть, утилита тут же отрубает VPN и переподключается.
Это заставляет докера чувствовать себя плохо.
Поэтому я решил использовать обычный Linux открытое соединение вместе с Сетевой менеджер .
с разрешением systemd
Доставленные посылки сетевой менеджер-openconnect сетевой менеджер-openconnect-gnome Я настроил соединение и оно даже подключилось.Проблема первая, каждый раз, когда я подключался снова, он забывал имя пользователя, что раздражало.
Я нашел решение и создал ошибка.
Решение простое, из консоли задаем свое имя в специальной форме nmcli con mod prgcvp vpn.secrets 'form:main:username=yourName','save_passwords=yes' После чего это запомнится.
Да, я поставил галочку «запомнить пароль» и он даже пароль запомнил, но в тексте галочки ничего не говорилось об имени пользователя, так что он его, честно говоря, забыл :) Напомню, настройки менеджера находятся в /etc/NetworkManager/системные соединения/ .
А если знать параметры, то можно отредактировать нужное соединение вручную.
Подключаться стало удобно, но возникла вторая проблема: имена ресурсов в сети VPN не преобразуются сервером в DNS-адреса.
Сервер есть, все настройки на месте, но nslookup someserver.local выдает ошибку и nslookup someserver.local somednsIP будет отображен правильный ответ. Странно, подумал я, как это так, что сервер существует и отвечает, а если его конкретно не указать, то выходит ошибка? Ответ оказался простым.
Когда с разрешением systemd пытается найти адрес сервера по имени, он действует как фасад для других DNS-серверов.
Вот как это делается, ссылка /etc/resolv.conf может указывать на несколько мест:
- /run/systemd/resolve/stub-resolv.conf Это опция по умолчанию, и этот файл будет содержать что-то вроде этого сервер имен 127.0.0.53 параметры edns0 Trust-Ad поиск somedomain.local
- /run/systemd/resolve/resolv.conf это можно использовать, если функциональность с разрешением systemd Меня что-то не устраивает, когда он выдает себя за DNS-сервер 127.0.0.53. В итоге это оказалось бесполезно, поэтому пишу это для информации.
Сама ссылка /etc/resolv.conf вы можете сами настроить его так, чтобы он смотрелся в любом из мест. Итак, дело в том, что открытое соединение при подключении к VPN он получает таблицу маршрутов, DNS-сервер, а также поиск домена и этот домен с VPN-сервера был неверным (это мы его неправильно настроили).
Это пришло с сервера какой-тодомен.
локальный , но это было просто необходимо местный к somesrver.local был признан.
Когда с разрешением systemd выдавал себя за локальный DNS-сервер и через /etc/resolv.conf Он посылал всех к себе за разрешением имен, логика его работы следующая.
Для каждого соединения, которое можно просмотреть командой Показать соединение nmcli (это те связи, которые он знает Сетевой менеджер ) с разрешением systemd запоминает DNS-серверы, полученные через DHCP. Это можно посмотреть командой:
Когда запрос на разрешение имени поступает на адрес 127.0.0.53, с разрешением systemd выглядит поиск домена для каждого из подключений (эти домены он тоже получал от DHCP при подключении).resolvectl dns Global: Link 6 (docker0): Link 5 (vpn0): 999.999.999.999 999.999.999.999 Link 3 (wlp4s0): 192.168.3.8 Link 2 (enp5s0f2):
Домены можно просмотреть командой: resolvectl domain
Global:
Link 6 (docker0):
Link 5 (vpn0): somedomain.local
Link 3 (wlp4s0): ~.
Link 2 (enp5s0f2):
Далее имя хоста проверяется на частичное совпадение с теми доменами, которые привязаны к соединениям, и по самому длинному совпадению определяется, к какому конкретному DNS-серверу обращаться.
Или все идет на DNS-сервер, где поиск домена "~.
" Я получил неверное сообщение от сервера компании поиск домена ( какой-тодомен.
локальный ) для VPN-соединения и, следовательно, когда я пытался разрешить адрес Someserver.local , с разрешением systemd Я не смог их найти, так как предполагал, что DNS-серверы, полученные от этого соединения, нужны для распознавания имен someserver.somedomain.local .
Я исправил это, заменив поиск домена В Сетевой менеджер команда Соединение nmcli измените yourConnectionName ipv4.dns-search "local" Доменов может быть несколько, разделенных пробелом.
В конце концов все заработало.
Кроме того, я удалил пакет avahi-daemon, так как сервисы bonjur, которые этот демон обслуживает по умолчанию, также резолвятся в локальном домене, а в нашей сети это имя, которое используется для локальной сети и будут конфликты.
докер
Теперь разрешение адресов работает в хост-системе, но при запуске докера разрешение локальных адресов в VPN может работать не так, как раньше.И есть несколько вариантов.
Контейнер начался с сетевой_режим: хост в этом случае для разрешения будет использоваться то, что находится в /run/systemd/resolve/resolv.conf, а там у меня первый DNS-сервер выбран для локального разрешения и он для этого не подходит. В итоге это не работает. Но из контейнера видны все сервисы хост-машины, что тоже неправильно.
Контейнер начался с network_mode: мост с созданием отдельной сети.
В этом случае сервисы хоста не будут видны, кроме того будет использоваться тот же /run/systemd/resolve/resolv.conf, который у меня не работает Контейнер запускается без сетевых настроек и использует мост по умолчанию, созданный Docker при установке (docker0).
В данном случае для разрешения имен используется внутренний Docker DNS, который, судя по всему, нормально взаимодействует с systemd-resolved и разрешает все как надо.
В /etc/resolv.conf будет что-то вроде этого: bash-5.0# cat /etc/resolv.conf
search local
nameserver 127.0.0.11
options ndots:0
Если нужно показать сервисам хост-машины доступ из контейнера, то просто запускаем сервисы прослушивать IP docker0 и получаем доступ.
ifconfig|grep -n1 docker0
27-
28:docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
29- inet 192.168.32.1 netmask 255.255.240.0 broadcast 192.168.47.255
Не забудьте открыть порты, у меня например ufw убил 8080 и его пришлось открывать.
Было бы здорово, если бы докер просто использовал DNS-заглушку, разрешенную systemd, как всегда в последнем описанном варианте.
Но, к сожалению, это не так.
В версии systemd-resolved 248, которая только вышла и ее нет в дистрибутивах, в документации есть параметр DNSStubListenerExtra, которым можно задать адрес, по которому слушать заглушку.
Подробности здесь .
В результате можно будет указать адрес, где слушать, не жестко закодированный 127.0.0.53, а доступный изнутри Docker, и все заработает, но не сейчас.
Есть и другое решение: когда контейнер перейдет на 53 порт, мы будем передавать его запросы в заглушку systemd, используя что-то вроде socat UDP-LISTEN:53,fork,reuseaddr,bind=yourInterfaceIP UDP:127.0.0.53:53 Соответственно, этот DNS можно будет указать докеру при запуске и весь функционал systemd будет работать.
Но я им не воспользовался.
В результате мы получаем рабочий VPN на хосте, который резолвирует имена в локальной сети, рабочий докер, который умеет резолвить эти адреса как нативные.
Теги: #linux #docker #установка Linux #docker-compose #systemd-resolvd #networkmanager
-
Помогает Ли Контраст В Вашем Дизайне?
19 Oct, 24 -
Отказ От Почтовых Ящиков Для Работы С Почтой
19 Oct, 24 -
Proxmox 4. День Второй. Тонкий Lvm
19 Oct, 24 -
История Одного Неудачного Взлома
19 Oct, 24 -
Кроссплатформенность — Это Круто
19 Oct, 24 -
Современный Миф О Стабильности. Кризис.
19 Oct, 24