← شروع آموزش

WIUNIX ACADEMY

احراز هویت OpenVPN با گواهی و Google Authenticator

صفحهٔ 2 از 5؛ مراحل قبلی و پیش‌نیازها را پیش از ادامه مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخه را انتخاب کن تا مراحل، دستورها و راه‌حل‌ها برای همان محیط نمایش داده شوند.

Ubuntu 26.04 LTSبررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

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

آی‌پی، دامنه یا پورت مثال‌ها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای به‌روز‌شده را کپی کن.

تنظیم مقادیر برای محیط من7 مقدار قابل‌تغییر
05

قدم بعدی

PAM مستقل را در فایل تازه باز کنید

فایل بعدی، احراز هویت فقط با OTP و کنترل انقضای حساب سیستم‌عامل است. common-auth یا pam_unix را به بخش auth اضافه نکنید؛ آن‌ها گذرواژهٔ لینوکس می‌خواهند و روش را عوض می‌کنند. pam_unix در بخش account انقضای حساب را کنترل می‌کند. قفل‌بودن گذرواژه یا nologin به‌تنهایی ابطال VPN نیست؛ برای قطع دسترسی حساب را منقضی یا گواهی را باطل کنید.

bash

VM مستقل پایلوت؛ ترمینال خصوصی برای ثبت دستگاه

set -eu
sudo test ! -e '/etc/pam.d/academy-mfa'
sudo test ! -L '/etc/pam.d/academy-mfa'
sudo sh -c 'umask 022; set -C; : > "/etc/pam.d/academy-mfa"'
sudo nano '/etc/pam.d/academy-mfa'
از کجا بدانم درست انجام شد؟

فایل PAM تازه آماده است؛ PAM ورود سیستم و SSH دست‌نخورده مانده‌اند.

06

قدم بعدی

TOTP را بدون مسیر جایگزین گذرواژه الزامی کنید

noskewadj یادگیری خودکار اختلاف زمان را خاموش می‌کند؛ به‌جای گسترش offset ساعت را اصلاح کنید. nullok، مهلت بدون کد، no_strict_owner، مجوز بازتر و allow_readonly فعال نیستند. ماژول برای ثبت مصرف کد و محدودیت تلاش باید وضعیت seed خصوصی را بنویسد؛ دیسک پر یا read-only باید اتصال را متوقف کند.

این کنترل، داشتن seed را در کنار کلید خصوصی گواهی بررسی می‌کند و ورود به حساب Google نیست. خط account نیز لازم است؛ auth-pam مدیریت حساب PAM را جدا فراخوانی می‌کند.

text · /etc/pam.d/academy-mfa

VM مستقل پایلوت؛ ترمینال خصوصی برای ثبت دستگاه

auth required pam_google_authenticator.so noskewadj
account required pam_unix.so
از کجا بدانم درست انجام شد؟

فقط کد شخصی معتبر و حساب منقضی‌نشده از این PAM عبور می‌کنند.

معنای فیلد password کلاینت را روشن کنید

افزونه به‌طور صریح prompt شروع‌شونده با Verification را به PASSWORD در OpenVPN نگاشت می‌کند. در این پشتهٔ OTP-only، فقط شش رقم کد جاری با حفظ صفر اول در فیلد password وارد می‌شود. کد بازیابی یک جایگزین یک‌بارمصرف است، نه گذرواژهٔ دائمی. برای استفادهٔ عادی static-challenge یا فایل ذخیرهٔ اطلاعات ورود لازم نیست.

روش password+OTP متفاوت است: گزینهٔ forward_pass در ماژول Google، مقدار ترکیبی گذرواژه و کد را تفکیک و گذرواژه را به pam_unix با use_first_pass منتقل می‌کند. افزودن سادهٔ pam_unix همان نتیجه را نمی‌دهد. static-challenge و نگاشت OTP نیز قرارداد دیگری دارند. این الگوها را بی‌آزمون ترکیب نکنید. auth-gen-token در این راهنما فعال نیست؛ اتصال دوباره و renegotiation ممکن است کد تازه بخواهند و کلاینت غیرتعاملی قطع شود. GUI واقعی کاربران را پیش از rollout امتحان کنید.

07

قدم بعدی

هوک تطبیق نام گواهی را آماده کنید

auth-pam حساب ارسالی را می‌سنجد، اما آن حساب را خودکار به گواهی مشخصی مقید نمی‌کند. هوک بعدی فقط خط اول فایل موقت OpenVPN را می‌خواند و با common_name اصلی گواهی، دقیق و حساس به بزرگی حروف، مقایسه می‌کند. این هوک گذرواژه را نمی‌خواند، در argv نمی‌گذارد و لاگ نمی‌کند. نام یا فایل غایب رد می‌شود.

فقط شناسهٔ ASCII با طول ۱ تا ۳۲، هماهنگ با کنترل عمومی نام کاربر، پذیرفته است. CN هر فرد باید در همین فضای نام منحصربه‌فرد باشد. duplicate-cn، گواهی مشترک، username-as-common-name و اختیاری‌کردن گواهی مجاز نیستند.

