Назад | Перейти на главную страницу

Правило iptables не работает с AWS NLB и Elastic IP, работает с общедоступным IP-адресом EC2 Instance

Я немного растерялся.

Сначала немного контекста: у меня есть экземпляр AWS EC2 за NLB. NLB использует эластичный 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 правила?

Есть другие идеи?

Глядя вокруг 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

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

Я запустил 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, использующий эластичный IP-адрес, который я использовал в запросе на копание. Будучи полностью сбит с толку, я затем выполнил ту же команду dig на машине Ubuntu, а также на компьютере с Windows 10. Истекло время ожидания для обоих запросов (правильно отфильтрованных iptables), я видел их в tcpdump, а сообщение журнала находилось в /var/log/kern.log, как и ожидалось. Я возвращаюсь к своему Macbook, выполняю ту же команду dig, но она по-прежнему возвращает ответ, а в tcpdump ничего нет ... WTF!

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

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

РЕДАКТИРОВАТЬ: чтобы уточнить. Я вижу запрос в tcpdump из моего Macbook (и он истекает, как ожидалось), если я использую общедоступный IP-адрес экземпляра, а не EIP. Это только с EIP не вижу запроса и он возвращает ответ ...

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