Блокування трафіку за країнами в Linux: GeoIP, nftables | INTROSERV
EUR
european

EUR

usa

USD

Ukraine Ua
Ex. VAT Ex. VAT 0%

Як заблокувати трафік за країною на брандмауері Linux за допомогою правил GeoIP

Рівень: Професійний
Орієнтовний час: ~35 хвилин
Мета: Налаштувати правила брандмауера GeoIP на сервері Linux для обмеження доступу за країною за допомогою iptables із модулем xtables-geoip або nftables із наборами IP-адрес – і автоматизувати оновлення, щоб списки залишалися актуальними.

Вступ

Якщо ваші служби орієнтовані на певний регіон, немає сенсу приймати трафік з решти світу. Геоблокування в брандмауері Linux дозволяє відкидати пакети за країною походження до того, як вони досягнуть вашого застосунку – зменшуючи шум від брутфорсу та зменшуючи поверхню атаки. У цьому посібнику ви заблокуєте трафік за країною на брандмауері Linux за допомогою правил GeoIP: спочатку за допомогою iptables та xtables-addons, потім за допомогою nftables і наборів IP-адрес на основі CIDR, включаючи автоматичні оновлення бази даних, щоб ваше блокування IP-адрес за країною залишалося точним.

Попередні вимоги

Перш ніж почати, переконайтеся, що виконано такі умови:

  • Операційна система: Ubuntu 22.04/24.04 LTS, Debian 12/13, AlmaLinux/RHEL 9/10
  • Доступ: доступ sudo або root до сервера
  • Брандмауер: iptables 1.8+ з xtables-addons або nftables 1.0+
  • Необхідні пакети: curl, iptables, linux-headers-$(uname -r) (Debian/Ubuntu); увімкнено репозиторій EPEL (RHEL/AlmaLinux 9)

Info

У Debian 12+, Ubuntu 22.04+ та RHEL/AlmaLinux 9+ команда iptables є обгорткою над бекендом nftables (iptables-nft). Перевірка -m geoip коректно працює з цим бекендом.

  • Мережа: чітке розуміння того, з яких країн ваші служби повинні приймати трафік
  • Необхідні знання: впевнене користування командним рядком Linux, базові концепції брандмауера та редагування файлів
  • Резервне копіювання: працююча out-of-band консоль (IPMI/KVM) або режим відновлення (rescue mode) провайдера на випадок, якщо правило заблокує вам доступ

Warning

Застосування правил брандмауера на рівні країн через сеанс SSH за своєю суттю ризиковане. Якщо ви помилково заблокуєте власну країну, ви втратите доступ. Завжди майте напоготові резервний out-of-band доступ і тестуйте правила, перш ніж робити їх постійними.

Крок 1: Визначте свої дозволені та заблоковані країни

Перш ніж змінювати брандмауер, визначтеся зі своєю політикою. Існує два підходи:

  • Білий список (рекомендовано): Дозволити лише ті країни, які вам потрібні, відкидати все інше. Це суворіше і безпечніше.
  • Чорний список: Дозволити все, відкидати певні країни. Простіше, але залишає більшу поверхню атаки.

У цьому посібнику ми будемо використовувати підхід білого списку – він відповідає принципу найменших привілеїв. Припустимо, ваші служби обслуговують користувачів лише зі США, Німеччини та Польщі. Дволітерні коди країн ISO: US, DE, PL.

Info

Коди країн відповідають стандарту ISO 3166-1 alpha-2. Повний список знайдете за адресою https://www.iso.org/obp/ui/#search/code/. Будьте точні – помилка тут непомітно заблокує легітимний трафік.

Крок 2: Налаштування GeoIP з iptables (xtables-addons)

Цей метод використовує модуль xt_geoip з xtables-addons, який додає перевірку -m geoip до iptables. Це один із найбільш усталених способів блокування діапазону IP-адрес за країною в Linux.

2.1 Встановіть xtables-addons та залежності

Debian/Ubuntu:

sudo apt install -y linux-headers-$(uname -r) sudo apt update && sudo apt install -y \ xtables-addons-common libtext-csv-xs-perl unzip iptables curl

Warning

xtables-addons відсутній у репозиторіях AlmaLinux 10. Скористайтеся методом nftables (Крок 3) або зберіть xtables-addons із вихідного коду.

Після встановлення перевірте доступність модуля:

modinfo xt_geoip

Очікуваний вивід включає рядок на зразок:

filename: /lib/modules/.../xt_geoip.ko description: Xtables: country matching via GeoIP

Якщо modinfo повертає помилку, модуль не встановлено правильно. Перевірте, чи відповідають заголовки вашого ядра запущеній версії ядра.

2.2 Завантажте та створіть базу даних GeoIP

Для модуля xt_geoip потрібна локальна база даних відображення країн на IP-адреси. Вони постачаються як файли CSV і повинні бути перетворені у бінарний формат.

Створіть робочий каталог та каталог бази даних:

sudo mkdir -p /usr/share/xt_geoip

Завантажте останні дані GeoIP у форматі CSV. Джерело надає дані за допомогою інструментів xtables-addons:

cd /tmp /usr/libexec/xtables-addons/xt_geoip_dl

Перетворіть завантажений CSV у бінарний формат:

/usr/libexec/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip *.csv

Очікуваний вивід - список кодів країн, що обробляються:

4540 IPv4 ranges for ZA 1071 IPv6 ranges for ZA 147 IPv4 ranges for ZW 94 IPv6 ranges for ZW ...

2.3 Застосуйте правила iptables із фільтрацією GeoIP

Тепер створіть власне правила брандмауера GeoIP. Наведений нижче сценарій дозволяє трафік із вибраних вами країн і відкидає все інше в ланцюжку INPUT.

Спочатку зробіть резервну копію поточних правил:

sudo iptables-save > /tmp/iptables-backup-$(date +%Y%m%d).rules

Застосуйте білий список країн:

# Дозволити loopback інтерфейс sudo iptables -A INPUT -i lo -j ACCEPT # Дозволити встановлені та пов'язані з'єднання sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Дозволити трафік тільки з США, Німеччини, Польщі sudo iptables -A INPUT -m geoip --src-cc US,DE,PL -j ACCEPT # Логувати відкинуті пакети sudo iptables -A INPUT -j LOG --log-prefix "GEOIP-DROP: " --log-level 4 # Відкидати все інше sudo iptables -A INPUT -j DROP

Warning

Останнє правило DROP блокує весь трафік, що не відповідає білому списку. Переконайтеся, що країну походження вашого SSH-підключення включено, інакше ви негайно втратите доступ. Якщо не впевнені, додайте тимчасове правило ACCEPT для вашої IP-адреси перед DROP: sudo iptables -I INPUT -s <YOUR_IP_ADDRESS> -j ACCEPT.

Перевірте, чи активні правила:

sudo iptables -L INPUT -v --line-numbers

Очікуваний вивід:

Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere /* loopback */ 2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 3 ACCEPT all -- anywhere anywhere -m geoip --source-country US,DE,PL 4 LOG all -- anywhere anywhere LOG level warning prefix "GEOIP-DROP: " 5 DROP all -- anywhere anywhere

2.4 Збережіть правила iptables після перезавантаження

Правила, застосовані за допомогою iptables, втрачаються після перезавантаження. Збережіть їх:

Debian/Ubuntu:

sudo apt install iptables-persistent -y sudo netfilter-persistent save

AlmaLinux/RHEL:

sudo service iptables save

Крок 3: Налаштування GeoIP з nftables (набори IP)

Якщо у вашій системі використовується nftables (за замовчуванням у Debian 11+, Ubuntu 22.04+ і RHEL 9+), ви можете досягти того ж результату за допомогою наборів IP-адрес (IP sets), заповнених блоками CIDR рівня країни. Цей підхід не вимагає модулів ядра, крім тих, що вже надає nftables.

3.1 Отримайте діапазони IP-адрес країн

Завантажте списки CIDR для країн, які ви хочете дозволити. Кілька публічних джерел надають їх, наприклад ipdeny.com:

sudo mkdir -p /etc/nftables/geoip cd /etc/nftables/geoip # Завантажити CIDR блоки для США, Німеччини, Польщі for CC in us de pl; do sudo curl -sS -o /etc/nftables/geoip/${CC}.zone \ "https://www.ipdeny.com/ipblocks/data/aggregated/${CC}-aggregated.zone"; done

