Docker میں OpenVPN: کم سے کم کلائنٹ کو درکار رن ٹائم معاہدہ
ایک جائزہ شدہ امیج، ایک محفوظ پروفائل، TUN رسائی اور NET_ADMIN۔ کنٹینر کیا حاصل کرتا ہے، کیا نہیں پانا چاہیے اور سرنگ کے کام کرنے کا ثبوت کیسے دیا جائے۔
VPN کلائنٹ کو کنٹینر میں رکھیں اور آپ کو اندر سرنگ والی ایک نام کی جگہ ملتی ہے، ایسا میزبان نہیں جو اپنا سارا ٹریفک VPN کے ذریعے روٹ کرتا ہو۔ یہ الگ الگ منصوبے ہیں، اور انہیں ایک سمجھنا ہی وہ طریقہ ہے جس سے کنٹینرز اتفاقاً مراعات یافتہ بن جاتے ہیں۔ یہ رہنما صرف پہلے کو محیط ہے: ایک جائزہ شدہ امیج، ایک محفوظ پروفائل اور اپنی نیٹ ورک نام کی جگہ تک محدود کلائنٹ عمل۔
کسی ایسے آرٹی فیکٹ سے شروع کریں جسے کسی نے پہلے ہی منظور کیا ہو۔ نیچے دیے گئے مراحل ایسی امیج فرض کرتے ہیں جس میں openvpn قابلِ عمل فائل اور مکمل کلائنٹ پروفائل ہے، جس کا سرٹیفکیٹ اور کلیدی مواد پہلے ہی ماؤنٹ کے اندر حل شدہ ہے۔ وہ سافٹ ویئر نہیں بناتے، اسناد جاری نہیں کرتے اور نہ root کے بغیر رن ٹائمز اور نہ ہی مقامی Windows کنٹینرز کا احاطہ کرتے ہیں، جن میں سے ہر ایک جواب بدل دیتا ہے۔
کنٹینر کیا حاصل کرتا ہے اور کیا نہیں
پروفائل اور وہ جس کا بھی حوالہ دیتی ہے، کو محدود اجازتوں والی مقامی ڈائریکٹری میں رکھیں، صرف-پڑھنے کے طور پر ماؤنٹ کیا ہوا۔ پروفائل کے اندر کے نسبتی راستے اسی ماؤنٹ کے اندر حل ہونے چاہئیں؛ یہ وہ تفصیل ہے جو لوگ چھوڑ دیتے ہیں جب سرٹیفکیٹ پروفائل سے ایک ڈائریکٹری اوپر ہوتا ہے اور کنٹینر اسے کبھی نہیں دیکھتا۔
services:
vpn:
image: ${VPN_CLIENT_IMAGE:?set the reviewed image reference}
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ./vpn:/vpn:ro
working_dir: /vpn
entrypoint: ["openvpn"]
command: ["--config", "/vpn/client.ovpn"]
وہ فائل تین چیزیں دیتی ہے اور کچھ اور نہیں مانگتی۔ اگر آپ کی تعیناتی پالیسی کہے تو امیج حوالہ ڈائجسٹ سے پن ہونا چاہیے، اور پروفائل جائزہ شدہ ہی ہونا چاہیے، میزبان پر کسی کا اسی جگہ ترمیم کردہ نقل نہیں۔
یہاں صرف-پڑھنے کا مطلب ہے کہ کنٹینر آپ کی میزبان فائلیں تبدیل نہیں کر سکتا؛ اس کا مطلب یہ نہیں کہ کنٹینر آپ کی ماؤنٹ کردہ نجی کلید نہیں پڑھ سکتا۔ ماؤنٹ کا پورا مقصد یہی ہے، اور اسی لیے فائل اجازتیں، ملکیت اور راز میزبان تک کیسے پہنچا، یہ اب بھی اہم ہیں۔ کبھی کمانڈ لائن پر پاس ورڈ نہ دیں اور نہ اسے امیج کی تہہ میں پکائیں، کیونکہ دونوں ایسی جگہوں پر رہتے ہیں جنہیں آپ بعد میں صاف نہیں کر سکتے۔
صلاحیتیں، entrypoint اور ان کے درمیان پھندا
دو ترتیبات درکار ہیں اور وہ غیر متعلق کام کرتی ہیں۔ NET_ADMIN کنٹینر کی نام کی جگہ کے اندر انٹرفیس اور راستوں کی تبدیلی کی اجازت دیتا ہے۔ /dev/net/tun ڈیوائس اندراج عمل کو سرنگ کا ڈیوائس بالکل کھولنے کی اجازت دیتا ہے۔ ایک کو دوسرے کے بغیر دینا واضح ناکامی پیدا کرتا ہے، جو سہولت بخش ہے: غیر موجود TUN ڈیوائس کھولتے وقت ناکام ہوتا ہے، جبکہ غیر موجود صلاحیت تب ناکام ہوتی ہے جب کلائنٹ انٹرفیس ترتیب دینے کی کوشش کرتا ہے۔
ان میں سے کوئی بھی privileged: true کا جواز نہیں بنتا۔ مراعات یافتہ کنٹینر کو تمام صلاحیتیں اور ڈیوائس تک رسائی ملتی ہے، اور یہ اس کام کے بوجھ کی ضرورت سے کہیں بڑا عطیہ ہے۔ رن ٹائم مراعات اور صلاحیتوں کا حوالہ بتاتا ہے کہ یہ عطیہ کتنی دور تک پہنچتا ہے۔ اگر کوئی chart یا بلاگ پوسٹ اس کی درخواست کرے، تو پہلے جانچیں کہ ضرورت درحقیقت غیر موجود ڈیوائس راستہ تھی یا غیر موجود صلاحیت۔
entrypoint کو اوور رائیڈ کرنا وہ حصہ ہے جو کاٹتا ہے۔ openvpn کو براہ راست کال کرنا عام امیج کے لیے درست ہے اور ہر ایسی پروڈکٹ امیج کے لیے غلط ہے جس کی اسٹارٹ اپ اسکرپٹ ڈیمون چلانے سے پہلے فائر وال قواعد، ریزولور فائلیں یا اسناد تیار کرتی ہے۔ اس اسکرپٹ کو اوور رائیڈ کرنا تیاری چھوڑ دیتا ہے اور آپ کو آدھی ترتیب شدہ نام کی جگہ میں اٹھی سرنگ کی ڈی بگنگ پر چھوڑ دیتا ہے۔
کلائنٹ کو پیش منظر میں چلائیں اور اسے کنٹینر کا مرکزی عمل بننے دیں۔ ڈیمون بننے والا عمل فوراً باہر نکل جاتا ہے، کنٹینر لوپ میں دوبارہ شروع ہوتا ہے، اور آپ کو درکار لاگز ایسے دوبارہ آغاز میں بکھرے ہوتے ہیں جو سب ایک جیسے دکھتے ہیں۔
نام کی جگہ کے اندر سے تصدیق کریں، میزبان سے نہیں
اسٹیک اوپر لائیں، لاگ میں تصدیق کریں کہ کلائنٹ جڑی حالت تک پہنچ گیا، پھر اس نام کی جگہ کا معائنہ کریں جو واقعی سرنگ رکھتی ہے۔
docker compose up -d
docker compose logs --tail 40 vpn
docker compose exec vpn ip -br addr
docker compose exec vpn ip route
پتوں کی فہرست میں پول سے پتے والا سرنگ انٹرفیس دکھنا چاہیے، اور راستوں کی جدول میں اس کی طرف اشارہ کرتے دھکیلے گئے منزلیں دکھنی چاہئیں۔ اگر انٹرفیس نہیں ہے، تو کلائنٹ اسے بنانے کے مقام تک کبھی نہیں پہنچا۔ اگر ہے مگر کوئی راستہ اسے استعمال نہیں کرتا، تو تلاش کی جگہ push یا راستے کے اختیارات ہیں۔
پھر آپ کے لیے اہم منزل کو اس نام کی جگہ سے آزمائیں جسے سرنگ استعمال کرنی چاہیے، ایپلیکیشن سے اور صرف ping سے نہیں۔ نام حل کرنا الگ ناکامی ہے جسے واضح طور پر جانچنا چاہیے: دھکیلا گیا DNS پتہ کنٹینر کے ریزولور کو خود اپ ڈیٹ نہیں کرتا، اور push کو نظر انداز کرنے والا خودمختار کلائنٹ نام اسی کے ذریعے حل کرے گا جو امیج نے ترتیب دیا ہے۔
منقطع حالت معاہدے کا حصہ ہے
دوبارہ جڑنے کے رویے کی اپنی جانچ درکار ہے، کیونکہ دوبارہ آغاز کی پالیسی ثابت کرتی ہے کہ عمل دوبارہ شروع ہوتا ہے اور اس دوران ٹریفک کیا کرتا ہے اس پر کچھ نہیں کہتی۔ سرنگ بند کریں، مطلوبہ منزل آزمائیں اور دیکھیں کہ کنکشن مسترد ہوتا ہے، لٹکتا ہے، یا کنٹینر کے معمول کے راستے سے خاموشی سے کامیاب ہوتا ہے۔ آخری نتیجہ ہی اہم ہے، اور یہ صحت مند لاگ میں نظر نہیں آتا۔
اگر کام کے بوجھ کو کبھی معمول کا راستہ استعمال نہیں کرنا چاہیے، تو اسے فائر وال قواعد اور نام کی جگہ کے اندر تیاری کے اشارے کے ساتھ واضح طور پر ڈیزائن کریں۔ Kill switch وہ پالیسی ہے جو آپ لکھتے اور جانچتے ہیں، کنٹینر میں کلائنٹ چلا کر وراثت میں ملنے والی خصوصیت نہیں۔
آخر میں، حد یاد رکھیں: یہ راستے کنٹینر کی نام کی جگہ میں رہتے ہیں اور میزبان کی روٹنگ جدول کی جگہ نہیں لیتے۔ Docker کے فارورڈنگ، ترجمہ اور فائر وال قواعد بیرونی راستے کا حصہ رہتے ہیں، اور شائع شدہ پورٹ VPN انٹرفیس نہیں ہے۔