====== Устанавливаем корпоративный шлюз (два провайдера) на базе Ubuntu Server ====== Рассмотрим далее построение шлюза компании, выполняющего функции фаерволла. Шлюз будет построен на базе ОС Ubuntu Server 10.10. Итак, пусть имеется такая схема подключения корпоративной сети к Интернет: {{:doc:os:ubuntu:network_plan.png|}} Задачи, которые необходимо решить: * построить корпоративный шлюз, выполняющий необходимую маршрутизацию между локальной сетью и провайдерами * шлюз должен реализовывать функцию фаерволла для фильтрации входящего трафика * также шлюз должен реализовывать VPN сервер * а также кеширующий DNS сервер Важнейшая составляющая задачи построения шлюза состоит в необходимости маршрутизации компьютеров локальной сети через провайдеров: основная часть компьютеров будет маршрутизироваться через Провайдера 2 (Yota, в моем случае модем USB модель SAMSUNG ???), т.к. это дешевый канал, но и медленный, а один из компьютеров локальной сети должен выходить в Интернет через Провайдера 1 (ADSL) - быстрее чем Yota, но соответственно и дороже. Этапы работы. **1)** Установка ОС. Процесс установки подробно описан в сети, в частности вы можете посмотреть источник: http://www.howtoforge.com/perfect_setup_ubuntu_6.06 Некоторые замечания: я устанавливаю базовую версию ОС (т. е. без графической оболочки и т. п.). Все, что нужно, вы потом сможете самостоятельно доставить. Итак, считаем, что ОС поставлена. **2)** Выполняем базовую настройку ОС. - Задаем имя шлюза в /etc/hostname - если нужно, меняем пароль для root: sudo passwd root - если нужно, правим файл /etc/hosts - выполняем обновление ПО системы: apt-get update && apt-get upgrade - устанавливаем SSH сервер: apt-get install ssh openssh-server Выполняем настройку сетевых интерфейсов /etc/network/interfaces: # The loopback network interface auto lo iface lo inet loopback # WAN (ADSL) auto eth0 iface eth0 inet static address 192.168.1.10 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 ##metric 100 dns-nameservers 192.168.1.1 ## dns-nameserver IP1 IP2 # WAN (WiMax) auto wimax0 iface wimax0 inet dhcp # LAN auto eth2 iface eth2 inet static address 192.168.0.250 netmask 255.255.255.0 network 192.168.0.0 broadcast 192.168.0.255 **3)** Установка драйвера модема Yota. Linux был выбран не случайно: на данный момент времени имеются корректно работающие драйвера под эту ОС для модема Yota, тогда как для FreeBSD ситуация плачевная: драйвер есть, однако пока только для Current (в котором есть libusb-1.0 ?), и работа его не стабильна (качество связи с провайдером низкое, иногда связь вообще пропадает). Итак, поставим драйвер для модема Yota. Для этого с адреса http://code.google.com/p/madwimax/ скачаем последнюю сборку драйвера (или можете скачать у нас {{:doc:os:ubuntu:madwimax-0.1.1.tar.gz|здесь}}). Как устанавливать: - Заходим в консоль от имени рута (sudo -s). Распаковываем архив в отдельную папку. - Выполняем скрипт ./configure. Смотрим внимательно на вывод, т.к. в только что установленной системе нет многих компонентов, необходимых для сборки. Например, среди прочего, скрипт потребует установить docbook, docbook2x (apt-get install <имя требуемого пакета>), также будет сообщено о необходимости установки компилятора C (apt-get install gcc). Итак, строк вида error не имеется, можно выполнить команду: - make (находимся в том же каталоге, куда распаковали драйвер), и make install. Если сборка и установка будет пройдена успешно, подключаем модем. При этом, в системе должно появиться новое сетевое устройство с именем wimax0: # ifconfig | grep wimax wimax0 Link encap:Ethernet HWaddr 00:24:91:34:18:d7 **4)** Итак, ОС поставлена, ПО обновлено, драйвер модема поставлен. Включим режим маршрутизации. Источники: - https://help.ubuntu.com/community/Internet/ConnectionSharing Выполняем: sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" Добавляем в /etc/sysctl.conf: net.ipv4.conf.default.forwarding=1 net.ipv4.conf.all.forwarding=1 **5)** Следующая задача состоит в настройке фаерволла iptables, который уже встроен в ядро. Источники: - https://help.ubuntu.com/community/Internet/ConnectionSharing - https://help.ubuntu.com/community/IptablesHowTo - http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html Для начала, я сгенерировал правила со странички http://easyfwgen.morizot.net/gen/index.php. Это самый быстрый и простой способ "въехать" в фаерволл (т.к. я всегда работал с ipfilter во FreeBSD). Полученный код сохранил в текстовый файл, сделал его исполняемым. Выполнил. Проверил, что выполняются функции NAT. Замечания. * Обратите внимание на сгенерированный код, если нужно, поправьте внутренние переменные. * Обратите внимание на код, включающий маршрутизацию: if [ "$SYSCTL" = "" ] then echo "1" > /proc/sys/net/ipv4/ip_forward else $SYSCTL net.ipv4.ip_forward="1" fi Также, я закомментировал блок: #if [ "$SYSCTL" = "" ] #then # echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter #else # $SYSCTL net.ipv4.conf.all.rp_filter="1" #fi Почему это сделано, я поясню ниже. Также закомментировал блок: # if [ "$SYSCTL" = "" ] # then # echo "1" > /proc/sys/net/ipv4/conf/all/log_martians #else # $SYSCTL net.ipv4.conf.all.log_martians="0" #fi Т.к. со всех сторон шлюза я получаю адреса из частной сети, фаерволл не пропускал такие пакеты при включенной опции net.ipv4.conf.all.log_martians. * Блок: $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP задает политику по умолчанию - т.е. все, что явно не разрешено, будет запрещено. * Поскольку у меня к шлюзу подключены сразу два провайдера, в локальных таблицах маршрутизации будут две записи маршрутов по умолчанию с нулевой метрикой (route -n | grep 0.0.0.0), указывающие на разные шлюзы моих провайдеров, что недопустимо. Т.к. когда пакет из локальной сети "закатиться" в ядро, ядро основываясь на таблице маршрутизации не сможет принять решение, куда смаршрутизировать пакет. Мы решим эту проблему далее с помощью таблиц маршрутизаци, а пока можно удалить какой-нибудь один маршрут по-умолчанию: route del -net 0.0.0.0 dev eth0 Здесь я удалил маршрут по умолчанию к ADSL провайдеру (см. рис. выше), т.е. у меня остался всего один маршрут по-умолчанию к провайдеру Yota. Советую сразу команду по удалению маршрута по-умолчанию прописать в /etc/network/interfaces в группе настройки соответствующего интерфейса: # WAN (ADSL) auto eth0 ... up route del -net 0.0.0.0 dev eth0 ... Что это дает? Каждый раз при старте компьютера будет удаляться один маршрут по-умолчанию. Дальше, отладив скрипт, проверив связность фаерволла и локальной сети с Интернет, выполняем скрипт с ключом save. При этом в отдельный файл будут записаны текущие правила фаерволла (в формате, читаемом iptables). Чтобы каждый раз при старте системы загружались сохраненные правила, прописываем в /etc/network/interfaces: # WAN (ADSL) auto eth0 ... pre-up iptables-restore < /etc/iptables.rules.2 Я прописал в секции eth0, хотя это не имеет значения, т.к. правила содержат инструкции по фильтрации для каждого имеющегося в системе сетевого интерфейса. **6)** Формирование таблиц маршрутизации Источники: - http://linux-ip.net/html/adv-multi-internet.html - http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables Итак, на данный момент у нас имеется "полунастроенный" шлюз, который маршрутизирует весь трафик к Интернет только по одному каналу (в моем случае, Yota) (выше было объяснено, почему был удален один из маршрутов по умолчанию в случае, когда вы имеете подключение более, чем к одному провайдеру). Вначале было сказано, что важнейшей задачей является маршрутизация одного из компьютеров в локальной сети по другом каналу, т.е. нужно так настроить шлюз, чтобы он принимал решение, к какому из провайдеров направить очередной пакет из локальной сети. Займемся этим. Для того, чтобы посмотреть текущую таблицу маршрутизации, выполните любую одну из двух команд: ip route show route -n По-умолчанию в Линукс имеется три таблицы маршрутизации: локальная, главная и по-умолчанию. Чтобы увидеть, какие таблицы маршрутизации имеются в системе, выполните команду ip rule list. Например, чтобы посмотреть, какие маршруты хранятся в таблице маршрутизации main выполните: ip route list table main. Кстати, по-умолчанию, ip route show и route -n выводят маршруты именно из этой таблицы. Наша задача состоит в том, чтобы создать новую таблицу маршрутизации, где будут храниться все маршруты для канала ADSL. Создадим новую таблицу, для этого добавим в конец файла /etc/iproute2/rt_tables строку в формате "число1 имя_таблицы". Здесь: число1 - порядковый номер таблицы, имя_таблицы - буквенное имя. Совет: чтобы не путаться дальше, лучше задать одинаковое числовое значение в обоих полях. К примеру, выполним команду: echo 4 4 >> /etc/iproute2/rt_tables Тем самым мы создали новую таблицу маршрутизации с именем и порядковым номером, равным 4. Далее выполним команды: echo "Erase the route..." /bin/ip route flush cache /bin/ip route flush table 4 echo "Copy main routing table to adsl (ID 4) table" /bin/ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table 4 $ROUTE ; done /bin/ip route add table 4 default via eth0 Первые две команды очищают кеш таблиц маршрутизации, третья команда копирует все содержимое главной таблицы маршрутизации в нашу только что созданную под номером 4, за исключением маршрута по-умолчанию. Действительно, зачем нам в новой таблице маршрутизации запись о маршруте по-умолчанию из главной таблицы, если мы хотим прописать новый маршрут по-умолчанию? Четвертая команда как раз добавляет запись о маршруте по-умолчанию для ADSL линии в таблицу 4. Итак, мы хотим, чтобы наш компьютер в локальной сети с IP 192.168.0.90 выходил в сеть через ADSL провайдера, а все остальные компьютеры - через WiMax модем. В главной таблице маршрутизации у нас уже имеется маршрут по-умолчанию для провайдера Yota. Его мы "трограть" не будем. Но как нам сказать, что все, что идет от 192.168.0.90 должно идти через другой канал, т.е. другими словами, как привязать только что созданную таблицу маршрутизации к пакетам от 192.168.0.90? Делается это так (добавьте в конце файла с правилами iptables): $IPT -t mangle -A PREROUTING -s 192.168.0.90/32 -j MARK --set-mark 0x4 /bin/ip rule add fwmark 4 table 4 Все, теперь все пакеты от 192.168.0.90 будут "привязаны" к новой таблице маршрутизации, где запись маршрута по-умолчанию говорит, что пакеты надо отсылать через сетевой интерфейс, соединенный с каналом ADSL. **Замечание.** * после fwmark число должно указываться в шестнадцатеричном виде (тогда как в rt_tables значения добавляются в десятичном) * в пункте 5 было закомментировано $SYSCTL net.ipv4.conf.all.rp_filter="1", но не было пояснено почему. Эта опция помогает избежать спуфинга, когда входящие пакеты имеют адрес отправителя (source IP) не соответствующий сетевому интерфейсу, с которого он был отправлен. В моем случае, ядро просто уничтожало такие пакеты "тихо", в результате чего было потрачено очень много времени на выяснение причины. * я создал отдельный скрипт касательно работы с таблицой маршрутизации: #!/bin/sh # #if.up.sh echo "Erase the route..." INET_ADSL_GW="192.168.1.1" /bin/ip route flush cache /bin/ip route flush table 4 echo "Copy main routing table to adsl (ID 4) table" /bin/ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table 4 $ROUTE ; done /bin/ip route add table 4 default via $INET_ADSL_GW /bin/ip rule add fwmark 4 table 4 /bin/echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter /bin/echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter и поместил вызов в соответствующий блок в /etc/network/interfaces, т.о.: # WAN (ADSL) auto eth0 iface eth0 inet static address 192.168.1.10 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 ##metric 100 dns-nameserver 192.168.1.1 pre-up iptables-restore < /etc/iptables.rules.2 up /root/scripts/if.up.sh up route del -net 0.0.0.0 dev eth0 **7)** Принуждение записи логов IPTABLES в отдельный файл Я думаю, что многие сталкивались с проблемой, как заставить писать Iptables в отдельный файл, а не системный syslog и пр. Вот решение: - Выполняем команды:touch /etc/rsyslog.d/iptables.confПрописываем /etc/rsyslog.d/iptables.conf: :msg, contains, "fw: " -/var/log/iptables.log - Самое главное: во всех log-инструкциях Iptables я указываю префикс, который начинается с fw, типа этого:$IPT -A bad_packets -p ALL -m state --state INVALID -j LOG --log-prefix "fw: Invalid packet: "Т.е. Rsyslog будет отлавливать такие инструкции и помещать в отдельный файл. - Создаем файл /var/log/iptables.log, выполняем chown syslog /var/log/iptables.log - Перезапускаем rsyslogd: /etc/init.d/rsyslog restart - Убеждаемся, что логи Iptables идут по правильному адресу и не мусорят syslog и messages. TAG: {{tag>Ubuntu iptables}}