วิธีที่จะทำให้การรับส่งข้อมูลทั้งหมดผ่านอินเทอร์เฟซเดียวใน Linux


12

ฉันมีอินเตอร์เฟสที่เขียนด้วยตนเอง tun0 ( อิงTUN / TAP ) ที่เอาต์พุตสิ่งที่ได้รับ
ฉันต้องการปริมาณข้อมูลทั้งหมดของระบบเพื่อให้ไหลผ่านอินเทอร์เฟซนี้
บทบาทของอินเตอร์เฟสคือ:

  1. เพื่อหาแพ็กเก็ตที่มีแนวโน้มว่าจะถูกเซ็นเซอร์และทำการอุโมงค์
  2. ผ่านการรับส่งข้อมูลอื่น ๆ ทั้งหมดโดยไม่มีการแตะต้อง

อย่างที่คุณคิดว่าฉันกำลังพยายามสร้างเครื่องมือต่อต้านมะเร็ง
การตัดสินใจเกี่ยวกับการทันเนลจะต้องดำเนินการภายในกระบวนการ tun0
เพราะมีเพียงเราเท่านั้นที่สามารถใช้ DNS ที่เชื่อถือได้

ฉันต้องการให้คุณช่วยแสดงวิธีทำให้ปริมาณการรับส่งข้อมูลทั้งหมดผ่านอินเทอร์เฟซที่เขียนเอง tun0 หาก tun0 ต้องการการเปลี่ยนแปลงฉันขอให้คุณแจ้งการเปลี่ยนแปลงดังกล่าว

ด้านล่างเป็นวิธีที่ฉันพยายามทำให้ทราฟฟิกทั้งหมดผ่าน tun0 และล้มเหลว (pings ล้มเหลว)

การรวบรวม

  1. gcc tun0.c
  2. sudo ./a.out

การกำหนดค่า

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. สร้างตารางจอห์น

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

คำสั่งซื้อเป็นสิ่งสำคัญ:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. sudo ip rule add iif tun0 lookup main priority 500

    $ ip rule
    0:      from all lookup local 
    500:    from all iif tun0 lookup main 
    32765:  from all lookup John 
    32766:  from all lookup main 
    35000:  from all lookup default 
    

การแก้ไขปัญหา

  1. sudo tcpdump -i wlp2s0 -qtln icmpจากนั้นping -I tun0 8.8.8.8แสดงว่าไม่มีการจับแพ็คเก็ตหมายความว่าไม่มีการส่งแพ็กเก็ตจาก tun0 ไปยัง wlp2s0 ผ่านiif tun0 lookup mainกฎ

  2. เมื่อฉันแทนที่tun0ด้วยloทุกที่มันก็ใช้ได้สำหรับฉัน

ยังพยายาม

  1. การปิดการกรองเส้นทางย้อนกลับrp_filter=0ใน/etc/sysctl.conf

คำตอบการแก้ไขปัญหา

iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD " 
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT " 
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING " 
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog

แหล่งที่แก้ไขจากคำตอบอยู่ที่นี่ด้วย

คำตอบ:


10

ดังนั้นในการกำหนดค่าของคุณแพ็คเก็ตทั้งหมดที่คุณพยายามส่งไปยังเครือข่ายเริ่มแรกเริ่มจาก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 มันไม่ทำงานwlp2s010.0.0.1wlp2s0wlp2s010.0.0.1
OUTPUTPREROUTING
วิธีที่ดีที่สุดในการแก้ไขปัญหา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
ilyaigpetrov

มันใช้งานได้ แต่ประสิทธิภาพไม่ต่อเนื่องมาก (อาจหยุดทำงานเป็นเวลา 10 วินาทีจากนั้นทำงานต่อไป) ฉันจะคิดว่าทำไมมันเกิดขึ้นและวิธีการแก้ไข
ilyaigpetrov

1
ขออภัยมันเป็นคำผิดของฉัน ฉันได้เพิ่มวิธีการอื่นในคำตอบของฉัน ไม่มีความคิดเกี่ยวกับปัญหาเรื่องประสิทธิภาพ ทำไมถึงไม่ใช้พร็อกซีแบบโปร่งใสที่มี iptables DNAT เพื่อกรองและโอนทราฟฟิก
tifssoft

ฉันไม่สามารถทำซ้ำวิธีการทำเครื่องหมายของคุณฉันได้เพิ่มเข้ามาเท่านั้นsudo ip rule add iif tun0 lookup main priority 500แต่ก็ยังใช้งานไม่ได้ ฉันชอบวิธีนี้น่าเสียดายที่ฉันไม่สามารถทำซ้ำได้
ilyaigpetrov

1
ขอบคุณสำหรับวิธีการใหม่ของฉันฉันทำตามมันทีละขั้นตอนและทำงานได้อย่างสมบูรณ์แบบ แต่ฉันไม่เข้าใจว่าทำไมเราต้องเปลี่ยน ips ที่สำคัญที่สุดใช้งานได้ ในกรณีที่แผนของฉันที่มีพร็อกซี TCP ล้มเหลวฉันจะสามารถตอบกลับคำตอบของคุณได้ คุณแสดงให้เห็นถึงทักษะเครือข่ายมากมายที่นี่และฉันไม่สงสัยว่าความสามารถของคุณจะเป็นที่ต้องการหรือไม่ โชคดี!
ilyaigpetrov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.