ดังนั้นในการกำหนดค่าของคุณแพ็คเก็ตทั้งหมดที่คุณพยายามส่งไปยังเครือข่ายเริ่มแรกเริ่มจาก10.0.0.1
(เพราะพวกเขากำลังผ่านtun0
ส่วนต่อประสานและที่อยู่ภายในของมันคือ10.0.0.1
) คุณจับแพ็คเก็ตทุกอย่างเรียบร้อยดี
ตอนนี้tun0
ส่งแพ็กเก็ตเพิ่มเติม ที่อยู่ต้นทางคือ10.0.0.1
และคุณต้องการให้แพ็กเก็ตปล่อยผ่านส่วนต่อประสานอื่น ( wlp2s0
ในกรณีของคุณ) นั่นคือการกำหนดเส้นทางดังนั้นให้เปิดใช้งานการกำหนดเส้นทางก่อน:
sysctl -w net.ipv4.ip_forward=1
หลังจากนั้นถ้าคุณจะดูที่tcpdump
สำหรับwlp2s0
คุณสามารถสังเกตเห็นแพ็คเก็ตออกไปกับแหล่งที่อยู่10.0.0.1
และไม่ได้มีแหล่งที่อยู่ของอินเตอร์เฟซ WLAN (สิ่งที่คุณจะคาดหวังว่าฉันเดา) ดังนั้นเราจึงต้องเปลี่ยนที่อยู่แหล่งที่มาและก็เรียกว่าแหล่ง NAT ใน linux นั้นง่ายด้วยความช่วยเหลือของnetfilter / iptables :
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
โปรดตรวจสอบว่าFORWARD
ห่วงโซ่ของคุณมีACCEPT
นโยบายหรือคุณจะต้องอนุญาตให้ส่งต่อด้วยบางสิ่งเช่น:
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
ทุกอย่างที่ควรทำงานในขณะนี้: ลินุกซ์เคอร์เนลไม่เส้นทางก็ย้ายแพ็กเก็ตจากอินเตอร์เฟซtun0
netfilterควรเปลี่ยน IP ต้นทางเป็นที่อยู่ที่ได้รับมอบหมายของอินเตอร์เฟสสำหรับแพ็กเก็ตเอาต์พุต มันจดจำการเชื่อมต่อทั้งหมดและเมื่อแพ็กเก็ตตอบกลับไป (ถ้าพวกเขา) มันจะเปลี่ยนที่อยู่ปลายทางของที่อยู่ที่ได้รับมอบหมายอินเทอร์เฟซที่จะ(คุณลักษณะ "conntrack")
ก็ควร แต่ก็ไม่ได้ ดูเหมือนว่าnetfilterจะสับสนกับการกำหนดเส้นทางที่ซับซ้อนนี้และความจริงที่ว่าแพ็คเก็ตเดียวกันครั้งแรกต้องผ่านห่วงโซ่แล้วถูกส่งและมาถึงโซ่ อย่างน้อยเปิดโดย Debian 8 box มันไม่ทำงานwlp2s0
10.0.0.1
wlp2s0
wlp2s0
10.0.0.1
OUTPUT
PREROUTING
วิธีที่ดีที่สุดในการแก้ไขปัญหาnetfilterคือTRACE
คุณสมบัติ:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
ฉันเปิดใช้งานการติดตามสำหรับแพ็คเก็ต ICMP เท่านั้นคุณสามารถใช้ตัวกรองอื่นเพื่อดีบัก
มันจะแสดงสิ่งที่ตารางและโซ่แพ็คเก็ตผ่านไป และฉันจะเห็นว่าแพ็คเก็ตไปไม่มีต่อFORWARD
ห่วงโซ่ (และก็ไม่ได้ถูกจับโดยnat/POSTROUTING
ลูกโซ่ที่ไม่จริงSNAT
)
ด้านล่างมีหลายวิธีในการทำงานนี้
แนวทางที่ 1
วิธีที่ดีที่สุดที่จะทำให้netfilterไม่สับสนคือการเปลี่ยนที่อยู่ IP ต้นทางของแพ็กเก็ตในtun0.c
แอปพลิเคชัน มันเป็นวิธีที่เป็นธรรมชาติที่สุด เราจำเป็นต้องเปลี่ยน 10.0.0.1 เป็น 10.0.0.2ทางขาออกและ10.0.0.2 เป็น 10.0.0.1ทางกลับ
ฉันแก้ไขtun0.c
ด้วยรหัสการเปลี่ยนแปลงที่อยู่แหล่งที่มา นี่คือไฟล์ใหม่และนี่คือ patchfiletun0.c
สำหรับคุณ การเปลี่ยนแปลงในส่วนหัวของ IP นอกจากนี้ยังเกี่ยวข้องกับการแก้ไขการตรวจสอบเพื่อให้ผมเอารหัสจากโครงการ OpenVPN นี่คือรายการคำสั่งทั้งหมดที่ฉันเรียกใช้หลังจากรีบูตใหม่ทั้งหมดและ tun0_changeip.c
เปิดใช้
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
โปรดทราบว่าคุณไม่จำเป็นต้องปิดการกรองเส้นทางย้อนกลับในกรณีนั้นเพราะทุกอย่างถูกกฎหมาย - tun0
รับและส่งแพ็คเก็ตที่เป็นของเครือข่ายย่อยเท่านั้น นอกจากนี้คุณสามารถทำการกำหนดเส้นทางตามแหล่งที่มาแทนอินเตอร์เฟสตาม
แนวทางที่ 2
เป็นไปได้ที่จะทำSNAT
ก่อนที่จะถึงtun0
ส่วนต่อประสานแพ็คเก็ต มันไม่ถูกต้องนัก คุณจะต้องปิดการกรองเส้นทางย้อนกลับอย่างแน่นอนในกรณีนี้:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
ตอนนี้ให้ทำSNAT
: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT - ไปยังที่มา ip.address.of.your.wlan.interface
ที่นี่เราเปลี่ยนที่อยู่ต้นทางก่อนที่แพ็กเก็ตจะไปถึงtun0
อุปกรณ์ tun0.c
รหัสส่งแพ็กเก็ตเหล่านี้ "ตามที่เป็น" (พร้อมที่อยู่แหล่งที่เปลี่ยนแปลง) และพวกเขาจะถูกส่งผ่านอินเตอร์เฟซ wlan ได้สำเร็จ แต่คุณอาจมี IP แบบไดนามิกบนอินเทอร์เฟซ wlan และต้องการใช้MASQUERADE
(เพื่อไม่ให้ระบุที่อยู่อินเตอร์เฟสอย่างชัดเจน) นี่คือวิธีที่คุณสามารถใช้ประโยชน์จากMASQUERADE
:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
โปรดทราบที่10.0.55.1
อยู่ IP "" - มันแตกต่างกัน คุณสามารถใช้ IP ใด ๆ ที่นี่มันไม่สำคัญ แพ็คเก็ตเข้าถึงnat/POSTROUTING
โซ่บนwlp2s0
อินเทอร์เฟซถ้าเราเปลี่ยน IP ต้นทางก่อน และตอนนี้มันไม่ได้ขึ้นอยู่กับ IP แบบคงที่สำหรับอินเตอร์เฟส wlan
แนวทางที่ 3
fwmark
นอกจากนี้คุณยังสามารถใช้ ด้วยวิธีนี้คุณไม่ต้องการSNAT
แต่คุณจะจับเฉพาะแพ็กเก็ตขาออก:
อันดับแรกเราต้องปิดใช้งานการกรองพา ธ ย้อนกลับสำหรับtun0
เพราะจะส่งต่อแพ็กเก็ตที่เป็นของเครือข่ายอื่น:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
นั่นเป็นอีก "แฮ็ค" สำหรับการกำหนดเส้นทางและตัวกรอง netfilterที่ทำงานบนกล่อง Debian 8 ของฉัน แต่ฉันก็ยังแนะนำให้ใช้แนวทางแรกเพราะมันเป็นธรรมชาติมากกว่าและไม่ใช้แฮ็คใด ๆ
นอกจากนี้คุณยังอาจพิจารณาการสร้างโปรแกรมประยุกต์ของคุณเป็นพร็อกซี่โปร่งใส ฉันคิดว่ามันจะง่ายกว่าการวิเคราะห์แพ็กเก็ตจากอุปกรณ์รับสัญญาณ
-j SNAT
ไม่ใช่-s SNAT