هوک client-connect در OpenVPN: آدرس شما واقعاً کجا میرود
اسکریپت client-connect نمیتواند با چاپ کردن، آدرسی برگرداند. ببینید چگونه فایل موقت هوک، وضعیت خروج و توپولوژی، IP کلاینت را تعیین میکنند.
برگرداندن یک آدرس از اسکریپت client-connect شبیه چیزی است که باید IP کلاینت را تنظیم کند. اما نمیکند: تنها کانال هوک به سرور یک فایل موقت است که مسیرش بهعنوان آخرین آرگومان اسکریپت میرسد، و آدرس باید آنجا با نحو ifconfig-push نوشته شود. اسکریپتی که آدرس را چاپ میکند یا بدون نوشتن چیزی با صفر خارج میشود، کلاینتی متصل با آدرسی از استخر تولید میکند، و گزارش سرور کاملاً سالم به نظر میرسد.
این سردرگمی منطقی است، چون چند هوک دیگر واقعاً از طریق کدهای خروج یا متغیرهای محیطی پاسخ میدهند. این یکی قرارداد خودش را دارد، و قرارداد با یک نام فایل شروع میشود.
هوک فایل مینویسد، نه مقدار بازگشتی
اعلان دو خط است: script-security 2 برای اجازه دادن به فراخوانی، سپس client-connect /etc/openvpn/server/assign-address.sh. وقتی کلاینت احراز هویت میکند، سرور آن اسکریپت را با مسیر فایل تولیدشده که بهعنوان آخرین آرگومان ضمیمه شده اجرا میکند، که تنها در صورتی $1 است که اعلان هیچ آرگومان اضافی خودش را نفرستد. هر چیزی که به آن کلاینت اعمال میشود بهصورت دستورالعملهای عادی، یکی در هر خط، دقیقاً همانطور که در یک پیکربندی ظاهر میشوند، در آن فایل نوشته میشود. پوششی که پارامترهای خودش را اضافه میکند موقعیت را جابهجا میکند، و نشانهٔ کلاسیک اسکریپتی است که در مسیری شبیه --verbose مینویسد.
وضعیت خروج نیمهٔ دیگر قرارداد است. صفر یعنی بپذیر و فایل را بخوان؛ هر چیز دیگری اتصال را رد میکند، و اینگونه هویت نقشهنشده رد میشود بهجای اینکه بیصدا به استخر بازگردد. دستورالعمل کامل را پیش از برگرداندن موفقیت بنویسید، تا فایلی نیمهنوشته هرگز پیکربندی یک کلاینت نشود.
دو دستورالعمل شایستهٔ توجهاند چون با همهچیز دیگر تعامل دارند. ifconfig-push آدرس را تثبیت میکند، در حالی که route ارسالی به کلاینت میگوید چه چیزی از طریق تونل در دسترس است؛ اولی را برگردانید و دومی را فراموش کنید و کلاینتی با آدرس و بیمقصد میگیرید. ترتیب داخل فایل مهم نیست، اما کامل بودن مهم است. هوکی که مسیری برای پیشوندی میفرستد که هیچ همتایی نمیتواند به آن برسد، همان اشتباه از سوی دیگر است.
ورودیها از طریق متغیرهای محیطی میرسند: common_name، trusted_ip، ifconfig_pool_remote_ip و بقیه. با همهٔ آنها مانند رشتههایی از بیرون سرور رفتار کنید، هرگز مانند قطعات پوسته.
نقشهبرداری آدرس یک سیاست است، نه حساب
میانبر وسوسهانگیز این است که نام گواهی را تجزیه کنید و ارقامش را بهعنوان آخرین اکتت به کار ببرید. این یک تخصیصدهنده نیست، و به روشهای معمولی شکست میخورد: دو نام با پسوند یکسان برخورد میکنند، نامی که به 300 ختم میشود آدرس نیست، و گواهیای که مدیر آن را تغییر نام دهد بیصدا دستگاهی را جابهجا میکند. در هر فراخوانی عضویت در زیرشبکه، محدودهٔ میزبان قابل استفاده، آدرسهای رزروشده و یکتایی را اعتبارسنجی کنید، و نقشه را در جدولی نگه دارید که انسان بتواند بخواند.
هر کس نام را کنترل کند آدرس را کنترل میکند، پس تصمیم بگیرید common_name در این استقرار واقعاً چه چیزی را نمایندگی میکند. با فعال بودن username-as-common-name، هویت همان ورود است نه موضوع گواهی. هرگز آن مقدار را به ارزیابی پوسته ندهید، و هرگز نگذارید کلاینت بر مسیر فایل تأثیر بگذارد.
تخصیصدهندهای که به یک رجیستری تکیه دارد باید در برابر همزمانی دوام بیاورد. آدرس را اتمی رزرو کنید، نوشتن ناموفق را بدون پذیرش کلاینت نیمهپیکربندیشده مدیریت کنید، و هر تخصیص را با اتصالی که مالک آن است برچسب بزنید، تا قطع دیرهنگام یک نشست قدیمی نتواند آدرسی را آزاد کند که نشستی جدیدتر آن را در اختیار دارد. چند نمونهٔ سرور که یک استخر را شریکاند این الزام را تیزتر میکنند نه اختیاری.
توپولوژی تعیین میکند ifconfig-push چه معنایی دارد
با topology subnet روی 10.77.0.0/24، ifconfig-push 10.77.0.20 255.255.255.0 یک آدرس بههمراه ماسک شبکهٔ آن است. زیر topology net30 آرگومان دوم اصلاً ماسک نیست بلکه آدرس همتا است، پس کپی کردن شکل زیرشبکه روی سرور net30 کلاینتی به شما میدهد که متصل میشود و نمیتواند ترافیک را عبور دهد. توپولوژی را آگاهانه تغییر دهید، هرگز برای اینکه یک مثال سازگار به نظر برسد. سروری که از قبل با net30 کار میکند کلاینتهای زندهای روی آدرسدهی قدیمی دارد، پس تغییر یک مهاجرت با پنجرهٔ نگهداری است، نه ویرایش یک خط.
آدرسهای ثابت باید بیرون از استخر پویا و بیرون از هر تخصیص ثابت دیگری باشند، از جمله آنهایی که فایلهای client-config-dir معمولی توزیع میکنند. اگر دو مکانیزم بتوانند یک آدرس را برای کلاینتهای مختلف تولید کنند، یکی از آنها سرانجام این کار را خواهد کرد.
پیش از اعتماد، چهار حالت را آزمایش کنید
همان بررسیها را روی هویت نقشهشده، نقشهنشده، اتصال دوباره و خرابی شبیهسازیشدهٔ رجیستری اجرا کنید. openvpn --config client.ovpn --verb 4 آدرس تخصیصیافته را در پاسخ push نشان میدهد، و روی سرور grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log تأیید میکند که واقعاً چه فرستاده شده است. برای هویت نقشهنشده نتیجهٔ انتظاری اتصال ردشده است، نه آدرسی از استخر.
سپس دایرکتوریای را بررسی کنید که دیمن آن فایلهای موقت را در آن مینویسد. اسکریپت در بافت سرویس تنزلیافته اجرا میشود، بنابراین مسیری که root میتواند در آن بنویسد ولی دیمن نه، هر اتصال را به رد شدن با خطای مجوز که چند خط پایینتر در گزارش دفن شده تبدیل میکند.
تخصیص مجوز نیست: آدرس تثبیتشده هنوز دسترسی به هر مقصدی پشت سرور را نمیدهد. سیاست مسیریابی و فایروال را در لایهٔ خودش نگه دارید، و آن را در برابر آدرسی که همین حالا تثبیت کردید بررسی کنید.