LXF87-88:Безопасность

Материал из Linuxformat.

(Различия между версиями)
Перейти к: навигация, поиск

Версия 14:51, 30 июля 2008

Безопасность

Содержание

Строим межсетевой экран на базе Linux

ЧАСТЬ 4 Любой подключенный к сети компьютер открыт для атаки. Д-р Крис Браун научит, как уменьшить вашу уязвимость, создав заслон при помощи стандартных утилит Linux.

В речи по поводу Дюнкеркской эвакуации, перед тем, как сказать «Мы будем сражаться на пляжах», Уинстон Черчилль изрек «Мы защитим наш остров любой ценой». Компьютеры – наши прекрасные маленькие островки, но они всегда находятся под обстрелом, о чем свидетельствуют журналы любого Linux-сервера, имеющего внешний IP-адрес.

Межсетевые экраны (брандмауэры) – один из наиболее важных рубежей обороны вашего компьютера. Это сетевые устройства (как аппаратные, так и программные, запускаемые на обычном компьютере), контролирующие трафик между внутренней сетью и Интернетом. Есть несколько технологий создания таких экранов. Например, запросы от клиента по протоколам прикладного уровня (HTTP, FTP или DNS) перенаправляются через прокси-сервер; таким образом, прямое соединение между узлом локальной сети и Интернетом становится ненужным. Трансляция сетевых адресов (NAT или маскарадинг) также делает вашу сеть невидимой снаружи, позволяя еще и использовать свой диапазон адресов внутри сети. Однако наш сегодняшний урок посвящен классическому пакетному фильтру, работающему на сетевом уровне (IP). Я покажу вам, как настроить его в Linux.

Часть 1: Разбираем iptables

Рис. 1. Три стандартных цепочки позволяют фильтровать входящие, исходящие и проходящие пакеты.
Рис. 1. Три стандартных цепочки позволяют фильтровать входящие, исходящие и проходящие пакеты.

В недрах ядра скрывается кусок кода под названием netfilter (сетевой фильтр) – он выполняет фильтрацию IP-пакетов: проверяет каждый исходящий и входящий пакет и решает его судьбу, основываясь на его параметрах, таких, как исходные и конечные адреса и порты или флаги заголовка TCP.

Два главных действия, выполняемых netfilter – принять пакет или, соответственно, отклонить его. Он также может вести журнал с помощью сервиса syslogd. Используя netfilter, можно настроить Linux-машину как межсетевой экран с фильтрацией пакетов.

Обычно в роли межсетевого экрана выступает машина, работающая между внутренней сетью предприятия и большим и злым Интернетом и защищающая данные корпоративных компьютеров от взломщиков, коварных скриптописцев и вирусов. В данном случае фильтрация применяется к пакетам, приходящим извне и переправляемым во внутреннюю сеть. Можно также фильтровать пакеты, идущие на межсетевой экран изнутри или исходящие из него; то есть использовать netfilter как персональный брандмауэр, пригодный даже для одиночной домашней машины, подключенной к сети через ADSL или модем.

Netfilter настраивается с помощью специальных правил, задаваемых из консоли командой iptables. Ее синтаксис – полноценный язык со своими правилами. Типичное правило включает в себя компоненты для распознавания определенных пакетов и заканчивается директивой принятия или отклонения подобного пакета. Вот пример того, как это выглядит:

iptables -A INPUT -i eth0 -p udp -s $NAMESERVER --sport 53 -d 140.116.5.1 --dport 53 -J ACCEPT

Чтобы разобраться в этом, нужно представить, какими путями пакеты приходят, проходят и уходят с вашей машины. Есть три варианта, показанные на рис. 1. Входящий пакет проверяется пакетным фильтром, и следует его решению. Если адрес доставки пакета соответствует данной машине, пакет проходит через входную цепочку (Input) и идет вверх по стеку протоколов. Если пакет предназначен для другой машины, реализация протокола сетевого уровня опрашивает таблицу маршрутизации, чтобы узнать, на какой сетевой интерфейс его отправить. Затем он идет по цепочке Forward и возвращается в сеть. Наконец, пакеты, формируемые на данной машине, проходят через выходную цепочку (Output) и попадают в сеть. Каждая из этих цепочек, в сущности, является простым набором условий, через проверку которых и проходит пакет.

Настроим индивидуальные фильтры

Теперь вы понимаете, что в примере выше мы добавляем правило во входную цепочку (-A INPUT). Условие гласит, что пакет должен придти на сетевой интерфейс eth0, и это должен быть UDP-пакет. Оно также указывает исходные адрес и порт, а также адрес и порт назначения, которым должен соответствовать пакет. Эта информация передается в заголовке пакета. Завершающая часть (-J ACCEPT) говорит netfilter, что делать с тем пакетом, который соответствует всем указанным в правиле параметрам. Эта часть называется целью условия. Возможные цели таковы:

  • ACCEPT – принять пакет;
  • DROP – молча отклонить пакет;
  • REJECT – отклонить пакет и сказать об этом отправителю;
  • LOG – записать прибытие пакета (и позволить ему пройти к следующему условию).

