การเข้าถึงเว็บเซิร์ฟเวอร์ DNAT จากภายใน LAN


12

ฉันมีเครือข่ายขนาดเล็กที่มีเราเตอร์ซึ่งรักษาการเชื่อมต่อกับอินเทอร์เน็ตเซิร์ฟเวอร์และเวิร์กสเตชันบางตัวในเครือข่ายท้องถิ่น

แผนที่เครือข่าย

เซิร์ฟเวอร์มีไว้เพื่อให้เข้าถึงได้จากอินเทอร์เน็ตและมีรายการ DNAT หลายรายการในเราเตอร์ iptables ดังนี้:

-A PREROUTING -i ppp0 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10

แพ็คเก็ตภายนอกมาถึงเราเตอร์ผ่านทางppp0อินเทอร์เฟซและภายในก็ไปจากbr-lanซึ่งรวมถึงสวิตช์และอะแดปเตอร์ WLAN ปัญหาคือในขณะที่การเข้าถึงภายนอกใช้งานได้ดีพยายามเข้าถึงเซิร์ฟเวอร์จากภายใน LAN โดย IP ภายนอกที่แก้ไขโดย DNS (มอบหมายให้ppp0) ล้มเหลว

ทางออกเดียวที่ฉันสามารถคิดค้นคือการเพิ่มรายการแบบคงที่ไปยังเราเตอร์ที่/etc/hostsชี้ไปยัง IP ภายใน แต่เนื่องจากไม่มี wildcard (และฉันมีโดเมนระดับบนสุดอย่างน้อยสามโดเมนที่กำหนดให้กับระบบนั้นไม่นับโดเมนย่อยนับหมื่น) ที่ค่อนข้างกรุบกรอบและล้มเหลวได้ง่าย คุณช่วยแนะนำสิ่งที่ดีกว่าได้ไหม?

ฉันเพิ่งพบคำถามนี้ซึ่งไม่เป็นประโยชน์มาก

หากเกี่ยวข้องเราเตอร์จะเรียกใช้ OpenWRT 10.03 Kamikaze ด้วย dnsmasq


OpenWRT รุ่นใด
Corey S.

@Corey 10.03 มีความเสถียร แต่นั่นไม่เกี่ยวกับ openwrt ใช่มั้ย
whitequark

คำตอบ:


3

ฉันประหลาดใจว่าหลังจากผ่านไปเกือบ 8 ปีไม่มีใครอธิบายวิธีการที่ถูกต้องในการใช้ระบบกำหนดค่า UCI ที่ใช้โดยค่าเริ่มต้นใน OpenWRT

คำตอบของ Steven Monday นั้นถูกต้อง แต่ก็ใช้iptablesคำสั่งโดยตรงซึ่งเป็นเลเยอร์ที่ต่ำกว่าระบบการกำหนดค่า UCI และเป็นสิ่งที่ดีที่สุดที่ผู้ใช้ OpenWRT ส่วนใหญ่จะไม่ถูกแตะต้องหากเป็นไปได้

วิธีที่ถูกต้องไปยังเซิร์ฟเวอร์ภายในการเข้าถึงผ่านคอมโบ IP สาธารณะ / พอร์ตของพวกเขาจากอีกโฮสต์ภายใน UCI คือโดยการเปิดใช้ตัวเลือกการกำหนดค่าreflectionภายใต้เป้าหมาย DNAT /etc/config/firewallที่เฉพาะเจาะจงในแต่ละไฟล์ ลักษณะการทำงานนี้เป็นเอกสารที่นี่

ตัวอย่างเช่น:

config redirect option target 'DNAT' option src 'wan' option dest 'lan' option proto 'tcp' option src_dport '44322' option dest_ip '192.168.5.22' option dest_port '443' option name 'apache HTTPS server' option reflection '1'

หมายเหตุ: ตามเอกสาร OpenWRT ที่ระบุreflectionจะเปิดใช้งานตามค่าเริ่มต้น ในการทดสอบของฉันนี่ไม่ใช่กรณี


15

ฉันลบคำตอบดั้งเดิมของฉันเพราะฉันไม่มั่นใจอย่างเต็มที่ว่าถูกต้อง ฉันมีเวลาพอที่จะตั้งค่าเครือข่ายเสมือนเล็ก ๆ ของ VM เพื่อจำลองเครือข่ายที่เป็นปัญหา นี่คือชุดของกฎไฟร์วอลล์ที่เหมาะกับฉัน (ในiptables-saveรูปแบบสำหรับnatตารางเท่านั้น):

