Bug 20345 - не получается использовать nameserver 127.*
Summary: не получается использовать nameserver 127.*
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: openresolv (show other bugs)
Version: unstable
Hardware: all Linux
: P3 normal
Assignee: Mikhail Efremov
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-06 02:55 MSD by Denis Ovsienko
Modified: 2009-06-12 13:39 MSD (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Denis Ovsienko 2009-06-06 02:55:18 MSD
Исходная ситуация. Имеется ноутбук с системой Desktop 4.1, который перемещается между двумя беспроводными сетями, рабочей и домашней. Обе сети используют WPA и DHCP, но есть ньюанс. В рабочей сети DHCP-сервер нормальный, а в домашней --- пластмассовый маршрутизатор. В результате, если не прикладывать дополнительных усилий, при получении адреса в домашней сети в /etc/resolv.conf оказывается строчка "nameserver" (без IP-адреса).

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

Второе движение --- введение домашнего профиля, для которого существует файл resolv.conf#home, в котором прописано "nameserver 127.0.0.1". В файле options#home имеется DHCP_ARGS='-R'. В результате на работе в /etc/resolv.conf присутствуют рабочие NS, а дома --- 127.0.0.1. То есть теперь всё нормально.

Третье движение --- переезд ноутбука на Sisyphus, а etcnet --- на openresolv. На работе /etc/resolv.conf продолжает получаться рабочим, а дома опять становится пустым. В нём единственная строчка -- комментарий от openresolv.

Разбирательство показывает следующее. Если скрипту resolvconf скормить файл со строкой "nameserver 127.0.0.1", то хотя содержимое файла и попадёт в рабочий пул openresolv, строчка использована не будет:

[root@dhcppc0 ~]# resolvconf -i
wifi 
[root@dhcppc0 ~]# resolvconf -l
# resolv.conf from wifi
# plumb
nameserver 127.0.0.1

[root@dhcppc0 ~]# resolvconf -v
DOMAINS=''
SEARCH=''
NAMESERVERS=''

Это происходит потому, что /sbin/resolvconf:parse_resolv() фильтрует такие строки по IP-адресу:

		"nameserver "*)
			case "${line#* }" in
			127.*|0.0.0.0|255.255.255.255) continue;;

