HAProxy 302 به یک اپ خصوصی: چه کسی پرش دوم را باز میکند؟
یک تغییرمسیر اتصال دوم را به مرورگر برمیگرداند. به جای آن درخواست را به یک بکاند بفرستید و سپس تغییرمسیرهای مطلق و کوکیهای خود اپ را درست کنید.
کسی یک میزبان عمومی HAProxy را به یک اپلیکیشن داخلی اشاره میدهد و میپرسد چرا مرورگر نمیتواند دنبال کند. پراکسی از طریق VPN خودش به اپ میرسد، تغییرمسیر یک هدر Location برمیگرداند و مرورگر بعد آدرسی را امتحان میکند که فقط داخل تونل وجود دارد. از بیرون صفحه به سادگی معلق میماند. تصمیم درباره این است که کدام طرف اتصال دوم را باز میکند، و همین چیزی است که تغییرمسیر را از بکاند جدا میکند.
دو مسیر که در پیکربندی شبیه هم به نظر میرسند
یک تغییرمسیر تبادل را با یک پاسخ تمام میکند. کلاینت Location را میخواند و درخواست تازهای از هر جایی که هست آغاز میکند، یعنی همان شبکهای که هرگز آن را کنترل نکردید. پراکسی دیگر دخیل نیست. هر چه بعد میآید به DNS، مسیر و اعتماد خود کلاینت بستگی دارد، پس نتیجه بسته به این که کاربر مرورگر را کجا باز کرده است فرق میکند:
GET /app client -> proxy
302 Location proxy -> client (http://10.40.0.20:8080/)
GET /app client -> 10.40.0.20:8080 client network, no route
یک بکاند پراکسی مرحله دوم را در سمت سرور نگه میدارد. پراکسی آن را از مسیری که از قبل دارد باز میکند و کلاینت همچنان با یک نام عمومی حرف میزند. اگر تونل بیفتد، کلاینت به جای URL که نمیتواند دنبالش کند خطا میگیرد. همین تفاوت است که خرابی را قابل تشخیص میکند، چون خطا همان جایی ظاهر میشود که گزارشها هستند:
GET /app client -> proxy
GET /app proxy -> 10.40.0.20:8080 over the VPN
response proxy -> client
مستندات تغییرمسیر HAProxy دقیقاً همین مرز را میکشد: پاسخ دادن به کلاینت با تغییرمسیر کاری متفاوت از فرستادن درخواست به بکاند است. دو دستور در فایل پیکربندی چند خط فاصله دارند و کاملاً متفاوت رفتار میکنند. یکی درخواست را پایان میدهد و دیگری دومی را آغاز میکند که متعلق به پراکسی است.
چیزی که مرورگر لازم دارد و VPN سرور به آن نمیدهد
درخواست خود مرورگر چهار چیز لازم دارد که ممکن است نداشته باشد: یک پاسخ DNS برای نام خصوصی، یک مسیر به آن آدرس، اجازه رسیدن به سرویس شنونده، و اعتماد به گواهیای که آن سرویس ارائه میکند. میزبان پراکسی هر چهار را از طریق تونل خود دارد. هیچکدام به کلاینتی که هرگز در آن تونل نبوده منتقل نمیشود، چون تونل ویژگی میزبان است، نه URL.
این شکاف نشانه تقریباً-کار-میکند را توضیح میدهد. درخواست اول موفق میشود، نوار آدرس عوض میشود و بعد اتصال معلق میماند یا شکست میخورد در حالی که پراکسی تمام مدت سالم است. هیچ چیز در پیکربندی پراکسی خراب نیست و تنظیم آن به کلاینتی که مسیری به 10.40.0.20 ندارد کمکی نمیکند. یا کلاینت مسیر میگیرد، یا پراکسی باید اتصال را از طرف آن برقرار کند.
وقتی فقط پراکسی میتواند به اپ برسد
کنش تغییرمسیر را بردارید و آن درخواستها را به بکاندی بفرستید که به آدرس خصوصی اشاره میکند. فرانتاند نام عمومی خود را نگه میدارد و بکاند تصمیم میگیرد درخواست واقعاً کجا میرود. هیچ چیز در مسیر کلاینت عوض نمیشود، چون پراکسی از توصیف یک مقصد دست میکشد و خودش مقصد میشود. برای اپی که عمداً روی پورت داخلی 8080 گوش میدهد، بلوک سرور کوتاه است:
backend private_app
mode http
option httpchk GET /health
server app1 10.40.0.20:8080 check
آن بلوک را به عنوان گزارهای درباره جدول مسیریابی پراکسی بخوانید: 10.40.0.20 باید از خود میزبان پراکسی قابل دسترسی باشد، که اینجا یعنی از طریق رابط VPN و نه مسیر پیشفرض. کلیدواژه check فقط گزارش میدهد که آن مسیر چه میکند، و مسیر سلامت باید روی اپ وجود داشته باشد وگرنه هر بررسی سرور را خاموش علامت میزند. بررسی موفق چیزی درباره کلاینت ثابت نمیکند و جای سیاستی را که تعیین میکند چه کسی میتواند از بکاند استفاده کند نمیگیرد.
این قطعه فرانتاند کامل نیست. شنونده، احراز هویت، انتخاب میزبان و مسیر مجاز، و قاعدهای که تعیین میکند اصلاً چه کسی میتواند به اپ برسد را نگه دارید. پروتکل بکاند را هم هماهنگ کنید، چون بکاند HTTPS به تأیید گواهی و پیکربندی هویت سرور نیاز دارد و رد کردن آن بررسی یک اتصال خصوصی را به اتصالی تأییدنشده تبدیل میکند.
مسیر بازگشت را در هر دو جهت تأیید کنید پیش از اعلام پیروزی. اپ اکنون اتصالی از پراکسی میبیند، پس گزارشهایش و هر فراداده آدرس کلاینت پراکسی را توصیف میکند مگر اینکه طور دیگری ترتیب دهید. تصمیم بگیرید هویت و آدرسهای ارسالشده چگونه اداره میشوند، و تصمیم را بیازمایید نه اینکه فرضش کنید.
تغییرمسیرهای خود اپ هنوز به داخل اشاره میکنند
فرستادن درخواست اول فقط نیمی از یکپارچهسازی است. اپ ممکن است تغییرمسیرهای مطلق، URLهای دارایی سختکدشده یا کوکیهای محدود به نامی که در داخل میشناسد منتشر کند، و هر یک از اینها مرورگر را به آدرسی برمیگرداند که نمیتواند برسد. هدر Location که به نام داخلی اشاره میکند دقیقاً شبیه مشکل اصلی به نظر میرسد، و همین باعث میشود اشتباهاً خرابی پراکسی تشخیص داده شود.
URL خارجی مستندشده اپ و گزینههای پراکسی آن را تنظیم کنید، بعد هدر Host را با میزبان مجازی و انتظارات گواهی هماهنگ کنید. کوکی محدود به نام داخلی از طریق نام عمومی برنمیگردد و حلقه ورودی که بعد میآید مانند یک باگ احراز هویت خوانده میشود. اول URL خارجی را عوض کنید، از پروفایل مرورگر پاک دوباره آزمایش کنید و انتظار داشته باشید تنظیمات نیمهمهاجرتشده ورودیای بسازند که موفق میشود و نشستی که فوراً میمیرد.
به فراداده ارسالشده فقط از پراکسی تعیینشده اعتماد کنید. هدری که هر کلاینتی میتواند تنظیم کند هرگز نباید مقدار مجوز شود، وگرنه پراکسی راهی میشود برای اینکه فراخواننده هویت دیگری را ادعا کند. این قاعده مستقل از پرسش تغییرمسیر است و از هر بازطراحی بعدی جان سالم به در میبرد.
تصمیم بگیرید واقعاً کدام طراحی را دارید
اگر هر کاربر از قبل دسترسی VPN مجاز دارد، تغییرمسیر به یک URL خصوصی میتواند طراحی عمدی باشد. آن نیاز را صریحاً تأیید کنید نه اینکه فرضش کنید، چون دو طراحی جمعیتهای کاملاً متفاوتی را خدمت میکنند. یکی از آنها از شبکه هتل اصلاً کار نمیکند و دیگری اپ را برای هر کسی که بتواند URL عمومی را بارگذاری کند آشکار میکند. این تمایز جایاش در یادداشت طراحی است.
بررسی را از ماشینی در شبکه کاربران اجرا کنید و هر پرشی که مرورگر انجام میدهد را دنبال کنید، نه فقط پاسخ اول. نوار آدرس و هر درخواست بعدی را زیر نظر داشته باشید، چون یک URL مطلق در برچسب یک دارایی کافی است تا جریانی را که پرش اول از آن گذشت بشکند. ورود باید از طریق نام عمومی کار کند و منابعی که باید رد شوند باید رد بمانند.
انتشار یک پراکسی معکوس تصمیم دسترسی جداگانهای است، نه گسترش شفاف VPN خود پراکسی به هر کسی که میتواند URL عمومیاش را بارگذاری کند. این دو در نمودار شبیه هم به نظر میرسند و در این که چه کسی اجازه ورود دارد فرق میکنند. تصمیمگیری درباره این پرسش پس از استقرار همان راهی است که یک اپ داخلی تصادفاً عمومی میشود.
بنویسید کدام یک را ساختید و چرا. نفر بعدی که به پیکربندی دست بزند دیگری را فرض میکند. یک تغییرمسیر که برای راحتی اضافه شده کافی است تا خرابی اصلی را بازسازی کند و نشانه دقیقاً مانند همانی خواهد بود که همین حالا درست کردید.