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

سه شرطی که این را تعیین می‌کنند

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

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

  • انسان پشت کنسول، بدون خودکارسازی: پرسش تعاملی.
  • اجرای بدون نظارت، راز را می‌توان ذخیره کرد: فایل اعتبارنامه با حالت 0600.
  • اجرای بدون نظارت، راز را نمی‌توان ذخیره کرد: جایگزینی فرایند یا fd که یک عامل راز در آن می‌نویسد.
  • فرایند دیگری مالک کلاینت است: رابط مدیریت.

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

هر مسیر ورودی در واقع چه کار می‌کند

--auth-user-pass به‌تنهایی نام کاربری و رمز عبور را روی کنسول می‌خواهد. با گرفتن نام فایل، کلاینت خط اول را نام کاربری و خط دوم را رمز عبور می‌گیرد؛ هیچ چیز از نقل‌قول، توضیح یا نحو کلید-مقدار پشتیبانی نمی‌کند. قالب همین است، پس هر کس آن را با انتظار یک فایل INI ویرایش کند خرابش می‌کند. یک بلوک <auth-user-pass> درون‌خطی همان دو خط را داخل پروفایل نگه می‌دارد، که خود پروفایل را به یک راز تبدیل می‌کند و آن را در همان دسته‌بندی مراقبت از کلید خصوصی قرار می‌دهد.

دو مسیر دیگر یک جریان و یک سوکت هستند. OpenVPN فقط به یک توصیف‌گر فایل خواندنی نیاز دارد، پس جایگزینی فرایند، ورودی /dev/fd پشتیبانی‌شده با لوله، یا نام فایلی را که در واقع یک FIFO است می‌پذیرد. رابط مدیریت از نظر ماهیت متفاوت است: کلاینت مقادیر را از یک فرایند ناظر می‌پرسد نه اینکه خودش بخواند. این تفاوت هنگام اتصال دوباره اهمیت دارد: فایل اعتبارنامه، FIFOای که یک کمک‌کننده راز می‌تواند دوباره در آن بنویسد، و رابط مدیریت می‌توانند بدون انسان دوباره تأمین کنند؛ جایگزینی فرایند نمی‌تواند، چون توصیف‌گر در نخستین خواندن مصرف می‌شود.

فایل باید دقیقاً دو خط باشد

دو حالت خرابی بیشتر فایل‌های اعتبارنامه خراب را پوشش می‌دهد. یک ویرایشگر ویندوز پایان‌های CRLF را جا می‌گذارد، بازگشت کالسکه بخشی از رمز عبور می‌شود و سرور مقداری را که روی صفحه درست به نظر می‌رسد رد می‌کند. خط دوم خالی - خط خالی جایی که رمز عبور باید باشد - کلاینت را با رمز عبور خالی می‌گذارد، که سرور آن را رد می‌کند هرچند مقدار روی صفحه درست به نظر برسد. یک خط جدید اضافی پس از رمز عبور بی‌ضرر است. فایل را از shell بنویسید نه از یک ویرایشگر، و بایت‌ها را بررسی کنید:

install -m 600 /dev/null /etc/openvpn/client.creds
printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS" > /etc/openvpn/client.creds
od -c /etc/openvpn/client.creds | head -3

مسیر به اندازه محتوا اهمیت دارد. مسیر نسبی نسبت به پوشه کاری فرایند حل می‌شود، که برای یک سرویس به‌ندرت همان پوشه‌ای است که در آن آزمایش کرده‌اید. از مسیر مطلق استفاده کنید، فایل را متعلق به حسابی کنید که کلاینت را اجرا می‌کند، و حالت 0600 را حفظ کنید تا گروه و دیگران نتوانند آن را بخوانند. راهنمای OpenVPN 2.6 شکل‌های پذیرفته‌شده این دستور را فهرست می‌کند؛ پیش از اختراع شکل سوم آن را بررسی کنید.

پیش از سرزنش سرور، فایل را آزمایش کنید. اجرای openvpn --config client.ovpn --auth-user-pass /etc/openvpn/client.creds --verb 4 چاپ می‌کند که آیا فایل باز شد و بعداً آیا اعتبارنامه‌ها پذیرفته شدند، که به شما می‌گوید لایه بعدی را کجا تغییر دهید.

جریان‌ها، stdin و خطاهایی که تولید می‌کنند

