OpenConnect دو تبادل جداگانه را با یک مقدار کوتاه‌عمر به هم می‌بندد: ورود وب و تونل VPN. تبادل اول HTTPS معمولی است: اعتبارنامه‌ها، یک سفر رفت‌وبرگشت SAML یا یک توکن به دروازه می‌روند و پاسخ یک کوکی احراز هویت می‌آورد. تبادل دوم همان کوکی را به همان دروازه نشان می‌دهد تا ثابت کند مرحله وب قبلاً رخ داده است، و تنها پس از آن تونل بالا می‌آید.

در هنگام ورود هیچ چیز درباره تونل مذاکره نمی‌شود. همین نکته ارزش فهمیدن دارد، چون بیشتر خطاهای اسکریپت‌نویسی گمان می‌کنند کوکی یک گذرواژه برای ذخیره است یا کلیدی که ترافیک را محافظت می‌کند، در حالی که در واقع بلیت حاملی برای یک نشست مشخص در دروازه است.

کلاینت و دروازه به ترتیب چه چیزی مبادله می‌کنند

مرحله احراز هویت شبیه یک وب‌سایت محافظت‌شده معمولی است. OpenConnect اعتبارنامه‌های کاربر را می‌فرستد یا تغییرمسیر دروازه به یک ارائه‌دهنده هویت را دنبال می‌کند، و دروازه با سندی پاسخ می‌دهد که کوکی احراز هویت را در خود جای داده است. در پروتکل AnyConnect این مقدار در سرآیند کوکی در درخواست‌های بعدی سفر می‌کند، معمولاً با نامی مانند webvpn، و راهنما آن را اعتبارنامه‌ای می‌داند که نشست را به جلو می‌برد.

مرحله دوم یک درخواست CONNECT به نقطه پایانی VPN دروازه با همان کوکی پیوسته‌است. دروازه آن را بررسی می‌کند، نشانی اختصاص می‌دهد، و کلاینت CSTP را روی TLS آغاز می‌کند، با DTLS به‌عنوان مسیر داده سریع‌تر اختیاری وقتی نشست وجود دارد. تنها در این نقطه است که پارامترهای تونل، مسیرها، تنظیمات DNS و کلیدهای ترافیک نشست برقرار می‌شوند. کوکی کلاینت را از در گذراند؛ چیزی را رمزگذاری نکرد.

همین ترتیب توضیح می‌دهد چرا openconnect --authenticate وجود دارد. آن را اجرا کنید: مرحله وب را انجام می‌دهد، بلوک کوچکی از متغیرهای پوسته مانند COOKIE، HOST، CONNECT_URL و FINGERPRINT را چاپ می‌کند و سپس پیش از ساختن هر تونلی خارج می‌شود. بعداً یک اسکریپت پوششی می‌تواند اتصال واقعی را با آن مقادیر آغاز کند، و این دقیقاً همان تفکیکی است که یک استقرار بی‌سر یا دوکانتینری لازم دارد.

کوکی حامل نشست است، نه کلید

با این مقدار همان‌گونه رفتار کنید که با شناسه نشست در یک برنامه وب رفتار می‌کردید. هرکس در طول عمرش آن را نگه دارد می‌تواند تونلی را که آن نشست مستحق آن است از دروازه بخواهد، پس محرمانه بودنش مهم است. اما کپی کردن آن ترافیک را آشکار نمی‌کند، چون محرمانگی تونل از دست‌دادن TLS و کلیدهای مشتق‌شده می‌آید، نه از رشته کوکی.

همچنین مجوز دائمی نیست. دروازه و ارائه‌دهنده هویت تعیین می‌کنند که نشست چقدر زنده بماند، و مرورگری که هنوز صفحه‌ای واردشده را نشان می‌دهد هیچ چیز درباره معتبر بودن نشست تونل نمی‌گوید. اتصال دوباره پس از انقضا یعنی تکرار مرحله وب و ساختن کوکی تازه، و این همان هدف احراز هویت دوباره است، نه مزاحمتی که با مهندسی دور زده شود.

