Come posso effettuare il port forwarding con iptables?


118

Voglio che le connessioni in arrivo su ppp0 sulla porta 8001 vengano instradate a 192.168.1.200 su eth0 sulla porta 8080.

Ho queste due regole

-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

e non funziona. Cosa mi sto perdendo?



Vado con il tag npr (anche se questo potrebbe essere legato alla programmazione, anche se ovviamente mal definito).
— Mihai Limbăşan,

Che ne dici di questo: sono un programmatore che tenta di impostare un ambiente in modo da poter eseguire il debug della mia applicazione server in eclipse chiamata da Internet. Abbastanza vicino?

Certo, questo è ciò che intendevo per "mal definito" ... Potresti modificare la domanda di conseguenza?
— Mihai Limbăşan,

Risposte:


97

Prima di tutto, dovresti verificare se l'inoltro è consentito a tutti:

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

Se entrambi ritorna 1va bene. In caso contrario, procedere come segue:

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

Seconda cosa: DNATpotrebbe essere applicato natsolo sul tavolo. Quindi, la tua regola dovrebbe essere estesa aggiungendo anche le specifiche della tabella ( -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

Entrambe le regole vengono applicate solo al traffico TCP (se si desidera modificare anche UDP, è necessario fornire regole simili ma con -p udpset di opzioni).

Infine, ma non meno importante è la configurazione del routing. Genere:

ip route

e controlla se 192.168.1.0/24è tra le voci di routing restituite.


16
Personalmente preferisco la sysctlsintassi del tiposysctl net.ipv4.conf.eth0.forwarding=1
— Doud,

1
Come rimuovo la regola inserita in modo errato?
— Nickolai Leschov,

2
seconda riga: "iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW, STTABLISHED, RELATED -j ACCEPT" NON è richiesto se non si hanno restrizioni / sicurezza del firewall, che è il caso con la maggior parte delle LAN domestiche, altrimenti fai attenzione con -A, perché lo aggiungerà DOPO restrizioni / sicurezza e potrebbe non funzionare (quindi controlla -I invece, che sta aggiungendo DAVANTI alle regole di iptables)
— THESorcerer

2
@ ÁronLőrincz, No. Le regole di Iptables sono volatili se non esplicitamente caricate all'avvio.
— Sherrellbc,

1
@Nickolai Leschov, inserisci lo stesso rimpiazzando -Acon-D
— Alexei Martianov il

14

Penso che quello che vuoi sia:

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
ummm ... quello è quello che ho già. Uso iptables-restore per caricarlo in modo che ognuno sia nella propria sezione, ma è quello che ho scritto sopra.

Va bene, la sintassi sembrava male nell'originale. Hai provato -i ppp0 nelle regole? Qual è esattamente il problema?
— Robert Gamble,

13

Dimentichi l'indirizzo di post-elaborazione 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

E non dimenticare di impostare il firewall Linux come gateway predefinito sul computer con indirizzo 192.168.1.200.


L'hai capovolto sul POSTROUNTINGgradino. A questo punto la conversazione riguarda ancora --destinationpiuttosto che --source.
— Sherrellbc,

6

Ho creato il seguente script bash per farlo sul mio router Linux. Inferma automaticamente l'IP WAN e conferma le selezioni prima di procedere.

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

L'uso dello script è semplice, basta copiarlo e incollarlo in un file e poi.

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

Per rimuovere la stessa regola

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

Pensavo che ciò potesse far risparmiare tempo a qualcuno sul rispettivo router.


2

Avevo il compito di convincere MACHINE_A a pensare che il servizio fosse fisicamente in esecuzione su MACHINE_B, ma reindirizzare in modo trasparente tutte le richieste a MACHINE_C.

Il trucco era usare 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

Tieni presente che potresti voler modificare i comandi:

  1. Consentire l'inoltro di pacchetti solo su un'interfaccia specifica. Per esempio:

    sysctl net.ipv4.conf.eth0.forwarding=1
    
  2. Per consentire non solo a MACHINE_A, ma anche a tutti gli altri di utilizzare il port forwarding, rimuovi:

    -s MACHINE_A
    

1

Provare

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

Questi file indicano al kernel che è consentito inoltrare i pacchetti tra le interfacce.


0

Questo comando non funziona per me:

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

Ho 2 interfacce LAN e lavoro AVANTI quando scriverò:

iptables -t nat -A POSTROUTING -o $LAN_IF -p tcp -m tcp --dport $FW_PORT -j SNAT --to-source $LAN_IP
  • LAN_IF - Interfaccia LAN (ad es. Eth1, br0 ...)
  • FW_PORD - porta inoltrata (sull'host di rilevazione)
  • LAN_IP - Indirizzo IP sull'interfaccia LAN (sul router)

Anche PREROUTING e FORWARD sono ovviamente necessari :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.