от Иво Гелов(26-01-2008)

рейтинг (24)   [ добре ]  [ зле ]

Printer Friendly Вариант за отпечатване

Сървърът, който администрирам предоставя DNS и DHCP услуги на потребителите. Разбира се, това става с помощта на
BIND (NAMED) и DHCPD - както при почти всички Linux дистрибуции, те се класика. BIND играе ролята на кеширащ DNS
сървър, за да намаля натоварването към доставчика си - а също и обработва локалните заявки от NetBIOS (WINS).
DHCPD от една страна предоставя удобство на потребителите, които са с лаптоп и често се местят от мрежа в мрежа,
а от друга осигурява постоянно съответствие между раздаваните IP адреси и познатите му MAC-адреси (като позволява
работата и на потребители с непознат MAC-адрес). Така за нуждите на различни статистики се осигурява постоянство на
IP-адресите на потребителите.
Така описаната конфигурация работи безпроблемно, но поради текучество и други причини се налага все по-често да
правя промени по настройките както на DHCPD, така и на BIND - а пък така и не успях да подкарам DDNS (Dynamis DNS,
при който DHCPD информира BIND по RNDC протокол за новопоявили се потребители, така че да бъдат добавени в DNS
листата). Поразрових се из GOOGLE и попаднах на 2 интересни неща:

