Каждый системный администратор, отвечающий за безопасность Linux-серверов, особенно в среде хостинга, сталкивается с классической задачей: необходимость блокировать или разрешать доступ с большого количества IP-адресов. Это могут быть списки стран, перечни известных ботнетов, адреса, участвующие в DDoS-атаке, или динамические whitelist'ы для клиентов.
Наивное решение — создание отдельных правил в iptables для каждого адреса. Команда вида iptables -A INPUT -s 192.0.2.1 -j DROP для тысячи адресов превратится в тысячу последовательных правил. Это приводит к ряду критических проблем:
-
Падение производительности.
iptablesпроверяет правила линейно. При каждом пакете ядро должно пройтись по сотням или тысячам записей, что потребляет ценные ресурсы CPU. -
Сложность управления. Добавление или удаление адреса требует выполнения отдельной команды
iptables. Работа с большими динамическими списками становится неэффективной. -
Длительная перезагрузка правил. Применение (
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
Это мощный метод для снижения нецелевого трафика и атак.
-
Скачиваем списки IP-адресов по странам (например, с https://www.ipdeny.com/ipblocks/).
-
Создаем набор для блокируемой страны
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
-
Применяем правило:
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: Ручное сохранение/восстановление (для резервных копий).
Сохраняем все наборы в файлsudo ipset save > /etc/ipset.rulesВосстанавливаем из файла
sudo ipset restore < /etc/ipset.rules -
Способ 2: Автоматическая загрузка при старте системы (рекомендовано).
Установите пакетiptables-persistent(в Debian/Ubuntu), который также умеет сохранять ipset.sudo apt-get install iptables-persistentВо время установки вам предложат сохранить текущие правила iptables. После установки можно сохранять наборы вручную:
Чтобы убедиться, что наборы загружаются при загрузке, можно создать systemd-сервис или добавить команду восстановления в скрипт инициализации (например, в# Сохранить текущую конфигурацию ipset (правила iptables сохраняются отдельно)
sudo ipset save > /etc/iptables/ipsets/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:ip6,hash:net6и т.д. (например,sudo ipset create blacklist6 hash:net6).
Заключение
Ipset — это не просто дополнение к iptables, а качественный скачок в управлении сетевой безопасностью для сред, где важны масштаб и производительность. Для хостинг-провайдера, VPS-владельца или администратора корпоративного сервера владение ipset — это обязательный навык, позволяющий эффективно противостоять современным сетевым угрозам, снижая при этом нагрузку на сервер. Начните с малого — создайте blacklist для заблокированных адресов и whitelist для админ-доступа, — и вы сразу оцените мощь, простоту и элегантность этого инструмента.