Pull to refresh
52.55
Cloud4Y
#1 Корпоративный облачный провайдер

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

Level of difficultyEasy
Reading time5 min
Views5.8K

Привет! Сегодня хотим поделиться простым способом защиты от 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>

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

Tags:
Hubs:
Total votes 10: ↑8 and ↓2+6
Comments6

Articles

Information

Website
www.cloud4y.ru
Registered
Founded
2009
Employees
51–100 employees
Location
Россия