Linux: Управление сетевой безопасностью с помощью ipset

Каждый системный администратор, отвечающий за безопасность Linux-серверов, особенно в среде хостинга, сталкивается с классической задачей: необходимость блокировать или разрешать доступ с большого количества IP-адресов. Это могут быть списки стран, перечни известных ботнетов, адреса, участвующие в DDoS-атаке, или динамические whitelist'ы для клиентов.

Наивное решение — создание отдельных правил в iptables для каждого адреса. Команда вида iptables -A INPUT -s 192.0.2.1 -j DROP для тысячи адресов превратится в тысячу последовательных правил. Это приводит к ряду критических проблем:

  1. Падение производительности. iptables проверяет правила линейно. При каждом пакете ядро должно пройтись по сотням или тысячам записей, что потребляет ценные ресурсы CPU.

  2. Сложность управления. Добавление или удаление адреса требует выполнения отдельной команды iptables. Работа с большими динамическими списками становится неэффективной.

  3. Длительная перезагрузка правил. Применение (iptables-restore) и проверка (iptables -L) огромного набора правил занимает значительное время.

Данная информация предназначена для услуг: VPS хостинг или Облачный хостинг

Ipset: Элегантное решение

Утилита ipset — это расширение для netfilter (подсистемы ядра, которая включает iptables), созданное специально для решения этих проблем. Её ключевая идея — хранить множества (sets) IP-адресов, сетей, портов, MAC-адресов или даже пар «адрес-порт» внутри ядра в виде высокооптимизированных структур данных (хэш-таблиц, деревьев). В правилах iptables вместо длинного списка отдельных IP вы ссылаетесь всего на один созданный набор.

Преимущества использования ipset:

  • Высокая производительность. Проверка принадлежности IP-адреса к хэш-таблице выполняется за константное время O(1), независимо от размера списка. Это кардинально снижает нагрузку на процессор.

  • Удобство управления. Вы можете добавлять или удалять адреса из набора одной командой, не трогая правила iptables.

  • Экономия правил. Один-единственный rule в цепочке iptables может охватывать тысячи адресов.

  • Поддержка различных типов данных. Можно создавать наборы не только для IP, но и для сетей, портов, комбинаций параметров, что обеспечивает гибкость.

Установка и базовые команды

На большинстве дистрибутивов установка выполняется одной командой:

  • Debian/Ubuntu: sudo apt-get install ipset

  • RHEL/CentOS/Fedora: sudo yum install ipset (или sudo dnf install ipset)

  • Arch Linux: sudo pacman -S ipset

Базовый синтаксис управления:

  • ipset create SETNAME TYPENAME [OPTIONS] — создать новый набор.

  • ipset add SETNAME ENTRY — добавить запись в набор.

  • ipset del SETNAME ENTRY — удалить запись из набора.

  • ipset list [SETNAME] — вывести содержимое набора (всех наборов).

  • ipset save [SETNAME] — сохранить набор(ы) в файл (для резервного копирования).

  • ipset restore — восстановить наборы из файла.

  • ipset destroy [SETNAME] — удалить набор.

  • ipset flush [SETNAME] — очистить набор (удалить все записи).

Типы наборов (set types) — основа эффективности

Выбор правильного типа набора — ключевой момент. Основные типы делятся на две категории: для хранения отдельных значений и для хранения пар (например, IP-адрес + порт).

1. Типы для хранения отдельных сущностей:

  • hash:ip — самый частый тип для хранения отдельных IPv4-адресов.

  • hash:net — для хранения подсетей (например, 192.0.2.0/24). Позволяет как добавлять конкретные IP (/32), так и целые диапазоны.

  • hash:mac — для хранения MAC-адресов.

  • hash:ip,mark — для хранения пар «IP-адрес + маркер пакета (fwmark)».

2. Типы для хранения пар «адрес-порт» (port matching):
Эти типы идеальны для создания комплексных правил, учитывающих и источник, и порт назначения/источника.

  • hash:ip,port — хранит пары IP:port. Порт может быть как назначения, так и источника (задается в iptables).

  • hash:net,port — хранит пары сеть/маска:port.

  • hash:ip,port,ip — тройки IP,port,IP (например, исходный IP, порт, целевой IP).

  • hash:ip,port,net — аналогично.

