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.