การเปลี่ยนเส้นทางพอร์ต iptables ไม่ทำงานสำหรับ localhost


54

ฉันต้องการเปลี่ยนเส้นทางการรับส่งข้อมูลทั้งหมดจากพอร์ต 443 ไปยังพอร์ตภายใน 8080 ฉันใช้การกำหนดค่านี้สำหรับ iptables:

iptables -t nat -I PREROUTING --source 0/0 --destination 0/0 -p tcp \
         --dport 443 -j REDIRECT --to-ports 8080

สิ่งนี้ใช้ได้กับไคลเอนต์ภายนอกทั้งหมด แต่ถ้าฉันพยายามที่จะเข้าถึงพอร์ต 443 จาก maschine เดียวกันฉันจะได้รับการเชื่อมต่อปฏิเสธข้อผิดพลาด

wget https://localhost

ฉันจะขยายกฎ iptables เพื่อเปลี่ยนเส้นทางการรับส่งข้อมูลภายในได้อย่างไร


หัวข้อนี้จะให้คำตอบทั่วไปเพิ่มเติม: serverfault.com/questions/380447/iptables-preroute-localhost
Jeroen

1
คนที่มีตัวแทนสามารถเพิ่มแบ็กสแลชไปที่คำสั่งก่อนที่จะขึ้นบรรทัดใหม่ได้หรือไม่?
Ciro Santilli 新疆改造中心法轮功六四事件

คำตอบ:


68

PREROUTING ไม่ได้ใช้โดยอินเตอร์เฟสย้อนกลับคุณต้องเพิ่มกฎเอาท์พุทด้วย:

iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 8080

3
ไม่จำเป็นต้องมีกฎข้อแรก แพ็คเก็ตที่สร้างขึ้นในท้องถิ่นไม่ผ่านห่วงโซ่ PREROUTING
เลด

9
ฉันเพิ่มกฎเริ่มต้นเพื่อประโยชน์ของการบังคับใช้เนื่องจากเขาต้องการรับส่งข้อมูลภายนอกเพื่อเปลี่ยนเส้นทางเช่นกัน กฎไม่จำเป็นต้องมีแหล่งที่มา / ปลายทางหากพวกเขาบอกว่าจะยอมรับ IP ทั้งหมดเท่านั้น
Andy

โอ้ฉันไม่เห็นคำตอบของคุณเมื่อตอบกลับ
Andy

สวัสดี Andy ฉันยังคงกำลังเชื่อมต่อกับ server.com | <ip> |: 443 ... ล้มเหลว: การเชื่อมต่อถูกปฏิเสธ
คริส

สวัสดีคริสนั่นคือการเชื่อมต่อกับ localhost | 127.0.0.1 | 443 หรือว่าเป็นโดเมน? หากหลังและคุณกำลังเรียกใช้จากเซิร์ฟเวอร์ของคุณคุณอาจมีปัญหาการกำหนดเส้นทางภายใน คุณสามารถตรวจสอบอีกครั้งโดยลองใช้ wget server.com:8080 (แม้ว่าฉันจะถือว่าเหตุผลที่คุณส่งต่อพอร์ตเพราะมันถูกบล็อกจากภายนอก?) VPC ของฉันมีปัญหานั้น แต่คุณอาจจะแก้ไขปัญหาด้วยการกำหนดโดเมนเป็น 127.0.0.1 ในไฟล์ / etc / hosts ของคุณ
Andy

10

หากต้องการเปลี่ยนเส้นทางแพ็คเก็ตจาก localhost ไปยังเครื่องอื่นกฎ:

 iptables -t nat -A OUTPUT -o lo -d 127.0.0.1 -p tcp --dport 443 -j DNAT  --to-destination 10.x.y.z:port

จะทำงาน แต่คุณต้องเปิดใช้งานตัวเลือกนี้ในเคอร์เนล:

sysctl -w net.ipv4.conf.all.route_localnet=1

หากไม่มีการตั้งค่าเคอร์เนลมันจะไม่ทำงาน


มันก็ใช้ได้เหมือนกัน ฉันคิดว่าการทำทุกอย่างใน iptables นั้นสะอาดกว่า
quadruplebucky

ที่จริงแล้วการตั้งค่าเคอร์เนลจะถูกกำหนดถ้าปลายทางอยู่ในเครื่องอื่นวางสาย VM หรือเครื่องระยะไกล

มันเป็นไม่ได้ถ้าคุณมีกฎที่สองเป็นแอนดี้แนะนำข้างต้น
quadruplebucky

ขออภัยฉันกำลังพูดถึงกรณีการส่งต่อไปยังเครื่องอื่นที่ DNAT ไม่ทำงาน ฉันดูคำตอบนี้เพื่อหาวิธีแก้ไขปัญหาเมื่อฉันพยายามส่งต่อสิ่งที่คิดว่ามันเชื่อมต่อกับ localhost ไปยัง containter บนเครื่องเดียวกัน เช่นการเรียกใช้เนมเซิร์ฟเวอร์ในคอนเทนเนอร์สำหรับเคียวรีโลคัล

ที่จริงแล้วมันขึ้นอยู่กับรุ่นของเคอร์เนล> = 3.6
quadruplebucky


2

คุณบอกว่าคุณได้รับการเชื่อมต่อปฏิเสธข้อผิดพลาด ซึ่งหมายความว่าไม่มีกระบวนการโลคัลบนพอร์ตที่คุณพยายามเชื่อมต่อ! ในการตรวจสอบกระบวนการฟังให้ใช้คำสั่ง:

$ sudo netstat -lnp | grep 8080

หลังจากใช้กฎนี้แล้วคุณควรมีกระบวนการรับฟังพอร์ต 8080 เพื่อเชื่อมต่อ

ดูเหมือนว่าคุณควรมีกฎต่อไปนี้แทน:

$ iptables -t nat -I OUTPUT --source 0/0 --destination 0/0 -p tcp
                                       --dport 443 -j REDIRECT --to-ports 8080

จำไว้ว่าคุณกำลังส่งจาก localhost ดังนั้นคุณต้องเปลี่ยนเส้นทางแพ็คเก็ตผลลัพธ์


1
ขอบคุณสำหรับคำตอบเล็กน้อย กระบวนการกำลังฟังบนพอร์ต 8080 ดังนั้นฉันต้องการเปลี่ยนเส้นทางการรับส่งข้อมูลทั้งหมดไปยังพอร์ตนั้น
คริส

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