FreeBSD tips: ARP в «заморозке»

Опубликована в журнале «Системный администратор«, Июль 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-таблицы статическими записями при перезагрузке компьютера.

Формат файла соответствия продемонстрирован на следующем примере:

	# Host			MAC-address
	192.168.0.1		00:05:5d:ce:d6:3f
	192.168.0.2		00:05:5d:29:ec:f4

То есть в каждой строке записывается IP-адрес хоста (либо его каноническое имя) и через пробелы или символы табуляции — соответствующий ему MAC-адрес. Заполнить его достаточно просто — включите все машины сегмента и обратитесь с них к серверу (или с сервера к ним) любым способом, например, запустите на них браузер или выполните обычный пинг. Это обновит ARP-таблицу, после чего достаточно будет сохранить в файл результат выполнения команды «arp -an» и немного его подправить, удалив все лишнее и добавив нужное. Сократить необходимые правки позволит следующая команда:

# arp -an | awk -v OFS="\t" '{print(substr($2, 2, length($2)-2), $4)}' > ethers

Теперь файл 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
		;;
	*)
		echo "Usage: `basename $0` {start|stop|restart|status}" >&2
		;;
esac
exit 0

Осталось не забыть сделать данный файл исполняемым.

Итак, мы получили статическую таблицу соответствия между IP- и MAC-адресами. Теперь выход в Интернет через FreeBSD-сервер с «чужого» IP-адреса станет невозможным, если, конечно, заодно не подменить и MAC-адрес (с последним явлением можно бороться разве что организационными методами).

Но любая палка, как известно, о двух концах. За повышение защищенности сети придется платить дополнительными заботами по администрированию, поскольку теперь добавление новой машины в сеть, замена сетевого адаптера, смена IP-адреса должны сопровождаться правкой и перезагрузкой ARP-таблицы. Хотя это все равно лучше, чем бегать по этажам, «вычисляя» недобросовестного пользователя.

Запись опубликована в рубрике *Lan&Wan, *Unix,*Linux, FreeBSD. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Я не спамер This plugin created by Alexei91