لوله کردن رمز عبور اولین کاری است که بیشتر مردم امتحان می‌کنند و پرغافلگیری‌ترین مسیر است. جایگزینی فرایند کار می‌کند چون کلاینت فقط به یک توصیف‌گر خواندنی نیاز دارد: openvpn --config client.ovpn --verb 3 --auth-user-pass <(printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS"). فرستادن /dev/stdin فقط وقتی کار می‌کند که stdin در لحظه پرسش کلاینت هنوز باز و خواندنی باشد، که در لوله‌ای که آن را مصرف کرده است درست نیست.

ERROR: could not read Auth username from stdin دو علت متمایز دارد. در برخی کلاینت‌های 2.3.x پیام از نقص پردازش stdin می‌آمد که نسخه‌های بعدی 2.3 آن را رفع کردند، پس کلاینتی با این قدمت فقط با ارتقا بهتر می‌شود. در کلاینت امروزی همین عبارت یعنی کلاینت ورودی کنسول خواسته و stdin ترمینال نبوده است - دقیقاً وضعیت یک واحد systemd، یک کار cron، یا کانتینری که بدون -t اجرا شده است.

auth-nocache حلقه سومی اضافه می‌کند که شبیه رمز عبور خراب است. اعتبارنامه‌ها را پس از استفاده از حافظه بیرون می‌اندازد، پس اتصال دوباره‌ای که تغییر شبکه ایجاد کرده چیزی برای تکرار ندارد و پرسش بازمی‌گردد. این همان دستور است که همان‌طور که طراحی شده کار می‌کند. auth-nocache چیزی را تغییر می‌دهد که کلاینت در حافظه نگه می‌دارد، نه آنچه سرور یا ارائه‌دهنده هویت درباره حساب فکر می‌کند، پس تمام راه‌حل تأمین دوباره همان فایل است، که هنگام راه‌اندازی مجدد دوباره خوانده می‌شود - و برای اتصال مدیریت‌شده این تأمین باید از مخزن راز تأییدشده بیاید، نه از رمز عبوری در یک اسکریپت.

رابط مدیریت وقتی فرایند دیگری مالک پرسش است

کنترل‌کننده‌ای که از قبل بر تونل نظارت می‌کند می‌تواند به پرسش‌های آن هم پاسخ دهد. کلاینت را با --management 127.0.0.1 7505 اجرا کنید، خطوط وضعیت را بخوانید و مراقب >PASSWORD:Need 'Auth' username/password باشید. کنترل‌کننده با username "Auth" alice و سپس password "Auth" ... در خطوط فرمان جداگانه پاسخ می‌دهد. توکن 'Auth' شناسه درخواست را تکرار می‌کند و باید مطابقت داشته باشد، وگرنه پاسخ نادیده گرفته می‌شود و کلاینت منتظر می‌ماند.

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

شکست‌هایی که شبیه مشکلات اعتبارنامه به نظر می‌رسند

دست‌دهی TLSی که هرگز کامل نمی‌شود، یا یک VERIFY ERROR: depth=0, error=certificate signature failure، یک مشکل اعتماد است و پیش از خواندن هر نام کاربری رخ می‌دهد. کلاینت proto tcp که به یک شنونده UDP اشاره می‌کند در همان نقطه شکست می‌خورد: بسته‌ها هرگز به مرحله احراز هویت نمی‌رسند، پس هر رمز عبوری به‌واسطه تداعی اشتباه به نظر می‌رسد. تأیید گواهی را پیش از ارسال اعتبارنامه روشن نگه دارید؛ یک پرسش آشنا درباره این که چه کسی رمز عبور را می‌گیرد چیزی نمی‌گوید. زنجیره گواهی، نام مشترک و انتقال را پیش از دست زدن به اعتبارنامه بررسی کنید.

اشکالات shell در اسکریپتی که پروفایل را می‌سازد دیگر سرنخ گمراه‌کننده است. یک فاصله گمشده در [ ! -f "$file" ] باعث command not found می‌شود، اسکریپت زود متوقف می‌شود، پروفایل هرگز بازسازی نمی‌شود و کلاینت با پروفایل قبلی اجرا می‌شود. آن خطا متعلق به shell است نه احراز هویت، و هر چقدر رمز عبور را دوباره تایپ کنید پاک نمی‌شود.

هر پرسشی در این جریان این اعتبارنامه نیست. عبارت عبور کلید خصوصی، ورود به پروکسی HTTP و رمز عبور سرویس سه راز متفاوت هستند که در مراحل مختلف پرسیده می‌شوند، و عبارت عبور کلید معمولاً توسط کلاینت یا یک عامل مدیریت می‌شود نه auth-user-pass. اگر پرسش پیش از برپا شدن نشست TLS ظاهر شود، به سؤال اشتباه پاسخ می‌دهید و هیچ بازنشانی حسابی کمک نمی‌کند. وقتی پرسش اشتباه کنار گذاشته شد، بررسی‌های باقی‌مانده از قدیمی‌ترین لایه شروع می‌شوند:

  • اولین خطای پروتکل را بخوانید، نه آخرین خط اعتبارنامه را: TLS، سپس احراز هویت، سپس push.
  • تأیید کنید که فایل دو خط است، بازگشت کالسکه ندارد، و با یک مسیر مطلق ارجاع داده می‌شود.
  • تأیید کنید که پروفایل و خط فرمان درباره دستور با هم اختلاف ندارند.
  • "اعتبارنامه‌ها پذیرفته شد" را از "ترافیک جریان دارد" جدا کنید - مسیریابی و DNS لایه‌ای بعدی هستند.

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

مقالات مرتبط