При настройке нашей среды OpenStack я столкнулся с проблемой, которая не позволяла экземплярам связываться с сервером, работающим на хосте. Служба метаданных (которая предоставляет HTTP API) работает на порту 8775 на хосте, а сетевой код OpenStack добавляет следующее правило DNAT для предоставления доступа через специальный адрес на порту 80:
-A PREROUTING -d 169.254.169.254/32
-p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8775
Экземпляры подключаются к хосту через локальное мостовое устройство, и 169.254.169.254
назначен на lo
.
Хотя это правило успешно сопоставляет пакеты, исходящие от гостевого экземпляра, пытающегося получить доступ http://169.254.168.254/
, они никогда не достигают службы прослушивания.
Замена этого правила DNAT на в значительной степени эквивалентное REDIRECT заставляет все работать правильно:
-A PREROUTING -d 169.254.169.254/32
-p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8775
Я пытаюсь понять, почему REDIRECT работает, а DNAT не работает. Из документации iptables неясно, есть ли DNAT
правило, как ожидается, будет работать для локального трафика. Я надеюсь, что кто-то здесь сможет предоставить авторитетный ответ, в идеале подкрепленный документацией, или может предложить, что может быть не так в моей конфигурации, что мешает правилу DNAT работать должным образом.
То, что вы пытаетесь сделать, явно отрицается ядром.
Вы не можете отправлять пакеты с адресов, отличных от 127/8, на 127/8. Ядро их отфильтровывает и отбрасывает, поскольку считает их «марсианами».
Предположительно это происходит потому, что rp_filter
по умолчанию включено. Возможное отключение может изменить это поведение (хотя это отключит некоторые потенциально важные средства защиты).
С REDIRECT вы не меняете IP, поэтому он работает. Другими словами, если вы собираетесь использовать DNAT, вы можете отправить его куда угодно. вне из 127.0.0.0/8.
Согласно netfilter NAT HOWTO:
Существует специальный случай NAT назначения, называемый перенаправлением: это простое удобство, которое в точности эквивалентно выполнению DNAT по адресу входящего интерфейса.
Это немного более разумно, поскольку в качестве адреса устройства, на которое был получен пакет, он выбирает целевой адрес DNAT. В вашем случае это будет DNAT пакетов на адрес на устройстве моста, а не на 127.0.0.1.