it-swarm-ru.tech

Возврат к перенаправленному общедоступному IP-адресу из локальной сети - Шпилька NAT

Это Канонический вопрос о шпильке NAT (Loopback NAT).

Общая форма этого вопроса:

У нас есть сеть с клиентами, сервером и маршрутизатором NAT). На маршрутизаторе имеется переадресация портов на сервер, поэтому некоторые его службы доступны извне. У нас есть DNS, указывающий на внешний IP. Клиентам локальной сети не удается подключиться, но внешняя работа.

  • Почему это не удается?
  • Как я могу создать единую схему именования (DNS-имена, которые работают как локально, так и внешне)?

Этот вопрос был объединен с несколькими другими вопросами. Первоначально они ссылались на FreeBSD, D-Link, Microtik и другое оборудование. Однако все они пытаются решить одну и ту же проблему.

46
adopilot

То, что вы ищете, называется "шпилька NAT". Запросы от внутреннего интерфейса для IP-адреса, назначенного внешнему интерфейсу, должны быть NAT-такими, как если бы они поступали от интерфейса внешней стороны.

Я совсем не знаком с FreeBSD, но читаю руководство по pf для OpenBSD ( http://www.openbsd.org/faq/pf/rdr.html ) предлагаемые решения DNS с разделенным горизонтом, использующий DMZ сеть или TCP прокси) заставляет меня поверить, что "pf" не поддерживает шпилечный NAT.

Я хотел бы взглянуть на маршрут DNS с разделенным горизонтом и не использовать IP-адреса в URL-адресах внутри, а вместо этого использовать имена.

16
Evan Anderson

Поскольку это было повышено до канонического вопроса о шпильке NAT, я подумал, что, вероятно, у него должен быть ответ, который был бы более общепринятым, чем принятый в настоящее время, который (хотя и превосходный) относится специально для FreeBSD.

Этот вопрос относится к услугам, предоставляемым серверами в сетях IPv4 с адресацией RFC1918, которые доступны внешним пользователям путем введения адресата NAT (DNAT) на шлюзе. Внутренние пользователи затем пытаются получить доступ к этим услугам через внешний адрес. Их пакет отправляется от клиента к устройству шлюза, который перезаписывает адрес назначения и немедленно вводит его обратно во внутреннюю сеть. Именно этот резкий поворот пакета делает на шлюзе, что приводит к название шпильки NAT , по аналогии с поворот шпильки .

Проблема возникает, когда устройство шлюза перезаписывает адрес назначения, но не адрес источника. Затем сервер получает пакет с внутренним адресом назначения (своим собственным) и внутренним адресом источника (клиентского); он знает, что может ответить прямо на такой адрес, поэтому он и делает. Поскольку этот ответ является прямым, он не проходит через шлюз, который поэтому никогда не получает возможности сбалансировать влияние входящего назначения NAT на исходный пакет, переписав исходный адрес возврата пакет.

Таким образом, клиент отправляет пакет на IP-адрес external, но получает ответ с IP-адреса internal. Он не знает, что эти два пакета являются частью одного и того же диалога, поэтому никакой беседы не происходит.

Решение состоит в том, что для пакетов, которые требуют такой NAT назначения и которые достигают шлюза из внутренней сети, также выполнить источник NAT (SNAT) на входящий пакет, обычно переписывая исходный адрес, чтобы он был адресом шлюза. Затем сервер думает, что клиент является самим шлюзом, и отвечает непосредственно на него. Это, в свою очередь, дает шлюзу возможность сбалансировать эффекты как DNAT, так и SNAT. во входящем пакете путем перезаписи адресов источника и назначения в возвращаемом пакете.

Клиент думает, что разговаривает с внешним сервером. Сервер думает, что говорит с устройством шлюза. Все стороны счастливы. Диаграмма может быть полезна на этом этапе:

enter image description here

Некоторые потребительские шлюзы достаточно ярки, чтобы распознавать те пакеты, для которых требуется второй 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-сервера для ответа по-разному в соответствии с адрес запрашивающего клиента.

49
MadHatter

Проблема здесь в том, что ваш маршрутизатор не NAT адрес вашего внутреннего клиента. Таким образом, рукопожатие TCP не удается).

