Open Source & Linux Lab

It's better when it's simple

User Tools

Site Tools


howtos:dnat

DNAT и с чем его едят

Исходная ссылка: http://www.koryazhma.ru/net/dimez/dnat/

ДАНО: Локальная сеть, роутер с 2-мя сетевыми карточками(под управлением Linux), в одну карточку включен шнур, по которому идёт интернет :-) Из роутера идёт второй шнур, который раздаёт этот интернет всей локалке.

НАДО: “Пробросить” порт(либо вообще “выкинуть” машину наружу) внутрь локалки, то-есть обеспечить доступ извне(из дикого интернета) к какой-то локальной машине.

РЕШЕНИЕ: Сразу скажу, что на ядрах 2.2.x это нормально не получается, только используя утилиты iproute2 Алексея Кузнецова(сам не пробовал, но, говорят, получается). Так что я рассматриваю вариант kernel-2.4.x + iptables.

Ставим ЯДРО (посвежее), в ядре включаем всё, что касаемо iptables, ставим IPTABLES(если ещё не поставлены, кстати, рекомендую ставить тоже самые свежие)

Обозначения

  • $EXT_R_IP - внешний IP роутера
  • $LOCAL_IP - внутренний “фэйковый” адрес машины, которую надо “выкидывать” наружу
  • $PORT1 - Порт, на который будут заходить извне и попадать на локальную машину
  • $PORT2 - Порт, который “выбрасывается” наружу(например, 80 - http, либо 21 - ftp)

На роутере говорим следующие команды(от рута)

  * # iptables -t nat -A PREROUTING -p tcp -d $EXT_R_IP --dport $PORT1 -j DNAT --to-destination $LOCAL_IP:$PORT2
  * # iptables -A FORWARD -i eth0 -d $LOCAL_IP -p tcp --dport $PORT2 -j ACCEPT

Вуаля! Машина видна снаружи!

!!!БОЛЬШОЕ ПРЕДУПРЕЖДЕНИЕ!!!

Прежде чем “выкидывать” порт наружу - имеет смысл поставить на эту машину FIREWALL, либо поставить новую версию программы(web-сервер или прочее), которую случайно не поломают.

Вариант #2 - требуется вообще “выкинуть” машину наружу, но административными мерами(то есть, не трогая самой машины)

Тут ЕЩЁ БОЛЬШЕЕ ПРЕДУПРЕЖДЕНИЕ!!! Это гораздо опаснее, чем обычный “проброс” порта - так что ставить нормальный FIREWALL просто необходимость, а не прихоть!!! Обозначения

  • $IFACE - внешний сетевой интерфейс на роутере(например, eth0)
  • $NEW_IP - новый IP, на который будем “сажать” “выведенную” машину из локалки

(не может же она жить без IP :)(Если провайдер дал Вам больше одного внешнего IP-адреса)

  • $BC,$NM,$GW - соответственно, broadcast,netmask,gateway, который выдаёт провайдер(в общих чертах)
  • $LOCAL_IP - тоже самое, что и вверху

Сначала надо сделать alias(у нас же нет третьей сетевой карточки) сетевого интерфейса(все команды - от рута, естественно)

# ifconfig $IFACE:0 $NEW_IP netmask $NM broadcast $BC
# route add $NEW_IP gw $GW netmask 0.0.0.0 metric 1 dev $IFACE:0
# iptables -t nat -A PREROUTING -p tcp -d $NEW_IP -j DNAT --to-destination $LOCAL_IP
# iptables -A FORWARD -i eth0 -d $LOCAL_IP -j ACCEPT

Ещё можно написать скрипт, который легко опускает/поднимает DNAT

—cat-/etc/rc.d/rc.dnat—

#!/bin/bash
$IFACE=eth0
$LOCAL_IP="192.168.1.251"
$NEW_IP="q.w.e.r"
$NM="a.s.d.f"
$BC="z.x.c.v"
$GW="p.o.i.u"
 
case "$1" in
        'stop')
        iptables -D FORWARD -i eth0 -d $LOCAL_IP -j ACCEPT
        iptables -t nat -D PREROUTING -p tcp -d $NEW_IP -j DNAT --to-destination $LOCAL_IP
        route del $NEW_IP gw $GW netmask 0.0.0.0 metric 1 dev $IFACE:0
        ifconfig $IFACE:0 down
        ;;
        'start')
        ifconfig $IFACE:0 $NEW_IP netmask $NM broadcast $BC
        route add $NEW_IP gw $GW netmask 0.0.0.0 metric 1 dev $IFACE:0
        iptables -t nat -A PREROUTING -p tcp -d $NEW_IP -j DNAT --to-destination $LOCAL_IP
        iptables -A FORWARD -i eth0 -d $LOCAL_IP -j ACCEPT
        ;;
        'restart')
        $0 stop && $0 start
        ;;
        *)
        echo "usage $0 start|stop|restart"
        ;;
esac

Discussion

Kirill V. Krinkin, 2007/09/28 23:26

Первый вариант имеет один забавный эффект: доступ из локальной сети по внешнему адресу к внутреннему серверу получить не удается

осьмилис, 2007/10/01 22:02

если очень хочется – надо убрать -d $EXT_R_IP в первой строке

Kirill V. Krinkin, 2007/10/14 14:35

Если убрать -d $EXT_R_IP в первой строке, то перестает работать доступ к 80 порту внешних хостов из внутренней сети

осьмилис, 2007/10/14 14:43

собственно, с чего?
понял.
тогда – добавить правило
# iptables -t nat -A PREROUTING -p tcp -d $INT_R_IP –dport $PORT1 -j DNAT –to-destination $LOCAL_IP:$PORT2

Kirill V. Krinkin, 2007/10/02 07:53

да в общем не очень хочется… пусть живет только с внешнего интерфейса

You could leave a comment if you were logged in.
howtos/dnat.txt · Last modified: 2016/08/07 01:20 by kel