Как заблокировать доступ к nginx из других стран

Смотря в логи доступа часто видим, что много китайских и голландских IP-адресов стучатся к нашему веб-серверу. Кардинальная мера, которая первая приходит, это ограничить доступ по IP-адресам, а можно просто ограничить по странам или разрешить только определённые страны.

Данная статья поможет не только для блокировки, но и распределение пользователей по контенту для определённого языка и страны на уровне nginx.

Задача: возможность распределение пользователей определённых стран на основании местоположения по IP-адресу.

Операционная система: CentOS 8

Подготовка дистрибутивов

  1. Обновляем операционную систему и устанавливаем необходимые библиотеки для работы:
dnf update

dnf groupinstall 'Development Tools'

dnf install epel-release

dnf install  wget nano openssl-devel pcre-devel libxslt-devel geoip-devel libmaxminddb-devel
  1. Скачиваем и распаковываем дистрибутив nginx. Если вы хотите сконфигурировать только модуль, проверьте вашу версию с помощью команды “nginx -v” и скачайте вашу версию nginx для сборки только одного модуля ngx_http_geoip2_module.
wget https://nginx.org/download/nginx-1.19.6.tar.gz
tar xvf nginx-1.19.6.tar.gz

3. Подключаем исходники модуля GeoIP2

cd /tmp

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

Конфигурация

4.1. Конфигурируем дистрибутив. Мы выполним компиляцию и установку nginx из исходных файлов.

./configure 
--prefix=/etc/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 
--pid-path=/var/run/nginx.pid 
--lock-path=/var/run/nginx.lock 
--http-client-body-temp-path=/var/cache/nginx/client_temp 
--http-proxy-temp-path=/var/cache/nginx/proxy_temp 
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 
--http-scgi-temp-path=/var/cache/nginx/scgi_temp 
--user=nginx --group=nginx --with-compat 
--with-file-aio --with-threads --with-http_addition_module 
--with-http_auth_request_module --with-http_dav_module 
--with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module 
--with-http_mp4_module --with-http_random_index_module --with-http_realip_module 
--with-http_secure_link_module --with-http_slice_module --with-http_ssl_module 
--with-http_stub_status_module --with-http_sub_module --with-http_v2_module 
--with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module 
--with-stream_ssl_module --with-stream_ssl_preread_module 
--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 -fPIC' 
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' 
--add-module=/tmp/ngx_http_geoip2_module

4.2. Если у вас уже установлен nginx, можете сконфигурировать следующим образом:

./configure --add-module=/tmp/ngx_http_geoip2_module $(nginx -V)

4.3. Если вам требуется только динамический модуль, проверьте вашу версию nginx, скачайте дистрибутив nginx нужной версии и соберите модуль с помощью команды:

./configure --add-dynamic-module=/tmp/ngx_http_geoip2_module

make modules

В папке objs будет модуль, который вы можете скопировать в папку /etc/nginx/modules и подключить в конфигурационном файле:

load_module modules/ngx_http_geoip2_module.so;

5. Собираем и устанавливаем подготовленный дистрибутив

make

make install

6. Разрешим в Firewall порты 80 и 443.

firewall-cmd --permanent --add-service=http

firewall-cmd --permanent --add-service=https

firewall-cmd --reload

 

Подготовка к запуску

7. Добавляем пользователя и группу nginx и создаём папку под кэш.

groupadd -g 994 nginx

useradd -g 994 -u 996 -c "Nginx web server" -d /var/lib/nginx -s /sbin/nologin nginx

mkdir -p /var/cache/nginx/client_temp

7.1. Описываем сервис для управления в файле /etc/systemd/system/nginx.service:

[Unit]

Description=The NGINX proxy server

After=syslog.target network-online.target remote-fs.target nss-lookup.target

Wants=network-online.target

[Service]

Type=forking

PIDFile=/var/run/nginx.pid

ExecStartPre=/usr/sbin/nginx -t

ExecStart=/usr/sbin/nginx

ExecReload=/usr/sbin/nginx -s reload

ExecStop=/bin/kill -s QUIT $MAINPID

PrivateTmp=true

[Install]

WantedBy=multi-user.target

7.2. Включаем в автозагрузку и запускаем nginx

systemctl daemon-reload

systemctl enable nginx

systemctl start nginx

7.3. В результате успешного запуска статус будет active (running)

nginx.service - The NGINX HTTP and reverse proxy server

   Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: disabled)

   Active: active (running) since Fri 2020-12-25 10:22:22 MSK; 927ms ago

  Process: 55616 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)

  Process: 55615 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)

 Main PID: 55618 (nginx)

    Tasks: 2 (limit: 23988)

   Memory: 2.1M

   CGroup: /system.slice/nginx.service

           ├─55618 nginx: master process /usr/sbin/nginx

           └─55619 nginx: worker process

 

Подготовка баз

1. Будем использовать бесплатные базы данных MaxMind. Для этого зарегистрируйтесь на сайте MaxMind и скачайте базы стран и городов.

wget "https://download.maxmind.com/app/geoip_download_by_token?edition_id=GeoLite2-Country&date=20201222&suffix=tar.gz&token=v2.local.XXXXXXXXXX" -O country.tar.gz

wget "https://download.maxmind.com/app/geoip_download_by_token?edition_id=GeoLite2-City&date=20201222&suffix=tar.gz&token=v2.local.XXXXXXXXXX" -O city.tar.gz

2. Распакуем и переместим в папку /etc/nginx/geo

mkdir -p /etc/nginx/geo

tar xvf city.tar.gz --dir /etc/nginx/geo/

tar xvf country.tar.gz --dir /etc/nginx/geo/

cd /etc/nginx/geo/

mv GeoLite2-City_20201222/GeoLite2-City.mmdb GeoLite2-City.mmdb

mv GeoLite2-Country_20201222/GeoLite2-Country.mmdb GeoLite2-Country.mmdb

3. В файл конфигурации nginx.conf добавляем следующие строки в блок http. Если после “default no” добавим “RU yes”, то доступ будет разрешен всем, у кого GEO Location установлен, как RU (Russia / Россия).

geoip2 /etc/nginx/geo/GeoLite2-Country.mmdb {
    $geoip2_data_city_name city names en;
}
geoip2 /etc/nginx/geo/GeoLite2-City.mmdb {
    $geoip2_data_country_iso_code country iso_code;
}
map $geoip2_data_country_iso_code $allowed_country {
    default no;
}
 

4. В блоке server описываем, что будет возвращать nginx, если совпадёт условие. Например, вернём 403.

if ($allowed_country = no) {
    return 403;
}

5. Проверяем корректность конфигурации и перезагружаем конфигурацию:

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

nginx -s reload

Автоматическое обновление баз MaxMind

1. Установим geoipupdate

rpm -i https://github.com/maxmind/geoipupdate/releases/download/v4.6.0/geoipupdate_4.6.0_linux_386.rpm

2. В файле /etc/GeoIP.conf укажем параметры из личного кабинета - AccountID и LicenseKey. Ключ можно сгенерировать в личном кабинете.
3. Для обновления баз достаточно запустить - geoipupdate.
4. Базы обновляются каждую неделю, поэтому раз в неделю будет автоматически их обновлять. Добавим в cron следующее задание

7 11 * * 4 /usr/local/bin/geoipupdate

5. Обновите пусть до баз:

/usr/share/GeoIP/GeoLite2-Country.mmdb
/usr/share/GeoIP/GeoLite2-City.mmdb

 

Наш телеграм-канал
Пишем про облака, кейсы, вебинары
Подписаться