Я пытаюсь перенаправить входящий интернет-трафик http на [:: 1]: 8080, к которому привязывается мой http-сервер. Я использую nftables на устройстве, поддерживающем только IPv6. Если я добавлю следующие правила:
sudo nft flush ruleset
sudo nft add table ip6 nat
sudo nft add chain ip6 nat prerouting { type nat hook prerouting priority 0 \; }
sudo nft add chain ip6 nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule ip6 nat prerouting ip6 daddr [global-ip6] tcp dport 80 dnat to ::1 :8080
sudo nft list ruleset
с результирующим набором правил:
table ip6 nat {
chain prerouting {
type nat hook prerouting priority 0; policy accept;
ip6 daddr [global-ip6] tcp dport http dnat to [::1]:http-alt
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
}
}
затем запросы к [global-ip6]: 80 будут проглочены (нет ошибки отказа в соединении), но соединение не установлено.
Если я воспользуюсь одним из правил
sudo nft add rule ip6 nat prerouting tcp dport 80 redirect to 8080
или
sudo nft add rule ip6 nat prerouting ip6 daddr [global-ip6] tcp dport 80 dnat to [global-ip6] :8080
и привязать мою программу к [global-ip6]:8080
, то связь работает должным образом.
Вы знаете, что мне не хватает? Я попробовал некоторые правила в postrouting
и input
цепи, но не смог заставить его работать. Вернувшись с IPv4 и iptables, мне пришлось сделать sudo sysctl -w net.ipv4.conf.all.route_localnet=1
, может есть аналогичный флаг IPv6?
К сожалению, вы не можете добиться того, чего хотите, с помощью nftables.
После цели dnat адрес назначения перезаписывается на адрес обратной связи (::1
), а затем входящий пакет обрабатывается кодом маршрутизации. Но любой входящий пакет с адресом назначения обратной связи, полученный извне, ДОЛЖЕН быть отброшен RFC 4291 2.5.3. Нет никаких sysctl
переменные, чтобы изменить это поведение.
Вы можете запустить какое-нибудь прокси-приложение, которое будет принимать соединение по внешнему адресу и подключаться к приложению, которое прослушивает адрес обратной связи.