इसलिए आपके कॉन्फ़िगरेशन में, शुरू में उत्पन्न होने वाले नेटवर्क को भेजने के लिए आपके द्वारा लिए गए सभी पैकेट 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 में नेटफिल्टर / आईटबल्स की मदद से यह आसान है :
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
इंटरफ़ेस से पैकेट को स्थानांतरित कर रहा है wlp2s0
। netfilter को आउटपुट पैकेट के लिए 10.0.0.1
आपके wlp2s0
इंटरफ़ेस असाइन किए गए पते पर स्रोत IP को बदलना चाहिए । यह सभी कनेक्शनों को याद करता है और जब उत्तर पैकेट वापस जाते हैं (यदि वे) तो यह wlp2s0
निर्दिष्ट इंटरफ़ेस के गंतव्य पते को 10.0.0.1
("कनवर्टर" सुविधा) में बदल देता है।
ठीक है, यह होना चाहिए, लेकिन यह नहीं है। ऐसा लगता है, नेटफिल्टर इस जटिल रूटिंग कॉन्फ़िगरेशन के साथ भ्रमित हो जाता है और यह तथ्य कि एक ही पैकेट पहले OUTPUT
चेन के माध्यम से जाता है और फिर रूट किया जाता है और PREROUTING
चेन में आता है । कम से कम डेबियन 8 बॉक्स पर यह काम नहीं करता है।
नेटफिल्टर की
समस्या निवारण का सबसे अच्छा तरीका है 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
)।
इस काम को करने के लिए नीचे कई दृष्टिकोण दिए गए हैं।
APPROACH # 1
नेटफिल्टर को अन-कन्फ्यूज करने का सबसे अच्छा तरीका tun0.c
एप्लीकेशन में पैकेट के सोर्स आईपी एड्रेस को बदलना है । यह सबसे प्राकृतिक तरीका भी है। हम की जरूरत है 10.0.0.2 को 10.0.0.1 बदल रास्ता बाहर पर और 10.0.0.1 को 10.0.0.2 तरह से पीठ पर।
मैंने tun0.c
स्रोत पता परिवर्तन कोड के साथ संशोधित किया है। यहाँ नई फ़ाइल है और यहाँ आपके लिए पैचफ़ाइल है tun0.c
। आईपी हेडर में परिवर्तन से चेकसम सुधार भी शामिल है , इसलिए मैंने ओपनवीपीएन परियोजना से कुछ कोड लिया । यहाँ एक साफ रिबूट और 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
केवल उसके सबनेट से संबंधित पैकेट प्राप्त करता है और भेजता है। इसके अलावा आप इंटरफ़ेस-आधारित के बजाय स्रोत-आधारित रूटिंग कर सकते हैं।
APPROACH # 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 --to-source ip.address.of.your.wlan.interface
यहां हम पैकेट को डिवाइस तक पहुंचने से ठीक पहले स्रोत का पता बदलते हैं tun0
। tun0.c
कोड इन पैकेटों को "जैसा है" (बदले हुए स्रोत पते के साथ) को फिर से जारी करता है और उन्हें सफलतापूर्वक वेलन इंटरफ़ेस के माध्यम से रूट किया जाता है। लेकिन आपके पास वेलन इंटरफ़ेस पर एक गतिशील आईपी हो सकता है और 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 पता नोट करें - यह अलग है। आप यहां किसी भी आईपी का उपयोग कर सकते हैं, इससे कोई फर्क नहीं पड़ता। पैकेट इंटरफ़ेस nat/POSTROUTING
पर श्रृंखला तक पहुंचते हैं wlp2s0
यदि हम स्रोत आईपी को पहले बदलते हैं। और अब यह wlan इंटरफ़ेस के लिए एक स्थिर IP पर निर्भर नहीं है।
अप्रोच # ३
आप भी इस्तेमाल कर सकते हैं 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
रूटिंग और नेटफिल्टर के लिए यह एक और "हैक" है जो मेरे डेबियन 8 बॉक्स पर काम करता है, लेकिन फिर भी मैं पहले दृष्टिकोण को लेने की सलाह देता हूं क्योंकि यह अधिक प्राकृतिक है और किसी भी हैक का उपयोग नहीं करता है।
आप अपने एप्लिकेशन को पारदर्शी प्रॉक्सी के रूप में बनाने पर भी विचार कर सकते हैं । मुझे लगता है कि यह ट्यून डिवाइस से पैकेट का विश्लेषण करने के बजाय बहुत आसान होगा।
-j SNAT
, नहीं-s SNAT