Списки условий для цепочки могут быть весьма длинными: 50 – обычнейшее количество. Для каждого пакета проверяется каждое условие. Как только произойдет совпадение, будет предпринято соответствующее решение (цель), и следующие условия проверяться уже не будут. Если пакет доходит до конца цепочки, не удовлетворив ни одному условию, его судьба зависит от «политики» цепочки. Например,

iptables -P INPUT DROP

говорит, что все такие пакеты будут отклонены. Простейший способ создания набора условий – установить политику по умолчанию в DROP, а затем добавлять условия для нужных пакетов. Это подход с «презумпцией виновности». Другой подход (установка политики по умолчанию в ACCEPT, а затем создание правил для блокировки ненужных пакетов) гораздо сложнее, менее безопасен и не рекомендуется. Вы можете улучшить организацию ваших правил, определив собственные цепочки и присвоив им имена. Например, я могу определить цепочки TCP_RULES и UDP_RULES. Затем, в главной входной цепочке я могу задать всего два предопределенных правила:

iptables -A INPUT -p tcp -J TCP_RULES
iptables -A INPUT -p udp -J UDP_RULES

Это позволяет более гибко управлять наборами правил, да и более эффективно; например, UDP-пакет никогда не будет сравниваться с правилами из цепочки TCP_RULES. Я предпочитаю думать, что прыжки по цепочке аналогичны проходам по процедурам (подпрограммам).

Механизм «попакетной» проверки IP-трафика – лишь половина умений iptables. Возможно еще записывать, когда происходит TCP или UDP-транзакция, и проверять пакеты не только по их заголовкам, но и в контексте совершаемого соединения... Борюсь с искушением вдаться в подробности, иначе урок разросся бы до размеров журнала.

Можно настроить межсетевой экран путем создания полного набора правил и команды iptables, как было показано. Начните с политики безопасности, определяющей, какие сервисы должны быть доступны, вычислите, какой трафик они генерируют, поместите соответствующие правила в цепочки, а все остальное запретите. Все это требует отличного знания TCP/IP и большой внимательности. Построение межсетевого экрана таким способом аналогично созданию большого web-сайта путем ручной верстки в vi или написанию программ на Ассемблере. Другими словами, это лучше оставить экспертам, которым нужен полный контроль над каждой настройкой.

Но если вы все-таки решите дерзнуть, ознакомьтесь с материалом по iptables из LXF47. Мы положили его на диск в формате PDF.

Часть 2: Простой путь

Я показал вам продвинутый путь настройки межсетевого экрана, однако большинство из нас (включая меня), возможно, предпочтут использование утилиты, которая позволит указать политику безопасности на более высоком уровне и сгенерирует команды iptables сама. А потом их можно будет подредактировать, как описано в первой части.

Мне нравится модуль конфигурации брандмауэра YaST в SUSE. Он позволит вам настроить брандмауэр примерно на том же уровне, на котором вы задаете политику безопасности, в противоположность уже рассмотренному нудному процессу ручного ввода команд. Модуль требует указать для каждого сетевого интерфейса три зоны: внешнюю, внутреннюю или демилитаризованную. Эти термины иллюстрируются рис. 2, где показана архитектура классического межсетевого экрана в корпоративной сети.

Внешние интерфейсы – те, что подключены к огромному злому Интернету; в домашних условиях это обычно ADSL или простой модем. Если у вас всего одна машина, ваш сетевой интерфейс будет внешним.

Внутренние сетевые интерфейсы – те, что подключены к доверенным узлам. В небольшом офисе, где как шлюз используется Linux-машина, это будет интерфейс, подключенный к локальной сети.

Демилитаризованная зона (DMZ) – это сеть, в которой находятся видимые снаружи машины, например, Web/FTP/почтовые-серверы. Сказать по правде, если вы настраиваете межсетевой экран для использования в корпоративной среде с DMZ, вы обязаны изучить более глубокие материалы по данной тематике. Тот же модуль YaST, к примеру, недостаточно гибок для настройки направления пакетов между внутренней сетью и DMZ; он всего лишь определяет правила ограничения доступа к машине из всех трех зон.

Если интерфейс у вас на компьютере только один, не имеет значения, считаете ли вы его внешней или внутренней зоной. Назначьте зону произвольно и определите доступные сервисы, как мы покажем далее.

Определив, какие сетевые интерфейсы соответствуют нужным зонам, переходите на экран доступных сервисов для каждой из зон (рис. 3). Слева вы видите перечень семи экранов модуля YaST, справа – выпадающие списки зон и сервисов (DNS, IMAP, HTTP и т. д.). Выберите зону и определите доступные ей сервисы.