-A PREROUTING -d 89.179.245.232/32 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
-A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -s 192.168.2.0/24 -d 192.168.2.10/32 -p tcp -m multiport --dports 22,25,80,443 -j MASQUERADE

POSTROUTINGกฎข้อแรกคือวิธีการแบ่งปันการเชื่อมต่ออินเทอร์เน็ตกับ LAN อย่างตรงไปตรงมา ฉันทิ้งไว้ที่นั่นเพื่อความสมบูรณ์

PREROUTINGกฎและครั้งที่สองPOSTROUTINGกฎร่วมกันสร้างแน็ที่เหมาะสมเพื่อให้การเชื่อมต่อที่ไปยังเซิร์ฟเวอร์ผ่านทางที่อยู่ IP ภายนอกสามารถเกิดขึ้นได้โดยไม่คำนึงว่าการเชื่อมต่อมาจากภายนอกหรือจากภายในระบบ LAN เมื่อไคลเอนต์บน LAN เชื่อมต่อกับเซิร์ฟเวอร์ผ่านที่อยู่ IP ภายนอกเซิร์ฟเวอร์จะเห็นการเชื่อมต่อที่มาจากที่อยู่ IP ภายในของเราเตอร์ (192.168.2.1)

ที่น่าสนใจก็คือปรากฎว่ามีกฎการ POSTROUTING ที่สองที่สามารถใช้งานได้หลายรูปแบบ หากเป้าหมายถูกเปลี่ยนเป็น-j SNAT --to-source 192.168.2.1เอฟเฟกต์คือ (ไม่น่าแปลกใจ) เหมือนกับMASQUERADE: เซิร์ฟเวอร์จะเห็นการเชื่อมต่อจากไคลเอนต์ LAN ในพื้นที่ว่าเกิดจากที่อยู่ IP ภายในของเราเตอร์ ในทางกลับกันหากเป้าหมายถูกเปลี่ยน-j SNAT --to-source 89.179.245.232เป็น NATs ยังคงใช้งานได้ แต่ในเวลานี้เซิร์ฟเวอร์จะเห็นการเชื่อมต่อจากไคลเอนต์ LAN ในพื้นที่ว่ามาจากที่อยู่ IP ภายนอกของเราเตอร์(89.179.245.232)

สุดท้ายโปรดทราบว่าต้นฉบับPREROUTING/ DNATกฎของคุณด้วย-i ppp0ไม่ทำงานเนื่องจากกฎไม่ตรงกับแพ็กเก็ตที่มาจากไคลเอนต์ LAN (เนื่องจากสิ่งเหล่านั้นไม่ได้ป้อนเราเตอร์ผ่านทางppp0อินเทอร์เฟซ) มันเป็นไปได้ที่จะทำให้มันทำงานได้โดยการเพิ่มPREROUTINGกฎข้อที่สองสำหรับไคลเอนต์ LAN ภายใน แต่มันจะไม่เหมาะสม (IMO) และจะต้องอ้างถึงที่อยู่ IP ภายนอกอย่างชัดเจน

ตอนนี้แม้หลังจากวาง "กิ๊บ NAT" (หรือ "วนรอบ NAT" หรือ "NAT reflection" หรืออะไรก็ตามที่ใครอยากโทรหา) วิธีแก้ปัญหาอย่างละเอียดฉันก็ยังเชื่อว่าโซลูชัน DNS แบบแยกส่วน - - ด้วยไคลเอนต์ภายนอกการแก้ไข IP ภายนอกและไคลเอนต์ภายในการแก้ไขกับ IP ภายใน --- จะเป็นเส้นทางที่แนะนำให้เลือกมากกว่า ทำไม? เพราะผู้คนจำนวนมากเข้าใจว่า DNS ทำงานอย่างไรมากกว่าเข้าใจว่า NAT ทำงานอย่างไรและส่วนใหญ่ของการสร้างระบบที่ดีคือการเลือกใช้ชิ้นส่วนที่สามารถบำรุงรักษาได้ มีความเป็นไปได้ที่จะเข้าใจการตั้งค่า DNS และทำการบำรุงรักษาอย่างถูกต้องมากกว่าการตั้งค่า NAT แบบลับ (IMO)


มันใช้งานได้ดีมากขอบคุณมาก! ฉันยอมรับว่าการตั้งค่า DNS นั้นดีกว่า แต่คุณไม่สามารถส่งต่อพอร์ตต่าง ๆ บน IP ภายนอกเดียวกันไปยังเครื่องต่าง ๆ บน LAN ได้ ยังไงก็ตามฉันเป็นคนเดียวที่จะดูแลการตั้งค่านี้ดังนั้นมันก็ดี
whitequark

