Блокируем посетителей сайтов по IP

—

от автора

Привет! Сегодня хотим поделиться простым способом защиты от L7 DDoS-атак.  Есть и другие варианты, но описанный в статье — лёгкий и быстрый.

В 2022 году был момент, когда мониторинги показали, что в определённое время на сайты наших клиентов, среди которых были и государственные организации, совершаются L7 DDoS-атаки. Надо было этому противостоять.

Самое быстрое и  простое, что приходило на ум — это запрет доступа к сайтам для всех пользователей не из России. Это действительно не сложно. Геоблокировка осуществляется через Nginx, а главная  задача заключается в сопоставлении адреса клиента и его вероятного физического местонахождения (страна источника).

Возможно, вы тоже знаете про замечательный сервис, который работает с 2002 года: MaxMind. Он ведёт базу данных IP-адресов и их месторасположения. Всё хорошо, но есть нюанс: MaxMind сообщил, что прекращает поддержку баз данных GeoIP Legacy с 31 мая 2022 г. и переходит на новой стандарт базы данных GeoIP2. Кроме того, он вроде как ушёл из России.

Суть письма

Уважаемый пользователь GeoLite!

В целях соблюдения санкций США в отношении определённых российских организаций MaxMind реализует своё право прекратить ваш бесплатный доступ к базам данных или веб-сервисам GeoLite2 в соответствии с разделом 10 (b) Лицензионного соглашения с конечным пользователем GeoLite2. 

Учётная запись больше не будет иметь доступа к базам данных или веб-сервисам GeoLite2 в понедельник, 25 апреля 2022 г.

Сначала попробовал зарегистрироваться в MaxMind из РФ (с почтовым доменом RU), но при регистрации нельзя было выбрать Россию.

Выбрал Турцию — ошибка (возможно, вы используете VPN или PROXY). Ну, дело привычное — использую все те же данные, но с турецкого IP. Регистрация пройдена успешно, можно входить в личный кабинет и скачивать актуальные базы Geo2Lite.

Есть и второй способ получения баз Geolite/Geo2lite бесплатно, без регистрации и СМС. Имею в виду сервис GeoIP Legacy. С мая 2022 года один хороший человек регулярно конвертирует базы с Geo2 в Geo, указывая дату обновления текущей БД.

Для версии Geo2 есть второй хороший человек, который делится в репозитории базами, но, к сожалению, без указания даты актуализации.

Итак, с вопросом о том, где брать базы данных, мы разобрались. Дальше нужно понять, какая ОС стоит на сервере, куда будем устанавливать модуль GeoIP для Nginx.

Если же у нас Ubuntu 20/22, то модули для GeoIP и geo GeoIP2 уже есть в стандартных репах:

libnginx-mod-http-geoip2 libnginx-mod-http-geoip

Ставятся просто: apt install libnginx-mod-http-geoip2 либо apt install libnginx-mod-http-geoip

Если стоит, допустим CentOS 8, то в стандартных репах отсутствует нужный нам модуль. Придётся перекомпиливать Nginx, чтобы добавить модуль geoip2. Кстати, модуль geoip2 отсутствует в исходниках Nginx, так как он есть только в платной версии Nginx Plus.

Но сам модуль есть на гитхабе, оттуда его и возьмём.

Существует два варианта сборки. 

  • Первый: собрать со статическим модулем и пересобрать весь бинарник Nginx.

  • Второй: собрать только динамический модуль и подключить его в конфиг, не пересобирая весь Nginx.

В любом случае рекомендуется после обновления Nginx заново пересобирать модуль для новой версии Nginx. Более логичным выглядит решение скомпилить только динамический модуль.

Все операции выполняем на CentOS 8.

Клонируем репу с модулем GeoIP2:

git clone https://github.com/leev/ngx_http_geoip2_module.git 

Ставим библиотеку MaxMind в CentOS 8, которая есть в репах, yum install libmaxminddb.x86_64, либо собираем по инструкции.

Далее нужен исходник Nginx нашей версии. Узнать его можно командой nginx -v

В моем случае это выглядит так:  nginx version: nginx/1.14.1

Скачаем исходник нашей версии Nginx

wget http://nginx.org/download/nginx-1.14.1.tar.gz tar -xvf  nginx-1.14.1.tar.gz cd nginx-1.14.1/

получаем вывод с nginx -V, копируем всё после --prefix=/... и добавляем  --add-module=/root/ngx_http_geoip2_module (путь к модулю, скачанного с гитхаба).

