fwmark کے ساتھ ایک ہی Linux ہوسٹ پر دو OpenVPN کلائنٹس کو جوڑیں
دونوں کلائنٹس کو ڈیفالٹ روٹ چاہیے۔ اندرونی سرور کو ہوسٹ روٹ سے پن کریں، دوسرے کلائنٹ کو جدول دوبارہ لکھنے سے روکیں، پھر fwmark سے بہاؤ کی سمت متعین کریں۔
ایک ہی Linux ہوسٹ پر دوسرا OpenVPN کلائنٹ رکھنا دو میں سے ایک جگہ ناکام ہوتا ہے۔ یا تو اندرونی کلائنٹ اپنے سرور تک نہیں پہنچ سکتا کیونکہ بیرونی سرنگ نے وہ ترسیل قبضے میں لے لی ہے، یا دوسرا کلائنٹ روٹ جدول دوبارہ لکھتا ہے اور پہلی سرنگ کام کرنا بند کر دیتی ہے۔ دونوں مسائل روٹنگ میں ہیں، انکرپشن میں نہیں، اور دونوں نئی سرنگ کے کسی بھی ایپلیکیشن ٹریفک لے جانے سے پہلے حل ہو جاتے ہیں۔ یہاں پتے مثال کے طور پر ہیں: tun0 بیرونی سرنگ ہے، 203.0.113.9 اندرونی سرور ہے، اور TCP 9999 وہ بہاؤ ہے جسے اندرونی راستہ استعمال کرنا چاہیے۔
ناکامی کے دو طریقے، ایک روٹ جدول
اندرونی کلائنٹ اپنے سرور کی طرف UDP ساکٹ کھولتا ہے، اور وہ ساکٹ کسی بھی دوسرے کی طرح موجودہ روٹ جدول کی پیروی کرتا ہے۔ اگر بیرونی سرنگ کے پاس پہلے سے ڈیفالٹ ہے تو ہینڈ شیک پیکٹ بیرونی سرنگ میں چلے جاتے ہیں۔ یہ تبھی کام کرتا ہے جب بیرونی سرور اندرونی سرور تک پہنچ سکے اور دوسرا فریق بہاؤ لے جانے پر رضامند ہو؛ ورنہ ہینڈ شیک رک جاتا ہے اور کلائنٹ دوبارہ کوشش کرتا ہے۔
دوسری ناکامی سرور کے push سے آتی ہے۔ عام push redirect-gateway def1 ہے، جو ڈیفالٹ روٹ بدلنے کے بجائے 0.0.0.0/1 اور 128.0.0.0/1 نصب کرتا ہے۔ اس لیے جو دو کلائنٹس اپنی اپنی /1 جوڑی نصب کرتے ہیں وہ ٹکراتے ہیں، اور تقریباً ہر منزل کے لیے نئی جوڑی جیتتی ہے۔ جب دوسرے کے جڑنے کے بعد سرنگ مر جائے تو جدول میں وہ دو سابقے دیکھیں، کیونکہ ہو سکتا ہے ڈیفالٹ روٹ خود کبھی نہ بدلا ہو۔
بہاؤ کو نشان زد کریں اور اسے جدول دیں
منتخب ٹریفک کو mangle جدول میں نشان زد کر کے اور پالیسی قاعدے میں اس نشان کا میل کر کے سمت دیں۔ قاعدہ اس مخصوص جدول کی طرف اشارہ کرتا ہے جس کا ڈیفالٹ روٹ اندرونی آلہ ہے، اس لیے صرف نشان زد پیکٹ اندرونی راستہ لیتے ہیں۔
iptables -t mangle -A PREROUTING -p tcp -m multiport --dport 9999 -j MARK --set-mark 0x9999
ip rule add fwmark 0x9999 table 200 pref 1000
ip route add default dev tun1 table 200اس قواعد کے مجموعے میں زیادہ تر ناکامیاں دو غلطیوں سے آتی ہیں۔ فائر وال کا مقرر کردہ نشان اور قاعدے کا میل کرایا گیا قدر یکساں ہونا چاہیے، کیونکہ فرق نہ کوئی خرابی دیتا ہے نہ اثر۔ اور PREROUTING صرف باہر سے آنے والے پیکٹ دیکھتا ہے، اس لیے اس ہوسٹ پر شروع ہونے والے کنکشن کو نشان زد ہونے سے پہلے اسی میل والا OUTPUT قاعدہ درکار ہے۔
دوسرے کلائنٹ سے روٹ کی ملکیت چھین لیں
دو اختیارات دوسرے کلائنٹ کو جدول میں ترمیم سے روکتے ہیں، اور وہ الگ الگ مقامات پر کام کرتے ہیں۔ route-nopull push کیے گئے روٹ اختیارات کو نظرانداز کرتا ہے، اس لیے کچھ بھی نصب نہیں ہوتا۔ route-noexec push کیے گئے اختیارات کلائنٹ کے ماحول میں قبول کرتا ہے مگر جدول کی تبدیلی hook پر چھوڑ دیتا ہے، اور یہی آپ کو تب چاہیے جب سرور نے کیا پیش کیا یہ دیکھنا ہو۔
Hook اپنے ماحول میں push کی گئی قدروں کے ساتھ چلتا ہے، اور اسے صرف وہی اندراجات شامل کرنے چاہییں جو آپ نے منظور کیے۔ اسے idempotent بنائیں: دوبارہ تعمیر سے پہلے جو جدول اس کی ملکیت ہے اسے خالی کریں، اور یہ نہ مانیں کہ پچھلی بار صاف حالت چھوڑی تھی۔ دوبارہ جڑنے پر hook پھر بلایا جاتا ہے، اور صاف کیے بغیر شامل کرنے والا hook نقل روٹ جمع کرتا ہے۔
ایک مالک منتخب کریں اور اسے لکھ دیں۔ جو پروفائل دونوں اختیارات مقرر کرتی ہے، یا جو hook دستی اسکرپٹ سے مقابلہ کرتا ہے، وہ ایسا جدول بناتا ہے جسے بعد میں کوئی سمجھا نہیں سکتا۔
دونوں سرور پتے پن کریں
اندرونی کلائنٹ کے جڑنے سے پہلے اندرونی سرور کو بیرونی آلے کے ذریعے ہوسٹ روٹ درکار ہے۔ وہی اندراج اندرونی ترسیل کو ڈیفالٹ کی پیروی کرنے دینے کے بجائے بیرونی سرنگ کے اندر رکھتا ہے۔
ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9مرکزی جدول میں بیرونی سرور کے لیے بھی میل کھاتا ہوسٹ روٹ شامل کریں، ورنہ دوبارہ جڑنے پر بیرونی کلائنٹ کی اپنی ترسیل اس کی اپنی سرنگ میں روٹ ہو سکتی ہے۔ ترتیب اختیاری نہیں: یہ اندراجات متعلقہ انٹرفیس موجود ہونے کے بعد شامل کریں، یعنی کنکشن کے بعد چلنے والا hook یا اسکرپٹ۔ بند آلے کی طرف اشارہ کرنے والا روٹ ہٹا دیا جاتا ہے یا نظرانداز کر دیا جاتا ہے، اس لیے بوٹ کے وقت لکھا اندراج آپ کی فرض کردہ ترتیب سے نہیں گزرتا۔
پورا جدول پڑھنے کے بجائے تلاش چیک کریں۔ روٹ تلاش کا آؤٹ پٹ وہ آلہ اور ماخذ پتہ بتاتا ہے جو kernel استعمال کرے گا، اور کلائنٹ اپنا ساکٹ کھولتے وقت بالکل وہی پاتا ہے۔
زنجیر آزمائیں اور ناکامی کو نظر آنے والی بنائیں
اندرونی کلائنٹ جڑتے وقت بیرونی انٹرفیس پر قید کریں۔ اندرونی ہینڈ شیک کو بیرونی سرنگ کے اندر خفیہ پے لوڈ کے طور پر نظر آنا چاہیے؛ اگر وہ 203.0.113.9 کی طرف سادہ UDP دکھے تو ہوسٹ روٹ نہیں ہے اور زنجیر کبھی بنی ہی نہیں۔
جسمانی اپ لنک پر خاموشی سے لوٹنے والی زنجیر بدترین نتیجہ ہے، کیونکہ انٹرفیس کی حالت کچھ نہیں بتاتی اور اندرونی ٹریفک غلط ماخذ پتے سے نکلتی ہے۔ اگر بیرونی سرنگ گرنے پر دوسرا کلائنٹ سیدھا دوبارہ جڑ سکتا ہے تو اس راستے کو بند کریں یا ناکامی نظر آئے اس لیے اسے بیرونی انٹرفیس سے باندھ دیں۔
دو بہاؤ اور ایک قاعدہ ڈمپ کے ساتھ ختم کریں: نشان زد اور بلا نشان کنکشن الگ راستے لیں، اور ip rule show وہ ترجیح دکھائے جو آپ کا ارادہ تھا۔ اگر دونوں بہاؤ ایک ہی راستہ لیں تو نشان وہاں لاگو نہیں ہو رہا جہاں آپ سمجھتے ہیں۔