کوکی را جانشین همگانی برای دیگر اعتبارنامه‌ها ندانید. یک ادعای SAML، یک گذرواژه مرورگر و کوکی صادرشده توسط سرویس دیگر اشیای متفاوتی با مخاطبان متفاوت‌اند، و چسباندن یکی در فیلد دیگری معمولاً در دروازه شکست می‌خورد یا بدتر، در برابر مرز اعتماد اشتباه موفق می‌شود.

انتقال کوکی بدون بر جای گذاشتن نسخه‌ها

امن‌ترین تحویل مکانیکی در لینوکس ورودی استاندارد است. --cookie-on-stdin مقدار را از stdin می‌خواند، پس کوکی هرگز در فهرست آرگومان‌های فرایند دیده نمی‌شود، جایی که هر کاربر محلی می‌تواند آن را با ps بخواند. خط لوله‌ای که در یک فرایند احراز هویت می‌کند و تونل را در فرایند دیگری تغذیه می‌کند، مقدار را در یک لوله نگه می‌دارد نه در فایل یا متغیر محیطی.

آرگومان‌ها و متغیرهای محیطی به دلایل متفاوتی ضعیف‌ترند. آرگومان در طول عمر کلاینت در جدول فرایندها دیده می‌شود و اغلب در تاریخچه پوسته می‌ماند. متغیر محیطی به فرایندهای فرزند به ارث می‌رسد، و واحدی از systemd که آن را در فایل واحد تنظیم می‌کند راز را در پیکربندی خواندنی ذخیره می‌کند. اگر به فایل نیاز دارید، آن را به حساب سرویس محدود کنید و هنگام پایان نشست پاکش کنید.

مرز اختیارات را هم آگاهانه نگه دارید. فرایندی که با ارائه‌دهنده هویت صحبت می‌کند و شاید مرورگر باز می‌کند باید با کاربری اجرا شود که صاحب آن ورود است. فرایندی که مسیرها، DNS و دستگاه تونل را پیکربندی می‌کند ممکن است اختیارات بیشتری بخواهد. اجرای کل مرورگر به‌صورت root تا کوکی‌اش برای تونلی متعلق به root در دسترس باشد معاوضه اشتباهی است، و تنظیمات مدرن OpenConnect می‌توانند مقدار را به‌صراحت از آن مرز عبور دهند.

ثبت وقایع هم همان سوءظن را می‌طلبد. خروجی پرجزئیات کلاینت، اسکریپت‌های کمکی و تشخیص‌های دروازه همه می‌توانند مطالب درخواست را بازتاب دهند، و هر سطح ثبت وقایع کوکی را پوشانده نمی‌کند. کوچک‌ترین رکورد خطای مورد نیازتان را ثبت کنید، آن را از کانال‌های مشترک بیرون نگه دارید و پیش از پیوست کردن به تیکت، نمونه‌ای پوشانده‌شده را بررسی کنید.

تأیید و انقضا در مرحله دوم

مرحله دوم هنوز باید سرور را تأیید کند. FINGERPRINT که --authenticate چاپ می‌کند یک سنجاق گواهی به شکل pin-sha256: است، و سپردن آن به فراخوانی تونل با --servercert بررسی را به همان دروازه‌ای لنگر می‌اندازد که به آن احراز هویت کرده‌اید. خاموش کردن بررسی گواهی برای ساده‌تر کردن یک اسکریپت تنها مدرک اینکه کوکی به میزبان موردنظر سپرده می‌شود را برمی‌دارد.

وقتی دروازه کوکی را رد می‌کند، راه‌حل یک دور احراز هویت جدید است، نه یک حافظه پنهان طولانی‌تر. کوکی را فقط برای عمر اتصال نگه دارید، فایل‌های موقت را هنگام خروج پاک کنید، و وقتی نشستی افشا می‌شود یا دستگاهی گم می‌شود از فرایند حذف نشست ارائه‌دهنده هویت یا دروازه استفاده کنید. کوکی ذخیره‌شده معافیتی از MFA نیست.

پیش از خودکارسازی این کار، چهار چیز را بررسی کنید: تونل با حساب درست اجرا می‌شود، کوکی از stdin می‌رسد، اثر انگشت گواهی سنجاق شده است، و نشست هنگام بسته شدن تونل دور انداخته می‌شود. اگر هر یک از اینها نباشد، خودکارسازی اعتماد به کوکی را گسترده کرده است نه جریان دستی را بازتولید.

مقالات مرتبط