Я новичок в iptables и хочу понять, как работает iptables nat. У меня есть машина linux с контейнером lxc. Конфигурация сети машины выглядит следующим образом: интерфейс eth0, который подключает машину к Интернету (его адрес IPv4 - 10.9.63.173) и интерфейс veth-1 (192.168.2.1) для контейнера lxc. В контейнере lxc есть интерфейс eth0 (192.168.2.2), подключенный к veth-1.

На Linux-машине я добавил два правила iptables:

1) iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 10.9.63.173
2) iptables -t nat -A PREROUTING -d 10.9.63.173 -j DNAT --to-destination 192.168.2.2

Если я выполняю ping 8.8.8.8 из контейнера lxc, все работает (исходный IP-адрес переводится в 10.9.63.173 при выходе из машины linux). Но второе правило никогда не соответствует ответам эхо-запроса. Я смотрел входящие пакеты на eth0 (10.9.63.173), используя tcpdump, и вывод выглядит следующим образом:

23:34:33.151565 IP google-public-dns-a.google.com > host.local: ICMP echo reply, id 536, seq 174, length 64

Поэтому пакеты с пунктом назначения 10.9.63.173 поступают на интерфейс eth0.

У меня три вопроса:

1) Почему правило предварительной маршрутизации nat никогда не совпадает?

2) Как iptables узнает, как изменить ответы так, чтобы они пересылались в 192.168.2.2?

3) Может ли цель SNAT изменить исходный порт (без явного указания переводить на определенный порт (ы))?

Спасибо!

3 ответа3

0

1) Почему правило предварительной маршрутизации nat никогда не совпадает?

iptables NAT работает на "соединениях" *, только первый пакет каждого "соединения" проходит через таблицы nat, управляемые пользователем.

2) Как iptables узнает, как изменить ответы так, чтобы они пересылались в 192.168.2.2?

Когда первый пакет "соединения" проходит через NAT, он устанавливает запись во внутренней таблице отслеживания соединений. Это используется для перевода более поздних пакетов соединения.

3) Может ли цель SNAT изменить исходный порт (без явного указания переводить на определенный порт (ы))?

Да, это возможно, но по умолчанию это будет сделано только в том случае, если необходимо избежать двусмысленности.

* "соединение" здесь относится к набору критериев, которые могут использоваться для сопоставления запросов с их соответствующими ответами. например, исходный ip/ исходный порт / целевой ip/ порт назначения для TCP / UDP или исходный ip/ type / id / code / destination ip для запросов ICMP.

0

Взгляните на TCP и отслеживание соединений, я думаю: http://www.iptables.info/en/connection-state.html

Насколько мне известно, SNAT может изменять только IP-адрес источника.

0

Iptables использует таблицу NAT и машину conntrack. Таким образом, если ваш контейнер инициирует соединение, он будет соответствовать правилу SNAT, записать в таблицу NAT и заполнить таблицу conntrack.

Когда приходит ответ, conntrack знает (с ip и портом источника и получателя, а также последовательностью TCP, если соединение является TCP), что пакет принадлежит соединению, и направит его в соответствии с правильным NAT.

Для каждого соединения только первый пакет будет соответствовать правилу NAT, затем каждый другой будет просто следовать тому же пути (или обратному пути).

Если новое соединение поступает извне к вашему контейнеру, оно будет соответствовать правилу DNAT.

SNAT не может изменить исходный порт.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .