UID नियमहरू प्रयोग गरी एउटा Linux एपलाई VPN मा जोड्ने तरिका
UID नियमले स्थानीय सकेट मात्र देख्छ, र सामान्य loopback अपवादले सुरुङ मार्छ। पहिले खातालाई मार्ग दिनुहोस्, त्यसपछि प्रत्येक चरण फिल्टर र जाँच गर्नुहोस्।
Linux मा एउटा कार्यक्रमलाई VPN मा जोड्नु मुख्यतः राउटिङको समस्या हो, र फायरवाल नियमले मार्ग छानिएपछि के हुन्छ मात्र निर्णय गर्छ। यदि सुरुङले पूर्वनिर्धारित मार्ग पाउनु अघि तपाईंले OUTPUT मा कार्यक्रमको UID मिलाउनुभयो भने, नियमले तपाईंले जोगाउन चाहेको त्यही ट्राफिक फ्याँक्छ। त्यही नियमले कार्यक्रमको DNS प्रश्नको उत्तर दिने रिजोल्भर प्रक्रिया पनि देख्दैन। क्रम ठीक बनाउनुहोस्, र विशेषाधिकार नभएको एउटा खाता भरपर्दो स्प्लिट-सुरुङ छनोटकर्ता बन्छ।
निर्णय अघि खातालाई मार्ग दिनुहोस्
मालिक-मिलानले एउटा प्रश्नको उत्तर दिन्छ: यो UID सँग सम्बन्धित स्थानीय सकेटले प्याकेट बनायो? यसले इन्टरफेस छान्दैन, र मुख्य तालिकाले पहिले नै भौतिक NIC बाट पठाइरहेको ट्राफिक सार्न सक्दैन। त्यसैले मिल्ने मार्ग नभएको UID नियमले कार्यक्रमलाई मोड्नुको सट्टा रोक्छ।
खातालाई पहिले यसको आफ्नै तालिकाबाट गुजार्नुहोस्, त्यसपछि फायरवालले नतिजा पुष्टि गरोस्। यो iproute2 ले uidrange बुझ्ने होस्टमा काम गर्छ, जुन ip rule help ले एकै लाइनमा रिपोर्ट गर्छ। तालिका 100 सुरुङबाट पूर्वनिर्धारित मार्ग राख्छ, र नियमले UID 1000 मात्र त्यो तालिकामा पठाउँछ। बाँकी सबै मुख्य तालिकामा रहन्छ र भौतिक जडान प्रयोग गर्न जारी राख्छ।
ip rule add uidrange 1000-1000 table 100 ip route add default dev tun0 table 100
अर्को सुरुङ चाहिने दोस्रो खाताले तालिका 101 र आफ्नै नियम पाउँछ, किनकि दुई प्रोफाइलले एउटै तालिकामा पूर्वनिर्धारित मार्ग सँगै राख्न सक्दैनन्। NetworkManager प्रोफाइल प्रणाली-व्यापी हुन्छन्, त्यसैले यो भाग हातैले रहन्छ, र रिबुटमा नियम हराउँछन्, जबसम्म कुनै कुराले तिनीहरूलाई पुनर्स्थापित गर्दैन। सुरुङ परिभाषाको छेउमा बुट स्क्रिप्टमा तालिकाहरू लेख्नुहोस्, ताकि पुनः जडानले एउटा खाता गलत बाटोमा छोड्न नसकोस्।
loopback अपवादले सुरुङ किन मार्छ
नियमका धेरैजसो प्रतिलिपि गरिएका संस्करणले loopback बाट ननिस्कने हरेक प्याकेट फ्याँक्छन्। सुरुङ loopback होइन, त्यसैले त्यो रूपले सुरुङको ट्राफिक पनि फ्याँक्छ, र नतिजा फायरवालको गल्ती नभई मृत VPN जस्तो देखिन्छ।
OUTPUT चल्दा कर्नेलले पहिले नै निकास इन्टरफेस छानिसकेको हुन्छ, त्यसैले -o प्याकेट हेडरसँग होइन, मार्गको उत्तरसँग तुलना गरिन्छ। मालिक-मिलान OUTPUT र POSTROUTING मा मात्र हेरिन्छ, र अगाडि पठाइएका प्याकेटमा यसले पढ्न सक्ने सकेट हुँदैन। यो संयोजनको अर्थ अपवादले loopback अस्वीकार गर्नुको सट्टा सुरुङको इन्टरफेस नाम दिनुपर्छ र त्यो मिलान अस्वीकार गर्नुपर्छ भन्ने हो।
loopback अझै DROP माथि आफ्नै ACCEPT को हकदार छ, किनकि कार्यक्रमको पहिलो DNS प्याकेट lo हुँदै स्थानीय स्टबमा जान्छ। दुई नियम यही क्रममा राख्नुहोस्, र खाता स्टबसम्म पुग्छ, त्यसपछि सुरुङसम्म, र अन्त कतै पुग्दैन।
iptables -I OUTPUT 1 -o lo -m owner --uid-owner vpnapp -j ACCEPT iptables -A OUTPUT -m owner --uid-owner vpnapp ! -o tun0 -j DROP
IPv6 छुट्टै नियम-समूह हो, र v4 का लागि मात्र बनेको जोडीले ip6tables लाई नछोई छोड्छ। AAAA रेकर्ड रुचाउने कार्यक्रम त्यसपछि DROP मा कहिल्यै नपुगी भौतिक जडानबाट बाहिर जान्छ। दुवै नियम ip6tables मा प्रतिबिम्बित गर्नुहोस्, वा सुरुङले v6 ठेगाना नबोकेको बेला होस्टमा IPv6 बन्द गर्नुहोस्। हातले थपिएका नियम पनि रिबुटमा हराउँछन्, त्यसैले तिनीहरूलाई netfilter-persistent save ले सुरक्षित गर्नुहोस् वा त्यही तर्कलाई बुट इकाइले लोड गर्ने nftables तालिकाका रूपमा पुनः बनाउनुहोस्।
DNS उत्तरहरू अर्को प्रक्रियाबाट आउँछन्
कार्यक्रमको 127.0.0.53 मा प्रश्न loopback ACCEPT पार गर्छ, र त्यहीँ UID मिलान रोकिन्छ। स्टब रिजोल्भर आफ्नै सेवा खाताबाट माथि पठाउँछ, त्यसैले vpnapp सँग बाँधिएको नियमले दोस्रो प्रश्न कहिल्यै देख्दैन। यदि रिजोल्भरले जडानका लागि LAN सर्भर छान्यो भने, उत्तरहरू भौतिक NIC बाट फर्किन्छन्, जबकि कार्यक्रमका आफ्नै प्याकेट सुरुङमै रहन्छन्। देखिने नतिजा भाँचिएका नामसहित चल्ने सुरुङ हो, वा तपाईंले नछानेको सर्भरले उत्तर दिने नामहरू।
नाम-समाधान कार्यक्रममा होइन, सुरुङको जडानमा सुधार्नुहोस्। सुरुङ प्रोफाइललाई DNS सर्भर र राउटिङ डोमेन दिनुहोस्, त्यसपछि resolvectl query र resolvectl status tun0 ले रिजोल्भरले महत्त्वपूर्ण नामहरूका लागि त्यो प्रयोग गर्छ भनी पुष्टि गर्नुहोस्। नेटवर्क नाम-स्थानभित्र समस्या हराउँछ, किनकि स्थानको रिजोल्भरले सुरुङ मात्र चिन्छ।
खाताबाटै नियम जाँच्नुहोस्
UID ले कुन मार्ग पाउँछ भनी कर्नेललाई सोध्नुहोस्, त्यसपछि त्यो खाताका रूपमा अनुरोध गर्नुहोस् र निकास ठेगाना आफ्नै खाताकोसँग तुलना गर्नुहोस्। दुवैले एउटै ठेगाना रिपोर्ट गरे, नियम तपाईंले जाँचेको ट्राफिकबाहेक अरू कुनैसँग मिल्छ। तलको पहिलो आदेशले प्याकेट नपठाई मार्ग-खोज देखाउँछ, जसले राउटिङ गल्तीलाई फायरवाल गल्तीबाट अलग गर्छ।
ip route get 1.1.1.1 uid 1000 sudo -u vpnapp curl -s https://ifconfig.co
काउन्टरले नियम कहिल्यै चल्यो कि भनेर देखाउँछ। iptables -vnL OUTPUT चलाउनुहोस्, प्रत्येक नियमको छेउमा प्याकेट-गन्ती पढ्नुहोस्, र वास्तविक ट्राफिकपछि DROP को छेउको शून्यलाई मिलानको गल्ती मान्नुहोस्।
अगाडि पठाइएको ट्राफिक यो डिजाइनबाहिर छ। पुलपछाडिको कन्टेनर वा VM सँग vpnapp को स्वामित्वको स्थानीय सकेट हुँदैन, त्यसैले मालिक-मिलान कहिल्यै चल्दैन र ती प्याकेटले FORWARD नीति पछ्याउँछन्। यदि त्यो कार्यभार ढाक्नुपर्ने भए, छुट्टै जाँच्नुहोस् र पुल वा कन्टेनर-ठेगानासँग बाँधिएको नीति लेख्नुहोस्। डिजाइन तब टिक्छ जब तालिका, इन्टरफेस अपवाद, रिजोल्भर र v6 नियम सबै एउटै दिशा देखाउँछन्; यीमध्ये कुनै एउटा छाड्नुभयो भने खाता चुहिन्छ वा जडान गुमाउँछ।