Исправляем Разрешение Адресов В Vpn Lan (Openconnect) Для Docker И Systemd-Resolved

Для подключения к корпоративной сети мы используем 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. Это можно посмотреть командой:

  
  
  
   

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):

Когда запрос на разрешение имени поступает на адрес 127.0.0.53, с разрешением systemd выглядит поиск домена для каждого из подключений (эти домены он тоже получал от DHCP при подключении).

Домены можно просмотреть командой:

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

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.