iptables เปลี่ยนเส้นทางนอกคำขอไปยัง 127.0.0.1


41

ฉันมีบริการที่ทำงานบน 127.0.0.1 ด้วยพอร์ต 2222 ฉันต้องส่งต่อคำขอทั้งหมดไปที่ 192.168.2.2:2222 (นอก IP) จากซับเน็ตเท่านั้น 192.168.1.0/24 ถึง 127.0.0.1:2222

ฉันพยายามใช้สิ่งนี้ แต่มันไม่ทำงาน

$ iptables -t nat -I PREROUTING -p tcp -d 192.168.1.0/24 --dport 2222 -j DNAT --to-destination 127.0.0.1:2222

ฉันจะทำให้เรื่องนี้ทำงานได้อย่างไร

UPD: แก้ไขรูปแบบที่อยู่


เราต้องการความกระจ่าง การจราจรมาจากไหน การรับส่งข้อมูลเริ่มต้นจากที่ใด การจราจรควรจะไปที่ไหน? ในขณะที่ฉันอ่านคุณต้องการปริมาณการใช้ข้อมูลจาก 192.168.1.0/24 ถึง 127.0.0.1:2222 เพื่อเปลี่ยนเส้นทางไปยัง 12.23.34.45:2222 แต่คำตอบของ Warren สันนิษฐานว่าคุณต้องการปริมาณข้อมูลจาก 192.168.1.0/24 ถึง 12.23.34.45:2222 เพื่อเปลี่ยนเส้นทางไปยัง 127.0.0.1:222
Patrick

1
การรับส่งข้อมูลมาจากเครือข่ายย่อย 192.168.1.0/24 ถึง 192.168.2.2:2222 และควรแปลเป็นบริการบน 127.0.0.1:2222 ฉันแก้ไขรูปแบบที่อยู่แล้ว
SimWhite

1
คุณต้องการกฎที่อนุญาตให้ทราฟฟิกไปยังพอร์ต2222บนอินเตอร์เฟสลูปแบ็คจากซับเน็ต192.168.1.0/24หรือไม่ นั่นไม่ใช่เพียงการตั้งค่ากฎประเภทเดียว ดูที่นี่: debuntu.org/…
slm

ใช่. เท่าที่ฉันเข้าใจฉันต้องเพิ่มกฎ masq หรือไม่ แน่นอนว่าการส่งต่อ IP ได้เปิดใช้งานแล้ว
SimWhite

ทำไมไม่ลองใช้งานบน IP "ของจริง" และกรองทราฟฟิกที่มาจากแหล่งที่ไม่ต้องการ นั่นคือสิ่งที่ไฟร์วอลล์สำหรับหลัก ...
vonbrand

คำตอบ:


60

กฎ iptables ที่คุณใช้จะทำงานได้ แต่มีการเปลี่ยนแปลงเพิ่มเติมหนึ่งอย่างที่คุณต้องทำ:

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

(แทนที่eth0ด้วย nic 192.168.2.2อยู่บน)

โดยค่าเริ่มต้นค่านี้ซึ่งสั่งเคอร์เนลที่จะไม่เส้นทางการจราจรภายนอกลิขิตมาให้0 127.0.0.0/8นี่เป็นเพียงเพื่อความปลอดภัยเนื่องจากทราฟฟิกดังกล่าวไม่ปกติ


หมายเหตุเพิ่มเติม: กฎ iptables ปัจจุบันของคุณกว้างเกินไป กฎของคุณระบุ-d 192.168.1.0/24 --dport 2222ว่าเป็นการจับคู่ปลายทางหมายความว่าหากเครื่องของคุณพยายามพูดคุยกับโฮสต์อื่นที่พอร์ต 2222 (เช่นปริมาณการใช้ขาออก) ก็จะได้รับการเปลี่ยนเส้นทางเช่นกัน คุณต้องเปลี่ยนการ-dจับคู่เป็น-d 192.168.2.2หรือเพิ่ม-i eth0(หรืออะไรก็ตามที่คุณชอบ)


8
ข้อมูลนี้หายากอย่างแปลกใจ
นกกระจิบต

ใช่ข้อมูลที่หายากมีค่ามาก! ขอขอบคุณ! route_localnetแต่ฉันไม่ได้มี เคยมีชื่ออื่นมาก่อนไหม? (ในลินุกซ์ 2.6.30) ls /proc/sys/net/ipv4/conf/lan/: accept_redirects arp_accept arp_filter arp_notify disable_policy force_igmp_version log_martians medium_id proxy_arp secure_redirects shared_media accept_source_route arp_announce arp_ignore bootp_relay disable_xfrm ส่งต่อ mc_forwarding promote_secondaries rp_filter send_redirects แท็ก
Imz - อีวาน Zakharyaschev

