Рассмотрим как добиться этого в случае если на ноутбуке установлен Debian sarge
Ноутбук может быть
Когда ноутбук использует GPRS или dialup-соединение, то все настройки которые мы можем получить определяются возможностями протокола PPP - локальный IP-адрес, адрес второго конца PPP-линка (он же шлюз по умолчанию) адреса одного-двух DNS-серверов и всё.
Возможности DHCP существенно шире. Если внимательно почитать man dhcpd.conf то можно обнаружить что с помощью DHCP можно настроить рутер с нетривиальным рутингом и рабочую станцию, использующую кучу различных сетевых протоколов. Естественно, если клиент достаточно умный, чтобы этими возможностями воспользоваться.
Я использую isc dhclient версии 3 (пакет dhcp3-client). Этот клиент может всё.
Если у вас в ноутбуке есть встроенная сетевая карта, то можно прописать в конфиге dhcp-сервера выдачу постоянного IP по этой сетевой карте. Но если вы используете PCMCIA или USB сетевую карту или какой беспроводной адаптер (bluetooth, wifi) подключаемый через pcmcia или USB, то существенно важно чтобы если вы поменялись сетевой картой с соседом, вы не поменялись бы заодно и IP-адресами.
Для этого в протоколе DHCP есть понятие client identifier.
В качестве идентификатора клиента может быть использована произвольная последовательность байт. В конфигах dhclient и dhcpd (предполагаем что в вашей локальной сети в качестве сервера используется ISC dhcpd) этот идентификатор можно прописать и как набор 16-ричных значений разделенных на байты двоеточиями, и как строку в кавычках. Аналогичные возможности имеют клиенты dhcp по умолчанию в FreeBSD и Solaris. В Windows с этим все гораздо хуже. Там почему-то идентификатор задается с в виде 32-битного числа (хотя протокол такого жесткого ограничения не накладывает)
Я всегда использую в качестве идентификатора hostname компьютера. Это существенно облегчает поддержку конфигурации dhcp-сервера.
Итак, пишем в /etc/dhcp3/dhclient.conf
send host-name "thinkpad"; send dhcp-client-identifier "thinkpad";Первая строчка почти никак не влияет на dhcpd. В dhcpd версии 3 может быть что-то и можно сделать, а dhcpd 2.x просто запишет полученные hostname в dhcp.leases (что тоже не вредно - администратор сервера сможет узнать какой IP получала данная машина, если она почему-то получила адрес из динамического диапазона).
В конфигурационном файле dhcpd вашему ноутбуку должен соответствовать блок:
host thinkpad { option dhcp-client-identifier "thinkpad"; option host-name "thinkpad"; fixed-address 192.168.217.9; }В домашней сети вы такой блок пропишете с легкостью, а в рабочей для этого нужно иметь кое-какое влияние на системного администратора.
В домашних сетях своих друзей, к которым вы ходите в гости, скорее всего придется удовлетвориться динамическим IP, если только вы не ходите к ним в гости достаточно регулярно.
Можно еще пытаться динамически проапдейтить локальный DNS, связав свое имя с полученным динамическим IP, но я этим никогда не развлекался, поэтому советов давать не буду.
Вот если в resolv.conf прописан в качестве DNS-сервера localhost, то всё в порядке. Нужно только уведомить DNS-сервер о смене форвардеров.
Для этой цели в debian есть пакет resolvconf. В случае если он установлен, скрипты dhcp-клиента и pppd, ответственные за прописывание адресов DNS передают эту информацию программе resolvconf, вместо того чтобы явным образом переписывать /еtc/resolv.conf.
А resolvconf обладает настраиваемой конфигурацией и может делать уйму полезных вещей. В комплекте большинства включенных в дистрибутив DNS-серверов есть скрипты, которые помещаются в /etc/resolvconf/update.d и выполняют необходимые модификации при смене адресов DNS-сервера.
Я выбрал для ноутбука кэширующий dns-сервеp pdnsd, специально разработанный в качестве кэширующего DNS для машины-клиента. Если вам хочется, можете, конечно, поставить полноценный bind, он тоже умеет взаимодействовать с resolvconf, но pdnsd проще в настройке и потребляет меньше памяти.
При использовании resolvconf вместе с кеширующим DNS-сервером нужно прописать строчку
nameserver 0.0.0.0в /etc/resolvconf/resolv.conf.d/head чтобы ссылка на локальный DNS-сервер всегда оказывалась первой в сгенерированном resolv.conf
Делать этот файл неперегенерируемым не стоит, поскольку dhcp отдает не только адреса name-серверов, но и domain-name - имя домена по умолчанию, которое имеет смысл прописывать в resolv.conf в качестве search.
Держать ntpd на ноутбуке, который может быть вообще вне сети, а может использовать достаточно дорогое GPRS соединение, я считаю излишиним. А вот при включении ноутбука в сеть с DHCP, особенно если dhcpd любезно сообщил о наличии в этой сети серверов времени - крайне полезно.
В dhcp-протоколе предусмотрена передача информации о двух видах серверов времени - старом протоколе time (порт 37) клиентом которого является команда rdate (пакет rdate) и более современного протокола ntp, клиентом которого является команда ntpdate (пакет ntpdate).
Поскольку не во всех сетях доступны оба протокола, будем синхронизироваться по тому протоколу, который доступен.
dhclient имеет два набора скриптов-хуков - dhclient-enter-hooks.d и dhclient-exit-hooks.d. Первый выполняется когда уже получен ответ от сервера, но еще не сконфигурирован интерфейс, а второй - после конфигурирования интерфейса. Естественно, запускать синхронизацию времени надо из второго.
Но сначала нужно объяснить dhclient-у, что эту необязательную информацию следует запрашивать. Для этого в dhclient.conf прописываем в список запрашиваемых параметров (опция request) кроме умолчательных параметров subnet-mask, broadcast-addres, time-offset, routers, domain-name, domain-name-servers, netbios-name-servers и netbios-scope еще параметры time-servers и ntp-servers.
Теперь, вызывая скрипты из dhclient-exit-hooks.d, dhclient будет выставлять им переменные среды new_ntp_servers и new_time_servers, если, конечно, сервер предоставит им соответствующую информацию.
Теперь пишем скрипт /etc/dhcp3/dhclient-exit-hooks.d/time.
time_setup () { if [ "$reason" != BOUND ] && [ "$reason" != RENEW ] \ && [ "$reason" != REBIND ] && [ "$reason" != REBOOT ] then return fi if [ x$new_ntp_servers != x -a -x /usr/sbin/ntpdate ]; then echo "Using NTP server(s) $new_ntp_servers" /usr/sbin/ntpdate -b -s $new_ntp_servers & elif [ x$new_time_servers != x -a -x /usr/sbin/rdate ]; then echo "Using time server(s) $new_time_servers" /usr/sbin/rdate $new_time_servers fi } time_setupЭтот скрипт работает следующим образом: основную работу делает функция time_setup, которая завершается командой return, если причина вызова скрипта (содержащаяся в переменной reason) не соответствует одной из причин по которой могли измениться передаваемые по dhcp параметры.
В случае если работа продолжается, мы проверяем можем ли мы установить время с помощью ntp, (для чего требуется чтобы сервер отдал соответствующий параметр, и у нас бы присутствовала программа-клиент, и если да, то выполняем синхронизацию, а если нет, аналогичным образом пытаемся синхронизироваться по более старому прототоколу time.
Очевидно, что в случае dial-up соединения параметры windows-networking никому неинтересны. Хотя... мелким хакерам они интересны. Сколько раз наблюдал как стоит мне установить GPRS-соединение, сразу ко мне на машину начинали ломиться на порты Samba, MS-SQL и Radmin. Поэтому, если у вас на ноутбуке запущен сервер samba, не поленитесь и пропишите в /etc/ppp/ip_up.d скриптик, который будет его выключать при установлении GPRS или диалапного соединения. Целее будете.
В принципе, dhcp-протокол содержит опцию smtp-servers, и вполне можно написать аналогичный enter-hook, который, получив эту опцию, будет прописывать её в качестве релея по умолчанию для локального MTA. Естественно, скрипт этот будет специфичен для каждого MTA.
Кроме того, потребуется придумать что делать в случае dialup и gprs соединений. У большинства сотовых операторов есть свои smtp-сервера, принимающие почту с GPRS-адресов. Тем более они есть и у диалапных провайдеров. Но протокол PPP этой информации не предоставляет.
Кроме того использование протоколов POP3, IMAP и SMTP по ненадежным и медленным dialup и gprs линкам чревато многократными передачами одного и того же письма - ведь эти протоколы не поддерживают докачку.
Поэтому я пошел по другому пути и настроил в качестве дефолтного почтового транспорта старую добрую UUCP, которая прекрасно работает over tcp. Протокол uucp предусматривает авторизацию, поэтому проблем с тем кого пускать на свой uucp-сервер, а кого нет - нет. Опять же есть докачка. Лучше, конечно, на всякий пожарный случай гонять uucp-траффик через ssl, например с использованием stunnel.
Для выполнения обмена по uucp я использую следующий скрипт:
#!/bin/sh if /sbin/route -n |grep -q "^0.0.0.0"; then /usr/sbin/uucico -s wagner fiОн запускается по крону раз в несколько минут, проверяет наличие route в интернет, и если таковая имеется, то выполняет обмен с системой wagner (моей домашней машиной).
Кроме того, uucico запускается из /etc/ppp/ip-up.d, поскольку неизвестно доживет ли дорогое и нестойкое диалапное соединение до следующего запуска этого скрипта по крону. А для очень дорогих каналов (например при дозвоне по сотовому телефону на IP-гейт провайдера, когда цена минуты сравнима с ценой голосового разговора, а скорость 9600), у меня есть expect-овский скрипт, который запускет ppp, мониторит вывод команды uulog, и обнаружив в логе uucp слова "Call complete" немедленно разрывает связь:
#!/usr/bin/expect spawn -noecho uulog -F set timeout 1 log_user 0 expect { -re . exp_continue timeout {} } puts "Starting ppp session" if [catch "exec pon $argv >&@ stderr"] { puts "ppp connection failed" exit 1 } set timeout -1 log_user 1 expect { "Call complete" { puts "Stopping ppp session" exec poff exit } }
Работа через UUCP по медленным каналам (GPRS, dialup) имеет те преимущества что
cat файл-для-печати|ssh соседняя-десктопная-машина lprА в случае использования cups вообще можно указывать URL сервера печати и печатать по протоколу ipp.