Правило iptables не работает с AWS NLB и Elastic IP, работает с использованием публичного IP-адреса экземпляра EC2

Правило iptables не работает с AWS NLB и Elastic IP, работает с использованием публичного IP-адреса экземпляра EC2

Я в некоторой растерянности.

Сначала немного контекста: у меня есть экземпляр AWS EC2 за NLB. NLB использует Elastic IP. Экземпляр EC2 запускает DNS-сервер и прослушивает UDP и TCP 53. NLB настроен на TCP и UDP-порт 53. Экземпляр находится в целевой группе и работоспособен с точки зрения NLB (и обслуживает запросы, как и ожидалось).

Проблема, которую я пытаюсь решить: я хочу быть уверенным, что все DNS-запросы для типа записи ANY(а также несколько других правил для ограничения скорости и фильтрации) будут отклонены, поэтому я добавил следующие iptablesправила:

$ iptables -t raw -I PREROUTING -p udp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 40 -j DROP

$ iptables -t raw -I PREROUTING -p tcp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 52 -j DROP

$ iptables -t raw -I PREROUTING -p udp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 40 -j LOG \
    --log-prefix "BLOCKED ANY: "

$ iptables -t raw -I PREROUTING -p tcp --dport 53 -m string \
    --hex-string "|0000FF0001|" --algo bm --from 52 -j LOG \
    --log-prefix "BLOCKED ANY: "

А теперь о проблеме...

Если я попробую, dig some.domain -t any @public.ip.of.instanceмой запрос будет заблокирован, и я увижу запись в журнале, /var/log/kern.logкак и ожидалось.

Если я попробую, dig some.domain -t any @elastic.ip.on.nlbзапрос не блокируется и я получаю ответ. Нет записи в журнале kern.log.

Самое странное для меня то, что я попытался убрать NLB из картины и назначить тот же Elastic IP экземпляру напрямую. Тот же результат — запрос, ANYотправленный в , EIPне отбрасывается даже при наличии вышеуказанных iptablesправил. Тот же ANYзапрос, отправленный с другого экземпляра, использующего частный IP вместо , EIPотбрасывается, как и ожидалось.

Я пробовал те же правила в таблицах nat(также с использованием PREROUTINGцепочки) и filter(с использованием INPUTцепочки). Я что-то очевидное упускаю в своих iptablesправилах?

Есть еще идеи?

решение1

Просматривая ServerFault, я нашел этот ответ -iptables отбрасывает пакет при совпадении шестнадцатеричной строкикоторый показывает пробелы между шестнадцатеричными значениями, я бы предложил попробовать это:

Пример из этого вопроса:

$ iptables --append INPUT --match string --algo kmp \
    --hex-string '|f4 6d 04 25 b2 02 00 0a|' --jump ACCEPT

Поэтому измените свои примеры следующим образом:

$ iptables -t raw -I PREROUTING -p udp --dport 53 -m string \
    --hex-string "|00 00 FF 00 01|" --algo bm --from 40 -j DROP

решение2

Хорошо, хорошо послемногоПосле нескольких часов устранения неполадок, похоже, что короткий ответ заключается в том, что все это время все работало...

Я запустил tcpdump на экземпляре EC2 за NLB ( tcpdump udp port 53 -X -nn). Затем я запустил его со своего Macbook (Catalina 10.15.2) dig some.domain -t any @elastic.ip.on.nlbи не только получил ответ, но и запрос даже не появился в захвате пакетов на экземпляре EC2. За NLB есть только один экземпляр EC2, использующий Elastic IP, который я использовал в запросе dig. Будучи совершенно сбитым с толку, я затем запустил ту же команду dig на машине Ubuntu, а также на компьютере Windows 10. Оба этих запроса истекли по времени (правильно отфильтрованы iptables), я увидел их в tcpdump, и сообщение журнала было в /var/log/kern.log, как и ожидалось. Я вернулся на свой Macbook, запустил ту же команду dig, и она по-прежнему возвращает ответ и ничего в tcpdump... wtf!

Я перезагрузил свой Macbook, проверил в миллионный раз, что я использую правильные IP-адреса и тот же запрос, пробовал разные домены и, вероятно, сотню других вещей. Я в полном недоумении, почему это, кажется, возвращает ответ без ничего в захвате пакетов, поступающих с моего Macbook.

Так что в конечном итоге это выглядит как странно изолированная проблема (возможно, какая-то хромота Apple...), а не как странное искажение пакетов, производимое AWS, или неисправное правило iptables, как я изначально думал. Так что настоящий ответ: попробуйте на нескольких машинах, прежде чем отправлять на StackExchange.

EDIT: Для ясности. Я вижу запрос в tcpdump с моего Macbook (и он, как и ожидалось, отстает по времени), если я использую публичный IP экземпляра, а не EIP. Только с EIP я не вижу запроса, и он возвращает ответ...

Кроме того, я не уверен, должен ли это быть ответным постом или мне следовало просто изменить свой первоначальный пост. Модераторам делать с ним что угодно!

Связанный контент