ฉันจะพอร์ตไปข้างหน้าด้วย 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

เกี่ยวกับสิ่งนี้: ฉันเป็นโปรแกรมเมอร์ที่พยายามตั้งค่าสภาพแวดล้อมเพื่อให้ฉันสามารถดีบักแอ็พพลิเคชันเซิร์ฟเวอร์ของฉันใน eclipse ที่ถูกเรียกใช้จาก innernet ใกล้พอไหม

แน่นอนนั่นคือสิ่งที่ฉันหมายถึงโดย "ใช้ถ้อยคำไม่ดี" ... คุณช่วยแก้ไขคำถามได้ไหม?
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
Doud

1
ฉันจะลบกฎที่ป้อนไม่ถูกต้องได้อย่างไร
Nickolai Leschov

2
บรรทัดที่สอง: "iptables -A ไปข้างหน้า -p tcp -d 192.168.1.200 - พอร์ต 8080 -m state - สถานะใหม่ - สถานะใหม่สร้างแล้วสัมพันธ์ -j ACCEPT" ไม่จำเป็นถ้าคุณไม่มีข้อ จำกัด ไฟร์วอลล์ / ความปลอดภัย เป็นกรณีที่มี LAN บ้านส่วนใหญ่มิฉะนั้นจะต้องระวังด้วย - จะทำให้มันเพิ่มหลังจากข้อ จำกัด / ความปลอดภัยและอาจไม่ทำงาน (ดังนั้นตรวจสอบ -I แทนที่เพิ่มในด้านหน้าของกฎ iptables)
THESorcerer

2
@ ÁronLőrinczไม่กฎ Iptables จะเปลี่ยนแปลงได้เว้นแต่จะโหลดไว้ตอนบูต
sherrellbc

1
@Nickolai Leschov, เข้ามาแทนที่คนเดียวกัน-Aด้วย-D
Alexei Martianov

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- restore เพื่อให้แต่ละไฟล์อยู่ในส่วนของตัวเอง แต่นั่นคือสิ่งที่ฉันเขียนไว้ด้านบน

โอเคไวยากรณ์ดูไม่ดีในต้นฉบับ คุณลอง -i ppp0 ในกฎหรือไม่ ปัญหาคืออะไรกันแน่?
Robert Gamble

13

คุณลืมการโพสต์ที่อยู่แหล่งที่มา 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

และอย่าลืมตั้งค่าไฟร์วอลล์ linux ของคุณให้เป็นเกตเวย์เริ่มต้นบนคอมพิวเตอร์ที่มีที่อยู่ 192.168.1.200


คุณได้มันไปข้างหลังในPOSTROUNTINGขั้นตอน ณ จุดนี้การสนทนายังคงเกี่ยวกับมากกว่า--destination --source
sherrellbc

6

ฉันได้สร้างสคริปต์ทุบตีต่อไปนี้เพื่อทำสิ่งนี้กับเราเตอร์ linux ของฉัน โดยอัตโนมัติ infers WAN IP และยืนยันการเลือกของคุณก่อนดำเนินการต่อ

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

ฉันมี 2 อินเตอร์เฟส LAN และไปข้างหน้าเมื่อฉันจะเขียน:

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 (บนเราเตอร์)

การเตรียมความพร้อมและการส่งต่อมีความจำเป็นเช่นกันแน่นอน :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.