Можно ещё понять, зачем это делается для скриптов-подписчиков dnsmasq и named, но для скрипта libc я пока вижу только негативный эффект. Предлагается аккуратно убрать фильтрацию "127.*".
Comment 1 Mikhail Efremov 2009-06-08 03:56:12 MSD
(In reply to comment #0)
> Можно ещё понять, зачем это делается для скриптов-подписчиков dnsmasq и named,
> но для скрипта libc я пока вижу только негативный эффект. Предлагается
> аккуратно убрать фильтрацию "127.*".

Логика в таком поведении есть. Openresolv предлагает добавлять 127.0.0.1 в свой файл конфигурации resolvconf.conf. При этом 127.0.0.1 всегда будет первой строчкой в resolv.conf. Но с профилями действительно получается проблема, предлагать подменять resolvconf.conf в зависимости от профиля даже предлагать не буду, мне самому такой вариант не нравится. Самым логичным пожалуй будет разрешить добавлять 127.0.0.1 от имени интерфейса lo, тогда можно будет и профили использовать, и логика работы openresolv сохранится. Ведь etcnet нормально отработает, если положить соответсвующий resolv.conf в /etc/net/ifaces/lo?
Comment 2 Mikhail Efremov 2009-06-08 19:26:25 MSD
Разрешил добавлять 127.0.0.1 от интерфейса 'lo'. В этом случае запускается только подписчик libc.
Вообще там несколько странная логика. Интерфейс с именем 'lo' имеет наибольший приоритет (nameserver от него всегда подставляется в начало /etc/resolv.conf), выше только то, что прописано в resolvconf.conf. Но при этом добавлять 127.0.0.1 было нельзя. Я вот не понимаю, что еще может приехать от lo? Т.к. я думаю, что добавление от имени lo чего-либо иного лишено смысла, то убрал запуск скриптов-подписчиков dnsmasq и named для lo.
Таким образом для использования в профилях 127.0.0.1 предлагается класть соответствующий resolv.conf в /etc/net/ifaces/lo. Насколько я вижу это работает. Если нет возражений против такой схемы отправлю в Сизиф.
P.S.
http://git.altlinux.org/people/sem/packages/?p=openresolv.git;a=commitdiff;h=46cef0aab3d1c1c65146d303e342d6ec0330e928
Comment 3 Denis Ovsienko 2009-06-08 21:45:10 MSD
resolv.conf в ifaces/lo класть можно, обработается.

Касательно "странной" логики: на loopback может оказаться любой адрес, в первую очередь тот, который административно назначем "вечноживым". Отсюда его наивысший приоритет в понимании openresolv. Как будто бы резон есть. Но с другой стороны это действительно странный резон. Свежие данные от приходящих и уходящих интерфейсов не всегда правильны, поэтому их нужно фильтровать. Понятно, что loopback-адрес никуда не денется, его версия resolv.conf стабильна и скорее всего присутствует всё время жизни системы. Если версия loopback всегда будет побеждать результат фильтрации, то на выходе алгоритма осмысленность содержимого resolv.conf никогда не повысится. И вообще, нет смысла фильтровать данные, которые заведомо будут отброшены.

Таким образом, думаю, что для выбора конфигурации резолвера версия loopback-интерфейса, если она имеется, должна иметь наинизший приоритет (или наивысшую метрику в системе координат openresolv). При этом появляющиеся позже и прошедшие отбор версии будут немедленно вытеснять умолчательное значение. Если администратор обнаружит, что свежая информация не является корректной, он сможет подавить её обработку для интерфейса (навсегда или только в части профилей) через options-файл.

Есть важный момент, который в дизайне openresolv никак не отражён. Нет смысла забивать в resolvconf.conf nameserver 127.0.0.1, чтобы он попадал в первую строчку /etc/resolv.conf. Более актуальные, но короткоживущие данные должны не выступать страховкой для "вечноживого" неизменного варианта, но заменять его целиком на время своей жизни (актуальности). При этом степенью актуальности данных выступает не IP-адрес nameserver, а метрика интерфейса, явная или производная из его имени. То есть имеет право на жизнь вариант, когда в lo/resolv.conf будет записано "nameserver 10.10.10.10", а в wifi/resolv.conf будет записано "nameserver 127.0.0.1", и при этом при запуске wifi в самом деле будет использоваться 127.0.0.1. Если администратор считает именно такое поведение правильным, не нужно его ограничивать технически. То есть 127.0.0.1 нужно принимать от всех интерфейсов, а не только от lo.

Также я думаю, что в первую очередь нужно обеспечить толковую работу сабскрайбера libc, а остальные чинить, только если от них нельзя избавиться. Но время покажет.
Comment 4 Mikhail Efremov 2009-06-09 03:36:52 MSD
(In reply to comment #3)
> Касательно "странной" логики: на loopback может оказаться любой адрес, в первую
> очередь тот, который административно назначем "вечноживым". Отсюда его
> наивысший приоритет в понимании openresolv.

Ну, то, что технически на loopback можно назначить любой адрес - это понятно. Я просто не думал, что в реальной жизни используется что-то, кроме 127.0.0.1. Значит нельзя предполагать, что с lo добавляется только 127.0.0.1. Видимо отфильтровывать 127.0.0.1 придется в самих подписчиках.

> Если версия loopback
> всегда будет побеждать результат фильтрации, то на выходе алгоритма
> осмысленность содержимого resolv.conf никогда не повысится. И вообще, нет
> смысла фильтровать данные, которые заведомо будут отброшены.

Не согласен. Как раз такое поведение, когда первой строкой всегда стоит loopback адрес - в большинстве случаев именно то, что нужно. Мне почему-то думается, что если уж используется локальный резолвер - он и должен всегда использоваться по-умолчанию. Я не вижу особого смысла в его использовании, если это не так. Данные же от других источников не отбрасываются, они используются для обновления конфигурации локального резолвера, чем и занимаются скрипты-подписчики bind'а и dnsmasq.

> Есть важный момент, который в дизайне openresolv никак не отражён. Нет смысла
> забивать в resolvconf.conf nameserver 127.0.0.1, чтобы он попадал в первую
> строчку /etc/resolv.conf. Более актуальные, но короткоживущие данные должны не
> выступать страховкой для "вечноживого" неизменного варианта, но заменять его
> целиком на время своей жизни (актуальности). 

Наоборот, на сервере, обслуживающем домен в локальной сети и являющемся одновременно openvpn-клиентом (к примеру), вряд ли имеет смысл, что приехавший от openvpn-сервера nameserver попадет в первую строчку resolv.conf. Но вот прописать его для bind'a в forwarders вполне можно, что и делает openresolv по-умолчанию.

> При этом степенью актуальности
> данных выступает не IP-адрес nameserver, а метрика интерфейса, явная или
> производная из его имени. То есть имеет право на жизнь вариант, когда в
> lo/resolv.conf будет записано "nameserver 10.10.10.10", а в wifi/resolv.conf
> будет записано "nameserver 127.0.0.1", и при этом при запуске wifi в самом деле
> будет использоваться 127.0.0.1. Если администратор считает именно такое
> поведение правильным, не нужно его ограничивать технически. То есть 127.0.0.1
> нужно принимать от всех интерфейсов, а не только от lo.

Задав свои значения interface_order и dynamic_order в resolvconf.conf легко можно добиться описанного поведения (при условии, что разрешено принимать 127.0.0.1 от любого интерфейса, конечно). Но поведение по-умолчанию, думаю, следует оставить как есть.

Таким образом, резюме: разрешить принимать 127.0.0.1 от любого интерфейса и отфильтровывать 127.0.0.1 в самих скриптах-подписчиках. Видимо так.
Я вот только не соображу, есть ли все-таки смысл запускать скрипты-подписчики, помимо libc, для loopback интерфейса?
Comment 5 Denis Ovsienko 2009-06-09 13:41:36 MSD
Я позволю себе подсказать, почему не сообразите. Дизайн openresolv (по крайней мере, того openresolv, который используется в Sisyphus) как таковой не существует, это фикция. Этот скрипт неплохо выглядит на бумаге, но при реальном использовании выясняется, что решаемые им задачки составляют ограниченный подкласс фактически возникающих задач. Это не ваша проблема и не моя, но, использовав этот скрипт, мы проблему скрипта сделали своей личной и навязали другим пользователям. Теперь нужно её решать.

Чтобы из этого предприятия вышел толк, не хватает двух главных вещей. Во-первых, нужно определиться, какая одна задача решается в первую очередь. На мой взгляд, это конфигурация glibc-резолвера (в Debian, похоже, только этим и ограничились). Как только на хосте окажется правильно сформирован /etc/resolv.conf, хост сможет его содержимым накормить всех своих клиентов с помощью dnsmasq. Лишнее движение в виде subscriber-скрипта dnsmasq ничего не улучшает, но создаёт дополнительную почву для возникновения ошибки. Лишнее лучше отбросить.

Во-вторых, чтобы действовать, нужно принимать решения, а чтобы принимать решения, нужна система приоритетов. У openresolv только одна надёжная система приоритетов --- сравнение числовых метрик. Списки interface_order и dynamic_order никак не связаны с фактическим набором интерфейсов на каждом взятом хосте (да и вообще ни с чем не связаны, кроме lo). Решать по IP-адресу нельзя. Выходит, что надёжно работающее решение должно принимать в расчёт только метрики. Таким образом оно станет детерминированным, то есть для известного набора входных данных принятое решение будет всегда постоянным и предсказуемым. Но у администратора должен быть способ влиять на происходящее, значит, этим средством будет задание метрик.

Выше я уже показал, какую пользу приносит "наихудшая" метрика для lo. Установка её в "наилучшее" значение (как вы предложили) равносильно фиксации содержимого /etc/resolv.conf и отключению openresolv вообще, по крайней мере, до тех пор, пока работают серверы, предложенные интерфейсом lo. С большой вероятностью это одна запись 127.0.0.1. Я предвижу контрдовод, что может случиться так, что "наилучшие" серверы перестанут отвечать, тогда "менее хорошие" выступят в качестве запасных. Отвечу, что не следует строить систему с расчётом на это.

Конкуренции между nameservers внутри одного финального файла /etc/resolv.conf необходимо избегать. Во-первых, список NS ограничен тремя записями. Во-вторых, этот список обрабатывается в порядке 1-2-3-1-2-3-1-2-3-... до исчерпания числа попыток. В-третьих, при включенной "options rotate" визуальный порядок строк немедленно потеряет своё фактическое значение. Поэтому конкуренция должна происходить не между серверами, а между группами серверов. Серверы внутри отдельно взятой группы должны рассматриваться как равнозначные и обеспечивающие доступ к одним и тем же данным. Это один из основных принципов работы DNS. Группа серверов, которая не выдержала конкуренции, не должна фигурировать в финальном файле вообще.

Сухой остаток: openresolv нужно доводить до ума, пока ещё не слишком поздно. Избежать этого не получится. Готовы?
Comment 6 Mikhail Efremov 2009-06-10 03:57:40 MSD
Ну, не думаю, что все так драматично :)

> Во-первых, нужно определиться, какая одна задача решается в первую очередь. На
> мой взгляд, это конфигурация glibc-резолвера (в Debian, похоже, только этим и
> ограничились). 

Нет, там точно так же вызываются подписчики для bind и dnsmasq, судя по их svn. Конфигурацией только glibc-резолвера занимается modify_resolvconf в SUSE, если не ошибаюсь.
Openresolv решает по сути 2 разные задачи. При отсутствии локального DNS-сервера - это именно конфигурация glibc-резолвера. И тут как раз играют роль приоритеты.

Кстати, числовые метрики - это специфично для openresolv, в Debian такого нет, там только приоритеты на основе перечисления имен интерфейсов. Другое дело, что не надо было в таком виде смешивать эти 2 варианта, логичнее выглядит присвоение дефолтных числовых значений группам интерфейсов. А так же дефолтного среднего значения метрики всем остальным, если она явно не указана при добавлении интерфейса. Наверно стоит предложить это апстриму. Я правильно понял, что примерно такую схему вы и имели в виду?

Вторая же задача заключается в обновлении конфигурации локального резолвера, если он используется. В частности прописать forwarders для bind'а с новым nameserver, при необходимости добавить зону переадресации. Так же и для dnsmasq. И вот тут как раз запись в /etc/resolv.conf отходит на второй план. Вообще говоря, туда можно вообще ничего не писать, если первой строкой стоит loopback адрес. Но такая конфигурация действительно не обязательна, хотя и наиболее вероятна, думаю. Видимо в первую очередь на этот случай запись туда и происходит, а не для страховки на случай отказа локального DNS-сервера. Хотя и для этого тоже, конечно.

Рассуждать какая из этих 2-х задач важнее нет смысла. Обе нужны и важны. И именно поэтому наивысший приоритет lo интерфейса имеет смысл. А вот возможность задать дополнительное умолчательное значение в resolvconf.conf действительно выглядит избыточной. Хотя наверно не всегда есть удобная возможность добавить 127.0.0.1 от имени lo, это хорошо, что etcnet такое позволяет :)