ฉันดีใจที่ได้ยินว่าสิ่งนี้เหมาะกับคุณ!
Steven Monday

"IMO" คืออะไร องค์กรอุกกาบาตนานาชาติ
Jonathan Komar

@ macmadness86 IMO == ในความคิดเห็นของฉัน
สตีเวนจันทร์

3

วิธีแก้ปัญหาทั่วไปคือการชี้โฮสต์ภายในของคุณไปที่เซิร์ฟเวอร์ DNS ในเครื่องที่ส่งกลับที่อยู่ "ภายใน" ที่ถูกต้องสำหรับชื่อโฮสต์เหล่านี้

โซลูชันอื่น - และเรากำลังใช้สิ่งนี้ที่ฉันทำงานกับไฟร์วอลล์ Cisco ของเรา - คือการเขียนการตอบสนอง DNS บนไฟร์วอลล์ที่สอดคล้องกับที่อยู่เหล่านี้ ฉันไม่คิดว่าจะมีเครื่องมือสำหรับ Linux ที่ทำสิ่งนี้ในตอนนี้

คุณควรกำหนดค่าการกำหนดเส้นทางบนเกตเวย์เพื่อทำสิ่งที่ถูกต้อง คุณอาจต้องกำหนดค่าเซิร์ฟเวอร์เพื่อให้ตระหนักถึงที่อยู่ IP ที่แมปภายนอกของพวกเขา (เช่นโดยการกำหนดให้กับอินเทอร์เฟซดัมมี่) ด้วยการกำหนดค่านี้การสื่อสารจากระบบภายในหนึ่งไปยังอีกระบบภายใน - โดยใช้ที่อยู่ "ภายนอก" - จะผ่านเราเตอร์


อืมมม คุณแนะนำให้เพิ่ม IP ภายนอกไปยังอินเทอร์เฟซของเซิร์ฟเวอร์แล้วกำหนดค่าเราเตอร์ดังนั้นมันจะส่งต่อแพ็กเก็ตทั้งหมดไปยัง IP ภายนอกที่มาจากภายใน LAN ไปยังเซิร์ฟเวอร์นั้นหรือไม่ น่าสนใจฉันจะทดสอบในไม่ช้า
whitequark

คุณสามารถแนะนำการกำหนดค่าได้หรือไม่ ฉันลองสิ่งนี้: ip rule add to 89.179.245.232 dev br-lan table 10; ip route add 89.179.245.232 via 192.168.2.10 dev br-lan table 10และมันไม่ทำงาน
whitequark

มีอะไรในตารางเส้นทางที่ 10 บนเซิร์ฟเวอร์ภายในคุณอาจต้องการให้ทั้งสองมีที่อยู่ 192.168.xx อยู่ภายในเครื่อง (สำหรับการสื่อสารในเครื่อง) และที่อยู่สาธารณะ (เป็นนามแฝง) บนอินเทอร์เฟซหลัก
larsks

2

สิ่งที่คุณต้องทำคือเรียกNAT Loopbackและมันต้องการให้คุณเพิ่มกฎ SNAT เพื่อให้แพ็คเก็ตที่มาจาก LAN ของคุณไปยังเซิร์ฟเวอร์ของคุณจะกลับไปที่เราเตอร์:

-A POSTROUTING -p tcp -s 192.168.2.0/24 -d 192.168.2.10 -m multiport --dports 22,25,80,443 -j SNAT --to-source 89.179.245.232

น่าเศร้าที่ไม่ได้ผล เดิมทีฉันพลาด-i ppp0ตัวเลือกในกฎของฉันเนื่องจากเป็นห่วงโซ่อื่นที่จัดการ กฎนี้จะป้องกันการกำหนดเส้นทางของแพ็กเก็ตที่มาจาก LAN (และหากฉันเปิดใช้งานแพ็คเก็ตจะไปจากแหล่งที่ผิดและจะถูกปฏิเสธ)
whitequark

คุณเคยลองไหม มันจะมีผลกับแพ็คเก็ตจาก LAN ของคุณไปยังเซิร์ฟเวอร์ IP ของคุณในพอร์ตเฉพาะเหล่านั้น
SiegeX

ใช่ฉันทำ. (และฉันก็ลองเปลี่ยนกฎข้อแรกด้วย) เช่นขุดส่งแพ็คเก็ตไปที่ 192.168.2.1 # 53 แล้วได้รับการตอบกลับที่ไม่คาดคิดจาก 192.168.2.10 # 53 โดยมีหรือไม่มีกฎของคุณ
whitequark

0

