CA ریشهٔ VPN خود را آفلاین نگه دارید و همچنان گواهی صادر کنید
کلید ریشه را از شبکه دور نگه دارید، گواهیهای برگ را با یک CA میانی امضا کنید، فهرست ابطال را بهموقع منتشر کنید و زنجیره را پیش از اتصال نخستین کارخواه بیازمایید.
VPN شما در ساعت 3 بامداد به اتصالها پاسخ میدهد، در حالی که ماشینی که گواهیهایش را امضا میکند خاموش در کشو است. کارخواهی که گواهی کارساز را اعتبارسنجی میکند هرگز با CA شما تماس نمیگیرد، بنابراین CA لازم نیست برای هیچ اتصالی در دسترس باشد. بخشی که نیاز به برنامهریزی دارد این است: روزی که باید گواهی صادر، تمدید یا باطل شود در حالی که کلید ریشه در قفل میماند.
یک اتصال در واقع چه چیزی را اعتبارسنجی میکند
وقتی کارخواه OpenVPN متصل میشود، زنجیرهٔ امضا را از گواهی برگ کارساز به بالا تا گواهی CA که از قبل به آن اعتماد دارد میپیماید، بازهٔ اعتبار را بررسی میکند و اگر پروفایل چنین بگوید، فهرست ابطال را میبیند. هرگز CA ریشهٔ شما را جستوجو نمیکند. کارساز برای گواهیهای کارخواه همین کار را آینهوار انجام میدهد. در زمان اتصال تنها برگ، میانی و بستهٔ اعتمادی که پیشتر توزیع کردهاید حاضرند.
آنچه در واقع شکست میخورد یکی از سه چیز است: کلید امضا در زمان صدور در دسترس نیست، فهرست ابطال کهنه شده است، یا بستهٔ اعتماد کارخواه از زنجیرهای که کارساز ارائه میدهد قدیمیتر است. اولی مشکل فرایند است؛ دو تای دیگر مشکلات توزیع. هیچکدام لازم نمیکند کلید ریشه آنلاین باشد، و سرویس VPN مدیریتشدهای که برای احراز هویت تونل گواهی خصوصی میخواهد، فقط اختیار امضا را به ارائهدهنده منتقل میکند. Azure نقطهبهسایت برعکس عمل میکند: گواهی ریشه را بارگذاری میکنید و گواهیهای امضاشده زیر آن معتبر شمرده میشوند، پس بپرسید چه کسی امضا میکند، چه کسی اعتبارسنجی میکند و چگونه گواهی زودتر پس گرفته میشود.
ریشه را روی میزبانی بسازید که هرگز نشانی نمیگیرد
از ریشهٔ آفلاین بهندرت استفاده میشود: برای امضای گواهی CA میانی و بعدها برای تمدید یا ابطال آن. همهٔ چیزهای دیگر یک سطح پایینتر رخ میدهند. کار ریشه را روی ماشینی انجام دهید که از شبکه دور نگه داشته میشود، در صورت امکان از یک سیستم زنده، و ثبت کنید چه کسی در اتاق بود. فرمانها OpenSSL 1.1.1 یا جدیدتر را فرض میکنند، چون -addext در ساختهای قدیمی نیست.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
-subj "/CN=Example VPN Root CA" -out root.crt \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
میانی را روی میزبان امضا بسازید و فقط درخواست آن را به ماشین آفلاین ببرید. ریشه آن درخواست را با طول مسیر صفر امضا میکند، بنابراین CA میانی میتواند گواهیهای نقطهٔ پایانی را امضا کند اما نمیتواند CA دیگری زیر خود بسازد. همان یک افزونه مانع میشود میزبان امضای بهخطرافتاده اختیاری همارز ریشه بسازد. ECDSA را فقط وقتی به کار ببرید که هر کارخواه OpenVPN 2.4 یا جدیدتر اجرا کند؛ در غیر این صورت کلیدهای RSA بسازید و جریان را یکسان نگه دارید.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
-CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt
intermediate.ext شامل basicConstraints=critical,CA:TRUE,pathlen:0، keyUsage=critical,keyCertSign,cRLSign و authorityKeyIdentifier=keyid:always است. پیش از اتصال دوبارهٔ میزبان امضا، کلید ریشه را به گاوصندوقش برگردانید. اگر ریشه باید بتواند میانی را باطل کند، آن را با openssl ca -config root.cnf -extensions intermediate_ca در برابر index.txt در سطح ریشه به جای openssl x509 -req امضا کنید تا شمارهٔ سری ثبت شود؛ سپس فهرست ریشهٔ حاصل را داخل پروفایل کارخواه بفرستید، جایی که crl-verify مبتنی بر فایل آن را در آغاز به کار میخواند. برای کارخواهها بستهای با هر دو گواهی CA بفرستید؛ یک برگ بهتنهایی در برابر ریشه اعتبارسنجی نمیشود.
برگها را از میانی صادر کنید، همراه با یک پایگاه داده
امضا با openssl x509 -req کار میکند تا وقتی به ابطال نیاز پیدا کنید، چون هیچ چیز شمارهٔ سری را ثبت نمیکند. از نخستین گواهی openssl ca را به کار ببرید تا شمارهٔ سری، انقضا و وضعیت ابطال در یک پایگاه داده زندگی کنند. فایلهای پایگاه داده را یکبار بسازید، سپس پیکربندی را به آنها اشاره دهید:
mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com
خط استفاده از کلید یک کلید ECDSA را فرض میکند؛ برای RSA keyEncipherment را اضافه کنید. به هر کارخواه نام مشترک خودش را بدهید، زیرا OpenVPN اتصال را با همان فیلد شناسایی میکند و دو لپتاپ که CN=vpn-client را شریکاند در گزارشها، در قواعد client-config-dir یا در هیچ Push هر کاربر از هم تشخیص داده نمیشوند، و شما انتسابی را از دست میدهید که تصمیم ابطال را قابل دفاع میکند. برگ را اینگونه صادر و اعتبارسنجی کنید:
openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt
کلید امضا را پشت مرز سیاست نگه دارید نه اینکه آن را روی میزبان VPN کپی کنید: سرویس کوچکی که درخواست را احراز میکند، نام مشترک را با فهرست مجاز میسنجد و تنها گواهی را برمیگرداند. هر شمارهٔ سری را ثبت کنید؛ گزارش تنها پیوند میان یک گواهی و شخصی است که آن را خواسته است.
ابطال را بدون بیدار کردن ریشه منتشر کنید
گواهیهای کارخواه را میانی باطل میکند، هرگز ریشه. فهرست ریشه فقط وقتی اهمیت دارد که یک میانی سوخته باشد. کارساز را با crl-verify به فهرست میانی اشاره دهید. CRL مبتنی بر فایل در آغاز سرویس بارگذاری میشود، پس پس از هر بازتولید دوباره بارگذاری کنید؛ شکل دایرکتوری وضعیت را در زمان اتصال میخواند و به ازای هر شمارهٔ سری یک فایل هزینه دارد.
با دو فرمان از همان پایگاه داده باطل کنید و بازتولید کنید:
openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem
سپس ساعت را بپایید. CRL فیلد بهروزرسانی بعدی را حمل میکند و وقتی آن تاریخ بگذرد، همتای اعتبارسنج فهرست را رد میکند نه اینکه نادیده بگیرد. بازتولید ماهانه با default_crl_days = 30 فرصت باقی میگذارد؛ سالانه نه. عمر کوتاهتر برگها کنترل قابلاعتمادتری است، چون ابطال فقط جایی اعمال میشود که فهرست بررسی میشود.
زنجیره را بیازمایید، سپس آیین را بنویسید
پیش از اعتماد به طرح، چهار شکست را بازتولید کنید. زنجیره را با openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt اعتبارسنجی کنید. با گواهی کارخواه منقضی وصل شوید و تأیید کنید کارساز آن را رد میکند. یک کارخواه آزمایشی را باطل کنید، دوباره بارگذاری کنید و تأیید کنید فهرست اثر میگذارد. ساعت یک میزبان را یک روز جلو ببرید، چون ساعت نادرست میتواند گواهیهایی صادر و رد کند که جای دیگر معتبر به نظر میرسند.
ریشهٔ آفلاین تنها وقتی یک کنترل است که کاغذبازی وجود داشته باشد: دو نفر نامدار برای آیین، سابقهٔ هر شمارهٔ سری امضاشده، پشتیبان رمزگذاریشدهای که جدا از ماشین نگه داشته میشود، و آزمون بازیابی روی میزبانی جداشده. در همان آیین یک میانی یدکی امضا کنید تا میزبان امضای مرده شما را ناچار نکند نیمهشب ریشه را باز کنید.
پیش از آنکه آن را تمامشده بخوانید، پنج چیز را تأیید کنید: کلید ریشه روی میزبان شبکهای نیست، کلید میانی فقط روی میزبان امضا زندگی میکند، بستهٔ کارخواه هر دو گواهی CA را دارد، CRL یک بهروزرسانی بعدی در آینده دارد، و کسی برای هر انقضا در زنجیره یک ورودی تقویم دارد. اگر یکی کم باشد، پیکربندی که آفلاین به نظر میرسد فقط مستندنشده است.