6

TL; версия DR: Как настроить dnsmasq для переключения на DNS-серверы, на которые указывает DHCP-сервер в моей локальной сети, для включения коммутации беспроводных сетей?

На своем ноутбуке для разработчиков я недавно начал использовать dnsmasq, чтобы я мог перехватывать весь трафик в * .dev и перенаправлять его на виртуальную машину (используя mod_vhost_alias).

Чтобы это работало, мне нужно было настроить параметры моей сети таким образом, чтобы dnsmasq (работает на 127.0.0.1) использовался в качестве основного DNS-сервера, а обычные DNS-серверы были вторичными - вызывая откат к этим DNS-серверам, когда dnsmasq не может обработать поиск домена. Это работает хорошо, за исключением того факта, что резервные DNS-серверы больше не настроены через DHCP. Всякий раз, когда я переключаю беспроводные сети, это разрывает мое соединение - особенно в сетях, которые требуют аутентификации через веб-страницу (в противном случае использование общедоступного DNS-сервера, такого как 8.8.8.8, будет возможным).

Я попытался прочитать документацию по dnsmasq, но ни один из вариантов gazillion, казалось, не делал то, что мне нужно, или, возможно, я неправильно понимаю, что делают некоторые из опций.

Примечание: этот вопрос был первоначально отправлен на ServerFault, учитывая серверную природу dnsmasq. Он был быстро закрыт из-за того, что Mac OS X не была серверной ОС. У меня там недостаточно репутации, чтобы начать движение, поэтому, вопреки своему здравому мнению, я перехожу к SU.

3 ответа3

14

Похоже, вы пытаетесь добиться того же, что я только что установил на своем новом MacBook и ранее работал на моих Linux-машинах.

Как вы знаете, ручное добавление 127.0.0.1 к вашим DNS-записям в настройках сети является проблемой, потому что его необходимо повторно применять при смене сетевых интерфейсов / подключении к альтернативным точкам доступа Wi-Fi, а также не позволяет вашему компьютеру автоматически выбирать DNS-серверы, назначенные через DHCP. К счастью, следующее решение полностью избавляет от необходимости связываться с настройками сети, поэтому вы можете использовать DHCP как обычно.

Прежде всего, если вы ранее вручную добавили 127.0.0.1 и внешние DNS-серверы в свой сетевой интерфейс, сейчас самое время удалить их и вернуть их к настройкам по умолчанию DHCP.

Сделав это, вам нужно создать папку /etc /resolver.

sudo mkdir /etc/resolver

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

Итак, для вашей настройки (так же, как у меня), мы хотим создать текстовый файл с именем /etc /resolver /dev (для перехвата всех запросов для * .dev), содержащий стандартную запись сервера имен для 127.0.0.1 (локальный IP, используемый dnsmasq).

sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/dev'

Теперь все DNS-запросы для доменов * .dev будут переданы dnsmasq на 127.0.0.1, и все, что не соответствует * .dev, будет обрабатываться как обычно любыми DNS-серверами, которые подобрал ваш DHCP.

1

Вот решение, которое я придумал:

Я использую Growl и HardwareGrowler для запуска сценария, который записывает файл распознавателя, который dnsmasq настроен для использования.

Может быть, я неправильно понимаю (ситуация с документацией Growl довольно отсутствует), но я подумал, что Growl 2.1 может напрямую запускать сценарий оболочки в правильном каталоге. Я не мог заставить это работать, как бы то ни было. Поэтому вместо этого я использую скрипт правил Applescript, чтобы запустить скрипт оболочки следующим образом ...

В ~/ Библиотека / Сценарии приложений / ком.Growl.GrowlHelperApp / Rules.scpt:

using terms from application "Growl"
on evaluate notification with notification
    --Rules go in here
    if notification's note title contains "IP Address" then
        set shell_result to do shell script "/usr/local/sbin/set_nameservers.sh"
    end if
    --Ultimately return what you want Growl to do with the notification
end evaluate notification
end using terms from

Затем мой скрипт /usr/local/sbin/set_nameservers.sh:

#!/bin/bash

# locking variables
LOCKDIR="/tmp/nameservers.lock"
PIDFILE="${LOCKDIR}/nameservers.pid"