3. Типы с поддержкой счетчиков (counters) и тайм-аутов (timeout):
При создании набора можно указать мощные опции:

  • counters — позволяет вести подсчет пакетов и байтов для каждой записи в наборе.

  • timeout — задает время жизни (в секундах) для каждой записи. После истечения тайм-аута запись автоматически удаляется из набора. Это невероятно полезно для временных блокировок.

  • skbinfo — позволяет задавать расширенные параметры, такие как skbmark или skbprio, для каждой записи.

Практические примеры для защиты сервера

Рассмотрим сценарии, максимально приближенные к реальным задачам администрирования хостинг-сервера.

Пример 1: Создание статичного Blacklist для заведомо опасных сетей

Допустим, мы хотим заблокировать несколько известных «плохих» подсетей.

# Создаем набор типа hash:net с именем blacklist
sudo ipset create blacklist hash:net

# Добавляем опасные подсети
sudo ipset add blacklist 203.0.113.0/24
sudo ipset add blacklist 198.51.100.0/28
sudo ipset add blacklist 192.0.2.0/25

# Создаем правило iptables, которое применяет этот набор
sudo iptables -I INPUT -m set --match-set blacklist src -j DROP
sudo iptables -I FORWARD -m set --match-set blacklist src -j DROP

Пояснение: Параметр -m set --match-set blacklist src загружает модуль set и проверяет, принадлежит ли исходный IP-адрес (src) пакета набору blacklist. Если да, пакет отбрасывается.

Пример 2: Динамический Blacklist с тайм-аутом для защиты от сканирования портов

Частая атака — сканирование портов. Мы можем автоматически блокировать IP на некоторое время при попытке подключения к запрещенным портам.

# Создаем набор scaners с автоматическим удалением через час (3600 секунд)
sudo ipset create scanners hash:ip timeout 3600

# Правило: если кто-то пытается подключиться к неиспользуемому порту 6667 (или любому другому), добавляем его IP в набор scanners
sudo iptables -A INPUT -p tcp --dport 6667 -m state --state NEW -j SET --add-set scanners src
# И тут же отклоняем пакет
sudo iptables -A INPUT -p tcp --dport 6667 -j DROP

# Дополнительное правило: сразу DROP для всех, кто уже есть в наборе scanners
sudo iptables -I INPUT -m set --match-set scanners src -j DROP

Пояснение: Первое правило с действием -j SET --add-set scanners src — это ключ. Оно динамически заносит IP-адрес атакующего в набор scanners. Через 3600 секунд запись автоматически исчезнет, разблокировав адрес (если атаки не повторятся).

Пример 3: Создание Whitelist для защиты панели управления (SSH, Web-admin)

Защищаем критически важные сервисы, разрешая доступ только с доверенных IP.

# Создаем whitelist для админов. Без тайм-аута.
sudo ipset create admin_whitelist hash:ip

# Добавляем доверенные IP
sudo ipset add admin_whitelist 93.184.216.34
sudo ipset add admin_whitelist 2001:db8::1

# Правила для SSH (22 порт). Сначала разрешаем whitelist, затем запрещаем всем остальным.
sudo iptables -A INPUT -p tcp --dport 22 -m set --match-set admin_whitelist src -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP

# Аналогично для веб-панели (порт 8080)
sudo iptables -A INPUT -p tcp --dport 8080 -m set --match-set admin_whitelist src -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8080 -j DROP

Пример 4: Блокировка по странам (GeoIP blocking) с помощью ipset