Для разрешения доступа к сервису, выберите его из списка и нажмите Add (Добавить). Чтобы запретить сервис, выделите его и нажмите Remove (Удалить). Для сервисов, которых нет в списке, вы должны будете указать номер порта. Например, для разрешения Telnet-сеансов (возможно, вы захотите разрешить их только для внутренней сети, поскольку Telnet небезопасен) нажмите на Advanced... и введите номер порта (23) в поле TCP Ports. Внутренняя зона должна обрабатываться по-особому. Внизу вы найдете флажок Protect Firewall From Internal Zone. Пока он не отмечен, к пакетам, исходящим из внутренней сети, не будут применяться никакие правила.

За кулисами

Модуль YaST не генерирует правила iptables напрямую. Вместо этого он редактирует файл /etc/sysconfig/SuSEfirewall2. Если у вас SUSE, рекомендую изучить этот файл. Он очень хорошо прокомментирован и углубит ваше понимание действий YaST, а также предоставит синтаксически более сложные примеры.

Сам межсетевой экран настраивается на раннем этапе загрузки через два скрипта, SuSEfirewall2_init и SuSEfirewall2_setup, находящиеся в директории /etc/init.d. Первый запирает брандмауэр (пропуская только трафик bootp и ping), а второй, запускающийся несколько позже, устанавливает цепочки правил при включении брандмауэра и очищает их при отключении. Оба скрипта в конечном итоге вызывают /sbin/SuSEfirewall2: это движок механизма межсетевого экрана в SUSE, и в нем генерируются команды iptables. Я бы не рекомендовал вам в нем копаться (особенно после плотного обеда), если вы не любитель скриптоужастиков.

Брандмауэр Fedora

Не только в SUSE есть графические утилиты для настройки брандмауэра. На рис. 4 показана утилита system-config-securitylevel, входящая в Fedora. Это более простой инструмент, чем модуль YaST. Она не позволяет определять зоны, а просто закрывает и открывает нужные порты, и подходит только для настройки личного брандмауэра на одиночной машине.

Вы можете просмотреть ваши правила, выполнив команду iptablessave (ее вывод показан на рис. 5). Здесь вы видите пример определенной пользователем цепочки (RH-Firewall-1-INPUT), устанавливающей правила как для входящей, так и для исходящей цепочек. Если сохранить вывод iptables-save в файле, из него можно будет восстановить правила командой iptables-restore.

Netfilter имеет и другие возможности (например, NAT и фильтрацию по состояниям), я о них успел только намекнуть. Есть и другие методы, например, прокси-серверы уровня приложений, они тоже полезны при настройке межсетевого экрана.

Предотвращение скрытого сканирования

В прошлом месяце я рассказывал о скрытом сканировании с помощью Nmap. Этот вид сканирования использует нештатные комбинации флагов TCP-пакетов, а скрытым называется, поскольку маловероятно, что системный журнал его зафиксирует. Однако, используя способность netfilter проверять флаги в заголовке TCP-пакета и записывать события в журнал, можно не только блокировать подобные попытки, но и регистрировать факт их наличия. Подробности довольно запутанны, но пример пары правил против FIN-сканирования прояснит суть этой идеи:

iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j LOG --log-prefix "Stealth scan"
iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP

Первое правило служит для обязательной записи события в журнал. После цели LOG пакет продолжает движение по цепочке условий (в отличие от целей DROP и ACCEPT. Принятые или отклоненные пакеты на дальнейшую проверку не пойдут). В данном случае пакет, удовлетворяющий первому условию, удовлетворит и второму, согласно которому он будет отклонен. Параметры --tcp-flags ACK,FIN FIN описывают комбинацию TCP-флагов. Первый список состояний (ACK,FIN) перечисляет тестируемые флаги, второй (FIN) – те из них, что установлены. Таким образом, условие соответствует тем пакетам, в которых есть FIN-флаг, но нет ACK. При нормальном TCP-соединении эта комбинация невозможна, зато типична для скрытого сканирования.

Проведите эксперимент: если у вас две Linux-системы, выберите одну из них мишенью, а на второй запустите нечто вроде

nmap -sF -p1-50 192.168.0.3

(подставьте нужный IP-адрес). Nmap сообщит вам об открытых портах. Если вы проследите судьбу пакетов через Ethereal, то увидите, что FIN-пакеты достигли цели, а в ответ были отправлены пакеты RST,ACK. Теперь добавьте на системе-мишени два правила, показанных выше, и повторите попытку. Вы увидите, что Nmap больше не обнаруживает открытые порты, а в журнале (у меня это /var/log/firewall) появились новые сообщения. Ethereal покажет, что FIN-пакеты по-прежнему доходят, но не получают ответа. На подобных экспериментах можно научиться многому. Вот вам развлечение для дождливого вечера!

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию