Динамическая настройка сети на ноутбуке под FreeBSD

Tuesday, 11 April 2006

http://www.rostovlinux.ru/content/view/781/56/

Однажды мне надоело каждый раз вручную перенастраивать на ноутбук для каждой локальной сети, к которой я поключаюсь.

Поскольку DHCP используется не везде, то я написал несколько скриптов, настраивающих сеть за меня.

Предположим, имеются три локальные сети с маской 255.255.255.0 и адресами

192.168.1.0

192.168.2.0

192.168.3.0

Предположим так же, что в каждой из них есть маршрутизатор:

192.168.1.1

192.168.2.1

192.168.3.1

DNS-сервер:

192.168.1.53

192.168.2.53

192.168.3.53

В каждой из них нам выдается постоянный IP-адрес:

192.168.1.3

192.168.2.4

192.168.3.5

Конфигурация сети в таком случае будет состоять из нескольких этапов:

1) Присвоение IP-aдреса

2) настройка DNS

3) Настройка Firewall'а

4) настройка маршрутизатора по умолчанию

С первым пунктом никаких проблем - добавляем в /etc/rc.conf интерфейс и алиасы для него:

ifconfig_rl0="inet 192.168.1.3 netmask 255.255.255.0"

ifconfig_rl0_alias0="inet 192.168.2.4 netmask 255.255.255.0"

ifconfig_rl0_alias1="inet 192.168.3.5 netmask 255.255.255.0"

С DNS-серверами особой сложности тоже нет. Если локальные сети имеют доменные имена localnet1.com localnet2.com и localnet3.com, то /etc/resolv.conf выглядит так:

search localnet1.com localnet2.com localnet3.com

server 192.168.1.53

server 192.168.2.53

server 192.168.3.53

Нужно только учитывать, что параметр search может содержать не более 6 доменов общей длинной не более 255 символов.

Firewall. Я использую ipfw.

У ipfw есть опция -p, которая позволяет пропускать правила через текстовый фильтр. Дело за малым - осталось фильтр написать.

В моём случае выглядит он так:

#!/bin/sh

# /usr/local/bin/preproc-ipfw

# фильтр для шаблона првил ipfw

# Включаем "конфигурационный файл", содержащий список

# портов, разрешеных всем и список доверенных сетей

. /usr/local/etc/preproc-ipfw.conf

SED="/usr/bin/sed"

IFCONFIG="/sbin/ifconfig"

# получаем список серверов DNS из /etc/resolv.conf

NS="`cat /etc/resolv.conf | grep nameserver | awk '{print $2}' `"

NS=`echo ${NS} | ${SED} 's_ _,_g'`

# получаем список локальных интерфейсов

LOCAL_INTERFACES="`${IFCONFIG} -l | ${SED} 's_ _,_g'`"

# обрабатываем шаблон правил ipfw

RULES="`cat ${1}`"

echo "`${CAT} ${1}" |

${SED} -e "s_%ns%_${NS}_g"

-e "s_%localnet%_${LOCALNET}_g"

-e "s_%allowedportstcp%_${ALLOWED_ALL_PORTS_TCP}_g"

-e "s_%localinterfaces%_${LOCAL_INTERFACES}_g"

-e "s_%allowedportsudp%_${ALLOWED_ALL_PORTS_UDP}_g" `"

Конфигурационный файл в моём случае выглядит так:

#!/bin/sh

# /usr/local/etc/preproc-ipfw.conf

# конфигурационный файл фильтра шаблонов ipfw

# порты открытые по TCP

ALLOWED_ALL_PORTS_TCP="21,22,25,80,443,2628,3306,6667"

# порты открытые по UDP

ALLOWED_ALL_PORTS_UDP="123"

# доверенные сети

LOCALNET="192.168.112.0/24,192.168.1.0/24"

Теперь, собственно шаблон правил (/usr/local/etc/firewall.conf):

add allow ip from me to me via %localinterfaces%

add allow udp from %ns% to me

add allow udp from me to %ns%

add allow tcp from any to me %allowedportstcp%

add allow udp from any to me %allowedportsudp%

add allow udp from me %allowedportsudp% to any

add allow ip from %localnet% to %localnet%

add deny tcp from any to me tcpflags !ack

add allow tcp from me to any

add allow tcp from any to me

Сразу хочу сказать, что такой набор правил не обеспечивает достаточной защиты и приведен здесь только в качестве примера.

Добавляю в /etc/rc.conf следующее:

firewall_type="/usr/local/etc/firewall.conf"

firewall_flags=" -p /usr/local/bin/preproc-ipfw"

firewall настроен, пришла очередь маршрутизатора. С моей точки зрения, BGP и прочий роутинговый инструментарий на ноутбуке - это аристократическое излишество, поэтому я сделал все при помощи рабоче-крестьянского шела. Итак, в /etc/rc.conf

routerautoconf_enable="YES"

#!/bin/sh

#/usr/local/etc/rc.d/routerautoconf.sh

# скрипт для определения маршрутизатора

. /usr/local/etc/preproc-ipfw.conf

# используемые утилиты

NETSTAT="/usr/bin/netstat"

AWK="/usr/bin/awk"

GREP="/usr/bin/grep"

SED="/usr/bin/sed"

PING="/sbin/ping"

ROUTE="/sbin/route"

IPFW="/sbin/ipfw"

IPFW_ADD_RULE="add 1 allow icmp from any to any"

IPFW_DELETE_RULE="add 1 allow icmp from any to any"

# Список локальных сетей

LOCALNET="`echo "${LOCALNET}" | ${SED} 's_,_ _g'`"

#временно разрешаем пинги

${IPFW} ${IPFW_ADD_RULE}

# ищем, есть ли уже маршрутизатор по умолчанию

CURRENT_DEFROUTER="`${NETSTAT} -r -n -f inet | ${GREP} "default" | ${AWK} '{print$2 }'`";

# если он есть и пингуется...

if [ "${CURRENT_DEFROUTER}" != "" ] && [ "`${PING} -i 0.1 -c 5 -t 1 ${CURRENT_DEFROUTER} | ${GREP} "100% packet loss"`" = "" ]

then

# то всё отлично

echo "/etc/rc.conf's defaultrouter seems ok"

${IPFW} ${IPFW_DELETE_RULE}

exit 0;

# a вот если его нет или не пингуется...

else

${ROUTE} delete default

#проверяем все локальные сети

for NET in ${LOCALNET}

do

# предполагаем, что у router'а первый адрес в подсети

DEFROUTER="${NET%0/24}1"

# и снова пингуем

if [ "`${PING} -i 0.1 -c 5 -t 1 ${DEFROUTER} | ${GREP} "100% packet loss"`" = "" ]

then

# до тех пор, пока не запингуется

${ROUTE} add default ${DEFROUTER}

echo "Set default router to ${DEFROUTER}"

${IPFW} ${IPFW_DELETE_RULE}

exit 0

fi

done

fi

# если ничего не помогло - беспомощно разводим руками

echo "No any routers found. Sorry.."

${IPFW} ${IPFW_DELETE_RULE}

exit 1

Вот, собственно говоря, и всё.

Обновлено: 12.03.2015