Я немного растерялся.
Сначала немного контекста: у меня есть экземпляр 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 не вижу запроса и он возвращает ответ ...
Кроме того, я не уверен, должно ли это быть ответным сообщением или мне следовало просто изменить свое первоначальное сообщение. Моды делайте с ним, что хотите!