Эта статья навеяна выполнением работ для одного из наших крупных клиентов ООО «ЕвроСтудио».
Известно, что в CentOS 7 было много нововведений. Одно из них — firewalld, демон-надстройка над iptables, добавляющая определенные удобства в работе с брандмауэром. Можно долго спорить на тему удобно/неудобно, и о том, что надстройка эта по умолчанию ставится только в разработках RedHat и совместимых с ними CentOS, но она есть, установлена, а значит почему бы ее не использовать?
Итак, IPset. Это именованные списки IP-адресов и подсетей, которые можно использовать в правилах iptables для уменьшения количества этих правил. Чем меньше правил — тем быстрее они анализируются, тем производительнее сеть на данном сервере. Поддержка IPset появилась в firewalld начиная с версии 0.4.0.
Смотрим версию firewalld
firewall-cmd -v
0.3.9
Видим, что версия ниже, чем 0.4.0, значит ее надо обновить
yum install firewall
Снова проверяем версию firewall
firewall-cmd -V
0.4.4.4
Если версия правильная, (>= 0.4.0, как у нас) можно работать с IPset. Например добавим список адресов
firewall-cmd --permanent --new-ipset=IP-whitelist --type=hash:ip
Если в списке должны быть и адреса, и подсети, то список следует добавлять так
firewall-cmd --permanent --new-ipset=IP-whitelist --type=hash:net
Мы добавили именованный список IP-whitelist. Опция «—permanent» добавляет конфигурационный файл этого списка, без нее после перезагрузки списка у нас не будет. А еще она сохраняет правила, списки и адреса в различные конфигурационные файлы .xml в директории /etc/firewalld, чтобы они автоматически применялись при перезагрузке сервера. Если нужно просто протестировать список или правило, опцию «—permanent» добавлять не нужно, правило или список в этом случае сохранится только до ближайшей перезагрузки.
Теперь будем добавлять в список адресов собственно адреса
firewall-cmd --ipset=IP-whitelist --add-entry=192.168.1.4 --permanent
firewall-cmd --ipset=IP-whitelist --add-entry=192.168.1.6 --permanent
firewall-cmd --ipset=IP-whitelist --add-entry=192.168.1.8 --permanent
И подсети
firewall-cmd --ipset=IP-whitelist --add-entry=192.168.2.0/24 --permanent
firewall-cmd --ipset=IP-whitelist --add-entry=192.168.1.100/28 --permanent
Перезагрузим настройки firewall
firewall-cmd --reload
Посмотрим, какие у нас есть списки адресов/сетей
Показать существующие списки адресов
firewall-cmd --get-ipsets
IP-whitelist
Показать сам список
firewall-cmd --ipset=IP-whitelist --get-entries
192.168.1.4
192.168.1.6
192.168.1.8
192.168.2.0/24
192.168.1.100/28
Список у нас есть, можем теперь добавить правила, работающие с этими списками.
Допустим, нам надо, чтобы сервис ssh был доступен только для белого списка адресов IP-whitelist, а порты 80 и 443 были закрыты для адресов в списке IP-blacklist
Добавим правило, разрешающее сервис ssh для белого списка «IP-whitelist»
firewall-cmd --permanent --zone=public --add-rich-rule='rule source ipset="IP-whitelist" service name="ssh" accept'
Если есть правило, разрешающее сервис ssh для всех, удалим его
firewall-cmd --permanent --zone=public --remove-service=ssh
Убедились, что ваш адрес есть в белом списке, иначе доступ к серверу будет закрыт!
firewall-cmd --ipset=IP-whitelist --get-entries
Перезагрузим настройки firewall
firewall-cmd --reload
Теперь создадим список IP-blacklist, добавим туда адреса
firewall-cmd --permanent --new-ipset=IP-blacklist --type=hash:net
firewall-cmd --ipset=IP-blacklist --add-entry=192.168.1.5 --permanent
firewall-cmd --ipset=IP-blacklist --add-entry=192.168.1.7 --permanent
firewall-cmd --ipset=IP-blacklist --add-entry=192.168.3.0/24 --permanent
firewall-cmd --ipset=IP-blacklist --add-entry=192.168.4.0/23 --permanent
Проверим, если хотим
firewall-cmd --get-ipsets
IP-whitelist
IP-blacklist
firewall-cmd --ipset=IP-whitelist --get-entries
192.168.1.5
192.168.1.7
192.168.3.0/24
192.168.4.0/23
И запретим доступ с этих адресов для портов 80 и 443 используя опцию service
firewall-cmd --add-rich-rule='rule source ipset=IP-blacklist service name="http" drop' --permanent
firewall-cmd --add-rich-rule='rule source ipset=IP-blacklist service name="https" drop' --permanent
Или опцию port
firewall-cmd --add-rich-rule='rule source ipset=IP-blacklist port protocol="tcp" port="80" drop' --permanent
firewall-cmd --add-rich-rule='rule source ipset=IP-blacklist port protocol="tcp" port="80" drop' --permanent
Перезагружаем настройки firewall
firewall-cmd --reload
Правила добавлены, блокировка включена, к ssh имеют доступ только разрешенные хосты. Теперь во время работы сервера мы можем добавлять и убирать адреса в эти списки
Добавление адреса в списки
firewall-cmd --ipset=IP-blacklist --add-entry=192.168.1.20 --permanent
firewall-cmd --ipset=IP-blacklist --add-entry=192.168.1.70 --permanent
firewall-cmd --ipset=IP-whitelist --add-entry=192.168.1.80 --permanent
firewall-cmd --reload
Удаление адреса из списка
firewall-cmd --ipset=IP-blacklist --remove-entry=192.168.1.5 --permanent
firewall-cmd --ipset=IP-blacklist --remove-entry=192.168.1.7 --permanent
firewall-cmd --reload
Люди, старайтесь избегать подобных конструкций:
-add-rich-rule=’rule source ipset=»IP-whitelist» service name=»ssh» accept’
Без особых причин, не ходите в rich, пользуйтесь стандартными source/service итп свойствами (если уж пользуетесь firewalld).
Чтобы применить ipset по source можно сказать так:
firewall-cmd —permanent —zone=trusted —add-source=ipset:IP-whitelist
Ок. Допустим, надо для ipset в зоне Public разрешить соединения на определенные порты(без привязки к известным sevice)/сервисы на локальном конкретном ip. Без rich сценарий какой? Я с наскока не въезжаю.