Як я можу переправити вперед за допомогою iptables?


118

Я хочу, щоб з'єднання, що надходять на ppp0 на порт 8001, були перенаправлені на 192.168.1.200 на eth0 на порт 8080.

У мене є ці два правила

-A PREROUTING  -p tcp -m tcp --dport 8001 -j DNAT --to-destination 192.168.1.200:8080

-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT

і це не працює. Що я пропускаю?



Я збираюся піти з тегом npr (хоча це може бути пов'язано з програмуванням, хоч це, звичайно, погано сформульовано.)
Mihai Limbăşan

Як щодо цього: я програміст, який намагається створити середовище, щоб я міг налагоджувати свою серверну програму в затемненні, викликаної з внутрішньої мережі. Достатньо близько?

Звичайно, саме це я мав на увазі під «погано сформульованою фразою» ... Чи можете ви відповідно відредагувати питання?
Mihai Limbăşan

Відповіді:


97

Перш за все - слід перевірити, чи дозволено переадресація взагалі:

cat /proc/sys/net/ipv4/conf/ppp0/forwarding 
cat /proc/sys/net/ipv4/conf/eth0/forwarding 

Якщо обидва повертаються, 1це нормально. Якщо не зробити наступне:

echo '1' | sudo tee /proc/sys/net/ipv4/conf/ppp0/forwarding
echo '1' | sudo tee /proc/sys/net/ipv4/conf/eth0/forwarding

Друге - DNATможна застосувати natлише на столі. Отже, ваше правило слід розширити, додавши також специфікацію таблиці ( -t nat):

iptables -t nat -A PREROUTING -p tcp -i ppp0 --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Обидва правила застосовуються лише до трафіку TCP (якщо ви також хочете змінити UDP, вам потрібно надати подібні правила, але з -p udpнабором опцій).

Останнє, але не менш важливе значення - конфігурація маршрутизації. Тип:

ip route

і перевірте, чи 192.168.1.0/24є серед повернених записів маршрутизації.


16
Я особисто віддаю перевагу sysctlсинтаксису на кшталтsysctl net.ipv4.conf.eth0.forwarding=1
Дуд,

1
Як видалити неправильно введене правило?
Микола Лещів

2
другий рядок: "iptables -A FORWARD -p tcp -d 192.168.1.200 --portport 8080 -m state - state NEW, ВСТАНОВЛЕНО, ЗВ'ЯЗАНО -j ACCEPT" НЕ потрібен, якщо у вас немає обмежень / безпеки брандмауера, які це стосується більшості домашніх локальних мереж, інакше будьте обережні з -A, тому що це додасть його ПІСЛЯ обмежень / безпеки та може не працювати (так що перевірте -Я замість цього, додаючи В
ПЕРЕДНИЙ

2
@ ÁronLőrincz, Ні. Правила iptables нестабільні, якщо явно не завантажені під час завантаження.
sherrellbc

1
@Nickolai Leschov, введіть ж заміна -Aз-D
Олексія Мартьянова

14

Я думаю, що ти хочеш:

iptables -A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state 
    NEW,ESTABLISHED,RELATED -j ACCEPT

iptables -t nat -A PREROUTING -p tcp --dport 8001 -j DNAT --to-destination
    192.168.1.200:8080

2
гммм ... це те, що я вже маю. Я використовую iptables-Resto, щоб завантажити його, щоб кожен був у своєму розділі, але ось що я написав вище.

Гаразд, в оригіналі синтаксис виглядав погано. Ви спробували -i ppp0 у правилах? У чому саме проблема?
Роберт Гембл

13

Ви забули встановити адресу джерела SNAT 'ing:

sysctl net.ipv4.ip_forward=1
yours_wan_ip=101.23.3.1
-A PREROUTING  -p tcp -m tcp -d $yours_wan_ip --dport 8001 -j DNAT --to-destination 192.168.1.200:8080

-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT

-A POSTROUTING -t nat -p tcp -m tcp -s 192.168.1.200 --sport 8080 -j SNAT --to-source $yours_wan_ip

І не забудьте встановити ваш брандмауер Linux як шлюз за замовчуванням на комп’ютері з адресою 192.168.1.200.


Ви отримали це назад на POSTROUNTINGсходинці. На даний момент розмова все ще йде, --destinationа не про --source.
sherrellbc

6

Я створив наступний сценарій bash для цього на моєму маршрутизаторі Linux. Він автоматично підводить IP-адресу WAN і підтверджує ваш вибір, перш ніж продовжувати.

#!/bin/bash

# decide which action to use
action="add"
if [[ "-r" == "$1" ]]; then
  action="remove"
  shift
fi

# break out components
dest_addr_lan="$1"
dest_port_wan="$2"
dest_port_lan="$3"

# figure out our WAN ip
wan_addr=`curl -4 -s icanhazip.com`

# auto fill our dest lan port if we need to
if [ -z $dest_port_lan ]; then
  dest_port_lan="$dest_port_wan"
fi

# print info for review
echo "Destination LAN Address: $dest_addr_lan"
echo "Destination Port WAN: $dest_port_wan"
echo "Destination Port LAN: $dest_port_lan"
echo "WAN Address: $wan_addr"

# confirm with user
read -p "Does everything look correct? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
  if [[ "remove" == "$action" ]]; then
    iptables -t nat -D PREROUTING  -p tcp -m tcp -d $wan_addr --dport     $dest_port_wan -j DNAT --to-destination $dest_addr_lan:$dest_port_lan
    iptables -D FORWARD -m state -p tcp -d $dest_addr_lan --dport     $dest_port_lan --state NEW,ESTABLISHED,RELATED -j ACCEPT
    iptables -t nat -D POSTROUTING -p tcp -m tcp -s $dest_addr_lan --sport     $dest_port_lan -j SNAT --to-source $wan_addr
    echo "Forwarding rule removed"
  else
    iptables -t nat -A PREROUTING  -p tcp -m tcp -d $wan_addr --dport     $dest_port_wan -j DNAT --to-destination $dest_addr_lan:$dest_port_lan
    iptables -A FORWARD -m state -p tcp -d $dest_addr_lan --dport     $dest_port_lan --state NEW,ESTABLISHED,RELATED -j ACCEPT
    iptables -t nat -A POSTROUTING -p tcp -m tcp -s $dest_addr_lan --sport $dest_port_lan -j SNAT --to-source $wan_addr
    echo "Forwarding rule added"
  fi
else
  echo "Info not confirmed, exiting..."
fi

Використання сценарію просто, просто скопіюйте та вставте його у файл, а потім.

# chmod +x port_forward.sh
# ./port_forward.sh 192.168.1.100 3000
... confirm details ... press y
# Forwarding rule added

Щоб видалити те саме правило

# ./port_forward.sh -r 192.168.1.100 3000
... confirm details ... press y
# Forwarding rule removed

Я думав, що це може заощадити комусь час на відповідному маршрутизаторі.


2

У мене було завдання змусити MACHINE_A думати, що сервіс працює фізично на MACHINE_B, але прозоро перенаправити всі запити до MACHINE_C.

Хитрість полягала в тому, щоб використовувати MASQUERADE.

sysctl net.ipv4.ip_forward=1

iptables -t nat -A PREROUTING -p tcp -d MACHINE_B --dport 443 -j DNAT --to-destination MACHINE_C

iptables -t nat -A POSTROUTING -s MACHINE_A -o INTERFACE_NAME -j MASQUERADE

Зверніть увагу, що ви можете налаштувати команди:

  1. Дозволити переадресацію пакетів лише на певному інтерфейсі. Наприклад:

    sysctl net.ipv4.conf.eth0.forwarding=1
    
  2. Щоб дозволити не тільки MACHINE_A, але і всі інші використовувати переадресацію портів, видаліть:

    -s MACHINE_A
    

1

Спробуйте

echo "1" > /proc/sys/net/ipv4/conf/ppp0/forwarding
echo "1" > /proc/sys/net/ipv4/conf/eth0/forwarding

Ці файли повідомляють ядру, що дозволяється пересилати пакети між інтерфейсами.


0

Ця команда для мене не працює:

-A POSTROUTING -t nat -p tcp -m tcp -s 192.168.1.200 --sport 8080 -j SNAT --to-source $yours_wan_ip

У мене є два інтерфейси LAN та FORWARD, коли я напишу:

iptables -t nat -A POSTROUTING -o $LAN_IF -p tcp -m tcp --dport $FW_PORT -j SNAT --to-source $LAN_IP
  • LAN_IF - інтерфейс LAN (наприклад, eth1, br0 ...)
  • FW_PORD - перенаправлений порт (на розміщення хоста)
  • LAN_IP - IP-адреса в інтерфейсі LAN (на маршрутизаторі)

Зрозуміло, необхідні також ПЕРЕДАЧА та Вперед, :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.