Списки IP адресов для iptables

Так как не все наши заказчики выполняют требование по защите наших серверов файрволлом (доступ по ssh только с доверенных IP), быстрым решением было ограничить подключения в /etc/ssh/sshd_config через AllowUsers. В целом задачу свою подобное решение выполняло, за исключением одного момента – подключение с неизвестного IP отвергается, а в логах записи, тем не менее, остаются. При активных bruteforce-атаках логи пухли как на дроджжах и в условиях ограниченного дискового пространства это вызывало определённые проблемы. В итоге, улучив минутку, сел переделывать по-человечески – настраивать iptables на подконтрольном сервере, раз заказчики не чешутся и не выполняют наши техтребования.
Как оказалось, сами iptables этого не умеют. Решение нашлось быстро – ipset. Конечно, в сравнении с pf, меня несколько удивляет, что для подобной элементарной задачи нужна отдельная утилита… Буду считать это ярчайшим проявлением unixway: одна задача – один инструмент.
Список для ipset готовится элементарно, потом экспотируется командой ipset save в понятный ipset формат и подгружается при помощи ipset restore.
В набор адресов для ipset я добавил внешние адреса офиса и внутренние подсети, определённые RFC. Вот что получилось:
create trusted hash:net family inet hashsize 1024 maxelem 65536
add trusted 192.168.0.0/16
add trusted 10.0.0.0/8
add trusted 172.16.0.0/12
add trusted xxx.xxx.xxx.0/24
add trusted yyy.yyy.yyy.yyy

Где trusted – это имя списка IP, точнее списка подсетей.
Правило для iptables трансформировалось из
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
в
-A INPUT -m state --state NEW -m set --set trusted src -m tcp -p tcp --dport 22 -j ACCEPT
т.е. добавил -m set --set trusted src, где -m set указание на использование списка ipset, --set trusted имя списка и параметр указывающий что это список источников – src.
А вот дальше началось самое интересное – как при загрузке ОС скормить эти списки iptables, т.к. если список не загружен, то правила iptables не применяются, ссылаясь на ошибку.
Т.е. комманда ipset restore должна выполняться ДО iptables rstore. Оказалось, что в Scientific Linux с этим проблема. В пакете ipset-6.11-1.el6.i686 службы ipset нет, а из /etc/rc.local комманды выполняются ПОСЛЕ iptables restore, что, как я писал выше, приводит к ошибке и правила не загружаются. Получается, что по умолчанию два варианта – писать свои скрипты инициализации (как вариант использовать найденные в интернете) или колхозить ещё более жутким образом, типа прописать ipset restore < /etc/ipset.rules в /etc/init.d/iptables. Оба этих варианта меня как-то не сильно радовали.
Выход таки нашёлся – в репозиториях CentOS есть пакет ipset-init, который содержит в себе необходимые для решения данной задачи скрипты init.d.
После установки пакета добавил вышеприведённый конфиг в /etc/sysconfig/ipset и все проблемы с подгрузкой списков разрешились.
К слову сказать, в Arch Linux пакет ipset идёт со скриптами для systemd и использование сторонних скриптов и пакетов не требуется.
UPDATE: В более позднем пакете ipset-6.11-3.el6.i686 из SL6.6 служба ipset всё-таки появилась и необходимость в стороннем пакете отпала.

Share