Это мощный метод для снижения нецелевого трафика и атак.

  1. Скачиваем списки IP-адресов по странам (например, с https://www.ipdeny.com/ipblocks/).

  2. Создаем набор для блокируемой страны

    sudo ipset create block_ru hash:net

    Добавляем подсети из скачанного файла (формат agregated)

    sudo ipset restore -f block_ru.ipset

    Файл block_ru.ipset должен содержать строки типа: add block_ru 2.56.0.0/14

  3. Применяем правило:

    sudo iptables -I INPUT -m set --match-set block_ru src -j DROP

Пример 5: Комбинированный набор для защиты веб-сервера от флуда запросов

Защитим порт 80 от слишком частых запросов с одного IP.

# Создаем набор для отслеживания соединений. Тайм-аут 300 секунд.
sudo ipset create http_flood hash:ip timeout 300

# Правило: если с одного IP пришло более 50 новых HTTP-соединений за 30 секунд, заносим его в черный список.
sudo iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --set --name HTTPFLOOD
sudo iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 30 --hitcount 50 --name HTTPFLOOD -j SET --add-set http_flood src
sudo iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 30 --hitcount 50 --name HTTPFLOOD -j LOG --log-prefix "HTTP Flood: "

# Главное правило блокировки для тех, кто в наборе
sudo iptables -I INPUT -p tcp --dport 80 -m set --match-set http_flood src -j DROP

 

Пояснение: Здесь комбинируются модули recent (для отслеживания частоты запросов) и set (для постоянной блокировки на 5 минут). IP, превысивший лимит, попадает в http_flood и блокируется на все порты (по правилу -m set), а не только на 80-й.

Сохранение и восстановление наборов ipset

Наборы ipset, созданные в командной строке, существуют только в оперативной памяти. После перезагрузки сервера они исчезнут. Для постоянного хранения необходимо настроить их сохранение.

  1. Способ 1: Ручное сохранение/восстановление (для резервных копий).
    Сохраняем все наборы в файл

    sudo ipset save > /etc/ipset.rules

    Восстанавливаем из файла

    sudo ipset restore < /etc/ipset.rules

  2. Способ 2: Автоматическая загрузка при старте системы (рекомендовано).
    Установите пакет iptables-persistent (в Debian/Ubuntu), который также умеет сохранять ipset.

    sudo apt-get install iptables-persistent

    Во время установки вам предложат сохранить текущие правила iptables. После установки можно сохранять наборы вручную:

    # Сохранить текущую конфигурацию ipset (правила iptables сохраняются отдельно)
    sudo ipset save > /etc/iptables/ipsets

    Чтобы убедиться, что наборы загружаются при загрузке, можно создать systemd-сервис или добавить команду восстановления в скрипт инициализации (например, в /etc/rc.local):
    Для systemd создаем сервисный файл /etc/systemd/system/ipset-persistent.service

    [Unit]
    Description=Load IP sets
    Before=network-pre.target

    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/sbin/ipset restore -f /etc/iptables/ipsets

    [Install]
    WantedBy=multi-user.target

    Активируем сервис
    sudo systemctl daemon-reload
    sudo systemctl enable ipset-persistent.service

Советы по оптимизации и безопасности

  • Порядок правил в iptables. Правило с -m set должно стоять как можно раньше в цепочке, чтобы отсекать нежелательный трафик до более ресурсоемких проверок (например, анализа строк в -m string).

  • Используйте hash:net вместо множества hash:ip. Блокировка целых подсетей /24 (256 адресов) одной записью в наборе эффективнее, чем 256 отдельных записей.

  • Мониторинг. Регулярно проверяйте содержимое и счетчики наборов: sudo ipset list -t. Это поможет выявить аномалии.

  • Логирование. Для отладки добавляйте правила с логированием перед блокировкой:

    sudo iptables -I INPUT -m set --match-set blacklist src -j LOG --log-prefix "IPset BLOCK: "

  • Осторожно с IPv6. Типы наборов по умолчанию для IPv4. Для IPv6 используйте типы с префиксом hash:ip6hash:net6 и т.д. (например, sudo ipset create blacklist6 hash:net6).

Заключение

Ipset — это не просто дополнение к iptables, а качественный скачок в управлении сетевой безопасностью для сред, где важны масштаб и производительность. Для хостинг-провайдера, VPS-владельца или администратора корпоративного сервера владение ipset — это обязательный навык, позволяющий эффективно противостоять современным сетевым угрозам, снижая при этом нагрузку на сервер. Начните с малого — создайте blacklist для заблокированных адресов и whitelist для админ-доступа, — и вы сразу оцените мощь, простоту и элегантность этого инструмента.

  • 0 Пользователи нашли это полезным

Помог ли вам данный ответ?

Ищете что-то другое?

xvps.ru