Перевірте, чи файли містять діапазони CIDR:

head -5 /etc/nftables/geoip/us.zone

Очікуваний вивід (діапазони CIDR, по одному в рядку):

1.178.0.0/23 1.178.4.0/22 1.178.8.0/21 ...

3.2 Створіть та завантажте конфігурацію nftables

Створіть скрипт, який зчитує файли CIDR і генерує набір nftables. Збережіть його як /etc/nftables/geoip-update.sh:

sudo nano /etc/nftables/geoip-update.sh

Вставте наступне:

#!/bin/bash # Generate nftables set from country CIDR files set -euo pipefail GEOIP_DIR="/etc/nftables/geoip" OUTPUT="/etc/nftables/geoip-sets.nft" echo "define ALLOWED_COUNTRIES = {" > "$OUTPUT" for zone_file in "$GEOIP_DIR"/*.zone; do while IFS= read -r cidr; do && continue echo " ${cidr}," >> "$OUTPUT" done < "$zone_file" done echo "}" >> "$OUTPUT" echo "GeoIP set generated: $(wc -l < "$OUTPUT") lines"

Зробіть його виконуваним:

sudo chmod +x /etc/nftables/geoip-update.sh

Запустіть скрипт:

sudo /etc/nftables/geoip-update.sh

Тепер пошліться на цей набір у вашій конфігурації nftables:

# Debian/Ubuntu: sudo nano /etc/nftables.conf # AlmaLinux/RHEL: sudo nano /etc/sysconfig/nftables.conf

Додайте включення (include) та використовуйте набір у своєму ланцюжку INPUT:

#!/usr/sbin/nft -f flush ruleset include "/etc/nftables/geoip-sets.nft" table inet filter { chain input { type filter hook input priority 0; policy drop; ct state invalid drop iif lo accept ct state established,related accept # Дозволити ICMP ip protocol icmp accept ip6 nexthdr icmpv6 accept # GeoIP: дозволити тільки перелічені країни ip saddr $ALLOWED_COUNTRIES accept # Логувати відкинуті пакети log prefix "geoip-drop: " level info # Все інше відкидається політикою } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }

Перевірте синтаксис перед застосуванням:

sudo nft -c -f /etc/nftables.conf

Якщо помилок немає, застосуйте та перевірте:

sudo nft -f /etc/nftables.conf sudo systemctl enable --now nftables sudo nft list ruleset | head -20

Tip

Для дуже великих наборів IP-адрес (понад 100 тис. записів) nftables справляється значно краще за iptables. Зіставлення на основі наборів у nftables внутрішньо використовує хеш-таблиці, тому продуктивність пошуку залишається постійною незалежно від розміру набору.

Крок 4: Автоматизація оновлень бази даних GeoIP

Відображення IP-адрес на країни постійно змінюється. База даних минулого місяця матиме прогалини. Заплануйте автоматичні оновлення за допомогою cron.

4.1 Створіть скрипт оновлення

Створіть /usr/local/sbin/geoip-refresh.sh:

sudo nano /usr/local/sbin/geoip-refresh.sh

Для iptables (xtables-addons):

#!/bin/bash set -euo pipefail cd /tmp /usr/libexec/xtables-addons/xt_geoip_dl /usr/libexec/xtables-addons/xt_geoip_build \ -D /usr/share/xt_geoip *.csv rm -f /tmp/*.csv /tmp/*.zip logger "GeoIP database updated successfully"

Для nftables:

#!/bin/bash set -euo pipefail GEOIP_DIR="/etc/nftables/geoip" for CC in us de pl; do curl -sS -o "${GEOIP_DIR}/${CC}.zone" \ "https://www.ipdeny.com/ipblocks/data/aggregated/${CC}-aggregated.zone" done /etc/nftables/geoip-update.sh systemctl reload nftables logger "GeoIP nftables sets updated and reloaded"

Зробіть його виконуваним:

sudo chmod +x /usr/local/sbin/geoip-refresh.sh

4.2 Розклад за допомогою cron

Перш ніж планувати завдання cron, переконайтеся, що служба nftables увімкнена і працює (якщо використовується метод nftables):

sudo systemctl enable --now nftables

Запускайте оновлення щотижня:

sudo crontab -e

Додайте:

0 3 * * 0 /usr/local/sbin/geoip-refresh.sh >> /var/log/geoip-update.log 2>&1

Це запускатиметься щонеділі о 3:00 ночі. Після першого запланованого запуску переконайтеся, що він спрацював:

cat /var/log/geoip-update.log

Крок 5: Перевірка та тестування

5.1 Перевірка з дозволеної країни

З машини в одній із дозволених країн підключіться через SSH або зробіть HTTP-запит:

curl -v http://<YOUR_SERVER_IP>

З'єднання має пройти успішно.

5.2 Симуляція заблокованої країни

Використовуйте curl з відомим IP-адресом із заблокованої країни через проксі-сервер або протестуйте локально, тимчасово видаливши власну країну з білого списку та спробувавши підключитися з другого терміналу.

Info

Онлайн-сервіси, як-от https://ipinfo.io, дозволяють перевірити, у якій країні зареєстровано певну IP-адресу. Скористайтеся curl https://ipinfo.io/<YOUR_IP_ADDRESS> для підтвердження.

5.3 Перевірте лічильники брандмауера

iptables:

sudo iptables -L INPUT -v -n

Подивіться на лічильники пакетів на правилі DROP – вони повинні збільшуватися по мірі надходження заблокованого трафіку.

nftables:

sudo nft list chain inet filter input

5.4 Моніторинг системних журналів

Перевірте наявність відкинутих пакетів у системному журналі:

sudo journalctl -k --since "1 hour ago" | grep -i "geoip-drop"

Warning

Якщо ви спостерігаєте великий обсяг повідомлень журналу ядра про відкинуті пакети, а система перестає відповідати, причиною може бути лавина логування. У гіршому випадку це може спричинити паніку ядра. Якщо ви налаштували параметр crashkernel та службу kdump, паніка ядра створить аварійний дамп (vmcore) у /var/crash, який можна проаналізувати пізніше. Без kdump ви отримаєте лише перезавантаження без жодної діагностики. Короткий огляд наведено в розділі нижче.

Крок 6: Захист від паніки ядра під час змін брандмауера

Агресивні зміни брандмауера на завантаженому робочому сервері – особливо ті, що спричиняють раптові сплески трафіку або лавину логування – у рідкісних випадках можуть призвести до паніки ядра (kernel panic). Якщо це станеться, і ви не підготувалися, ви не отримаєте нічого: лише перезавантаження і жодних даних про те, що пішло не так.

Kdump – це стандартний механізм Linux для збереження аварійного дампу під час паніки ядра. Він використовує kexec для завантаження вторинного ядра захоплення (capture kernel), яке записує образ пам'яті (vmcore) на диск перед перезапуском системи.

Щоб забезпечити наявність діагностики:

  1. Переконайтеся, що kdump встановлено та увімкнено. На RHEL/AlmaLinux він зазвичай попередньо встановлений. На Debian/Ubuntu:

    sudo apt install kdump-tools kexec-tools -y

  2. Перевірте, чи встановлено параметр crashkernel у конфігурації вашого завантажувача:

    cat /proc/cmdline | grep crashkernel

    Ви повинні побачити щось на кшталт crashkernel=256M. Якщо його немає, вам потрібно налаштувати параметр crashkernel у GRUB і перезавантажитися. Точний обсяг пам'яті, який слід зарезервувати для kdump linux, залежить від загального обсягу вашої оперативної пам'яті – 256M є безпечним значенням за замовчуванням для серверів з 4 ГБ або більше.

  3. Перевірте, чи активна служба kdump:

    sudo systemctl status kdump

Info

Якщо паніка ядра все ж станеться, система використає kexec для завантаження ядра захоплення, запише vmcore у /var/crash і потім перезавантажиться у звичайному режимі. Після цього ви можете виконати vmcore analysis linux за допомогою утиліти crash, щоб визначити першопричину. Це стандартна частина linux kernel panic troubleshooting на робочих системах. Повний посібник про те, як enable kdump in linux, і налаштування kexec kdump linux дивіться в окремому посібнику з kdump.

Усунення несправностей

  • Втрата доступу через SSH: Використовуйте out-of-band консоль / режим відновлення (rescue mode).
  • modinfo xt_geoip: not found: Встановіть linux-headers-$(uname -r).
  • iptables: command not found (Debian 13): Встановіть iptables за допомогою sudo apt install iptables.
  • nftables.service is not active: Виконайте sudo systemctl enable --now nftables.
  • Empty /etc/sysconfig/nftables.conf on AlmaLinux: Використовуйте цей шлях замість /etc/nftables.conf для налаштування правил.

Відкат змін (Rollback)

Щоб скасувати блокування за країнами та відновити відкритий доступ:

iptables - відновлення з резервної копії:

sudo iptables-restore < /tmp/iptables-backup-*.rules

Info

Якщо ви застосували правила GeoIP на сервері без попередньої конфігурації брандмауера, файл резервної копії буде порожнім. У такому разі використайте наведені нижче команди очищення та політики замість iptables-restore.

Або очистіть всі правила:

sudo iptables -F INPUT sudo iptables -P INPUT ACCEPT

Warning

Очищення з переходом на ACCEPT прибирає весь захист брандмауера. Негайно застосуйте після цього свій стандартний набір правил безпеки.

nftables - відновлення за замовчуванням:

sudo nft flush ruleset

Потім відновіть вашу базову конфігурацію nftables (без GeoIP):

sudo nft -f /etc/nftables.conf.backup

Щоб повністю видалити компоненти GeoIP:

sudo rm -rf /etc/nftables/geoip sudo rm -f /etc/nftables/geoip-sets.nft /etc/nftables/geoip-update.sh sudo crontab -l | grep -v geoip-refresh | sudo crontab -

Видалення xtables-addons (якщо встановлено):

Debian/Ubuntu:

sudo apt remove xtables-addons-common -y

AlmaLinux/RHEL:

sudo dnf remove xtables-addons -y

Висновок

Тепер ваш сервер використовує правила брандмауера GeoIP для блокування трафіку за країною в Linux – або через iptables із xt_geoip, або через nftables із наборами IP-адрес на основі CIDR. База даних оновлюється автоматично, у вас є план відкату, і завдяки налаштованому kdump для збору аварійного дампу у випадку паніки ядра, ваше робоче середовище захищене як від рутинних загроз, так і від найгірших сценаріїв.

Версія документа: 1.0
Останнє оновлення: Травень 2026
Власник: Команда технічної документації

VAT

  • Other

    Ex. VAT

    0%
  • austria

    Austria

    20%
  • Belgium

    Belgium

    21%
  • Bulgaria

    Bulgaria

    20%
  • Croatia

    Croatia

    25%
  • Cyprus

    Cyprus

    19%
  • Czech Republic

    Czech Republic

    21%
  • Denmark

    Denmark

    25%
  • Estonia

    Estonia

    22%
  • France

    France

    20%
  • Finland

    Finland

    24%
  • Germany

    Germany

    19%
  • Greece

    Greece

    24%
  • Hungary

    Hungary

    27%
  • Ireland

    Ireland

    23%
  • Italy

    Italy

    22%
  • Latvia

    Latvia

    21%
  • Lithuania

    Lithuania

    21%
  • Luxembourg

    Luxembourg

    17%
  • Malta

    Malta

    18%
  • Netherlands

    Netherlands

    21%
  • Poland

    Poland

    23%
  • Portugal

    Portugal

    23%
  • Romania

    Romania

    19%
  • Slovakia

    Slovakia

    20%
  • Slovenia

    Slovenia

    22%
  • Spain

    Spain

    21%
  • Sweden

    Sweden

    25%
  • USA

    USA

    0%
european
states
  • germany
  • Español
  • Italiano
  • Poland
  • Русский
  • Slovenski
  • Türkçe
  • ukraine
  • kingdom
  • French
  • Hrvatska
  • Other
  • Austria
  • Belgium
  • Bulgaria
  • Croatia
  • Cyprus
  • Czech Republic
  • Denmark
  • Estonia
  • Finland
  • France
  • Germany
  • Greece
  • Hungary
  • Ireland
  • Italy
  • Latvia
  • Lithuania
  • Luxembourg
  • Malta
  • Netherlands
  • Poland
  • Portugal
  • Romania
  • Slovakia
  • Slovenia
  • Spain
  • Sweden
  • USA