Центральная часть моей конфигурации брандмауэра:
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Кажется, что RELATED
не работает для многоадресных ответов: когда хост отправляет в группу многоадресной рассылки (в моем случае обнаружение UPnP SSDP, на 239.255.255.250:1900), соответствующие ответы с определенного IP-адреса обратно на случайно выбранный порт отправителя отбрасываются.
Как правильно сохранить --state ESTABLISHED,RELATED
семантика, но заставить сопоставление ответов работать для многоадресной рассылки?
В последних ядрах Linux (> = 2.6.39) вы можете использовать ipset ядра для обхода ограничения отслеживания соединений. Вам не нужно писать какое-либо пользовательское пространство или помощник ядра. Для UPnP SSDP это можно записать как:
$ ipset create upnp hash:ip,port timeout 3
$ iptables -A OUTPUT -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j SET --add-set upnp src,src --exist
$ iptables -A INPUT -p udp -m set --match-set upnp dst,dst -j ACCEPT
Первая команда создает новый ipset с именем upnp в котором хранится кортеж (IP-адрес, IP-протокол, IP-порт), и каждая вставленная запись истекает через 3 секунды.
Вторая команда сопоставляет исходящий пакет SSDP UPnP (адресат - адрес многоадресной рассылки 239.255.255.250 на порту udp 1900) и сохраняет исходный IP-адрес и исходный порт UDP пакета в ipset upnp. Первое ключевое слово src средства исходный IP-адрес и второе ключевое слово src средства исходный порт как ipset типа хеш: ip, порт всегда нужна такая пара. Ключевое слово --существуют означает, что для существующей записи таймер сброшен. Эта сохраненная запись автоматически удаляется через 3 секунды.
Третья команда соответствует входящему пакету udp, и если его адрес назначения и порт назначения совпадают с некоторой записью в ipset upnp тогда этот пакет принят. Синтаксис dst, dst средства IP-адрес получателя и порт назначения.
Клиенты UPnP обычно отправляют пакет udp на номер 239.255.255.250:1090 и ждут ответа всего 2 секунды. Так что автоэкспирации через 3 секунды в ipset достаточно.
Я не нашел в Интернете какой-либо рабочей конфигурации брандмауэра / iptables для клиентов UPnP, которая не слишком расслабляла (например, принимала все входящие пакеты UDP) или без какого-либо отслеживания пользовательского пространства или необходимости исправления ядра. Поэтому я надеюсь, что этот пример вам поможет.
Это проблема многоадресной рассылки: netfilter никогда не может быть уверен, связано это или нет.
Таким образом, единственный способ разрешить UPnP SSDP:
-A INPUT -p udp --sport 1900 -j ACCEPT
В дополнение к существующим ESTABLISHED,RELATED
правило.