Давайте предположим, что следующие IP

  • Клиент: 192.168.1.3
  • Сервер: 192.168.1.2
  • Маршрутизатор внутренний: 192.168.1
  • Маршрутизатор внешний: 123.123.123.1

Вот что происходит:

  1. Клиент (192.168.1.3) отправляет TCP-SYN на ваш внешний IP, порт 80 (123.123.123.1:80)
  2. Маршрутизатор видит правило переадресации портов и пересылает пакет на сервер (192.168.1.2:80) без изменения исходного IP-адреса (192.168.1.3)
  3. Клиент ожидает SYN-ACK с внешнего IP
  4. Сервер отправляет свой ответ обратно клиенту напрямую, потому что он находится в той же подсети. Он не отправляет пакет на маршрутизатор, который может изменить NAT.
  5. Клиент получает SYN-ACK с 192.168.1.2 вместо 123.123.123.1. И отбрасывает это.
  6. Клиент по-прежнему ожидает SYN-ACK с 123.123.123.1 и время ожидания истекло.
9
PEra

Почему бы не использовать DNS с расщепленным горизонтом вместо жесткого IP-адреса везде? У вас будет ext.yourdomain, указывающий на 217.x.x.x снаружи, а затем на 192.x.x.x внутри.

4
Ryaner

Если это оригинальный маршрутизатор D-Link (т. Е. Не Rev. D/Firmware Version 1.00VG от Virgin Media), вы должны иметь возможность отрегулировать настройки, чтобы обойти это. (Однако я согласен с предложением предыдущего автора о DD-WRT по многим другим причинам!)

  1. Войдите в веб-интерфейс маршрутизатора
  2. Перейдите на вкладку "Дополнительно" вверху
  3. Перейдите на вкладку "Параметры брандмауэра" слева.
  4. Нажмите Независимую конечную точку переключатель под Фильтрация конечной точки TCP , как показано в снимок экрана ниже (или см. эмулятор маршрутизатора на сайте D-Link)
  5. Сохранить изменения; ты сделал

D-Link router web UI screenshot

Этот скриншот взят из модели Rev. C; у тебя может быть немного по другому.

2
David

Недавно ответил на аналогичный вопрос: Cisco static NAT не работает на стороне локальной сети и только что понял, что это канонический вопрос. Итак, позвольте мне обобщить решение здесь.

Прежде всего: забудьте о NAT (если можете) - вопрос не в настройке NAT, а в том, чтобы получить доступ к серверу, расположенному позади NAT из как Интернет, так и локальная сеть. Использование двух зон DNS является жизнеспособной альтернативой, но не всегда решением. Но решение существует и невероятно простое (хотя, возможно, и не идеальное):

(1) на сервере: добавьте общедоступный IP-адрес в качестве вторичного IP-адреса в сетевой интерфейс сервера с маской 255.255.255.255 (веб-служба или все, что вы хотите на сервере также должны прослушивать этот IP-адрес); все современные операционные системы позволят вам сделать это (или вместо добавления вторичного IP к первичному интерфейсу можно использовать петлевой интерфейс с назначенным ему публичным IP-адресом).

(2) на хостах локальной сети: добавьте маршрут хоста для общедоступного IP-адреса, например, для хостов Windows используйте следующую команду: route -p add маска 203.0.113.130 255.255.255.255 192.168 .1.11 (вы также можете использовать опцию DHCP "статический маршрут" для распределения маршрута). Или, если есть (а) коммутатор (ы) L3/маршрутизатор (ы) между клиентами и маршрутизатором, выходящим в Интернет, настройте этот маршрут хоста на этом (этих) промежуточных коммутаторе (ах)/маршрутизаторе (ах), а не на клиентов.

Для тех, кто имеет отношение к TCP трехстороннему рукопожатию: он будет работать нормально в предлагаемой конфигурации.

Пожалуйста, оставьте отзыв (хотя бы, проголосуйте).

2
Sergio

С технической точки зрения лучшее решение этой проблемы - включить IPv6 в вашей сети. Когда IPv6 включен, вам нужно создать запись AAAA для вашего домена. Сохраните существующую запись A, указывающую на внешний IPv4 маршрутизатора . Создайте запись AAAA, указывающую на IPv6-адрес сервера .

У IPv6 достаточно адресов, чтобы избежать NAT, поэтому вам не понадобится шпилька NAT для IPv6. А после включения IPv6 и создания записей AAAA любой клиент, поддерживающий RFC 8305 попробует IPv6 до IPv4. Это означает, что вам не нужна шпилька NAT для IPv4, потому что клиенты не будут ее использовать.

Вам все еще понадобится ваш существующий IPv4 NAT для исходящих подключений и переадресации портов для входящих подключений, пока в большинстве стран мира также не будет включен IPv6.

Это также быстрее.

Использование IPv6 даст вам лучшую производительность, чем шпилька NAT.

С помощью шпильки NAT ваш клиент отправит пакет через коммутатор на маршрутизатор, затем маршрутизатор выполнит два раунда трансляции и, наконец, отправит пакет через коммутатор на сервер. Пакеты с сервера чтобы клиент прошел весь этот путь в обратном порядке.

С IPv6 вы избегаете NAT, вместо этого пакеты отправляются непосредственно через коммутатор между клиентом и сервером. Это означает, что при передаче туда и обратно вы уменьшаете количество проходов через коммутатор с 4 до 2, и вы избегаете 2 поездок через маршрутизатор и 4 трансляций, которые выполнял бы маршрутизатор. Это приводит к лучшей производительности.

Это верно, даже если вы используете коммутатор, встроенный в тот же блок, что и маршрутизатор.

Что если у провайдера нет IPv6?

Если вы используете провайдера, который не поддерживает IPv6, я задам вопрос, должны ли вы размещать серверы в этой сети. Вот мои предложения о том, что делать, если провайдер в настоящее время не поддерживает IPv6.

Сначала скажите провайдеру, что вам нужен IPv6. И, возможно, напомните им, что протокол IPv6 существует уже 20 лет, поэтому им давно пора поддержать его. Если этого недостаточно, чтобы провайдер отнесся к вам серьезно, начните искать других провайдеров.

Если вы найдете провайдера с поддержкой IPv6, вы можете работать с обоими провайдерами в течение переходного периода. На маршрутизаторе, подключенном к новому провайдеру, вы можете отключить IPv4 на стороне LAN, а затем подключить стороны LAN обоих маршрутизаторов к одному коммутатору. IPv4 и IPv6 являются двумя независимыми протоколами, и, таким образом, нет проблем, если эти соединения проходят через разные маршрутизаторы. Дополнительным преимуществом является некоторая избыточность в случае сбоя одного из соединений.

Если вы не можете найти интернет-провайдера с поддержкой IPv6, вам следует подумать о переносе вашего сервера на хостинг. С сервером в хостинге вы меньше зависите от географического местоположения, и по этой причине существует большая конкуренция между провайдерами, которая поможет обеспечить тот, который удовлетворит ваши потребности.

Перемещение сервера на хостинг не даст вашим клиентам IPv6, но перемещение сервера означает, что вам больше не нужна шпилька NAT, чтобы добраться до нее.

Чего не следует делать

Не включайте IPv6 и не создавайте записи AAAA, если у вас нет способа маршрутизировать трафик IPv6. Если ваш провайдер не поддерживает IPv6, но вы все равно хотите включить IPv6 в вашей локальной сети (возможно, с использованием адресов RFC 4193) и создать записи AAAA, он будет работать для клиентов в вашей локальной сети, которые достигают сервера в вашей локальной сети. Но связь между вашей локальной сетью и внешним миром вначале будет использовать IPv6 (который не будет работать), и вы будете полагаться на возврат к IPv4, который в лучшем случае немного медленнее или в худшем случае не происходит.

1
kasperd

Я отвечу на мои вопросы только для того, чтобы расширить кругозор для людей с похожими проблемами.

Я связался со своим провайдером и попросил их попытаться решить мои проблемы. Они предложили мне еще один публичный IP-адрес только для сервера. Теперь у меня есть локальный трафик на стороне WAN FreeBSD), и мы создали специальные каналы для более быстрой пропускной способности локального трафика к общедоступному IP-адресу сервера.

1
adopilot

Я добавлю ответ здесь, так как комментарии здесь не решают мою конкретную проблему. Я подозреваю, что это потому, что я столкнулся с неприятной ошибкой ядра Linux. Настройка:

internet <--> modem 1.1.1.1/30 <--> switch <---> LAN 10.1.1.0/24
                                      ^
        +----------------------+      |
        |              /--eth0 o <----/
        |              |       |           
        | 10.1.1.1/24 br0      |           v (antenna)
        |  1.1.1.2/30  |       |           |
        |              \-wlan0 o ----------/
        +----------------------+ 

Несмотря на сложную картину, единственным значимым изменением в ситуациях, описанных в других комментариях, является добавление программного моста br0. Это происходит потому, что шлюз также является беспроводной точкой доступа для локальной сети.

Наш шлюз по-прежнему выполняет NAT обязанности для машин в локальной сети. Поскольку он имеет только 1 порт Ethernet, он вынужден выполнять шпилечный NAT. Я подозреваю, что он должен просто работать с правилами iptables, указанными в других комментариях здесь, но в ядре Linux 4.9 по крайней мере это не так. В версии 4.9 наш шлюз в то время как наш шлюз может получить доступ к Интернету, машины в локальной сети пытаются получить к нему доступ через NAT может "т.

tcpdump показывает ответы на входящие пакеты, обращающиеся к eth0, но они не выделяются из br0. Выполнение этой команды исправляет следующее:

ebtables -t brouter -A BROUTING -d 01:00:00:00:00:00/01:00:00:00:00:00 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 --ip-dst 10.1.1.0/24 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 --ip-src 10.1.1.0/24 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 -j DROP

Перед выполнением этой команды входящие пакеты обрабатываются в соответствии с поведением ядра по умолчанию, которое заключается в том, чтобы передать их мосту, а затем передать им модули маршрутизации ядра. Команда заставляет пакеты, которые не из локальной сети, обходить мост и переходить непосредственно к маршрутизации, что означает, что у моста нет возможности отбросить их. Широковещательные и многоадресные адреса должны быть соединены, иначе такие вещи, как DHCP и mDNS, не будут работать. если вы используете IPv6, вы также должны добавить правила для него.

У вас может возникнуть соблазн решить проблему с помощью этого:

brctl hairpin br0 eth0 on
brctl hairpin br0 wlan0 on

Я, конечно, был так искушен - это была моя первая попытка. Как только я сделал это, машины в локальной сети получили доступ к Интернету, так что он работает некоторое время. Затем произошло следующее (и я не хотел повторять эксперимент):

  1. Время пинга через локальную сеть к шлюзу удваивалось с интервалами примерно в 10 секунд, увеличиваясь с 0,1 мс до 0,2 мс, 0,4 мс, 0,8 мс, 2 мс и т.д. До тех пор, пока шлюз не был недоступен из локальной сети. Он пах как шторм пакетов, но STP был включен везде.
  2. Вскоре после того, как все точки беспроводного доступа умерли.
  3. При попытке диагностировать, что происходит с беспроводной связью, все IP-телефоны перезагрузились.
  4. Вскоре после этого проводные машины потеряли все контакты с локальной сетью.

Единственным выходом было перезагрузить каждую машину в здании. Единственным исключением были аппаратные переключатели, которые не могли быть перезагружены. Они должны были быть выключены.

0
Russell Stuart

Поскольку я также задавал этот вопрос (см. Как я могу получить доступ к сетевой службе NAT, находящейся за брандмауэром изнутри, используя его внешний IP-адрес? ), он был перенаправлен сюда, но ответы здесь не дали решение (в отличие от общих объяснений ) позвольте мне предоставить мой Linux (iptables конкретное) решение здесь, чтобы сэкономить всем несколько часов экспериментов. Этот файл находится в iptables-restore _ и может быть считан непосредственно в iptables (после редактирования IP-адресов, конечно). Это для веб-сервера (порт 80) и только для IPv4 - правила для IPv6 и для SSL (порт 443) аналогичны.


# Port forwarding for VM / Container access with „hairpin NAT“.
*nat
:PREROUTING ACCEPT [3:205]
:INPUT ACCEPT [59:670]
:OUTPUT ACCEPT [16:172]
:POSTROUTING ACCEPT [20:257]

# This was simple port forwarding - access works from outside but not from inside
#-A PREROUTING  -4 -p tcp -i eth0 --dport 80 -j DNAT --to web.local:80

# This is real hairpin NAT which allows „web.local“ to access itself via the VM hosts external IP.
# First we need to masquerade any traffic going out the external interface:
-A POSTROUTING -o eth0 -j MASQUERADE

# Then we need to reroute incoming traffic on the public IP to the local IP:
-A PREROUTING  -4 -p tcp -d web.public.com --dport  80 -j DNAT --to web.local:80

# And finally we need to tell the router that the source IP of any traffic
# coming from the LAN must be source-rewritten when going to the web server:
-A POSTROUTING -4 -p tcp -s lan.local/24 -d web.local --dport  80 -j SNAT --to-source web.public.com:80

COMMIT

Заменить lan.local, web.local а также web.public.com с вашей локальной сетью (например, 10.0.x.0/24), локальным IP-адресом вашего веб-сервера (например, 10.0.1.2) и открытым IP-адресом вашего маршрутизатора (например, 4.5.6.7). -4 просто разрешить правила IPv6 и IPv4 в одном файле (такие строки игнорируются ip6tables). Кроме того, не забывайте помещать адреса IPv6 в [скобки], когда они включают объявления портов, например, [fe0a:bd52::2]:80.

Это было все, что заставило меня вырваться из головы, когда я попытался реализовать объяснения в этом вопросе. Я надеюсь, что ничего не пропустил.

0
Jens

Как это канонический вопрос. Я отвечу, если у вас есть роутер Sonicwall.

Выражение, которое нужно знать: политика обратной связи NAT

В этом документе описывается, как хост в локальной сети SonicWall может получить доступ к серверу в локальной сети SonicWall, используя публичный IP-адрес сервера для полного доменного имени. Представьте себе NSA 4500 (SonicOS Enhanced) сеть, в которой основной подсетью локальной сети является 10.100.0.0/24, а основной WAN IP равен 3.3.2.1. Давайте скажем, у вас есть веб-сайт для ваших клиентов, и его имя хоста такое. Вы уже написали необходимые политики и правила, чтобы посторонние могли попасть на веб-сайт, но он действительно работает на частном сервере 10.100.0.2. Теперь представьте, что Вы являетесь человеком, использующим ноутбук в частном порядке с IP-адресом 10.100.0.200. Вы хотите подключиться к серверу, используя его публичное имя, потому что вы делаете то же самое, когда ваш ноутбук находится с вами в дороге. Если вы сидите на приватная сторона и request http://www.example.com >, loopback - это то, что позволяет этому работать, даже если сервер фактически находится рядом с вами по локальному IP-адресу ,.

Чтобы разрешить эту функцию, вам нужно создать политику обратной петли NAT), также известную как NAT отражение или шпилька).

Политика обратной связи с использованием WAN IP-адрес интерфейса

Login to the SonicWall Management GUI.
Navigate to Manage | Rules | NAT Policies submenu.
Click on the Add button.
Create the following NAT Policy.
Original Source: LAN Subnets (or Firewalled Subnets if you want hosts in other zones to be included)
Translated Source: WAN Interface IP
Original Destination: WAN Interface IP
Translated Destination: (LAN server object)
Original Service: Any
Translated Service: Original
Inbound Interface: Any
Outbound Interface: Any

Sonicwall распознает внешнюю службу, с которой вы пытаетесь связаться, и перепишет адрес назначения в соответствии с внутренним адресом сервера, таким образом, он будет перенесен на компьютер.

0
yagmoth555