У меня получилась такая строка:

Вывод

./configure —prefix=/usr/share/nginx —sbin-path=/usr/sbin/nginx —modules-path=/usr/lib64/nginx/modules —conf-path=/etc/nginx/nginx.conf —error-log-path=/var/log/nginx/error.log —http-log-path=/var/log/nginx/access.log —http-client-body-temp-path=/var/lib/nginx/tmp/client_body —http-proxy-temp-path=/var/lib/nginx/tmp/proxy —http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi —http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi —http-scgi-temp-path=/var/lib/nginx/tmp/scgi —pid-path=/run/nginx.pid —lock-path=/run/lock/subsys/nginx —user=nginx —group=nginx —with-file-aio —with-ipv6 —with-http_ssl_module —with-http_v2_module —with-http_realip_module —with-http_addition_module —with-http_xslt_module=dynamic —with-http_image_filter_module=dynamic —with-http_sub_module —with-http_dav_module —with-http_flv_module —with-http_mp4_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_random_index_module —with-http_secure_link_module —with-http_degradation_module —with-http_slice_module —with-http_stub_status_module —with-http_perl_module=dynamic —with-http_auth_request_module —with-mail=dynamic —with-mail_ssl_module —with-pcre —with-pcre-jit —with-stream=dynamic —with-stream_ssl_module —with-debug —with-cc-opt=’-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection’ —with-ld-opt=’-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E’ —add-dynamic-module=/root/ngx_http_geoip2_module

Дальше будут появляться сообщения, что не получается выполнить сборку из-за нехватки определенных библиотек. В моём случае получился такой список:

yum install gcc gcc-c++ kernel-devel pcre-devel zlib-devel openssl-devel libxslt-devel install libgeoip-dev libgeoip-dev gd gd-devel perl-ExtUtils-Embed -y

Выполняем make modules (именно так, а не make install, чтобы не пересобирать весь Nginx).

и в папке /root/nginx-1.14.1/objs/ngx_http_geoip2_module.so должен появиться наш модуль.

Копируем его в  /usr/share/nginx/modules/ командой cp ngx_http_geoip2_module.so /usr/share/nginx/modules/

Подключаем модуль в конфиге

/etc/nginx/nginx.conf load_module modules/ngx_http_geoip2_module.so;

В папку /usr/share/GeoIP/ копируем нашу базу GeoLite2-Country.mmdb 

В конфиге http прописываем

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {         $geoip2_data_country_iso_code country iso_code;         $geoip2_data_continent_code   continent code;     }    #здесь запрещаем доступ всем, кроме разрешенных стран     map $geoip2_data_country_iso_code $allowed_country {        default no;        RU yes;     }

Наверное, нет смысла копипастить сюда инструкцию по автоматическому обновлению баз Geo2Lite с сервера MaxMind. Если вам она нужна, вот ссылка.

На практике нужно разрешать и другие сети в других странах (либо адреса).

Добавим в тот же конфиг http

  geo $exclusions {          default 0;          123.123.123.123 1;  # сюда прописываем сети либо адреса, которым разрешаем независимый доступ         12.13.11.0/24 1;     }

В конфиге server указываем 

if ($allowed_country = yes) {     set $exclusions 1; }  if ($exclusions = "0") {     return 403; }

Не помешает и добавить логи стран, с которых приходят запросы. Для этого в log_format  main нужно добавить $geoip2_data_country_iso_code

Должно получиться что-то вроде такого:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                       '$status $body_bytes_sent "$http_referer" '                       '"$http_user_agent" "$http_x_forwarded_for"' "$geoip2_data_country_iso_code"; 

Ещё можно поменять страницу для ответа 403

        error_page 403 @not_allowed;                 location @not_allowed {                  try_files /my_403_error.html 403;        } 

и саму страницу положить в root location. В моём случае это /usr/share/nginx/html/my_403_error.html

Сама страница:
<h1>Oops, error 403. Access denied.</h1> <p>You do not have permission to access the page, let's try to solve this problem together:</p> <li>Let us know by mail: mail@domain.com and we will try to solve the problem together.</li> </ul> 

Таким нехитрым способом можно защитить сайты от внешних угроз, если нужно быстрое решение. Нам помогло, атаки сошли на нет. Спасибо за внимание!


ссылка на оригинал статьи https://habr.com/ru/articles/735932/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *