EUR
european

EUR

usa

USD

Russian Ru
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 сеты, заполненные 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-сетов (100K+ записей) 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

Если вы наблюдаете большой объём сообщений в журнале ядра об отброшенных пакетах, а система перестаёт отвечать, причиной может быть шквал логирования. В худшем случае это может вызвать панику ядра (kernel panic). Если вы настроили параметр 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 в Linux с помощью утилиты crash, чтобы определить первопричину. Это стандартная часть диагностики паники ядра Linux в рабочих системах. Полное руководство по тому, как включить kdump в 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.
  • Пустой /etc/sysconfig/nftables.conf в 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