From: Сергей Супрунов <amsand@yandex.ru.>
Date: Wed, 16 Feb 2006 18:21:07 +0000 (UTC)
Subject: Заморозка ARP таблицы во FreeBSD
Оригинал:http://amsand.narod.ru/articles/arp.html
Статья опубликована в журнале "Системный администратор", Июль 2004
При работе в локальной сети правила безопасности на сервере, как
правило, относятся сразу ко всей подсети. Причем вполне обычная
практика - оставлять в адресном пространстве резерв для будущего
расширения. Да и невозможно в принципе задать подсеть, содержащую
ровно 7 адресов - все равно придется выделять 14. То есть практически
в любой сети есть неиспользуемые адреса, на которые распространяются
общие правила доступа. Конечно, любые поползновения извне можно очень
эффективно отсекать пакетными фильтрами и прочими изобретениями
изворотливого человеческого разума. Но вряд ли найдется организация, в
которой системный администратор может свято верить в грамотность,
ответственность и порядочность всех без исключения сотрудников,
работающих в сети изнутри. А если политика компании включает еще и
попытки учитывать и ограничивать трафик с каждого IP-адреса, то нет
никаких гарантий, что никому не придет в голову "случайно" прописать в
своих настройках адрес соседа...
Данная заметка о том, как решить указанную выше проблему, если роутер,
через который локальная сеть выходит в "мир", построен на базе
FreeBSD, а сама сеть включает два-три десятка машин, сосредоточенных в
одном сегменте (при большем количестве компьютеров эффективность
описываемой методики заметно снижается, хотя она и остается вполне
работоспособной). Не могу гарантировать, что на всех версиях этой ОС
все будет работать так, как описано, но для FreeBSD 5.2 никаких
проблем обнаружено не было. Да, собственно, и взяться им неоткуда,
настолько все просто.
Сначала - немного теории. Для передачи кадра (речь будет идти об
Ethernet) другому устройству сетевой адаптер машины должен знать его
физический (MAC) адрес. Удаленное устройство будет принимать только
кадры, содержащие в заголовке (поле Destination) его адрес, то есть
адресованные именно ему. Ну, еще широковещательные кадры, адресованные
на специальный адрес ff:ff:ff:ff:ff:ff. Но поскольку работа протоколов
верхних уровней основана на IP-адресах, то кто-то должен уметь
сопоставлять IP-адрес сетевого устройства с MAC-адресом его адаптера.
Этим "кем-то" является протокол ARP (address resolution protocol).
Собственно говоря, вся работа ARP заключается в том, чтобы по
IP-адресу хоста возвратить MAC-адрес его адаптера, который
используется для связи с данной машиной. Для этого ARP формирует в
памяти компьютера (или другого устройства, на котором он запущен,
например, коммутатора) таблицу соответствия, именуемую далее
ARP-таблицей. Если требуемый физический адрес в ARP-таблице
существует, то все соответствующие кадры направляются на него. Если
нет, то отправляется широковещательный фрейм с IP-адресом искомого
хоста. Этот фрейм принимают все адаптеры, и если, обработав этот
запрос, удаленный хост видит в нем свой Интернет-адрес, то он отсылает
ответ запросившему устройству, в котором, помимо прочего, содержится и
MAC-адрес его адаптера. Эта информация добавляется в ARP-таблицу для
дальнейшего использования.
Формируемые описанным выше способом, то есть динамически, записи в
ARP-таблице сохраняются временно. Если в течение 20 минут (значение по
умолчанию) обращения к записи не происходит, она удаляется из таблицы.
Помимо динамических записей, в ARP-таблице могут быть созданы
постоянные (permanent), они же статические, записи. Они хранятся
"вечно" (точнее - до перезагрузки), и, кроме того, попытка установить
соединение с "чужим" IP-адресом с треском провалится, а в системном
журнале появится сообщение об ошибке. К слову сказать, изменение
динамической записи также сопровождается соответствующим сообщением,
но соединение при этом устанавливается без каких-либо трудностей.
Кроме того, если на момент подмены IP-адреса динамической записи с его
участием в ARP-таблице не существует, то и никаких разоблачающих
сообщений не появится.
Управлять записями ARP-таблицы позволяет одноименная утилита arp. Ее
полный синтаксис доступен в man arp(8). Нам понадобятся следующие
команды:
arp -a выводит содержимое таблицы ARP.
arp <host> выводит ARP-запись для заданного хоста.
arp -d <host> удаляет запись, соответствующую хосту.
arp -d -a удаляет все записи таблицы.
arp -s <host> <MAC-address> добавляет запись.
arp -f <file> добавляет записи из файла соответствия <file>.
Таким образом, дальнейшие действия понятны - для всех "критических" (а
если сеть небольшая - то просто для всех) IP-адресов можно создать
статические записи в ARP-таблице, тем самым исключив их подмену. Для
этого существует два пути:
* Использовать команду arp -s для создания каждой записи;
* Создать файл соответствия и выполнить команду arp -f .
Первый способ слишком трудоемкий, поэтому возьмем на вооружение второй
вариант. В этом случае файл соответствия требуется создать один раз, и
в дальнейшем будет очень легко обеспечить автоматическое заполнение
ARP-таблицы статическими записями при перезагрузке компьютера.
Формат файла соответствия продемонстрирован на следующем примере:
То есть в каждой строке записывается IP-адрес хоста (либо его
каноническое имя) и через пробелы или символы табуляции -
соответствующий ему MAC-адрес. Заполнить его достаточно просто -
включите все машины сегмента и обратитесь с них к серверу (или с
сервера к ним) любым способом, например, запустите на них браузер или
выполните обычный пинг. Это обновит ARP-таблицу, после чего достаточно
будет сохранить в файл результат выполнения команды "arp -an" и
немного его подправить, удалив все лишнее и добавив нужное. Сократить
необходимые правки позволит следующая команда:
Теперь файл ethers будет заполнен нужным образом. Останется только
удалить записи, которые мы хотим оставить динамическими (например,
маршрутизаторы CISCO при перезагрузке могут менять MAC-адрес своих
интерфейсов, выбирая их из некоторого пула, а добираться среди ночи на
работу, чтобы подправить ARP-таблицу - занятие не из приятных).
Для адресов, которые не задействованы в подсети, можно создать
статические записи с фиктивными физическими адресами (например,
00:11:22:33:44:55). Это исключит возможность использования кем-либо
данных IP-адресов.
Далее очищаем ARP-таблицу и заполняем ее из сформированного файла:
# arp -d -a
# arp -f /usr/local/etc/ethers
Естественно, имя и местоположение файла соответствия может быть любым
удобным для Вас. Теперь осталось занести указанные команды в сценарий
автозапуска, например, с именем /usr/local/etc/rc.d/statarp.sh:
#!/bin/sh
# Static ARP-table loader
case $1 in
start)
arp -d -a > /dev/null
arp -f /usr/local/etc/ethers > /dev/null
echo 'Static ARP-table is loaded'
;;
stop)
arp -d -a > /dev/null
echo 'Static ARP-table is unloaded'
;;
restart)
arp -d -a > /dev/null
arp -f /usr/local/etc/ethers > /dev/null
echo 'Static ARP-table is reloaded'
;;
status)
arp -an
;;
Осталось не забыть сделать данный файл исполняемым.
Итак, мы получили статическую таблицу соответствия между IP- и
MAC-адресами. Теперь выход в Интернет через FreeBSD-сервер с "чужого"
IP-адреса станет невозможным, если, конечно, заодно не подменить и
MAC-адрес (с последним явлением можно бороться разве что
организационными методами).
Но любая палка, как известно, о двух концах. За повышение защищенности
сети придется платить дополнительными заботами по администрированию,
поскольку теперь добавление новой машины в сеть, замена сетевого
адаптера, смена IP-адреса должны сопровождаться правкой и
перезагрузкой ARP-таблицы. Хотя это все равно лучше, чем бегать по
этажам, "вычисляя" недобросовестного пользователя.