larsks ความคิดเห็นเกี่ยวกับการโฮสต์เนมสเปซ \ ภายในเวอร์ชันภายในเป็นวิธีที่ฉันจัดการกับปัญหานี้ในอดีต แน่นอนว่าคุณต้องมีเซิร์ฟเวอร์ DNS ภายในเพื่อดำเนินการนี้


ใช่ฉันเขียนว่าฉันใช้ dnsmasq แนวคิดใดบ้างในการตั้งค่าการทดแทนอัตโนมัติ
whitequark

ฉันไม่รู้อะไรเกี่ยวกับ OpenWRT และ Kamikaze แต่ขึ้นอยู่กับสิ่งที่ฉันกำลังอ่าน - จะทำอย่างไรถ้าคุณเพิ่มสิ่งต่อไปนี้ใน /etc/dnsmasq.conf "cname = ext-hostname.domain.com, int-hostname.domain.com"
CurtM

เท่าที่ฉันสามารถระบุได้ dnsmasq cnameไม่รองรับมาสก์ดังนั้นจึงไม่สามารถใช้ได้กับฉันเนื่องจากการนับโดเมนย่อย
whitequark

0

ฉันคิดวิธีต่อไปนี้เพื่อให้เครือข่ายแขกของฉันเชื่อมต่อกับพอร์ตที่ส่งต่อจากเครือข่าย WAN ของฉันไปยัง LAN สคริปต์นี้อยู่ในส่วน "เครือข่าย -> ไฟร์วอลล์ -> กฎที่กำหนดเอง" ของฉัน:

# lookup the public IP (DDNS resolves to this)
wanip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

# Guest network to LAN
# srcname is the guest network name, this needs to match for iptables
srcname=guest
# CIDR notation of guest and lan networks
srcnet=192.168.15.0/24
tgtnet=192.168.10.0/24
# router (openwrt) IP on lan network
tgtrouter=192.168.10.1
# host on lan network where ports are normally forwarded
tgthost=192.168.10.5
# ports to forward as a list or range
tcpports=8080,9090
udpports=12345

prechain=prerouting_${srcname}_rule
postchain=postrouting_${srcname}_rule

# reset the tables to prevent duplicate rules
iptables -t nat -F ${prechain}
iptables -t nat -F ${postchain}

iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP SNAT" -j SNAT --to-source ${tgtrouter}
iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP SNAT" -j SNAT --to-source ${tgtrouter}

เพื่อรองรับการรีบู๊ตฉันต้องเรียกใช้สิ่งต่อไปนี้จากบรรทัดคำสั่ง ssh บน openwrt (ไม่เช่นนั้นฉันเชื่อว่ามีเงื่อนไขการแข่งขันที่มีการเพิ่มกฎบางอย่างแล้วจึงล้างออกระหว่างการรีบูต):

uci set firewall.@include[0].reload="1"
uci commit firewall

NAT reflection เป็นการตั้งค่าสำหรับการเชื่อมต่อภายในเครือข่าย LAN แต่ไม่ได้เชื่อมต่อกับเครือข่ายอื่นหากคุณสร้างหลายอินเตอร์เฟสเพื่อแยกทราฟฟิก ฉันพยายามกำหนดค่ากฎการส่งต่อจากเว็บอินเตอร์เฟส แต่นั่นจะส่งปริมาณข้อมูลทั้งหมดไปยังพอร์ตจากเครือข่ายแขกไปยังโฮสต์ LAN นั้น ข้างต้นจะขัดขวางการร้องขอไปที่ WAN IP แทนการรับส่งข้อมูลเครือข่ายทั้งหมด

DNS ภายในสามารถใช้แทนสิ่งนี้ได้ แต่ถ้าพอร์ตทั้งหมดส่งต่อไปที่โฮสต์เดียวเท่านั้น หากคุณมีหลายโฮสต์ที่คุณส่งต่อพอร์ตต่าง ๆ คุณสามารถทำซ้ำกฎสำหรับพอร์ตต่าง ๆ ไปยังtgthostIP และพอร์ตที่ต่างกัน


ในเมล็ดปัจจุบันมีconntrackโมดูลการจับคู่ และสิ่งที่คุณจะต้องแก้ปัญหาคือการใช้กฎเดียวเช่นที่:iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
Anton Danilov

@AtontonDanilov ดีฉันชอบที่ กฎที่ฉันใช้นั้นอ้างอิงจากกฎ NAT ที่มีอยู่แล้วใน OpenWRT สำหรับการเชื่อมต่อจากซับเน็ตเดียวกัน ไม่แน่ใจว่าพวกเขามีเหตุผลอื่น ๆ ที่นอกเหนือไปจากการเขียนก่อนที่จะมี conntrack
BMitch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.