РЕДАКТИРОВАТЬ: tldr: я хочу использовать TEE и NAT для клонирования трафика UDP. Я не беспокоюсь об обработке ответов. В идеале я не хочу устанавливать новое программное обеспечение. Я использую TEE для успешной отправки в локальный сегмент (127.0.0.2), затем я хочу преобразовать этот трафик в глобальную сеть через NAT.
У меня bind9 прослушивает порт 53 на моем сервере Debian. У меня есть внешний клиент, выполняющий DNS-запросы к указанному серверу. Все это работает нормально. Я хотел бы скопировать входящие запросы DNS на порт 53 и отправить их, скажем, на 8.8.8.8. Обратите внимание на слово копировать.
Из-за большого количества поисков в Google и чтения на SU я обнаружил, что наиболее часто рекомендуемый метод - использовать iptables TEE и NAT. У меня TEE работает неплохо, вот моя команда:
iptables -t mangle -A POSTROUTING -p udp -d 127.0.0.1 --dport 53 -j TEE --gateway 127.0.0.2
Я подтвердил, что получил копию DNS-запроса на 127.0.0.2:53 с помощью netcat. Все идет нормально.
Теперь мне нужно изменить IP-адрес назначения. Я пытаюсь добиться этого с помощью:
iptables -t nat -A PREROUTING -p udp -d 127.0.0.2 --dport 53 -j DNAT --to 8.8.8.8
Я использовал tcpdump для отслеживания исходящего трафика на 8.8.8.8. Ничего. Я подумал: может быть, мне нужно изменить исходный IP-адрес, чтобы ядро не отбрасывало этот пакет, поскольку он прибывает на 127.0.0.2, но исходный IP-адрес установлен на IP-адрес моего внешнего DNS-клиента. Почему нет?
iptables -t nat -A POSTROUTING -p udp -d 127.0.0.2 --dport 53 -j SNAT --to DNS_SERVERS_PUBLIC_IP
Тем не менее, tcpdump ничего не показывает.
У меня есть IP-переадресация:
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
У меня почти нет идей, и я был бы признателен за любую помощь. Спасибо.
В документации говорится
В Тройник target клонирует пакет и перенаправляет этот клон на другую машину на местный сетевой сегмент. Другими словами, следующий шаг должен быть целью, иначе вам придется настроить следующий шаг, чтобы пересылать его дальше, если это необходимо.
Я не знаю причину этого ограничения, но кажется, что его невозможно преодолеть с помощью iptables NAT, что имеет смысл, потому что, если базовая реализация поддерживает внешние цели, тогда зачем ограничивать целевой диапазон TEE. Подозреваю, что TEE делается ниже уровня NAT.
Это все равно не сработает, потому что ответ придет с неправильным адресом источника.
С iptables нет ничего невозможного.
# iptables -t nat -L -v --line-numbers -n
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 5 281 MARK udp -- docker0 * 0.0.0.0/0 172.17.0.1 udp dpt:53 MARK set 0xc0fe
2 5 281 TEE udp -- docker0 * 0.0.0.0/0 172.17.0.1 udp dpt:53 TEE gw:127.1.2.3
3 3 167 DNAT udp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0xc0fe to:1.1.1.1:53
Я тестировал это с помощью докера, так как с его интерфейсом легче играть. Обратите внимание, что я поместил эти правила перед любыми другими правилами в таблице предварительной маршрутизации nat.
Что вы делаете, так это отмечаете интересующий вас пакет, затем TEE (копируете) этот пакет, и теперь вы можете DNAT этого пакета на 1.1.1.1.
Отметьте их, здесь вы должны использовать свой eth0 или eno1, а не docker0.
iptables -t nat -I PREROUTING 1 -i docker0 -p udp -d 172.17.0.1 --dport 53 -j MARK --set-mark 0xc0fe
Скопируйте его на localhost, правило может быть таким
iptables -t nat -I PREROUTING 2 -i docker0 -p udp --dst 172.17.0.1 --dport 53 -j TEE --gateway 127.1.2.3
Но это также может быть так: iptables -t nat -I PREROUTING 3 -p udp -m mark --mark 0xc0fe -j TEE --gateway 127.1.2.3
в заключение
iptables -t nat -I PREROUTING 3 -p udp -m mark --mark 0xc0fe -j DNAT --to-destination 1.1.1.1:53
Эй, значит, вы были на правильном пути, за исключением использования TEE в таблице mangle, здесь я использую как TEE, так и DNAT в таблице nat, и MARK не нужен, за исключением упрощения отладки и обработки изменений правил. Еще одна ваша ошибка заключалась в том, что вы позволили правилу DNAT действовать в момент, когда, по вашему мнению, должен переходить TEE, но вместо этого TEE и DNAT должны действовать на тех же условиях. Но я оставлю здесь правила, просто чтобы повеселиться с культистами карго.
В более коротком виде iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dst 172.17.0.1 --dport 53 -j TEE --gateway 127.3.3.3 iptables -t nat -I PREROUTING 2 -i eth0 -p udp --dst 172.17.0.1 --dport 53 -j DNAT --to-destination 1.1.1.1:53
Поскольку TEE можно использовать только в той же подсети, вы можете использовать инструмент Демонлоггер, так же доступно на github (где вроде посвежее?).
Daemonlogger - это регистратор пакетов и программный отвод, разработанный Мартином Рошем. Программа на основе libpcap имеет два режима выполнения:
- Он перехватывает пакеты и отправляет их прямо на диск и может демонизировать себя для фоновой регистрации пакетов. По умолчанию файл обновляется при регистрации 2 ГБ данных.
- Он прослушивает пакеты и перезаписывает их на второй интерфейс., по сути, действуя как мягкий кран. Это также можно сделать в режиме демона. Эти два режима выполнения являются взаимоисключающими: если программа находится в режиме касания (с помощью переключателя -I), запись на диск отключается.
Некоторые записи: