هوک PHP در OpenVPN: trusted_ip در برابر ifconfig_pool_remote_ip
دو نشانی با دو معنی متفاوت که فرایندی میخواندشان که خودتان راهش نینداختهاید. متغیرهای هوک چیست و چرا $_ENV خالی چیزی را اثبات نمیکند.
آرایهٔ خالی $_ENV در اسکریپت هوک شبیه مدرکی است که OpenVPN چیزی تحویل نداده است. معمولاً مدرک چیز دیگری است: PHP طوری تنظیم شده بود که آن ابرجهانی را پر نکند و مقادیر تمام مدت در محیط فرایند نشسته بودند. نتیجهٔ غلط دوم ظریفتر است، چون دو متغیر نشانی در هوک اتصال معناهای متفاوتی دارند و بهجای هم به کار میروند. هر دو اشتباه یک بعدازظهر را میخورند، اگر از اشتباهی شروع کنید.
دو نشانی، دو ادعای متفاوت
نقطهٔ پایانی بیرونی همان چیزی است که سرور هنگام اتصال کارخواه مشاهده کرد، در دسترس بهصورت trusted_ip برای IPv4 و trusted_ip6 برای IPv6. نشانی مجازی همان چیزی است که استخر برای این نشست تخصیص داد، در دسترس بهصورت ifconfig_pool_remote_ip.
به پرسشهای متفاوتی پاسخ میدهند و یک رکورد معمولاً یکی از آن دو را میخواهد نه هر دو را. اولی این است که اتصال از کجا آمد، که میتواند یک نشانی NAT مشترک باشد که صدها نفر از آن استفاده میکنند. دومی این است که این نشست کجای درون تونل زندگی میکند و بعداً میتواند به نشست دیگری واگذار شود. اشتباه گرفتن این دو رکوردهایی میسازد که معقول به نظر میرسند و غلطاند.
یک خواندن کمینه چنین است.
$outer4 = getenv('trusted_ip');
$outer6 = getenv('trusted_ip6');
$inner = getenv('ifconfig_pool_remote_ip');
$outer = $outer4 !== false ? $outer4 : $outer6;هیچیک از دو مقدار یک شخص را شناسایی نمیکند. یکی مشاهدهٔ شبکه است و دیگری اجارهنامه، و رکوردی که هرکدام را شناسهٔ پایدار دستگاه بداند، نخستین بار که کارخواه از شبکهٔ دیگری دوباره متصل شود یا نشانی استخر دیگری بگیرد غلط خواهد بود. فیلد را بر پایهٔ پرسشی انتخاب کنید که رکورد باید پاسخ دهد، سپس آن پرسش را کنار ستون بنویسید.
بررسی کنید PHP چگونه راهاندازی شده، نه شل خودتان
هوک بهعنوان فرزند دیمن VPN با محیطی که دیمن میسازد اجرا میشود. شل تعاملی شما محیط دیگری دارد و اجرای دستی اسکریپت، محیط شل را میآزماید نه محیط هوک را.
با تأیید این شروع کنید که هوک واقعاً در مرحلهای که انتظار داشتید فعال شده است. اسکریپتی که به مرحلهٔ نادرست وصل شده، یا اسکریپتی که هرگز اجرا نشده چون دستور به مسیر دیگری اشاره میکند، دقیقاً همان نشانهٔ متغیر غایب را میدهد. یک خط نشانگر عمدی در بالای اسکریپت بیفزایید و پیش از بررسی هر چیز دیگری تأیید کنید که ظاهر میشود. یک خط زماندار در گزارش، «هرگز اجرا نشد» را از «بدون مقدار اجرا شد» جدا میکند.
سپس تأیید کنید که آن فراخوانی از کدام مفسر و کدام فایل پیکربندی استفاده میکند. ویرایش پیکربندی PHP برای یک کارساز وب هیچ تغییری در فرایند CLI که OpenVPN راه میاندازد نمیدهد، و این دو میتوانند فایلهای php.ini کاملاً متفاوتی بار کنند.
چرا $_ENV خالی چیزی را اثبات نمیکند
مرجع getenv در PHP خواندن مستقیم محیط فرایند را مستند میکند که وقتی نام غایب باشد false برمیگرداند. ابرجهانی $_ENV جداگانه پر میشود و دستور variables_order تعیین میکند کدام ابرجهانیها پر شوند.
اگر آن دستور E را حذف کند، $_ENV خالی میماند هر چه محیط داشته باشد. کدی که آن را ایندکس میکند آنگاه از متغیر غایبی گزارش میدهد که در واقع حاضر است، و بررسی به سمت OpenVPN میرود در حالی که پاسخ در php.ini است. دستور را مشخصاً برای پیکربندی CLI بررسی کنید، نه برای کارساز وب.
خواندن با getenv از کل این دستهٔ سردرگمی پرهیز میکند، و اسکریپت پوششی که پیش از فراخوانی مفسر محیط را پاک میکند آن را به شکلی دیگر بازمیگرداند.
یک ارتباط را ذخیره کنید، نه بهروزرسانی سطر
پیش از نوشتن تصمیم بگیرید رکورد به کدام مقدار نیاز دارد. اگر هدف ثبت این است که نشست از کجا آمده، نقطهٔ پایانی بیرونی را ذخیره کنید و آن را مشاهده برچسب بزنید. اگر هدف نگاشت نشست به نشانی تونل در طول یک اتصال است، نشانی استخر را ذخیره کنید و آن را به نشست کلید کنید.
بهروزرسانی را بر پایهٔ هویت احرازشده و نشست کنونی انجام دهید نه بر پایهٔ هر سطری که یک نشانی تونل را شریک است، چون نشانیهای استخر دوباره استفاده میشوند و یک رویداد قطع دیرهنگام میتواند دادههای اتصال تازهتری را بازنویسی کند. IPv6 را صریح رسیدگی کنید بهجای آنکه بیصدا فقط مقدار IPv4 را بنویسید. سطری با نشانی بیرونی NULL بهتر از سطری با نشانی غلط است، چون اولی بهطور آشکار ناقص است.
نوشتن را به شناسهٔ نشستی که OpenVPN فراهم میکند کلید کنید تا اتصال دوباره رکوردی تازه بسازد نه آنکه قدیمی را ویرایش کند. از دستورهای پارامتری و حسابی فقط با اجازههایی که عملیات نیاز دارد استفاده کنید. هوک با اختیار دیمن اجرا میشود، پس یک پرسوجوی بیدقت مسئلهای گستردهتر از یک خط گزارش غلط است.
بیآنکه محیط را بیرون بریزید تشخیص دهید
ثبت کنید کدام نامها حاضر بودند، کدام مرحله اجرا شد و کدام مفسر به کار رفت. کل محیط را چاپ نکنید، چون فرایند هوک میتواند مقادیر بیربطی را به ارث ببرد که نباید در فایل گزارش بیایند.
یک اتصال را سرتاسر بررسی کنید: نقطهٔ پایانی بیرونی را بخوانید، نشانی تخصیصیافته را بخوانید و هر دو را با دید خود سرور نسبت به آن نشست تأیید کنید. وقتی جفت برای یک کارخواه تأیید شد، میتوان در جاهای دیگر به ارتباط اعتماد کرد.