Содержание статьи
Файрвол, как и многое другое в RouterOS, пришел из Linux и представляет собой доработанный iptables. Поэтому многие мануалы по настройке iptables легко можно сконвертировать в формат RouterOS. Файрвол состоит из следующих таблиц:
- Filter — занимается фильтрацией трафика — определяет, пропустить пакет в сеть или отбросить его. Мы будем рассматривать работу только этой таблицы;
- NAT — Network Address Translation. Изменяет проходящие пакеты. Поменять адрес источника или порт назначения — дело именно этой таблицы. В основном она используется для обеспечения доступа в интернет из локалки и обратно. Иногда без NAT невозможно работать в плохо спроектированных сетях, а еще его, бывает, используют в качестве «костыля»;
- Mangle — классифицирует и маркирует трафик и может менять некоторые поля в заголовке (TTL, ToS, DF). Применяется для построения сложных путей трафика (например, когда подключено два провайдера или нужны разные пути трафика для RDP и VoIP);
- Raw — обрабатывает пакеты до их попадания в Connection Tracking. Пригодится для защиты от DoS или при работе с большими объемами трафика.
Таблицы состоят из цепочек. Цепочки в разных таблицах могут отличаться. Чуть позже станет ясно почему. В нашей таблице Filter три цепочки:
- input — трафик к самому роутеру. Обязательное условие попадания в input — адресом назначения пакета должен быть один из адресов роутера, широковещательный адрес сети или широковещательный адрес работающей на роутере службы. Сюда попадает WinBox, SSH, WebFig, ping, VPN и другой трафик, предназначенный роутеру. Полный список можешь посмотреть в вики. В этой цепочке мы должны защищать сам роутер;
- output — трафик от роутера. Ответы на прилетевшее в input или новые пакеты от роутера (пинг, VPN, SSH-сессия с самого роутера). Эта цепочка редко используется, так как часто роутер считается доверенным звеном и пакеты, генерируемые им, по умолчанию легитимны. Но, как показывает история взломов, контроль исходящего трафика может выявить заражение на начальных этапах;
- forward — трафик, проходящий через роутер (когда пакет прилетел в один интерфейс и вылетел с другого или того же самого). Трафик из локалки в интернет, из интернета в локалку, из одного VLAN локалки в другой;
- user chains — пользовательские цепочки. Админ может создавать цепочки правил по своему усмотрению. Это бывает полезно для декомпозиции больших конфигураций. К примеру, можно весь трафик на порты 80 и 443 завернуть в отдельную цепочку WEB и в ней уже делать десятки правил для фильтрации — это визуально упростит настройку, хотя качественно на прохождение трафика не повлияет.
Два важных момента, о которых нужно помнить.
Момент первый. У трафика в forward всегда есть входящий и исходящий интерфейсы — трафик влетел в input, обработался процессом маршрутизации и должен вылететь в output. У входного трафика не может быть исходящего интерфейса — он обработается внутри роутера и никуда дальше не полетит. Также у выходного трафика не может быть входящего интерфейса — этот трафик генерируется самим роутером (это либо новый трафик, либо созданный роутером ответ на трафик, пришедший в input).
Момент второй. У трафика не существует «внешнего» или «внутреннего» интерфейсов. Роутеру плевать, что ты считаешь внешним, — для него есть интерфейс, в который трафик вошел, и интерфейс, с которого трафик уйдет.
Правила образуют цепочки. У каждого правила может быть только одна цепочка. По умолчанию политика у всех цепочек — все разрешено. Правила срабатывают в таблицах в зависимости от их порядка: сначала пакет обработается первым правилом, затем вторым и так далее. Хорошим тоном считается упорядочивать правила внутри таблиц по цепочкам: сначала — пачка правил input, затем — forward, в конце — output.
Трафик будет проходить по правилам только в пределах своей цепочки. И если сначала идет input, потом forward, затем снова input, то трафик input все равно никогда не попадет в forward, то есть такое расположение правил не повлияет на прохождение трафика, а только запутает админа. В пределах одной таблицы пакет не перепрыгнет из одной цепочки в другую, пока админ это явно не укажет.
Connection Tracking
Еще одна важная вещь для понимания работы файрвола — механизм определения состояния соединений — Connection Tracking (или просто ConnTrack). У RouterOS есть специальная таблица, в которой хранятся данные о состоянии соединений. Благодаря ей работает NAT и многие другие части файрвола.
Механизмы ConnTrack проверяют, принадлежит ли пришедший на роутер пакет какому-либо из потоков, чтобы применить к нему политики всего потока или как-то упорядочить пакеты в пределах одного или нескольких потоков (например, для нарезки скорости).
Для ConnTrack существуют четыре состояния пакетов:
- new — новый пакет, не принадлежащий ни одному из известных потоков. Это может быть первый пакет для коннекта к серверу RDP, или первый пакет в потоке WinBox, или запрос к DNS. Система запоминает Source IP, Source Port, Destination IP, Destination Port и некоторые другие параметры и записывает эти данные в таблицу. Следующий пакет с такими же данными будет относиться к записанному потоку;
- established — пакет, принадлежащий существующему потоку. То есть пакет, у которого Source IP, Source Port, Destination IP, Destination Port подходят под одну из записей таблицы ConnTrack (или обратный пакет);
- related — пакет, порожденный другим потоком. Некоторые протоколы, такие как FTP, SIP, PPTP, используют для работы несколько потоков. Например, управляющие команды FTP ходят по порту TCP 21, но данные передаются с порта TCP 20. При попытке получения или отправки данных на FTP в потоке на порт 21 сервер сообщает: «А сейчас я открою 20-й порт, и ты забирай данные с него», после этого клиент посылает пакет на 20-й порт сервера. Этот пакет будет считаться related, так как он порожден потоком 21-го порта;
- invalid — все, что не относится к перечисленным выше состояниям. Пример: сессия корректно закрылась, но из-за ошибок маршрутизации часть пакетов из середины сессии улетела другим путем. Когда они пришли, их сессия уже закрыта и роутер о них ничего не знает. Они не new и не относятся к существующим соединениям, поэтому считаем их invalid.
Состояние потока не связано с флагами TCP: SYN, ACK, FIN. Для UDP и других stateless-протоколов в таблице ConnTrack тоже содержатся все возможные состояния.
Работа ConnTrack требует ресурсов процессора и при больших объемах трафика может существенно нагрузить CPU. Но ConnTrack нужен не везде, и его можно отключить. Например, у провайдеров на стыке с вышестоящим провайдером стоят роутеры, которые молотят десятки гигабит трафика. На этих роутерах, как правило, нет NAT (прямая маршрутизация), а трафик фильтруется уровнем ниже, чтобы не перегружать и без того нагруженный бордер. То есть в этом случае ни к чему проверять каждый пакет на принадлежность какому-либо потоку.
Нажав кнопку Tracking, можно отключить механизм ConnTrack или подкрутить таймеры. В большинстве случаев тебе не понадобится заходить в эти настройки, но знать о них нужно. Режима ConnTrack три: что такое yes
и no
, думаю, понятно, а в режиме auto
ConnTrack выключен до тех пор, пока хотя бы один пакет не попадет в существующие правила таблицы NAT или Filter.
WARNING
Выключенный ConnTrack ломает NAT и фичи файрвола, основанные на трекинге потоков: connection-bytes, connection-mark, connection-type, connection-state, connection-limit, connection-rate, layer7-protocol, new-connection-mark, tarpit.
Рекомендации по настройке
Переходим к практике настройки. В этой статье я расскажу о таблице Filter — той, что занимается фильтрацией трафика. Как мы выяснили чуть выше, за трафик к самому роутеру отвечает цепочка input, а за трафик, который проходит через роутер, — forward. Займемся защитой самого роутера.
Первое и самое главное, что нужно помнить при работе с файрволом, было описано еще в утерянной главе «Слова о полку Игореве»: «удаленная настройка файрвола — к дальней дороге». Так что уважай предков — чти их заветы и используй Safe Mode.
Работает этот режим так: ты нажимаешь кнопку Safe Mode в интерфейсе, и она остается нажатой. Дальше ты делаешь все, что собирался, но применятся эти изменения, только когда ты снова кликнешь по кнопке. Если они приведут к обрыву взаимодействия роутера и конфигуратора WinBox (например, если ты зафильтровал свои же пакеты или отключил интерфейс), то роутер вернется в состояние, которое было до входа в Safe Mode.
Запоминается только 100 действий, но этого хватит на большинство случаев. Перезагрузки не будет — откат мгновенный. Из консоли этот режим активируется по Ctrl-X.
Есть два подхода к настройке файрвола:
- разрешено все, что не запрещено;
- запрещено все, что не разрешено.
Ни один из них нельзя назвать однозначно правильным. Я приверженец второго подхода, но в незнакомых сетях применяю первый.
Чтобы разрешить нужный трафик, нужно определиться с этим самым трафиком. В случае с input это сделать довольно просто. Вот что нужно для корректной работы роутера.
- Management: WinBox, SSH, в некоторых случаях WebFig, например для просмотра графиков нагрузки.
- Если провайдер выдает адрес по DHCP, то разрешить этот протокол на внешнем интерфейсе.
- Если роутер является сервером DHCP, то разрешить этот протокол на внутренних интерфейсах.
- То же самое с DNS.
- Если будем поднимать туннели, то разрешить их.
- OSPF.
- ICMP.
- NTP.
- Neighbor Discovery.
- SNMP.
- Другие сервисы.
Определились? Открываем нужное и закрываем все остальное.
Файрвол работает по принципу «если [условие], то [действие]». Если выполняются условия, заданные во вкладках General, Advanced, Extra, то к пакету применяется действие из вкладки Action. На сегодня нам будет достаточно условий src/dst address, protocol, src/dst port, in/out interface, connection-state. Их значения понятны по названию, но если вдруг неясно — вперед, читать про основы TCP/IP. Самые распространенные действия: accept — разрешено, drop — запрещено (пакет просто уничтожится), reject — запрещено, но отправитель получит информацию, что пакет был уничтожен по причине, указанной в reject-with.
Каждое правило на пути пакета отнимает процессорное время. И если в небольших сетях это некритично, то при серьезных объемах трафика нужно учитывать этот момент. Рассмотрим на примере.
/ip firewall filter
add action=accept chain=input dst-port=8291 protocol=tcp src-address=10.0.0.0/24
add action=accept chain=input dst-port=8291 protocol=tcp src-address=10.10.0.0/24
add action=accept chain=input dst-port=8291 protocol=tcp src-address=10.11.0.0/24
add action=accept chain=input dst-port=22 protocol=tcp src-address=10.0.0.0/24
add action=accept chain=input dst-port=22 protocol=tcp src-address=10.10.0.0/24
add action=accept chain=input dst-port=22 protocol=tcp src-address=10.11.0.0/24
add action=drop chain=input
В этом случае при попытке подключиться к роутеру по SSH с адреса 10.11.0.11 файрвол будет шесть раз обращаться к CPU с вопросом, пропустить ли этот трафик. Выглядит это примерно так: «8291 — не наш порт — пропускаем дальше. 10.0.0.0/24 — не наша подсеть, пропускаем дальше. То же для 10.10.0.0/24, и только шестое правило подходит». На шестом шаге файрвол поймет, что трафик легитимный и его можно пропустить.
Пакеты FTP и весь другой неразрешенный трафик будет дергать CPU семь раз — первые шесть и последний дроп. И это в выдуманном примере из семи правил. В реальной жизни правил на порядок или два больше.
Первое, что мы можем сделать, — объединить два порта в одном правиле:
/ip firewall filter
add action=accept chain=input dst-port=8291,22 protocol=tcp src-address=10.0.0.0/24
add action=accept chain=input dst-port=8291,22 protocol=tcp src-address=10.10.0.0/24
add action=accept chain=input dst-port=8291,22 protocol=tcp src-address=10.11.0.0/24
add action=drop chain=input
Немного снизили нагрузку. Но осталось три идентичных правила с разницей лишь в адресах. С помощью списка адресов (Address List) мы можем объединить их в одно.
INFO
Address List — фича RouterOS, которая позволяет объединять IP-адреса, подсети и DNS-имена в одну запись.
Создаем три записи в одном Address List.
/ip firewall address-list
add address=10.0.0.0/24 list=MGMT
add address=10.10.0.0/24 list=MGMT
add address=10.11.0.0/24 list=MGMT
И применяем его к нашему правилу.
/ip firewall filter
add action=accept chain=input dst-port=8291,22 protocol=tcp src-address-list=MGMT
add action=drop chain=input
Так из семи правил мы получили два и избавились от лишней нагрузки. По аналогии со списками адресов работают списки интерфейсов (я рассматривал их в предыдущей статье — «Защищаем MikroTik»): объединяем в один interface list интерфейсы разных провайдеров и вешаем правила уже не на сами интерфейсы, а на списки. Так мы не только уменьшим нагрузку, но и упростим жизнь админа: чем меньше правил, тем удобнее обслуживать систему.
Еще один способ облегчить работу файрволу — использовать ConnTrack. Понятно, что established-пакетов будет намного больше, чем new, related и invalid, вместе взятых. А раз мы разрешили первый пакет из потока, то все остальные пакеты в этом потоке можно считать легитимными. Поэтому просто создаем правило «разрешить established» и помещаем его в самом верху.
Выбирай нужные тебе протоколы и порты, создай соответствующие списки адресов и интерфейсов. Открой все, что нужно, и поставь последним правилом drop all. На этом основную настройку цепочки input можно считать завершенной.
К слову, по умолчанию файрвол снабжен достаточно крепкой настройкой — ее вполне хватит, чтобы нормально работала сеть практически любых размеров. Но всегда есть какие-то особенности и любой конфиг можно улучшить с учетом своих условий.
Для примера конфигурации можешь взять мой шаблон.
Траблшутинг
Когда файрвол не работает или работает не так, как подразумевалось при настройке, виноват админ. Магии не бывает. Первое, на что стоит обратить внимание при траблшутинге, — счетчики пакетов. Если счетчик не увеличивается, значит, трафик в него не попадает. А если трафик не попадает, значит, либо этого трафика просто нет, либо он был обработан стоящим выше правилом.
Ты же помнишь, что правила файрвола работают по принципу «кто первый встал — того и тапки»? Если пакет попал под действие правила, то дальше он уже не пойдет. Значит, нужно искать проблему выше. Просто копируем наше правило, action ставим accept (для траблшутинга не делай дроп — так при проверке можно сломать себе доступ или нарушить работу сети) и постепенно двигаем его наверх до первого увеличения счетчиков в этом правиле. Если через это правило уже проходил трафик, то счетчики будут ненулевые и можно пропустить нужные нам пакеты, — просто сбрось счетчики в этом правиле или во всех кнопками Reset Counters.
/ip firewall filter reset-counters-all
или
/ip firewall filter reset-counters numbers=<номер правила>
Предположим, мы нашли правило, в которое попадает наш трафик, а попадать не должен. Нужно понять, почему так происходит. В этом нам поможет опция Log. Во вкладке Action ставим галочку Log (можно написать префикс для правила, чтобы было проще отлавливать его в логах) и смотрим логи, где написаны все характеристики пакетов, попадающих под правило. Среди характеристик: цепочка, входящий и исходящий интерфейсы, адреса и порты источника и получателя, протокол, флаги, размер пакета, действия NAT.
Если даже в самом верху в правиле не будут увеличиваться счетчики, убирай правила из условия по одному. Начинай с интерфейсов — админы часто путаются в своих представлениях о том, откуда или куда должен идти трафик (например, при коннекте к провайдеру через PPPoE или в туннелях между филиалами или сложном роутинге). Счетчики пошли? Включаем лог и смотрим интерфейсы и другие параметры.
Если и это не помогает — пришло время тяжелой артиллерии. Идем в Tools → Torch и изучаем трафик на роутере. Может, ожидаемого трафика вовсе нет. Еще один крутой инструмент — аналог tcpdump — Tools → Packet Sniffer. Разбор работы этих инструментов тянет на отдельную статью (если она тебе интересна — сообщи об этом в комментариях к статье).
Чтобы упростить траблшутинг, можно использовать функцию комментирования. Если из-за комментов окно становится слишком большим и это мешает смотреть на правила, воспользуйся инлайновыми комментариями (Inline Comments). Так комменты встанут с правилом в одну строку и в окно будет умещаться больше правил.
Также рекомендую распределять правила по порядку, следуя какой-то определенной логике. И старайся ее поддерживать на всех роутерах.
Итоги
В этой статье приведены только основы настройки файрвола и главные методы диагностики. Кроме RouterOS, эти принципы применимы и для Linux. В следующей статье разберем более сложные правила, которые позволяют защититься от не самых простых атак, и разберем цепочку Forward, а также создадим свои цепочки.