OpenVPN پشت stunnel: بستهبند را جلو بفرستید، نه پورت 1194
دو شنونده، سه پورت. بررسی کنید که هدایت به کجا میرسد، بستهبند کجا مقید میشود، به کجا وصل میشود، یک آزمون محلی چه چیزی را جا انداخت و هر دو هویت.
یک بستهبند TLS جلوی OpenVPN بگذارید و استقرار یک شنونده دوم به دست میآورد که فقط یکی از آن دو باید هرگز رو به اینترنت باشد. وقتی تونل از همان ماشین کار میکند و از بیرون شکست میخورد، هدایت معمولاً به یکی از آن دو که اشتباه است نشانه رفته است. آنچه باید همراستا شود یک زنجیره است: قاعده عمومی به بستهبند میرسد، و اتصال بکاند خود بستهبند به سوکت واقعی VPN میرسد. چهار گام این زنجیره را حمل میکنند و هر یک از آنها میتواند تحقیق را زود پایان دهد.
دو سوکت، دو مالک، یکی از آنها عمومی
بستهبند TLS را برای اتصال بیرونی خاتمه میدهد و جریان بایت رمزگشاییشده را به یک شنونده ساده OpenVPN TCP میسپارد. اینها سوکتهای جداگانه با فایلهای پیکربندی جداگانه هستند، پس ویرایش یکی دیگری را دستنخورده و ظاهراً سالم باقی میگذارد. همچنین یعنی این دو میتوانند هرگاه یکی بدون دیگری تغییر کند از هم فاصله بگیرند.
کار از خود ماشین بنابراین درباره مسیر عمومی چیز بسیار کمی اثبات میکند. اتصال مستقیم به پورت بومی بستهبند را جا میاندازد، اتصال به بستهبند روی نشانی LAN آن ترجمه را جا میاندازد، و تنها آرایش کامل سمت کلاینت همان کاری را تمرین میکند که کاربر بیرونی انجام میدهد. نامها را هم باید با دقت خواند، چون localhost یعنی میزبانی که همان جزء را اجرا میکند، نه میزبانی که تصادفاً روی آن تایپ میکنید. این تمایز را در یادداشتهایتان نگه دارید، چون آزمونی که بدون گامی که پوشش داده بود ثبت شود، به مقایسه دو چیز متفاوت دعوت میکند.
هدایت واقعاً به کجا میرسد
نگهداشتن زنجیره بهصورت چهار گام آسانتر از سه شماره پورت است، چون همان شماره میتواند در هر سر معنی متفاوتی داشته باشد. جدول را سطر به سطر بخوانید: هر سطر یک سوکت است که باید یک اتصال را بپذیرد و سپس بعدی را باز کند. وقتی سطری به همتای اشتباه نشانه رفته باشد، نشانه در ستون آخر همان چیزی است که کاربر گزارش میکند.
| Hop | Listens on | Must reach | Symptom when it points elsewhere |
|---|---|---|---|
| Client machine | A local plaintext port | The wrapper's public TLS address | Plain text offered to a TLS endpoint |
| Router forward | Public TCP 443 | The wrapper host on its translated port | Wrapper records no connection at all |
| Wrapper, server mode | Its accepted port, 8443 here | The native VPN socket on loopback | Handshake completes, then silence |
| Native VPN listener | Loopback TCP port | Its peer, over TCP only | A UDP socket behind a byte-stream relay |
قاعدهای که به جای بستهبند پورت بومی VPN را هدف میگیرد، خاتمه TLS را کاملاً جا میاندازد، که رایجترین شکل این خطاست: کلاینت دستدهی را با شنوندهای باز میکند که انتظار قاببندی OpenVPN دارد، پس اتصال ممکن است باز شود و سپس متوقف شود. پورت ترجمهشده را با فایل پیکربندی بستهبند بسنجید نه با حافظه، چون نفر بعدی که آن فایل را ویرایش میکند ممکن است شماره دیگری انتخاب کرده باشد. دو فرمان زیر هر دو سوی این پرسش را همزمان نشان میدهند.
grep -nE '^[[:space:]]*(accept|connect)' /etc/stunnel/stunnel.conf
ss -lntp | grep -E ':443|:8443|:1194'
نشانی مقیدسازی که شما را رد میکند
خط accept مقید به 127.0.0.1 فقط به خود میزبان پاسخ میدهد، پس هدایتی که به نشانی LAN میرسد نمیتواند وصل شود و کلاینت رد شدنی میبیند که شبیه مشکل فیلتر بسته به نظر میرسد. پیش از دست زدن به دیوار آتش به سوکت نگاه کنید، چون سوکت پاسخ ارزانتر است. یا بستهبند را به رابطی که هدایت هدف گرفته مقید کنید، یا آن را روی loopback نگه دارید و کاری کنید هدایت از طریق چیزی که واقعاً کار میکند به loopback برسد. اینها دو طرحاند و هر یک قاعده خودش را میخواهد.
مخلوط کردنشان همان چیزی است که باعث میشود یک بستهبند کارآمد از بیرون دسترسیناپذیر شود در حالی که هر فایل درست به نظر میرسد. بررسی زیر یک فرمان است و به پرسشی پاسخ میدهد که بازبینی قواعد دیوار آتش نمیتواند. اگر خروجی نشانی loopback را نشان دهد در حالی که هدایت نشانی LAN را هدف گرفته، اصلاح جای خط accept است نه فیلتر بسته.
ss -lntp '( sport = :8443 )'
آزمون محلی واقعاً چه چیزی را اثبات کرد
موفقیتی که بدون گامی که پوشش داده بود ثبت شود، درباره گامهای دیگر شواهد نیست. یادداشت کنید آزمون از کدام نشانی استفاده کرد و کدام فرایند پاسخ داد. سپس از بیرون شبکه تکرار کنید نه از تلفنی روی همان Wi-Fi، چون رفتار سنجاق سر بین روترها متفاوت است و اتصالی که هرگز از LAN خارج نشده میتواند کلاینتی را راضی کند بدون آنکه هدایت اصلاً دخیل باشد. فقط همان تلاش دوم مسیری را که یک غریبه طی میکند تمرین میکند.
وقتی تلاش شکست میخورد، یک اتصال را در هر دو گزارش دنبال کنید: خطوط پذیرش و اتصال بستهبند، سپس گزارش نشست خود دیمن VPN. نخستین مرزی که چیزی ثبت نمیکند جای تغییر بعدی است. وقتی OpenVPN شروع به مقایسه گزینههای همتا میکند، آن پیامها را با قواعد همان پیادهسازی بسنجید. هشدار ناسازگاری link-mtu بهطور خودکار مرگبار نیست، ثابت کردن link-mtu روی 1500 اثبات نمیکند که قطعهبندی متوقف شده، و مذاکره رمز متعلق به پیکربندی درونی OpenVPN است نه هدایت روتر.
nc -vz 127.0.0.1 1194
journalctl -u stunnel -n 50 --no-pager
این کاوشها سوکت بکاند و گزارش بستهبند را پوشش میدهند، که بکاند ردشده را از دستدهی ردشده جدا میکند. آنها را در حالی که یک تلاش در جریان است اجرا کنید نه بعد از آن. مهرهای زمانی یک تلاش همان چیزی است که مقایسه را قابل اعتماد میکند.
دو هویت، دو ترتیب شکست
گواهی بیرونی متعلق به بستهبند است و هویت درونی متعلق به OpenVPN، و ممکن است از مراجع مختلف بیایند. غیرفعال کردن هر یک از دو بررسی برای سالم جلوه دادن یک مسیر، حفاظت واقعی را با نتیجهای ظاهری معاوضه میکند. هر دو بررسی را نگه دارید و آنها را به ترتیب اشکالزدایی کنید، چون ترتیب پیامها لایه را نام میبرد: مشکل گواهی بستهبند پیش از مذاکره هر گزینه VPN ظاهر میشود، در حالی که شکست هویت درونی فقط پس از برقراری جریان ظاهر میشود.
راهنمای stunnel accept، connect و حالت کلاینت را دقیق تعریف میکند و آن بخشها به پرسش سوکت سریعتر از حدس پاسخ میدهند. وقتی هنوز نمیتوانید بگویید کدام لایه پاسخ داده، گواهیای را که پورت عمومی ارائه میدهد با فرمان زیر بخوانید. بودن گواهی بستهبند در خروجی یعنی هدایت به بستهبند رسیده، و سکوت یا خطای پروتکل یعنی نرسیده. همین یک تمایز بیش از هر بررسی دیگر اینجا وقت صرفهجویی میکند.
openssl s_client -connect vpn.example:443 -servername vpn.example </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer