Дата: 22.07.2010       |  Сергей «grinder» Яремчук | Хакер №5/10

Большинство из нас привыкло к стандартным решениям, которые не пересматриваются годами. Так защиту винды мы доверяем одному и тому же комплекту программ — файрвол, антивирус, антишпионская программа… Подобный набор есть у каждого, отличаются лишь производители. Мы же попробуем другой путь — использовать в качестве блокпоста *nix-систему, запущенную в виртуальной машине. А насколько этот подход окажется эффективным в каждом конкретном случае, решать уже тебе.

Суть идеи
Встроенные виндовые средства — Windows Firewall и Internet Connection Sharing (Общий доступ к интернету) достаточно неудобны, малофункциональны и не обеспечивают должного уровня защиты. Поэтому, чтобы раздать интернет на несколько компов, с возможностью полноценного контроля всего процесса, требуется либо хардварный роутер, либо одно из софтовых решений, вроде UserGate Proxy & Firewall, NetworkShield Firewall или Kerio WinRoute Firewall. Роутер понятен в настройках, даже самые простые железки имеют минимальные функции фильтра пакетов, маршрутизации, защиты от атак и так далее. Но часто его возможности не дают развернуться на полную, и руки связаны тем, что заложено в него производителем. Более функциональные решения стоят соответственно, но и их возможностей может не хватать (например, шейпинга, учета трафика, мониторинга загрузки канала). Аналогичная ситуация и с софтовыми решениями. За хороший файрвол со всеми наворотами придется заплатить. Не стоит забывать о том, что защита работает, пока пользователь остается в домашней локальной сети, но стоит подключиться к инету через одну из многочисленных точек доступа за пределами дома, как мы оставляем компьютер с Windows Firewall, то есть практически беззащитным.

Мощности современных настольных систем вполне достаточно, чтобы установить виртуальную машину, которую и использовать в качестве файра для защиты локальной системы или шлюза для подключения других компьютеров домашней сети. Кроме того, на нем можно развернуть прокси, кэширующий DNS и прочие необходимые сервисы (например, IDS, VPN или IP-PBX). Естественно, в целях экономии ресурсов в виртуальной машине не стоит запускать десктопную ОС, вполне можно обойтись серверным дистрибутивом Linux в минимальной инсталляции, или взять одну из BSD систем. Например, OpenBSD в дефолтовой установке прекрасно работает, если ей выделить всего 32-64 Мб ОЗУ и 300 Мб места на харде, что, согласись, совсем немного, особенно учитывая возможности этой операционки. В дальнейшем мы рассмотрим настройки PF в OpenBSD и iptables в Linux. В качестве виртуальной машины будем использовать бесплатный VirtualBox, который достаточно прост в настройках и не жаден до оперативки. Хотя при желании его можно заменить QEMU, Virtual PC или другим решением. Еще вариант: создать образ в VMware Server (ключ выдается бесплатно), который затем задействовать в VMware Player.

Виндовые разборки
Чтобы исключить выход хостовой ОС в интернет, в настройках реального сетевого адаптера снимаем все флажки, за исключением VirtualBox Bridged Networking Driver. В том числе нужно убрать поддержку "Протокол Интернета (TCP/IP)" и "Клиент для сетей Microsoft". В настройках виртуального сетевого интерфейса, появившегося после установки VirtualBox, в качестве шлюза по умолчанию и DNS-сервера указываем IP-адрес "внутреннего" (LAN) интерфейса гостевой ОС, запущенной в виртуальной машине (vic1 в случае OpenBSD или eth1 в Linux). Здесь также выключаем "Клиент для сетей Microsoft". При создании виртуальной машины указываем два сетевых адаптера. В одном указываем тип подключения "Сетевой мост" и выбираем в списке "Имя" реальный сетевой адаптер (например, Wi-Fi), подключенный к интернет. Тип второго указываем как "Виртуальный адаптер хоста", через него и будем подключаться к глобальной сети.

Считаем, что гостевая система уже установлена, и переходим непосредственно к настройкам.

