У меня в iptables есть правило для блокировки доменов, заканчивающихся на .watch
:
sudo iptables -A OUTPUT -j DROP -m string --string ".watch" --algo kmp
Но проблема в том, что .
не может быть сопоставлено. Так что строка выше не соответствует ничему. Но если я уберу точку из .watch
to watch
, то все будет нормально.
Как заблокировать точки «.» в правилах iptables?
решение1
Синтаксически это кажется правильным, но ваш подход не подходит для этой цели.струнный патчсоответствует строке в любом месте пакета:
- Вы отбрасываете любой пакет, который имеет
watch
или.watch
где-либо. Это, скорее всего, вызовет ложные срабатывания и даже вводит новый вектор для атак типа «отказ в обслуживании». - Он не может обрабатывать зашифрованный трафик. Он не может блокироватьбольшая часть веб-трафика.
- Хотя у вас есть относительно хорошие варианты для алгоритма сопоставления (
bm
Бойер–Мур иkmp
Кнут–Пратт–Моррис), использование строкового фильтра все равно может потребовать больших вычислительных ресурсов.
Документация также прямо предостерегает от этого:
Пожалуйста, используйте это соответствие с осторожностью. Многие люди хотят использовать это соответствие для остановки червей, вместе с целью DROP. Это серьезная ошибка. Его побеждает любой метод обхода IDS.
Аналогичным образом, многие люди использовали это соответствие как средство для остановки определенных функций в HTTP, таких как POST или GET, путем отбрасывания любого HTTP-пакета, содержащего строку POST. Пожалуйста, поймите, что эта работа лучше выполняется фильтрующим прокси-сервером. Кроме того, любой HTML-контент со словом POST будет отброшен при использовании предыдущего метода. Это соответствие было разработано для того, чтобы иметь возможность ставить в очередь интересные пакеты пользовательского пространства для лучшего анализа, вот и все. Отбрасывание пакета на основе этого будет побеждено любым методом уклонения от IDS.
Есть лучшие альтернативы тому, чего вы пытаетесь достичь:
- Фильтрация на основе DNS. Любой DNS-сервер может это сделать. Например,Dnsmasq— это обычный облегченный DNS-пересылатель: вы можете просто добавить
address=/watch/0.0.0.0
его в конфигурацию. - Фильтрация на основе веб-прокси.
решение2
DNS-имена кодируются как метки с префиксом длины (см.рфк 1035для получения подробной информации), поэтому вам нужно использовать --hex-string "|05|watch|00|"
для сопоставления имен, заканчивающихся на.watch
(обратите внимание, что длина записывается как 2 шестнадцатеричные цифры, например, serverfault.com
будет закодирована как "|0b|serverfault|03|com|00|"
). Обратите внимание, что это следует объединить с -p udp
и --destination-port 53
(или 5353, если совпадают .local
адреса), в противном случае это, скорее всего, будет соответствовать множеству других несвязанных пакетов.
DNS-запросы также можно выполнять по TCP, но фильтрация TCP более сложна, и существующие комментарии о зашифрованных запросах, а также предложения об использовании фильтрации на уровне приложений с DNS и/или веб-прокси по-прежнему актуальны.