> Как только на хосте окажется правильно сформирован
> /etc/resolv.conf, хост сможет его содержимым накормить всех своих клиентов с
> помощью dnsmasq.

Локальные резолверы вообще не должны читать /etc/resolv.conf, не для них он. У них есть свои собственные конфигурационные файлы, вот из них они и должны получать эту информацию. То, что dnsmasq читает /etc/resolv.conf - это костыль, вынужденная мера, и использование resolvconf с его подписчиками, создающими эти конфиги, как раз позволяет отказаться от этого. Я собираюсь на dnsmasq повесить соответствующий баг, только хочу сначала немного сам в этом покопаться. Да и использование openresolv у нас пока еще все-таки опционально.

> В-третьих, при включенной "options rotate" визуальный порядок строк
> немедленно потеряет своё фактическое значение. 

Использование rotate действительно может сломать логику работы resolvconf. Но как этого можно избежать я не знаю. Есть конкретные предложения?

> Поэтому конкуренция должна
> происходить не между серверами, а между группами серверов. Серверы внутри
> отдельно взятой группы должны рассматриваться как равнозначные и обеспечивающие
> доступ к одним и тем же данным. Это один из основных принципов работы DNS.
> Группа серверов, которая не выдержала конкуренции, не должна фигурировать в
> финальном файле вообще.

