Поскольку этот вопрос был повышен до канонического вопроса о шпильке NAT , я подумал, что, вероятно, у него должен быть ответ, который был бы более общепринятым, чем принятый в настоящее время, который (хотя и превосходный) относится конкретно к FreeBSD.
Этот вопрос относится к услугам, предоставляемым серверами в сетях IPv4 с адресацией RFC1918, которые доступны внешним пользователям путем введения целевого NAT (DNAT) на шлюзе. Внутренние пользователи затем пытаются получить доступ к этим службам через внешний адрес. Их пакет отправляется от клиента к устройству шлюза, который перезаписывает адрес назначения и немедленно внедряет его обратно во внутреннюю сеть. Именно этот резкий разворот, который делает пакет на шлюзе, приводит к названию шпильки NAT , по аналогии с поворотом шпильки .
Проблема возникает, когда устройство шлюза перезаписывает адрес назначения, но не адрес источника. Затем сервер получает пакет с внутренним адресом назначения (своим собственным) и внутренним адресом источника (клиентского); он знает, что может ответить прямо на такой адрес, поэтому он и делает. Поскольку этот ответ является прямым, он не проходит через шлюз, который, следовательно, никогда не получает возможности сбалансировать влияние NAT входящего назначения на исходный пакет путем перезаписи исходного адреса возвращаемого пакета.
Таким образом, клиент отправляет пакет на внешний IP-адрес, но получает ответ с внутреннего IP-адреса. Он не знает, что два пакета являются частью одного и того же диалога, поэтому никакой беседы не происходит.
Решение заключается в том, что для пакетов, которым требуется такой NAT назначения и которые достигают шлюза из внутренней сети , также необходимо выполнить NAT источника (SNAT) для входящего пакета, обычно путем перезаписи адреса источника в адрес шлюза. Затем сервер считает, что клиент является самим шлюзом, и отвечает непосредственно на него. Это, в свою очередь, дает шлюзу возможность сбалансировать влияние как DNAT, так и SNAT на входящий пакет путем перезаписи адресов источника и назначения в возвращаемом пакете.
Клиент думает, что разговаривает с внешним сервером. Сервер думает, что говорит с устройством шлюза. Все стороны счастливы. Диаграмма может быть полезна на этом этапе:
Некоторые потребительские шлюзы достаточно ярки, чтобы распознавать те пакеты, для которых необходим второй шаг NAT, и они, вероятно, будут работать «из коробки» в сценарии с заколками NAT. Другие нет, и поэтому не будут, и вряд ли их можно заставить работать. Обсуждение устройств потребительского уровня, не относящихся к теме отказа сервера.
Правильным сетевым устройствам, как правило, говорят, что они работают, но - потому что они не занимаются вторым угадыванием своих администраторов - им нужно сказать, что они делают это. Linux использует iptables
для создания DNAT таким образом:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.3.11
который включит простой DNAT для порта HTTP, для внутреннего сервера 192.168.3.11
. Но для того, чтобы включить NAT для шпильки, необходимо также правило, например:
iptables -t nat -A POSTROUTING -d 192.168.3.11 -p tcp --dport 80 -j MASQUERADE
Обратите внимание, что для правильной работы такие правила должны находиться в нужном месте в соответствующих цепочках, и в зависимости от настроек в filter
цепочке могут потребоваться дополнительные правила, чтобы разрешить поток NAT-трафика. Все подобные обсуждения выходят за рамки этого ответа.
Но, как уже говорили другие, правильное включение шпильки NAT не лучший способ справиться с этой проблемой. Лучше всего использовать DNS с разделенным горизонтом , где ваша организация предоставляет разные ответы для исходного поиска в зависимости от того, где находится запрашивающий клиент, либо с помощью разных физических серверов для внутренних и внешних пользователей, либо путем настройки DNS-сервера для ответа по-разному в соответствии с адрес запрашивающего клиента.