ฉันเห็นว่าแพทช์สำหรับroute_localnetล่าสุดกว่า (7 มิถุนายน 2012) กว่าเคอร์เนลของฉัน (2.6.30-std-def-alt15 # 1 SMP จันทร์ 14 ธันวาคม 08:45:48 UTC 2009) ตกลงฉันจะเพียงแค่บรรลุการส่งต่อพอร์ตที่ต้องการ (จากภายนอกสู่ภายใน) ด้วยกระบวนการส่งต่อเช่นnetcat( nc) xinetdหรือตัวเลือกการส่งต่อพอร์ตของssh(หลังมีประสิทธิภาพและโง่แน่นอน แต่ฉันพูดถึงมัน เพราะความเป็นไปได้นี้มีอยู่)
imz - Ivan Zakharyaschev

2
My 2 cents: คุณสามารถเปิดใช้งานพารามิเตอร์นี้สำหรับทุกอินเตอร์เฟสด้วยsysctl -w net.ipv4.conf.all.route_localnet=1
Dmitriusan

เช่นเดียวกับคนอื่น ๆ ข้อมูลนี้หายาก ขอบคุณถ้าฉันพบสิ่งนี้ก่อนหน้านี้ฉันจะประหยัดความพยายามได้มาก
Stephen Simpson

3

คุณสามารถเปลี่ยนเส้นทางไปยัง localhost แต่จะไม่ย้อนกลับ (127.0.0.0/8/8) Loopback เป็นช่องโหว่ คุณต้องเปลี่ยนเส้นทางไปยังหนึ่งในอินเทอร์เฟซที่แท้จริงของคุณ ลองใช้ REDIRECT

iptables -t nat -A PREROUTING ..... -j REDIRECT --to-port 222


นี่อาจเป็นคำตอบที่ดีที่สุดหากไม่มี sysctl voodo ...
Lester Cheung

ยังไม่ช่วยถ้าพอร์ต 222 กำลังรับฟังอยู่บน
โลคัลโฮสต์

ในกรณีนี้ให้ใช้-j DNAT --to-destination w.x.y.z:222
dresende

2

เกิดอะไรขึ้นถ้าคำตอบที่ถูกต้องroute_localnetไม่ทำงาน?

หากเคอร์เนลของคุณไม่ได้รวมแพตช์route_localnetแล้ว ... อัพเกรดเคอร์เนล!

หรือมีวิธีอื่น ๆ ในการส่งต่อทราฟฟิกที่มาถึงหนึ่งอินเทอร์เฟซไปยังพอร์ตอื่นบนอินเทอร์เฟซอื่น (โดยเฉพาะกับ localhost) โดยการเรียกใช้กระบวนการที่จะฟังบนอินเทอร์เฟซภายนอก

netcat( nc), xinetdและssh(และอาจมากกว่า) เป็นตัวอย่างทั้งหมดของโปรแกรมที่สามารถทำได้ (แม้ว่าการเลือกsshจะแปลกและไม่มีประสิทธิภาพ)

ฉันเขียนการกำหนดค่าxinetdสำหรับสิ่งนี้ ตอนนี้บริการนี้จะปรากฏขึ้นโดยอัตโนมัติ:

# cat /etc/xinetd.d/z-from-outside 
# default: off
# description: Forward connections to the z port.
service z-from-outside
{
    disable         = no
    socket_type     = stream
    type        = UNLISTED
    wait            = no
    user            = nobody
    bind        = vaio.ob
    port        = 7070
    redirect    = localhost 7070
}
# 

( vaio.obเป็นชื่อของโฮสต์นี้บนอินเตอร์เฟสเครือข่ายภายนอก)

หลังจาก a service xinetd reloadมาตรวจสอบว่ามันกำลังฟังอยู่:

# lsof -i -P | fgrep 7070
xinetd    556      root    6u  IPv4 1797906      0t0  TCP vaio.ob:7070 (LISTEN)
sshd    27438 tun_zzoom    4u  IPv4 1059100      0t0  TCP localhost.localdomain:7070 (LISTEN)
# 

และแน่นอนว่าการเชื่อมต่อต้องผ่าน!

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