Jak mogę przekierować za pomocą iptables?

118

Chcę, aby połączenia przychodzące na ppp0 na porcie 8001 były kierowane do 192.168.1.200 na eth0 na porcie 8080.

Mam te dwie zasady

-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

i to nie działa. czego mi brakuje?

Stu
źródło
6
NAT HOWTO
Paul Tomblin,
Idę z tagiem npr (chociaż może to być związane z programowaniem, choć oczywiście źle sformułowane.)
Mihai Limbăşan,
A co powiesz na to: jestem programistą, który próbuje skonfigurować środowisko, aby móc debugować aplikację serwera zaćmieniem wywoływanym z sieci wewnętrznej. Wystarczająco blisko?
Jasne, to właśnie miałem na myśli przez „źle sformułowane” ... Czy możesz odpowiednio edytować pytanie?
Mihai Limbăşan,

Odpowiedzi:

97

Po pierwsze - powinieneś sprawdzić, czy w ogóle dozwolone jest przekazywanie:

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

Jeśli oba zwracają, 1jest w porządku. Jeśli nie, wykonaj następujące czynności:

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

Druga sprawa - DNATmoże być zastosowana nattylko na stole. Tak więc twoja reguła powinna zostać rozszerzona poprzez dodanie specyfikacji tabeli ( -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

Obie reguły dotyczą tylko ruchu TCP (jeśli chcesz również zmienić UDP, musisz podać podobne reguły, ale z -p udpustawioną opcją).

Ostatnia, ale nie mniej ważna, to konfiguracja routingu. Rodzaj:

ip route

i sprawdź, czy 192.168.1.0/24znajduje się wśród zwróconych pozycji routingu.

oo_olo_oo
źródło
16
Ja osobiście wolę taką sysctlskładnięsysctl net.ipv4.conf.eth0.forwarding=1
Doud,
1
Jak usunąć niepoprawnie wprowadzoną regułę?
Nickolai Leschov
2
druga linia: „iptables -A DO PRZODU -p tcp -d 192.168.1.200 --port 8080 -m stan - stan NOWY, USTANOWIONY, POWIĄZANY -j AKCEPTUJ” NIE jest wymagany, jeśli nie masz ograniczeń / zabezpieczeń zapory ogniowej, które jest tak w przypadku większości domowych sieci LAN, w przeciwnym razie należy zachować ostrożność z -A, ponieważ spowoduje to dodanie PO ograniczeniach / zabezpieczeniach i może nie działać (więc zaznacz -I zamiast tego, to znaczy
PRZED
2
@ ÁronLőrincz, Nie. Reguły Iptables są niestabilne, chyba że są jawnie ładowane przy starcie systemu.
sherrellbc
1
@Nickolai Leschov, ENTER samo zastąpienie -Az-D
Alexei Martianov
14

Myślę, że chcesz:

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
Robert Gamble
źródło
2
ummm ... to już mam. Używam iptables-restore, aby go załadować, więc każdy jest w osobnej sekcji, ale tak napisałem powyżej.
Dobra, składnia wyglądała źle w oryginale. Czy próbowałeś -i ppp0 w zasadach? Na czym dokładnie polega problem?
Robert Gamble,
13

Zapomniałeś adresu źródłowego SNAT:

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

I nie zapomnij ustawić zapory linux jako domyślnej bramy na komputerze z adresem 192.168.1.200.

Gorliwy
źródło
Masz POSTROUNTINGkrok wstecz . W tym momencie rozmowa jest --destinationraczej o --source.
sherrellbc
6

Stworzyłem następujący skrypt bash, aby to zrobić na moim routerze Linux. Automatycznie podaje adres WAN IP i potwierdza wybór przed kontynuowaniem.

#!/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

Korzystanie ze skryptu jest proste, wystarczy skopiować i wkleić go do pliku, a następnie.

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

Aby usunąć tę samą regułę

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

Myślałem, że może to zaoszczędzić komuś czas na odpowiednim routerze.

Nullivex
źródło
2

Miałem za zadanie zmusić MACHINE_A do myślenia, że ​​usługa działa fizycznie na MACHINE_B, ale transparentnie przekierowuje wszystkie żądania do MACHINE_C.

Sztuka polegała na użyciu 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

Pamiętaj, że możesz chcieć ulepszyć polecenia:

  1. Aby umożliwić przekazywanie pakietów tylko na określonym interfejsie. Na przykład:

    sysctl net.ipv4.conf.eth0.forwarding=1
    
  2. Aby zezwolić nie tylko MACHINE_A, ale także wszystkim innym na korzystanie z przekierowania portów, usuń:

    -s MACHINE_A
    
Denis Scherbakov
źródło
1

Próbować

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

Pliki te informują jądro, że wolno przekazywać pakiety między interfejsami.

Adam Liss
źródło
0

To polecenie nie działa dla mnie:

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

Mam 2 interfejsy LAN i pracuję w przód, kiedy napiszę:

iptables -t nat -A POSTROUTING -o $LAN_IF -p tcp -m tcp --dport $FW_PORT -j SNAT --to-source $LAN_IP
  • LAN_IF - interfejs LAN (np. Eth1, br0 ...)
  • FW_PORD - port przekazany (na hoście detekcji)
  • LAN_IP - adres IP w interfejsie LAN (na routerze)

Oczywiście PREROUTING i FORWARD są również niezbędne :)

Andrzej
źródło