1. MyDNS (http://mydns.bboy.net/) - малък DNS сървър, написан от нулата, който вместо от текстов файл взима DNS
записите си от SQL база данни (MySQL или PostgreSQL). Не е рекурсивен - това означава, че ако търсеният запис го
няма в базата данни, няма да бъде направено запитване до DNS сървъра на доставчика, или пък към ROOT сървърите,
а ще се върне съобщение, че няма такъв адрес. Така че явно приложението му е само за големи организации с голям
брой локални адреси, които често се променят. Всъщност, може да се използва в комбинация с DNScache
(http://cr.yp.to/djbdns/dnscache.html) - това е рекурсивен кеширащ DNS клиент, част от пакета "djbdns" (по-известен
като TinyDNS) на професор D. J. Bernstein (автор на Qmail) - на адрес http://cr.yp.to/djbdns.html
Струва си да бъде разгледан, и вероятно дори инсталиран. Лично на мен точно в този момент ми липсва достатъчно време,
но определено бих посъветвал всички, които имат сериозни интереси в мрежовото администриране да погледнат този
проект.

2. DNSmasq (http://www.thekelleys.org.uk/dnsmasq/do...) - много апетитна комбинация от типа 2-в-1 (DNS + DHCP).
Използва се в някои фирмуери (firmware) за специализирани (dedicated или embedded) рутери - например в OpenWRT
(http://openwrt.org/). Това е кеширащ рекурсивен (по-скоро термина е forwarder, защото препраща заявките към
DNS сървъра на доставчика, а не директно към ROOT DNS сървърите) DNS сървър с модул за DHCP/BOOTP - тясно интегрирани
един с друг.

Реших да си направя "upgrade" - да премина от BIND + DHCPD към DNSmasq. Хем по-малък и по-бърз сървър, хем DDNS ще
си се прави автоматично :-) Речено-сторено - свалих си последната версия 2.40 и започнах да разучавам параметрите
в конфигурацията. Написах си елементарен скрипт на PHP, с който през WEB-интерфейс да обновявам списъка с IP адреси
и тяхното съответствие с MAC-адреси и имена на хостове. Първо ще покажа моят конфигурационен файл, а след това ще
го обясня заедно с 1-2 подводни камъка, на които се натъкнах.

addn-hosts = /etc/dnsmasq/dns_host
expand-hosts
log-facility = /var/log/dnsmasq.log
group = nobody
listen-address = 127.0.0.1
listen-address = 192.168.0.1
listen-address = 192.168.2.1
bind-interfaces
localise-queries
bogus-priv
filterwin2k
no-resolv
no-poll
domain-needed
server = xx.xx.xx.xx
cache-size = 9000
dhcp-range=net0,192.168.0.2,192.168.0.100,10h
dhcp-range=net2,192.168.2.150,192.168.2.220,10h
#dhcp-hostsfile = /etc/dnsmasq/dhcp_host
read-ethers
domain = my-domain.com
dhcp-ignore-names
dhcp-authoritative
#log-dhcp

# This tells M$ to release their lease when they shutdown
dhcp-option=vendor:MSFT,2,1i
# Router
dhcp-option=net0,3,192.168.0.1
dhcp-option=net2,3,192.168.2.1
# DNS
dhcp-option=net0,6,192.168.0.1
dhcp-option=net2,6,192.168.2.1
# WINS server
dhcp-option=net0,44,192.168.0.1
dhcp-option=net2,44,192.168.2.1
# NetBIOS over TCP/IP Datagram Distribution Server Option
dhcp-option=net0,45,192.168.0.1
dhcp-option=net2,45,192.168.2.1
# Node type - P (Point-to-Point UDP, not generate and not accept broadcasts)
dhcp-option=net0,46,2
dhcp-option=net2,46,2
# NetBIOS over TCP/IP Scope Option (probably domain - they usually leave empty)
dhcp-option=net0,47
dhcp-option=net2,47

ОПИСАНИЕ

addn-hosts = /etc/dnsmasq/dns_host - добавя съдържанието на този файл към информацията, прочетена от "/etc/hosts".
Този файл (/etc/dnsmasq/dns_host) се генерира чрез моя PHP скрипт и съдържа DNS информация за локалните потребители.
Форматът му е същия както на "/etc/hosts"

expand-hosts - автоматично добавя домейн-име към имената от "/etc/hosts" и файла от "addn-hosts", ако липсва

group = nobody - групата, с чиито права да се стартира DNSmasq. По дефолт е "dip", което мен не ме устройва

listen-address - изброяват се адресите на сървъра, през които ще получава заявки. По дефолт слухти на всички
достъпни интерфейси (0.0.0.0)

bind-interfaces - по дефолт, дори ако се укаже "listen-address", DNSmasq пак слухти на 0.0.0.0, и игнорира
заявките, които не са от изброените интерфейси. Това е "удобство", така че ако интерфейсите динамично си сменят
адресите, това не пречи на работата на DNSmasq (при мен няма такава опасност, затова и bind-interfaces)

localise-queries - ако едно и също DNS име е обявено за няколко IP адреса в "/etc/hosts" (или "addn-hosts"),
DNSmasq се опитва да върне само адреса, който отговаря на същата подмрежа, от която идва запитването

bogus-priv - всички обратни запитвания (тоест от IP към домейн име) за частни адреси (10, 172.16-31, 192.168) се
обработват само локално без да се препращат към DNS сървъра на доставчика (ако ги няма описани в "/etc/hosts" се
връща съобщение, че няма такъв адрес)

filterwin2k - елиминира LDAP заявките (тъй като потребителите ми не са в Windows-domain, а в Workgroup-и)

no-resolv - не взима автоматично адресите за DNS сървърите на Интернет доставчика от "/etc/resolv.conf", а
само изрично указаните в конфигурационния файл

no-poll - не проверява периодично "/etc/resolv.conf" за промени (приложимо само при PPP и PPPoE)

domain-needed - забранява да се препращат към DNS сървъра на доставчика заявки за имена, които не съдържат точка "."
Това са локални имена - ако ги няма описани в "/etc/hosts" или настройките на DHCP модула, се връща грешка "Not found"

server = xx.xx.xx.xx - това е адресът на DNS сървъра на Интернет доставчика

cache-size = 9000 - колко DNS отговора от сървъра на доставчика да се кешират (максимума е установен на 10000
в изходния код на DNSmasq)

dhcp-range=net0,192.168.0.2,192.168.0.100,10h - тази команда разрешава обработването на DHCP заявки за съответната
подмрежа, дава й име (net0) което може да се използва след това в "dhcp-option" и установява времетраенето по подразбиране
на раздаваните IP адреси да бъде 10 часа

#dhcp-hostsfile = /etc/dnsmasq/dhcp_host - това беше основния препъни-камък. Този файл се генерираше от моя PHP
скрипт, в него се описваше съответсвието между IP и MAC адреси и се задаваха имена на хостовете. DNSmasq упорито отказва
да признае това, и при получаване на заявка DHCPREQUEST с IP, което е описано в този файл - връща отговор DHCPNAK със
съобщение "address reserved", след което клиента изпраща отново DHCPREQUEST (този път без IP) и получава IP-адрес - само
че НЕ ТОЗИ, който съм описал във файла, а някой свободен от обхвата на "dhcp-range". Борих се няколко дни, рових се
в изходния код - и не можах да схвана защо е направено така. В документацията на DNSmasq е указано, че ако в "dhcp-range"
вместо краен адрес се напише ключовата дума "static", той престава да раздава динамично адреси - тоест IP адрес ще получат
само клиентите, чиито MAC адреси са описани в "dhcp-hostsfile" или "dhcp-host" директиви. Когато обаче го изпробвах,
получих грешка за DHCPDISCOVER "no address available in the range". Накрая, абсолютно случайно, реших да изпробвам какво
ще стане с директивата "read-ethers". Тя е подобна на "dhcp-hostsfile" - прочита от "/etc/ethers" съответствието между
MAC и IP адресите, но не позволява никакви други опции (например времетраене на IP адреса, идентификатор на мрежата, на
хоста и т.н.). Форматът на файла е MAC-адрес, 1 или повече шпации (или табулации) и след това или IP-адрес, или име на хоста
(но не и двете). И о, чудо ! Всичко се получи - DNSmasq започна да раздава точно посочените IP адреси за всеки MAC адрес.
Не успях да открия никаква информация в GOOGLE за тази или подобна ситуация, скоро ще пиша до автора на DNSmasq, и при
нужда ще напиша коментар към статията.

read-ethers - както написах по-горе, това решава проблема за статичното привързване на MAC към IP адрес. В моя случай
"/etc/ethers" е символична връзка към "/etc/dnsmasq/ethers", който се генерира от моя PHP скрипт

domain = my-domain.com - фиктивен локален домейн, може да си измислите собствен

dhcp-ignore-names - винаги игнорира името на хоста, което той сам предлага в DHCP заявката, и го регистрира в DNS
списъка с името, което е зададено в конфигурационните файлове ("/etc/hosts", "/etc/ethers" или "dhcp-hostsfile")

dhcp-authoritative - използва се, когато DNSmasq със сигурност е единствения DHCP сървър в мрежата. Тогава той вече
не игнорира заявки, които не е раздал той самия. По този начин ако се развали файла с описание на раздадените адреси
(/var/lib/misc/dnsmasq.leases) - той се създава динамично по информацията от клиентските заявки. Аз лично го използвам, за
да намаля времето за time-out при преход от DHCPD към DNSmasq (или пък ако в мрежата се включи лаптоп, който има lease от
друга DHCP сървър в друга мрежа)

#log-dhcp - указва на DNSmasq да записва информация за DHCP заявките и отговорите в лог-файла (log-queries се използва
да записва информация за DNS заявките и отговорите)