Звучит разумно, но опять-таки, я не представляю, как этого можно добиться.
Ведь resolvconf вообще не знает, насколько верна информация, которую он добавил. И сам он этого определить никак не может.
К тому же слишком много мозга в достаточно простой утилите может принести больше вреда, чем пользы. Возможно такие вещи должен отслеживать кто-то над resolvconf.
Впрочем, надо подумать.

> Сухой остаток: openresolv нужно доводить до ума, пока ещё не слишком поздно.
> Избежать этого не получится. Готовы?

Openresolv может и не идеален, но все-таки лучше с ним, чем без него. Он хоть как-то уменьшает бардак вокруг resolv.conf. А допиливать я готов, главное понять, что и как пилить.

Но возвращаясь к сути бага. Как я уже говорил, с тем, что можно разрешить добавление 127.0.0.1 от любого интерфейса я согласен. Запуск же подписчиков для lo (кроме libc, конечно), видимо смысла не имеет. loopback он и есть loopback, что бы на него не назначили, добавлять его адрес в конфиги самих локальных резолверов не надо. Но раз уж в подписчиках все равно придется отфильтровывать 127.0.0.1 (вообще по хорошему отфильтровывать надо не 127.0.0.1, а адрес назначенный loopback, но над этим тоже надо думать), то можно и вызывать, это будет уже не важно.
Comment 7 Denis Ovsienko 2009-06-11 00:04:12 MSD
rotate --- обоснованная опция, делать с ней ничего не нужно. openresolv --- прототип, а не готовая программа. Чтобы он ей стал, необходимо (перефразируя уже изложенное выше):
1. Решать одну, самую главную задачу (конфигурация glibc resolver). Остальные задачи решаются в последнюю очередь, если вообще фигурируют к тому времени.
2. Механизм выбора "победившей" версии resolv.conf сделать предельно формальным, компактным и предсказуемым. Унаследованные предпосылки в виде hardcoded списков interface_order и dynamic_order отбросить вообще. Серверов в /etc/resolvconf.conf не прописывать, им там не место.
3. Назначенная администратором системы степень "хорошести"/"плохости" данных должна _всегда_ иметь решающее значение.