bash

VM مستقل پایلوت؛ ترمینال خصوصی برای ثبت دستگاه

set -eu
sudo sh -c 'umask 022; set -C; : > "/srv/academy-openvpn-mfa/bind-cn.py"'
sudo nano '/srv/academy-openvpn-mfa/bind-cn.py'
از کجا بدانم درست انجام شد؟

فایل هوک تازه بدون بازنویسی فایل قبلی آماده است.

08

قدم بعدی

نام کاربر را با CN اصلی مقایسه کنید

OpenVPN همهٔ verifierهای تنظیم‌شده را اجرا می‌کند؛ شکست این هوک اتصال را رد می‌کند، حتی اگر PAM کد را پذیرفته باشد. خروجی فقط exit status است. مالک هوک root است؛ daemon کاهش‌یافته می‌تواند اجرا کند، ولی امکان تغییر ندارد. استفاده از فایل از ارسال OTP در محیط اسکریپت جلوگیری می‌کند.

python · /srv/academy-openvpn-mfa/bind-cn.py

VM مستقل پایلوت؛ ترمینال خصوصی برای ثبت دستگاه

#!/usr/bin/python3
import os
import re
import sys

def main():
    if len(sys.argv) != 2:
        return 1
    try:
        with open(sys.argv[1], 'rb') as stream:
            raw = stream.readline(128)
        name = raw.rstrip(b'\r\n').decode('ascii')
    except (OSError, UnicodeError):
        return 1
    if not re.fullmatch(r'[A-Za-z_][A-Za-z0-9_-]{0,31}', name):
        return 1
    return 0 if name == os.environ.get('common_name', '') else 1

raise SystemExit(main())
از کجا بدانم درست انجام شد؟

نام نامنطبق یا نامعتبر رد می‌شود و دادهٔ محرمانه خروجی ندارد.

09

قدم بعدی

PKI بررسی‌شده را از مسیر خصوصی وارد کنید

با فرایند CA موجود، فایل‌های ca.crt، server.crt، server.key، crl.pem و tls-crypt.key را به پوشهٔ pki خصوصی منتقل کنید. کلید امضای CA روی VM VPN قرار نگیرد. گواهی سرور باید EKU سرور و CN برابر vpn-server داشته باشد؛ گواهی پایلوت EKU کلاینت و CN دقیقاً academyvpn می‌گیرد. کلید سرور برای اجرای بدون حضور اپراتور باید با سیاست مصوب حفاظت از کلید سازگار باشد. کلید خصوصی کلاینت روی همان دستگاه می‌ماند.

انتقال از کانال احرازشده و خصوصی باشد، نه فرم وب. کلیدها متعلق به root و ۰۶۰۰، گواهی عمومی و CRL با مجوز ۰۶۴۴ باشند. پس از کاهش امتیاز، مسیر CRL باید قابل پیمایش و بازخوانی بماند و کلید خصوصی همچنان محافظت شود. این پنل فایل موجود را کنترل می‌کند، نه صدور گواهی یا کاهش اعتبارسنجی. مسئول تمدید و ابطال CA و مانیتورینگ انقضا مشخص باشد.

bash

VM مستقل پایلوت؛ ترمینال خصوصی برای ثبت دستگاه

set -eu
sudo chmod 0755 '/srv/academy-openvpn-mfa/pki'
sudo chown root:root '/srv/academy-openvpn-mfa/pki/'*
sudo chmod 0600 '/srv/academy-openvpn-mfa/pki/server.key' '/srv/academy-openvpn-mfa/pki/tls-crypt.key'
sudo chmod 0644 '/srv/academy-openvpn-mfa/pki/ca.crt' '/srv/academy-openvpn-mfa/pki/server.crt' '/srv/academy-openvpn-mfa/pki/crl.pem'
sudo openssl verify -purpose sslserver -CAfile '/srv/academy-openvpn-mfa/pki/ca.crt' '/srv/academy-openvpn-mfa/pki/server.crt'
sudo openssl x509 -in '/srv/academy-openvpn-mfa/pki/server.crt' -noout -subject -ext extendedKeyUsage -checkend 86400
sudo openssl crl -in '/srv/academy-openvpn-mfa/pki/crl.pem' -noout -issuer -lastupdate -nextupdate
sudo openssl crl -in '/srv/academy-openvpn-mfa/pki/crl.pem' -verify -CAfile '/srv/academy-openvpn-mfa/pki/ca.crt' -noout
sudo chmod 0755 '/srv/academy-openvpn-mfa/bind-cn.py'
sudo python3 -m py_compile '/srv/academy-openvpn-mfa/bind-cn.py'
از کجا بدانم درست انجام شد؟

زنجیره و کاربرد سرور و امضای CRL معتبرند؛ CN، EKU، تاریخ و مجوز کلیدها کنترل شده‌اند.

همهٔ آموزش‌های آکادمی ↗