- Вопрос или проблема
- Ответ или решение
- Использует ли cURL все серверы имен из resolv.conf?
- Как работает разрешение имен в cURL?
- Причины ошибки cURL
- Как определить, какой DNS-сервер использует cURL?
- Как настроить cURL для использования нескольких серверов имен?
- Использование локального DNS-резолвера
- Преимущества использования локального DNS-резолвера:
- Заключение
Вопрос или проблема
В моем /etc/resolv.conf
есть несколько записей серверов имен, некоторые публичные, а некоторые — мои собственные:
search subdomain.example.com
nameserver 8.8.8.8
nameserver 10.20.30.1
nameserver 10.20.30.2
Я хочу, чтобы cURL загружал файл по адресу, который может разрешить только мой собственный DNS-сервер:
curl subdomain.example.com/myfile
Запрос завершается неудачей с сообщением
curl: (6) Невозможно разрешить хост: subdomain.example.com
Мне кажется, что cURL пробует первый сервер имен и прекращает попытки, если он неудачен. Я не смог подтвердить это, потому что curl -v
не выводит, какой DNS-сервер он использует.
Таким образом, другой вопрос заключается в том, как определить, какой DNS-сервер cURL использует по умолчанию, и в идеале, как заставить его повторить попытку с другими записями из resolv.conf. Я знаю опцию командной строки --dns-servers
. Если возможно, я предпочел бы использовать настройки DNS, предоставленные DHCP.
“Попробует ли он снова” зависит от причины сбоя. cURL будет повторять попытку, если сервер не отвечает; он не будет повторять попытку, если сервер отвечает ‘Неизвестно’.
Практически ни одно программное обеспечение не будет повторять попытку с другим сервером после получения действительного ответа от первого сервера, даже если он получил ответ “Домен неизвестен” — это все еще действительный ответ. Возможность перечислять несколько серверов предназначена только для случаев, когда первый сервер вообще не отвечает — не для ситуаций, когда разные серверы знают разные данные.
Если у вас есть внутренний DNS-домен, вам понадобится отдельный резолвер, чтобы объединить оба набора серверов в единый обзор. Обычно внутренние DNS-серверы уже делают это сами, но если вы по какой-то причине не хотите отправлять общие интернет-запросы DNS на 10.20.30.1, то вам придется запустить другой локальный DNS-сервер поверх этого.
Например, Dnsmasq на localhost — распространенный способ сделать это; он предоставляет как локальный кэш DNS, так и возможность маршрутизировать разные запросы к разным верхним серверам. Unbound и systemd-resolved также возможны.
Я нашел https://serverfault.com/questions/398837/second-nameserver-in-etc-resolv-conf-not-picked-up-by-wget. Не стесняйтесь переместить или пометить мой вопрос как дублирующийся. @grawity, спасибо за ваш ответ, я выбрал export RES_OPTIONS="rotate"
, который я нашел в man resolv.conf
, вместо этого (не настройки DNS, предоставленные DHCP, но это решает мою проблему)
Ответ или решение
Использует ли cURL все серверы имен из resolv.conf?
При работе с cURL и DNS, важно понимать, как приложение взаимодействует с файлами конфигурации и какие механизмы разрешения имен используются. В частности, ваше наблюдение о поведении cURL связано с тем, как оно обращается к различным серверам имен, заданным в файле /etc/resolv.conf
.
Как работает разрешение имен в cURL?
По умолчанию cURL полагается на системные настройки DNS, указанные в файле /etc/resolv.conf
. При наличии нескольких записей nameserver
в этом файле cURL обращается к ним в порядке, в котором они указаны. Однако, важно отметить, что cURL не будет пытаться обратиться ко всем серверам по очереди в случае, если первый сервер возвращает ответ, даже если это ответ "неизвестный домен".
Причины ошибки cURL
В вашем случае вы столкнулись с ошибкой:
curl: (6) Could not resolve host: subdomain.example.com
Это происходит, если все запрашиваемые серверы имен не могут разрешить указанный домен. Однако, если сервер отвечает с информацией о том, что домен не существует, cURL не будет обращаться к следующему серверу. Таким образом, cURL завершает процесс, поскольку получает "валидный" ответ.
Как определить, какой DNS-сервер использует cURL?
К сожалению, cURL не предоставляет встроенной информации о том, какой именно сервер имен он использует для конкретного запроса. В этом контексте полезно использовать утилиты для диагностики DNS, такие как dig
или nslookup
, которые могут быть использованы для проверки того, какой сервер имен отвечает на запросы. Например:
dig @8.8.8.8 subdomain.example.com
Этот запрос позволит вам выяснить, какой ответ дает определенный DNS-сервер.
Как настроить cURL для использования нескольких серверов имен?
Хотя к cURL нельзя напрямую настроить повторные попытки на нескольких серверах, описанные более ранние методы могут быть полезны. Например, можно использовать опцию системной переменной среды:
export RES_OPTIONS="rotate"
Эта настройка позволяет системе рандомизировать запросы к различным серверам имен, что может помочь использовать более оптимальный сервер и, возможно, исправить возникшие проблемы с разрешением имен.
Использование локального DNS-резолвера
Если требуется более продвинутое управление DNS-запросами, стоит рассмотреть установку локального DNS-резолвера, такого как Dnsmasq или Unbound. Они могут эффективно контролировать, какие запросы идут к какому серверу, и предоставлять кэширование, что улучшает производительность.
Преимущества использования локального DNS-резолвера:
- Кэширование: Ускоряет последующие запросы.
- Настройка маршрутизации: Позволяет гибко управлять фильтрацией и маршрутизацией DNS-запросов.
- Совмещение публичных и внутренних запросов: Объединяет данные из различных серверов в единый вариант.
Заключение
Таким образом, несмотря на то что cURL не будет обращаться ко всем серверам имен в случае проблем с разрешением, существуют способы оптимизации процесса и диагностирования причин сбоев. Использование локального DNS-резолвера и изменение параметров конфигурации системы могут значительно улучшить опыт работы с cURL и DNS в целом.