Ставлю заведующего glibc в копию.
Comment 8 Dmitry V. Levin 2009-06-11 00:56:43 MSD
(In reply to comment #7)
> Ставлю заведующего glibc в копию.

Спасибо, с интересом прочитал вашу дискуссию.
Не хочу писать общие слова, вы их уже написали достаточно.

У меня вопрос к Денису, в чём, по его мнению, принципиальная разница, что конфигурировать,
файл /etc/resolv.conf,
или файлы /var/lib/bind/etc/resolvconf-*.conf при неизменном /etc/resolv.conf?
Comment 9 Denis Ovsienko 2009-06-11 01:07:57 MSD
Разница в том, чтобы пропускать через локально запущенный named не всё подряд и всегда, а только в нужные администратору периоды. И ещё в том, что этим "вечноживым" сервером может оказаться адрес не 127.0.0.1 и вообще не локального узла адрес. Не нужно без спросу заменять резолвер каждого процесса кэширующим сервером всего хоста.
Comment 10 Repository Robot 2009-06-11 02:10:17 MSD
openresolv-3.3.2-alt2 -> sisyphus:

* Wed Jun 10 2009 Mikhail Efremov <sem@altlinux> 3.3.2-alt2

- Allow 'nameserver 127.0.0.1' from all interfaces (closes: #20345).
Comment 11 Denis Ovsienko 2009-06-12 13:39:33 MSD
Вижу эффект, данный тикет закрываю, спасибо.