Aqui está a solução que eu criei:
Estou usando Growl e HardwareGrowler para acionar um script que grava um arquivo de resolução que o dnsmasq está configurado para usar.
Talvez eu esteja entendendo mal (a situação da documentação do Growl é bastante carente), mas eu pensei que o Growl 2.1 tinha a capacidade de acionar um script de shell, diretamente no diretório correto. Eu não consegui fazer isso funcionar, no entanto. Então, em vez disso, estou usando um script de regras do Applescript para executar o script de shell da seguinte maneira ...
Em ~ / Biblioteca / Scripts de Aplicativos / com.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
Em seguida, meu script /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
Em seguida, configurei o HardwareGrowler para mostrar eventos de rede e o Growl para disparar uma ScriptAction para o endereço IP alterado, o link de rede para baixo e o link de rede para cima.
Por fim, eu configurei meu servidor de nomes nas preferências de rede como 127.0.0.1, de modo que eu esteja atingindo o dnsmasq.
O dnsmasq é então configurado com as seguintes opções:
resolv-file=/etc/nameservers.conf
all-servers
A primeira linha aponta o dnsmasq para o arquivo que o script acima está preenchendo com servidores de nomes descobertos via DHCP e qualquer servidor público que você queira.
A segunda linha deve permitir que o dnsmasq envie uma consulta para todos os servidores de nomes que conhece e aceite a primeira resposta. O resolvedor do Mac OS X deve evitar a necessidade dos arquivos do resolvedor e da pesquisa de domínio DHCP ... e confiar nisso faria de você um internauta melhor do que consultar todos os servidores da sua lista a cada vez. Eu posso remover essa opção depois de mais alguns testes e apreciaria qualquer insight que alguém tenha sobre isso.