Решил рассказать о вариантах решения достаточно часто встречающейся проблемы для обладателей мобильных устройств. Проблема заключается в том, что зачастую лаптопы подключаются к достаточно большому количеству разных сетей, в которых далеко не всегда есть DHCP-сервер, либо же DHCP-сервер «отдаёт» не все необходимые настройки, либо же отдаёт неверные.
Автоподнятие интерфейса — вещь достаточно удобная, так как избавляет от необходимости каждый раз вручную поднимать и опускать интерфейс (хотя я знаю людей, которым больше по душе именно ручное поднятие интерфейсов). В большинстве случаев для этих целей можно использовать замечательную программу ifplugd.
Настройка ifplugd не представляет особой сложности сама по себе, но как минимум в Debian есть возможность опции указать в файле
Теоретически, ifplugd умеет работать и с отключаемыми адаптерами (параметр
В этом файле первая после комментария строка отрабатывает при подключении внешнего адаптера. Остальные же строки отрабатывают при получении события rfkill, которое означает изменение состояния переключателя встроенного Wi-Fi. Значения параметров здесь указаны для драйвера b43, у других драйверов они могут отличаться. К сожалению, так и не удалось придумать, как не указывать при этом имя интерфейса вручную.
Содержимое файла
Установка переменной
Файл
После того, как интерфейс, собственно, поднят, возникают две проблемы. Первая заключается в том, чтобы в случае Wi-Fi определить, какая из знакомых нам сетей доступна. Вторая заключается в том, чтобы непосредственно эту сеть настроить, если по какой-либо причине настройка по протоколу DHCP невозможна.
В Debian есть замечательнейший пакет guessnet, который позволяет достаточно легко решить обе проблемы, не прибегая к километровым колдунствам на bash, grep и sed, которыми мне пришлось воспользоваться до того, как я его нашёл.
guessnet пользуется такой возможностью механизма настройки сети в Debian
Всё, что необходимо, чтобы подключить guessnet в
Ключевое слово
Сами профили определяются в точности так же, как и любые другие интерфейсы, с одной лишь только разницей: имя логического интерфейса не совпадает с именем физического (хотя может содержать его как подстроку в себе):
Как видно, в настройках каждого из приведённых логических интерфейсов присутствует ключевое слово
Логический интерфейс
Конфигурация
Конфигурация
Наконец, конфигурация
Кроме этого, как я уже упоминал, guessnet умеет обнаруживать Wi-Fi-сети. Для этого ключевое слово
Необходимо учесть, что достаточно часто guessnet не может корректно определить «наличие кабеля» для Wi-Fi (оно и понятно), из-за чего в
Более подробно с возможностями guessnet можно ознакомиться на странице
Одна из сетей, в которых мне довольно часто приходится бывать, имеет DHCP-сервер, настроенный так, что запросы на обновление адреса отправляются два раза в минуту. Вместе с тем, через DHCP раздаются не подходящие мне настройки DNS и раз в полминуты перезаписывают мой
Поместить его нужно в
Конечно, такое решение является довольно грубым «хаком», так что возможно, установка пакета resolvconf и «подкручивание» приоритетов интерфейсов будут более предпочтительными.
Кроме того, рекомендуется поставить пакет ifupdown-extra, в нём есть несколько полезных дополнений к стандартным возможностям ifupdown.
Вот, пожалуй, и всё, что хотелось рассказать. Спасибо за внимание.
Автоподнятие интерфейса
Автоподнятие интерфейса — вещь достаточно удобная, так как избавляет от необходимости каждый раз вручную поднимать и опускать интерфейс (хотя я знаю людей, которым больше по душе именно ручное поднятие интерфейсов). В большинстве случаев для этих целей можно использовать замечательную программу ifplugd.
Настройка ifplugd не представляет особой сложности сама по себе, но как минимум в Debian есть возможность опции указать в файле
/etc/default/ifplugd
. Стоит обратить внимание на опцию -d
— время между определением отключения среды передачи данных (кабеля) и деконфигурацией интерфейса, возможно, имеет смысл его увеличить, так как весьма неприятно, когда из-за случайно выдернутого кабеля разрываются соединения. Опцию -u
же, напротив, можно установить в небольшое значение — поднять интерфейс при появлении кабеля практически никогда не вредно.Теоретически, ifplugd умеет работать и с отключаемыми адаптерами (параметр
HOTPLUG_INTERFACES
в конфигурационном файле), на практике же мне не удалось заставить его работать, потому это было сделано через udev. Всего у меня использовалось три Wi-Fi-адаптера, один из них подключался как PC Card (PCMCIA), другой — через USB, а позже появился встроенный, подключаемый через MiniPCI. Соответственно, в /etc/udev/rules.d/80-LOCAL-wlan-start.rules
постепенно дописывались правила:# WLAN adapters
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNEL=="wlan*", RUN+="/etc/network/wlan-up $env{INTERFACE}"
SUBSYSTEM=="rfkill", ACTION=="change", ENV{RFKILL_STATE}=="1", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", RUN+="/etc/network/wlan-up wlan2"
SUBSYSTEM=="rfkill", ACTION=="change", ENV{RFKILL_STATE}=="0", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", RUN+="/sbin/ifdown wlan2"
SUBSYSTEM=="rfkill", ACTION=="change", ENV{RFKILL_STATE}=="2", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", RUN+="/sbin/ifdown wlan2"
В этом файле первая после комментария строка отрабатывает при подключении внешнего адаптера. Остальные же строки отрабатывают при получении события rfkill, которое означает изменение состояния переключателя встроенного Wi-Fi. Значения параметров здесь указаны для драйвера b43, у других драйверов они могут отличаться. К сожалению, так и не удалось придумать, как не указывать при этом имя интерфейса вручную.
Содержимое файла
/etc/network/wlan-up
:#!/bin/sh
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
if=$1
logger -s -t wlan "Bringing up $if"
ifconfig $if up
poweroff=$(iwconfig $if|grep Tx-Power=off|wc -l)
if [ $poweroff -ne 0 ] ; then
ifconfig $if down
exit
fi
ifup --force $if 2>&1 | logger -s -t wlan
Установка переменной
PATH
необходима, так как при вызове скрипта из udev эта переменная не установлена, потому многие вещи начинают работать совершенно не так, как хотелось бы.Файл
/etc/network/wlan-up
изначально представлял собой достаточно сложный bash-скрипт, производивший поиск сетей, а также предпринимавший попытки входа в них, но был значительно упрощён после того, как я случайно наткнулся на пакет guessnet, о котором речь пойдёт ниже.Автоконфигурация сети
После того, как интерфейс, собственно, поднят, возникают две проблемы. Первая заключается в том, чтобы в случае Wi-Fi определить, какая из знакомых нам сетей доступна. Вторая заключается в том, чтобы непосредственно эту сеть настроить, если по какой-либо причине настройка по протоколу DHCP невозможна.
В Debian есть замечательнейший пакет guessnet, который позволяет достаточно легко решить обе проблемы, не прибегая к километровым колдунствам на bash, grep и sed, которыми мне пришлось воспользоваться до того, как я его нашёл.
guessnet пользуется такой возможностью механизма настройки сети в Debian
/etc/network/interfaces
, как логические интерфейсы и ключевое слово mapping
. Логические интерфейсы, как подсказывает их название, представляют собой ни что иное, как профили настроек сети, которые можно применить при поднятии того или иного интерфейса примерно так: ifup eth0=home
. Ключевое слово mapping
представляет возможность написать скрипт, который осуществляет сопоставление физического интерфейса логическому.Всё, что необходимо, чтобы подключить guessnet в
/etc/network/interfaces
— добавить секцию (stanza) mapping
для соответствующего интерфейса:mapping eth1
script guessnet-ifupdown
# map default: dhcp
# map debug: true
# map verbose: true
map syslog: true
Ключевое слово
map
приобретает новый смысл: оно используется для передачи параметров в guessnet (про оригинальный смысл можно прочитать на странице interfaces (5)
или в документации на ifupdown). Но об этом позже.Сами профили определяются в точности так же, как и любые другие интерфейсы, с одной лишь только разницей: имя логического интерфейса не совпадает с именем физического (хотя может содержать его как подстроку в себе):
iface no-link inet manual
test missing-cable
pre-up echo No link present.
pre-up false
iface dhcp inet dhcp
iface eth-home inet dhcp
post-up route del default 2>&1 >/dev/null || true
post-up pon dsl-eth-vpn
post-up ifup ipv6-vps
pre-down ifdown ipv6-vps
pre-down poff dsl-eth-vpn
test peer address 192.168.1.1 mac 00:19:CB:48:02:2A source 192.168.1.5
iface eth-lab inet static
address 192.168.23.238
netmask 255.255.255.224
gateway 192.168.23.225
test peer address 192.168.23.225
Как видно, в настройках каждого из приведённых логических интерфейсов присутствует ключевое слово
test
. Очень гибкая архитектура программы ifupdown позволяет сторонним программам (таким, как guessnet) перехватить их обработку либо просто игнорировать их (хотя конкретно guessnet работает иначе — он просто разбирает файл заново). Слово test
позволяет задать условие, по которому будет выбрана та или иная конфигурация.Логический интерфейс
no-link
рекомендуется создавать специально для того, чтобы guessnet не пытался запускать другие тесты при отсутствии кабеля.Конфигурация
dhcp
принимает все настройки по DHCP, не заменяя ничего. Её бывает полезно установить как конфигурацию по умолчанию — большинство сетей всё же имеют хоть какой-нибудь DHCP сервер, слушая указания которого можно хотя бы получить базовый набор настроек.Конфигурация
eth-lab
используется в сети с DHCP-сервером, который игнорирует запросы от незнакомых ему клиентов. Потому делается arping шлюза в данной сети — такой запрос отработает только в случае, если оба узла находятся в одном физическом сегменте сети.Наконец, конфигурация
eth-home
одновременно использует настройки от DHCP-сервера, но дополнительно поднимает IPv6-туннель, а также удаляет IPv4-шлюз по умолчанию, фактически превращая машину в IPv6-only узел. Ещё одна особенность: для того, чтобы получить доступ к «другому концу» IPv6-туннеля, используется ADSL-соединение, которое любезно предоставляет модем Zyxel серии P-660. У модемов этой марки есть одна интересная прихоть: они игнорируют анонимные ARP-запросы (а именно такие рассылает по умолчанию guessnet). Чтобы избежать этого, в явном виде прописан адрес, который записывается в поле «источник» пакета. Кроме того, здесь в явной форме указан MAC-адрес модема.Кроме этого, как я уже упоминал, guessnet умеет обнаруживать Wi-Fi-сети. Для этого ключевое слово
test
поддерживает опцию wireless
:iface wifi-MTS.BY inet dhcp
test wireless essid MTS.BY
wireless-essid MTS.BY
wireless-key off
Необходимо учесть, что достаточно часто guessnet не может корректно определить «наличие кабеля» для Wi-Fi (оно и понятно), из-за чего в
mapping
для Wi-Fi-интерфейса нужно добавлять строку map !no-link
.Более подробно с возможностями guessnet можно ознакомиться на странице
guessnet(8)
. Также к пакету прилагается неплохая документация с примерами использования. В принципе, ничто не мешает использовать guessnet и в других дистрибутивах — существует режим работы, «отвязанный» от специфичного для Debian пакета ifupdown.Пара штрихов
Одна из сетей, в которых мне довольно часто приходится бывать, имеет DHCP-сервер, настроенный так, что запросы на обновление адреса отправляются два раза в минуту. Вместе с тем, через DHCP раздаются не подходящие мне настройки DNS и раз в полминуты перезаписывают мой
/etc/resolv.conf
. Решением такой проблемы может быть следующий скрипт (для dhclient3):
case $reason in
RENEW)
make_resolv_conf () {
true
}
;;
*)
return
;;
esac
Поместить его нужно в
/etc/dhcp3/dhclient-enter-hooks.d
под любым именем.Конечно, такое решение является довольно грубым «хаком», так что возможно, установка пакета resolvconf и «подкручивание» приоритетов интерфейсов будут более предпочтительными.
Кроме того, рекомендуется поставить пакет ifupdown-extra, в нём есть несколько полезных дополнений к стандартным возможностям ifupdown.
Вот, пожалуй, и всё, что хотелось рассказать. Спасибо за внимание.