proxy_redirect، NGINX را به هاست VPN شما وصل نمیکند
proxy_redirect سرآیندهای پاسخی را که پیشتر رسیده بازنویسی میکند؛ هرگز upstream را انتخاب نمیکند. proxy_pass، مسیر تا بکاند و سپس سرآیندها را بررسی کنید.
نام این دستور شامل واژه redirect است، بنابراین وقتی بکاندی پشت VPN در دسترس نیست آن را داخل یک بلوک location میچسبانند. هیچ چیز تغییر نمیکند و نتیجهگیری آشکار این است که دستور خراب است یا به نحو دیگری نیاز دارد. آنچه واقعاً رخ داده سادهتر و کمتر تمجیدآمیز است: proxy_redirect روی پاسخی کار میکند که پیشتر بازگشته، و در این استقرار هیچ درخواستی هرگز تا آنجا نرسیده است.
دو دستور، دو لحظه در یک درخواست
یک درخواست HTTP از طریق پروکسی معکوس به ترتیب از چند تصمیم میگذرد و دو دستور در دو سر مقابل این زنجیره قرار دارند. یکی انتخاب میکند که درخواست کجا برود. دیگری سرآیندهای مشخصی را در پاسخی که برمیگردد ویرایش میکند.
| Directive | When it acts | What it can change |
|---|---|---|
proxy_pass | Before any bytes leave the proxy | Which upstream receives the request |
proxy_redirect | After the upstream responds | Matching Location and Refresh text |
همین ترتیب تمام پاسخ است. اگر سطر دوم هرگز اجرا نشود چون سطر اول شکست خورده، دستور دوم پیکربندی غلط ندارد، فقط دستنیافتنی است. هر قدر هم سطر دوم را بازنویسی کنید، پاسخی که باید ویرایش میکرد ساخته نمیشود. از سطر اول به بیرون عیبیابی کنید و رفتار گیجکننده به یک مسیر گمشده یا یک اتصال ردشده فرو میکاهد.
انتخاب upstream به proxy_pass تعلق دارد
فرض کنید NGINX روی یک هاست ورودی عمومی اجرا میشود و از طریق VPN خود به برنامهای در 10.40.0.20:8080 میرسد. قطعهای که آن برنامه را انتخاب میکند چنین است، داخل یک بلوک server موجود:
location / {
proxy_pass http://10.40.0.20:8080;
}
از طرحواره، نشانی و درگاه واقعی استفاده کنید و این را قطعهای بدانید نه یک استقرار. هاست ورودی همچنین باید مسیر VPN، مسیر ارسال مجاز و ترافیک بازگشتی سالم به آن سرویس را نگه دارد، چون پروکسیای که روی کاغذ به نشانیای میرسد هنوز به موافقت هسته نیاز دارد.
مرجع ماژول proxy انتخاب upstream را از بازنویسی سرآیندهای پاسخ جدا نگه میدارد و یادآور میشود که مقدار proxy_pass دارای URI تغییر میدهد که پیشوند location منطبق چگونه جایگزین میشود. افزودن یا حذف اجزای مسیر بدون بررسی URLی که برنامه انتظار دارد راهی مطمئن برای تولید 404 است که شبیه خطای مسیریابی به نظر میرسد.
proxy_redirect پاسخهایی را که نشانی خصوصی را لو میدهند درست میکند
وقتی ترافیک جاری شد، بکاند ممکن است با سرآیند Location پاسخ دهد که نشانی خصوصی خود را نام میبرد. مرورگری که آن سرآیند را دنبال کند نقطه ورود عمومی را ترک میکند و میکوشد به چیزی برسد که نمیتواند تجزیه کند. بازنویسی پاسخ که آگاهانه پیکربندی شده، URL خصوصی را روی عمومی نگاشت میکند:
proxy_redirect http://10.40.0.20:8080/ https://app.example.com/;
هر دو طرف را با مقادیر واقعی جایگزین کنید. دامنه باریک را هم بفهمید: متن سرآیندهای منطبق Location و Refresh بازنویسی میشود، اما URLهای جاسازیشده در HTML، JavaScript یا فایلهای دانلودشده نه.
اگر برنامهای همهجا پیوندهای مطلق میسازد، اصلاح پایدار پیکربندی URL خارجی خودش است، نه فهرست روبهرشدی از قواعد بازنویسی روی پروکسی. افزودن قاعده تا وقتی خروجی درست به نظر برسد، پیکربندیای میسازد که در نخستین صفحهای که کسی آزمایش نکرده شکست میخورد. یک تنظیم درست برنامه تمام مجموعه را جایگزین میکند.
چیزی که بازنویسی سرآیند نمیتواند ترمیم کند
چند مشکل مجاور شبیه مشکلات تغییرمسیر به نظر میرسند و نیستند. سرآیند Host که به upstream فرستاده میشود شاید باید با هاست مجازی بکاند بخواند. یک upstream مبتنی بر TLS ممکن است به نام سرور مشخص بههمراه بررسی گواهی نیاز داشته باشد، و بازنویسی سرآیند پاسخ به هیچیک کمکی نمیکند.
گستره کوکی و ویژگیهای دامنه به برنامه و پیکربندی آن تعلق دارد. پروکسی میتواند تمام روز سرآیندها را بیندازد یا بازنویسی کند و باز هم نشستی بسازد که در درخواست دوم شکست میخورد، چون کوکی برای هاستی صادر شده که مرورگر هرگز آن را ندیده است. آن شکست گاهبهگاه به نظر میرسد، و برای همین اینقدر در صف بلیت زنده میماند. خواندن دامنه کوکی معمولاً بررسی را در یک دقیقه پایان میدهد.
احراز هویت و انتخاب بکاند را هم به برنامه موردنظر محدود نگه دارید. پروکسی معکوس عمومی باید یک برنامه را از طریق VPN سرور ارائه دهد نه اینکه به دروازه عمومی برای هر نشانی خصوصی تبدیل شود که آن هاست میتواند به آن برسد. یک location عمومی که هر چیزی را که فراخواننده بخواهد ارسال کند، یک سرویس افشاشده را به نقشهای از شبکه خصوصی شما تبدیل میکند. upstream را صریح نام ببرید و همانجا نگه دارید.
به همان ترتیبی آزمایش کنید که درخواست سفر میکند
سه چیز را به ترتیب تأیید کنید: NGINX همان location موردنظر را انتخاب کرد، درخواست را به بکاند کامل کرد، و مرورگر هر تغییرمسیر بعدی را دنبال کرد و زیرمنابع را بارگذاری کرد. هر مرحله خطوط لاگ خودش را دارد و خواندن آنها به ترتیب یک 502 مبهم را به یافتهای مشخص تبدیل میکند.
تمایزی که نیاز دارید میان اتصال upstream شکستخورده و مرورگری است که به نام خصوصی دستنیافتنی فرستاده شده. اولی در لاگ خطای پروکسی پیدا میشود؛ دومی به شکل درخواستی است که هرگز نمیرسد و مرورگر از هاستی شکایت میکند که نمیتواند تجزیه کند. دو مشکل متفاوت، دو فایل متفاوت، و فقط یکی از آنها اصلاً به proxy_redirect مربوط است.