Настраиваем блокировку по GeoIP для веб-сервисов используя PFsense, HaProxy и бесплатные базы IPDeny
Сегодня многие организации которые переводят свои сервисы на web-платформы, вынуждены предоставлять точку входа в интернет для аутентификации пользователя. Даже при наличии 2-факторной аутентификации, веб-сервис, доступный через интернет, остается уязвимым к сложным атакам, итогом которых может стать похищение данных, загрузка зловредного кода в приложение или нарушение работы сервиса. Не всегда имеется возможность установить WAF (web application firewall) для ограничения доступа к сервису. Одним из способов защиты веб-сервиса может быть ограничение доступа к нему по IP, в том числе по GeoIP, на основе расположения пользователя.
Это позволит полностью закрыть доступ как со списка скомпрометированных, заспамленных IP-адресов, так и с целых стран и континентов. От намеренной хакерской атаки такой метод не поможет, но драматически снизит число нападений ботов, которые как правило сканируют уязвимости в автоматическом режиме через прокси серверы с IP-адресов стран третьего мира.
NAT или HaProxy?
Даже если у вас в сети один-единственный веб-сервер, смотрящий "наружу" 443 портом, всё равно имеет смысл отказываться от NAT в пользу HaProxy как более гибкого варианта, и переносить обновление сертификатов на шлюз безопасности. PFSense позволит использовать блокировку по GeoIP и для правил обычного Firewall (если у вас NAT), но этот способ мы рассматривать не будем.
Что такое списки GeoIP?
Обычные списки GeoIP содержат информацию о географическом месте IP-адресов. Этот тип списка используется для определения страны, региона или города, откуда происходит запрос к веб-сервису.
Где брать базы данных (списки GeoIP)?
Обычно, все рекомендуют сервисы Maxmind, но есть более простая альтернатива, как говорится, "без SMS и регистрации" - сервис ipdeny.com, где в открытом доступе лежат GeoIP базы, отсортированные по странам.
Как добавить GeoIP в PFSense?
В PFSense имеется возможность создания алиасов для правил встроенного Firewall. В качестве источника можно указать URL списка GeoIP или ввести IP-адреса подсетей вручную. Обычно один URL представляет собой диапазон IP-адресов для конкретной страны или региона и имеет соответствующий 2-буквенный код в названии файла. Поскольку регионов может быть много, имеет смысл не запрещать каждый из них отдельно, а наоборот добавить только разрешенный регион, а все остальные запретить. Это повысит работу межсетевого шлюза и снизит объем занимаемой памяти.
Например, если мы хотим использовать Россию или США как единственные регионы которым открыт доступ к нашим веб-сервисам, мы должны создать два алиаса: Russia и USA указав для каждого из них в виде содержимого - URL ленты GEOIP. По умолчанию, ленты обновляются один раз в день, чего вполне достаточно для работы с бесплатно доступными базами, которые как правило, обновляются еще реже – раз в неделю, а то и месяц.
Настройка ACL Haproxy
Для настройки ACL (Access Control List) в Haproxy (использовалась версия 2.8-d12 из пакета haproxy-devel 0.63_1) вы открываете ваш Backend и переходите к настройкам ACL. Здесь вы можете выбрать триггер, который будет срабатывать при определенных условиях - например, если источник IP соответствует алиасу Russia или USA.
В зависимости от ваших потребностей и конфигурации, вы можете создавать отдельные триггеры для каждого из ваших алиасов. Это может быть особенно полезно, если у вас есть VPN подключения к корпоративной сети или диапазоны локальных подсетей, которые должны быть исключены из правил доступа. Важно: если доступ к защищаемым веб-сервисам осуществляется через интранет, вам обязательно нужно создать отдельный алиас с IP адресами локальных сетей и создать условие (триггер) в списке ACL для каждого backend-а.
Теперь осталось только выбрать действие для триггеров. Тут надо понимать, что действия срабатывают сверху вниз, до первого совпадения, поэтому сначала указываем разрешительные правила, а ниже по списку – запретительные. Установив флажок “Not” мы можем включить инверсное правило. В самом простом случае нам потребуется разрешить доступ из локальной сети и разрешить доступ из России. Первое разрешение мы указываем явно, а второе – инверсно, то есть запрещаем все любые адреса, кроме тех что из России и США.
Само действие задается ответом сервера на запрос, с разрешительным все понятно – сервер должен принимать заголовок. А вот запретительных может быть несколько, в том числе редирект. Я не вижу смысла мудрствовать лукаво в выборе отбивки и считаю что выбирать http-request allow нужно для разрешительного действия и http-request deny для запрета доступа. Пользователи из разрешённых регионов даже не заметят, что была какая-то фильтрация, а из запрещённых получат 502-ю ошибку и пойдут искать других жертв.
Напоследок
Ограничение доступа к веб-сервису только из разрешенных регионов на основе GeoIP значительно снижает количество нежелательных запросов и атак ботов, что в конечном итоге увеличивает стабильность работы сервиса и безопасность данных пользователей. Однако стоит помнить, что этот метод защиты неэффективен против намеренных атак со стороны злоумышленников, которые могут обойти ограничения GeoIP с помощью прокси-серверов в разрешенном регионе.
Михаил Дегтярёв (aka LIKE OFF)
28/09.2023