Настройка PACKET FILTER
Первым делом нужно включить форвардинг пакетов между двумя сетевыми интерфейсами:

# sysctl net.inet.ip.forwarding=1

Чтобы изменение вступало в силу после каждой перезагрузки, снимаем комментарий с соответствующей строки файла /etc/sysctl.conf. Далее создадим простейшее правило для выхода в интернет через NAT, пишем в pf.conf:

# vi /etc/pf.conf

nat on vic0 from vic1:network to any -> vic0
block in all
pass in on vic1

Здесь активирована трансляция адресов для сети, подключенной к интерфейсу vic1, с которого разрешен весь трафик. Все порты прикрыты. Проверяем файл на наличие ошибок и применяем правила:

# pfctl -nf /etc/pf.conf
# pfctl -vf /etc/pf.conf

В выводе консоли получим все активные правила PF, причем вместо названий интерфейсов будут указаны IP-адреса. Чтобы проверить состояние NAT, набираем:

# pfctl -s state

Теперь входим в интернет с локальной системы и сканируем внешний IP (выданный провайдером) при помощи сканера вроде nmap на наличие открытых портов. Далее развиваем созданные правила, разрешив, например, выход в интернет только по определенным портам:

# vi /etc/pf.conf

tcp_srv = "{ ssh, smtp, domain, www, pop3 }"
udp_srv = "{ domain }"
block all
pass out inet proto tcp to any port $tcp_srv
pass out inet proto udp to any port $udp_srv

Вместо названий сервисов из /etc/services в правиле можно указать номера портов, здесь кому как удобнее. Просмотреть статистику при помощи pfctl достаточно просто:

# pfctl -s info

Для более наглядного мониторинга можно использовать утилиты вроде ntop или pftop. Для этого через переменную окружения PKG_PATH указываем FTP-зеркало (wwwopenbsd.org/ftp.html), с которого будем ставить прекомпилированные пакеты:

# export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.6/packages/i386

И выполняем установку:

# pkg_add pftop
# pkg_add ntop

Дополняем схему
Уменьшить количество входящего трафика, сократить время загрузки страниц и порезать баннеры поможет кэширующий прокси-сервер Squid.

# pkg_add squid-2.7.STABLE6.tgz

Открываем конфигурационный файл /etc/squid/squid.conf и разрешаем подключения:

# vi /etc/squid/squid.conf

http_port 3128
### В случае прозрачного проксирования директива примет вид:
# http_port 127.0.0.1:3128 transparent
### Указываем диапазон IP внутренней сети
acl lan_net src 192.168.1.0/24
### Разрешаем выход в интернет из сети 192.168.1.0/24
http_access allow lan_net
### Размер кэша указываем с учетом объема ОЗУ, выделенного VM
cache_mem 32 MB
maximum_object_size 10240 KB
cache_dir ufs /var/squid/cache 5000 16 256

Создаем каталог для кэша и запускаем кэширующий проксик:

# squid -z
# squid

Теперь можно проверить, слушается ли нужный порт:

# netstat -ant | grep 3128

Перестраиваем браузеры на подключение через порт 3128 интерфейса vnec1 и пробуем обратиться к внешнему веб-сайту. Как вариант, можно настроить прозрачное проксирование, чтобы пользователи, пытающиеся подключиться к 80 и 8080 портам внешних web-серверов, автоматически перенаправлялись на локальный порт, на котором работает Squid:

# vi /etc/pf.conf

table <clients> { 192.168.1.2, 192.168.1.5 }
table <nocache> { 192.168.1.0/24 }
rdr on inet proto tcp from <clients> to ! <nocache> port { 80 8080 } -> 127.0.0.1 port 3128

Когда все настроено, обеспечиваем автозагрузку Squid при старте системы:

# vi /etc/rc.local

if [ -x /usr/local/sbin/squid ]; then echo -n 'squid'; /usr/local/sbin/squid
fi