# Temporary file for discovered nameservers
TMP_NAMESERVERS_FILE="${LOCKDIR}/nameservers.conf"
# List of public nameservers to add to the list
PUB_NAMESERVERS_FILE="/etc/nameservers_public.conf"
# The nameserver list read in by dnsmasq
SYS_NAMESERVERS_FILE="/etc/nameservers.conf"

# Commands
GROWL="/usr/local/bin/growlnotify"

# Setup a lock in case Growl triggers this script multiple times due to multiple network changes
if mkdir "${LOCKDIR}"; then
    echo "$$" >"${PIDFILE}";
    echo "# DHCP supplied nameserves:" > "${TMP_NAMESERVERS_FILE}";

    # 1) For each interface listed by the networksetup command...
    while IFS=" " read -r -a interfaces;
    do
        ((int_count = ${#interfaces[@]} - 1));
        for ((i = 0; i <= int_count; i++));
        do
        # 2) Try to get a nameserver from DHCP. (Only the first of multiple is returned)
        nameserver=`/usr/sbin/ipconfig getoption ${interfaces[i]} domain_name_server`
        # 3) If a nameserver was returned, add it to our configuration.
        if [ ${nameserver} ]; then
            echo "nameserver" ${nameserver} >> ${TMP_NAMESERVERS_FILE};
        fi
        done
    done <<< `networksetup -listallhardwareports | grep Device | sed 's/Device: //g'`

# 4) If a file of public nameservers exists, add these to our configuration.
if [ -e ${PUB_NAMESERVERS_FILE} ]; then
    cat ${PUB_NAMESERVERS_FILE} >> ${TMP_NAMESERVERS_FILE};
fi
cp ${TMP_NAMESERVERS_FILE} ${SYS_NAMESERVERS_FILE};

# Display a Growl notification showing what our new nameserver config looks like.
${GROWL} -d "us.loranz.steve.set_nameservers" \
         -N "Nameserver Configuration" \
         -m "`cat ${SYS_NAMESERVERS_FILE}`" \
         "System nameservers set to:";

rm -rf "${LOCKDIR}";
else
# Display an informational message if we failed to establish a lock.
${GROWL} -d "us.loranz.steve.set_nameservers" \
         -N "Nameserver Configuration Failed" \
         -m "$0 ($$) failed to run, lock already established by process: " `cat ${PIDFILE}` \
         "Failed to set nameservers:";
exit 1;
fi

exit 0

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

Наконец, я установил свой сервер имен в настройках сети на 127.0.0.1, чтобы я нажал dnsmasq.

Затем dnsmasq настраивается со следующими параметрами:

resolv-file=/etc/nameservers.conf
all-servers

Первая строка указывает dnsmasq на файл, в котором скрипт выше заполняется серверами имен, обнаруженными через DHCP, и любыми публичными серверами, которые вы хотите.

Предполагается, что вторая строка позволяет dnsmasq отправлять запрос всем серверам имен, о которых он знает, и принимает первый ответ. Средство распознавания Mac OS X должно устранять необходимость в данных файлах распознавания и поиске домена DHCP ... и полагаться на это сделает вас лучше, чем каждый раз запрашивать каждый сервер в вашем списке. Я могу удалить эту опцию после некоторого дополнительного тестирования и был бы признателен любому, кто еще что-то знает об этом бите.

0

Если я правильно понимаю сценарий - и я могу быть вне базы, я не до конца понимаю, что вы пытаетесь сделать или где возникает ваша проблема - я думаю, что есть 2 части / элемента для решения вашей проблемы -

  1. Используйте IP-адрес, связанный с сетевой картой на вашем компьютере, для DNSMasq, а не 127.0.0.1.

  2. DNSMasq читает /etc/resolv.conf для чтения серверов имен, которые он должен использовать там, где он не является авторским. (Если вы хотите, вы можете изменить его, чтобы прочитать другой файл с опцией --resolv-file (-r). Практически вам нужно будет указать рекурсивные DNS-серверы, к которым можно обращаться из любого места, например, Googles на 8.8.8.8, о котором вы упоминали. Я был бы очень удивлен, если бы существовал "интегрированный" способ для DNSMasq автоматически получать серверы имен с DHCP-сервера - хотя это может произойти косвенно, если ваш DHCP-клиент переписывает ваш файл resolv.conf - но это не так дело для вас.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .