Доступ к внутреннему ресурсу через внешний ip-адрес (На примере MikroTik) [Решено]

  • 9 November 2016
  • Alexandr Blinov

Добрый день, коллеги!

Недавно появилась достаточно простая задача, с которой по какой-то причине не справился мой напарник- обеспечить доступ к локальному ресурсу сети через внешний ip.

Суть в следующем:
Есть mikrotik, который выполняет роль шлюза. На нём настроен внешний ip, NAT для некоторых ресурсов и прочие плюшки.
Есть локальная машина с адресом 192.168.0.99
Есть внутренний ресурс по адресу, скажем, 192.168.0.25 и порт 8080.
На этот ресурс проброшен NAT с внешним адресом 10.20.30.40 и порт 32154.
При доступе извне - ресурс доступен и всё прекрасно работает, но при попытке зайти на 10.20.30.40:32154 из внутренней сети получаем таймаут соединения или что-то подобное.

Почему так происходит? Да всё просто:
1 шаг: Исходная машина отправляет запрос на внешний адрес. Пакет имеет заголовок "src-address 192.168.0.99" и "dst-address 10.20.30.40"
2 шаг: Шлюз перенаправляет данный пакет на внутренний ресурс. Заголовки меняются на "src-address 192.168.0.99" и "dst-address 192.168.0.25".
3 шаг: Ресурс получает этот пакет и, для установки соединения, отвечает на него. Но отвечает не через шлюз (Как изначально был получен пакет), а напрямую, в обход NAT, так как адрес на который нужно отправить ответ находится в одной с ним подсети.
4 шаг: Исходная машина получает ответ от запрашиваемого ресурса. Но поскольку ответ ожидается от шлюза, а ответ пришёл от другого адреса - пакет просто отбрасывается. В итоге соединение не устанавливается.

Примерная схема:

Для того чтобы целевой ресурс отвечал тем же маршрутом (То есть через шлюз/маршрутизатор) необходимо включить маскарадинг (Masquerade) для пакетов из локальной сети. Маскарадинг (Если в двух словах) это подмена src ip адреса в заголовке пакета на ip устройства, которое выполняет перенаправление.
То есть, на шаге 2 src-address будет изменён на 10.20.30.40.

Итак, у нас на MikroTik уже настроено одно правило NAT:

  • Chain: dstnat
  • Dst. Address: 10.20.30.40
  • Protocol: 6 (tcp)
  • Dst. Port: 32154
  • Action: dst-nat
  • To Addresses: 192.168.0.25
  • To Ports: 8080

Для настройки доступа изнутри по внешнему адресу добавим ещё одно правило NAT:

  •  Chain: srcnat
  • Src. Addresses: 192.168.0.0/24 (Правило работает для всей внутренней подсети)
  • Dst. Addresses: 192.168.0.25 (Только для пакетов с этим целевым адресом)
  • Protocol: 6 (tcp)
  • Dst. Port: 8080 (Для пакетов отправляемых на этот порт. Внимание! Указывается внутренний порт!)
  • Action: masquerade

Сохраняем, profit!

Теперь наш шлюз выполняет подмену ip адреса и ответы от целевого ресурса вернутся нужным нам маршрутом. Схема будет выглядеть так:

Теперь всё работает. Всем бобра и плюшек.