Как заблокировать доступ к nginx из других стран
Смотря в логи доступа часто видим, что много китайских и голландских IP-адресов стучатся к нашему веб-серверу. Кардинальная мера, которая первая приходит, это ограничить доступ по IP-адресам, а можно просто ограничить по странам или разрешить только определённые страны.
Данная статья поможет не только для блокировки, но и распределение пользователей по контенту для определённого языка и страны на уровне nginx.
Задача: возможность распределение пользователей определённых стран на основании местоположения по IP-адресу.
Операционная система: CentOS 8
Подготовка дистрибутивов
- Обновляем операционную систему и устанавливаем необходимые библиотеки для работы:
dnf update dnf groupinstall 'Development Tools' dnf install epel-release dnf install wget nano openssl-devel pcre-devel libxslt-devel geoip-devel libmaxminddb-devel |
- Скачиваем и распаковываем дистрибутив 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 |