dhcp-option - използват се за указване на опции към цяла група от клиенти. Форматът е
"dhcp-option=net-id,option-id,option-value". NET-ID трябва да съвпада с този, зададен в "dhcp-range" или "dhcp-host", това е
наименованието на групата клиенти. Опциите са описани в RFC2132 (http://www.faqs.org/rfcs/rfc2132.html), точка 3. Най-често
използваните са като тези в моя конфигурационен файл (от коментарите се вижда предназначението им)

Макар и описано най-накрая, всъщност това е нещото, което трябва да проверите най-напред - става дума за настройките на
защитната стена (IPtables). DHCPD е така написан, че в повечето случаи успява да заобиколи IPtables вътре в самото ядро.
Така че, дори DHCPD да е работил във вашата мрежа - това не значи, че и DNSmasq ще заработи. По-конкретно, трява да сте
уверени, че за всички интерфейси, на които слухти DNSmasq е разрешено получаването на пакети с източник 0.0.0.0 и
получател 255.255.255.255. Иначе ще се чудите защо DHCPD си раздава адреси с кеф, а пък DNSmasq сякаш изобщо не усеща
заявките :-)

Документацията на DNSmasq е доста пестелива, а и в мейлинг-листите не забелязах достатъчно специалисти - така че пускането
му в действие е едно малко предизвикателство. Но пък според мен за не особено натоварени мрежи успешно може да замени
BIND и DHCPD.

Искаше ми се да публикувам и PHP скрипта за елементарния WEB интерфейс, но може би е по-добре направо да дам линк. Сложил
съм го на безплатен сървър - така че след 30-ина дни линка ще бъде неактивен. Но всеки желаещ може да ми прати PM с емайла
си, и ще му го изпратя. А линкът е
http://rapidshare.com/files/86787611/dn...
http://www.zshare.net/download/68957842...
http://www.uploading.com/files/G92VLP4M...


Таблиците в базата данни имат следния формат:

DROP TABLE IF EXISTS `host`;

CREATE TABLE `host` (
 `NET` tinyint(3) unsigned NOT NULL default '0',
 `IP` tinyint(3) unsigned NOT NULL default '0',
 `MAC` varchar(12) NOT NULL,
 `PERSON` varchar(24) NOT NULL,
 PRIMARY KEY  (`NET`,`IP`),
 UNIQUE KEY `MAC` (`MAC`),
 UNIQUE KEY `PERSON` (`PERSON`)
) ENGINE=MyISAM /*!40100 DEFAULT CHARSET=cp1251*/;

DROP TABLE IF EXISTS `mreza`;

CREATE TABLE `mreza` (
 `ID` tinyint(3) unsigned NOT NULL default '0',
 `MREZA` varchar(20) NOT NULL,
 PRIMARY KEY  (`MREZA`,`ID`)
) ENGINE=MyISAM /*!40100 DEFAULT CHARSET=cp1251*/;


<< | >>