При желании Squid можно дополнить другими модулями. В портах есть squidGuard и HAVP (HTTP Anti Virus Proxy). Первый поможет в борьбе с баннерами, блокировкой файлов и определенных ресурсов, второй умеет проверять трафик несколькими антивирусами.

# pkg_add squidguard
# pkg_add havp

Настройка squidGuard и HAVP подробно описана в статье "Вооруженный бронекальмар", опубликованной в июньском номере ][ за 2008 год, поэтому здесь не останавливаемся. Кстати, подобная схема с виртуальным файрволом может быть интересна тем, кто хочет максимально обезопасить свое пребывание в интернет. Не секрет, что браузер на сайте оставляет своеобразный отпечаток, который может поведать многое о твоей системе. Применение прокси-сервера позволяет скрыть большую часть информации путем модификации заголовков. Для тех, кто не хочет возиться со Squid, могу порекомендовать Privoxy (Privacy Enhancing Proxy) — некэширующий прокси с возможностями фильтрации контента для повышения приватности и безопасности веб-серфинга. Установка Privoxy сводится к выполнению команды:

# pkg_add privoxy

Теперь настраиваем браузер, чтобы он выходил в интернет через порт 8118, и набираем в адресной строке http://config.privoxy.org/ (краткая форма: --). В результате получаем возможность редактирования параметров прокси-сервера. Дефолтные правила обеспечивают блокировку Cookies, pop-up, некоторых типов баннеров. По умолчанию Privoxy слушает только локальный интерфейс, для доступа к нему с хостовой машины или из LAN следует изменить инструкцию listen-address в config.txt, указав IP сетевого интерфейса vic1:

listen-address 191.168.1.1:8118

Возможностей, как и настроек, в Privoxy очень много, подробно он рассматривался в статье "Маленькое окно в большую сеть", опубликованной в ][ 03.2007. При необходимости можно заставить его работать в тандеме с кальмаром, для чего в squid.conf достаточно добавить всего одну строку:

cache_peer 127.0.0.1 parent \8118 7 no-query

В качестве еще одного бонуса к нашему интеллектуальному файрволу можно порекомендовать легкий кэширующий DNS (а также TFTP и DHCP) сервер Dnsmasq. Ставится он просто:

# pkg_add dnsmasq

После этого в конфигурационном файле dnsmasq.conf указываем сетевой интерфейс, на котором он будет принимать запросы:

listen-address=127.0.0.1, 192.168.1.1

Теперь все повторные DNS-запросы будут выдаваться из кэша и выполняться быстрее.

Настройка IPsec В OpenBSD
Теперь научим виртуальный файр подключаться по VPN. Разберем соединение по протоколу IPsec при помощи утилиты ipsecctl, входящей в стандартную поставку. Итак, наша внутренняя сеть 192.168.1.0/24, внешний WAN интерфейс получает IP-адрес 1.2.3.4, соответственно в  удаленном офисе LAN - 192.168.2.0/24 и WAN — 5.6.7.8. Открываем в редакторе конфиг /etc/ipsec.conf и указываем настройки сетей:

# vi /etc/ipsec.conf

ike esp from 192.168.1.0/24 to 192.168.2.0/24 \peer 5.6.7.8
ike esp from 1.2.3.4 to 192.168.2.0/24 \peer 5.6.7.8
ike esp from 1.2.3.4 to 5.6.7.8

На удаленном хосте файл /etc/ipsec.conf будет аналогичным, только заменяем IP и в описании подключения добавляем ключ passive, означающий, что данный узел будет ожидать подключение (соединение инициализирует удаленная система):

ike passive esp from 5.6.7.8 to 1.2.3.4

В правилах PF разрешим подключение с удаленного узла и укажем, что не нужно фильтровать трафик, проходящий через интерфейс обратной петли, а также через внутренний и виртуальный интерфейсы:

# vi /etc/pf.conf

set skip on { lo vic1 enc0 }
pass quick on vic0 from 5.6.7.8

Теперь с VPN-сервера копируем публичный ключ и сохраняем его в /etc/isakmpd/pubkeys/ipv4/5.6.7.8, а свой ключ /etc/isakmpd/private/local.pub передаем на 5.6.7.8. Набираем на обоих хостах:

# isakmpd -K
# ipsecctl -f /etc/ipsec.conf

Если все проходит нормально, обеспечиваем автозапуск при загрузке системы (если в этом есть необходимость). Для чего добавляем в /etc/rc.conf.local одну строку:

isakmpd="-K"

C OpenBSD, надеюсь, все понятно. Перейдем к Linux, многие вопросы, за исключением настройки правил пакетного фильтра и установки программ, будут аналогичны.

Организация NAT в Linux
В Linux пакетный фильтр Netfilter управляется при помощи консольной утилиты iptables. Настройки отличаются по написанию, но, по сути, остаются теми же. Для начала разрешаем форвардинг пакетов:

# echo 1 > /proc/sys/net/ipv4/ip_forward

Или как вариант:

# sysctl -w net.ipv4.ip_forward=1

Чтобы форвардинг активировался при загрузке системы, используем /etc/sysctl.conf:

net.ipv4.ip_forward = 1

Обрати внимание, переменная механизма sysctl несколько отличается от аналогичного параметра в OpenBSD. В различных дистрибутивах могут быть свои особенности. Так в CentOS/Fedora достаточно ввести одну команду:

# system-config-securitylevel

Проверяем:

# service iptables status

В качестве альтернативы в этих дистрибутивах можно использовать chkconfig. Смотрим статус запуска iptables:

# chkconfig --list iptables

И активируем при необходимости:

# chkconfig iptables on

Пусть внутренний сетевой интерфейс (к которому подключается локальная система) будет eth1, а внешний — eth0. Чтобы включить NAT в Linux и разрешить все соединения, достаточно прописать три правила:

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

Для большей защиты можно разрешить доступ только к определенным сервисам:

iptables -A OUTPUT -j ACCEPT -m state --state NEW,ESTABLISHED,RELATED -o eth0 -p tcp -m multiport --dports 80,443,8080 --sport 1024:65535

Чтобы NAT работал и после перезагрузки, в Ubuntu сохраняем все настройки iptables в файл при помощи утилиты iptables-save:

# iptables-save > /etc/iptables.rules

И заносим эту строку в один из скриптов, выполняющихся при остановке системы (например, скрипты из каталога /etc/network/if-postdown.d). Чтобы правила при загрузке загружались автоматически, добавляем в конец файла /etc/networks/interfaces следующую запись:

# vi /etc/networks/interfaces

### Загружаем правила при поднятии интерфейса
pre-up iptables-restore < /etc/iptables.rules

В CentOS правила сохраняются командой:

# service iptables save

После этого все рулесеты можно найти в /etc/sysconfig/iptables. Для автоматической их загрузки при старте системы достаточно разрешить два параметра в файле /etc/sysconfig/iptables-config:

# vi /etc/sysconfig/iptables-config

IPTABLES_SAVE_ON_STOP="yes"
IPTABLES_SAVE_ON_RESTART="yes"

Просмотреть список правил iptables можно командой:

# iptables -L -v

Все, с файром разобрались. Теперь можно наращивать функционал. Squid есть в репозитариях пакетов и ставится очень просто. В Debian/Ubuntu:

# apt-get install squid

Или в CentOS:

# yum install squid

Чтобы не перестраивать клиентские системы, добавим правила iptables:

iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --todestination 192.168.1.1:3128
iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128

При желании Squid можно дополнить другими модулями — Adzapper, squidGuard и HAVP.

Заключение
Мы получили абсолютно бесплатный файрвол с продвинутыми функциями, надежно защищающий хостовую Windows машину, и функционал которого можно наращивать до бесконечности. Возможно, кто-то посчитает его неудобным, но проблему быстрой загрузки можно решить, просто замораживая состояние виртуальной машины. К тому же такой виртуальный блокпост можно использовать не всегда, а только в особых случаях.