گواهیهای gNSI — چرخه حیات گواهی TLS در Cisco IOS XR
مشکل
مجوزدهی (Authz) و مسیردهی (Pathz) کنترل میکنند که کلاینتها در بستر gRPC و gNMI چه اقداماتی میتوانند انجام دهند، اما تمامی این موارد به تنظیم صحیح TLS وابسته است. گواهیها (Certificates) منقضی میشوند. بستههای اعتماد (Trust Bundles) قدیمی میشوند. لیستهای ابطال گواهی (CRLs) نیاز به بهروزرسانی دارند. و هر یک از این تغییرات باید بدون قطع شدن سرور gRPC انجام شود. به طور سنتی، مدیریت منابع TLS در IOS XR به معنای کپی کردن فایلهای PEM در مسیرهای مشخص و امید به قرارگیری فایلهای صحیح در جای درست بود. هیچ API استانداردی برای چرخش گواهیها (Certificate Rotation)، هیچ قابلیت بازگشتی (Rollback) در صورت بروز خطا و هیچ روش تمیزی برای مدیریت چندین پروفایل TLS بر روی یک دستگاه وجود نداشت.
Certz چیست؟
گواهینامههای gNSI این مشکل را با دستهبندی تمام موارد مورد نیاز TLS درپروفایلهای SSL (SSL Profiles)حل میکند. هر پروفایل شامل موارد زیر است:
- گواهی و کلید خصوصی (Private Key)— مستندات احراز هویت سرور
- بسته اعتماد (Trust Bundle)— زنجیره گواهی مرجع (CA) که کلاینتها برای اعتبارسنجی استفاده میکنند
- بسته CRL— لیستهای ابطال گواهی (Certificate Revocation Lists)
- سیاست احراز هویت (Authentication Policy)— برای TLS متقابل و الگوهای مشابه
به جای کپی کردن فایلها، یک کنترلر (Controller) مطالب جدید را از طریق یکچرخش (Rotate)فراخوانی رویه از راه دور (RPC) مرحلهبندی میکند، آن را اعتبارسنجی کرده و نهایی میکند — یا جریان را برای بازگشت به حالت قبل (Roll back) رها میکند. در IOS XR،EMSdقابلیت Certz را پیادهسازی کرده و پروفایلها را در مسیر/misc/config/grpc/gnsi/certz/ssl_profiles/.
این مقاله به بررسی پروفایلهای SSL، شش RPC، دو جریان چرخش (Rotation) سرتاسری (CSR تولید شده توسط روتر در مقابل کلید تولید شده توسط ایستگاه کاری) وgrpcurlمثالها میپردازد. احراز هویت در سطح سرویس توسط Authz؛ و احراز هویت در سطح مسیر توسط Pathz مدیریت میشود. Certz امنیت لایه انتقال (Transport) را قابل اعتماد نگه میدارد.
در چارچوب AAA، بخش Certz نقشاحراز هویت (Authentication)را برای مدیریت gRPC ایفا میکند؛ این بخش مسئول مدیریت متریال TLS است که پیش از اجرای هرگونه تصمیم Authz/Pathz،هویتکلاینت را تأیید میکند. (بخش همتای آن یعنی Credentialz نقش مشابهی را برای بخش SSH ایفا میکند.)
گواهیها (Certificates) در مقایسه با gNOI cert
سیستمعامل IOS XR مدتهاست که از gNOI پشتیبانی میکند cert.proto برای عملیات گواهی (Certificate). پروتکل Certz تکاملیافته gNSI در OpenConfig است و جایی است که قابلیتهای جدید در آن پیادهسازی میشوند. جدول زیر نشان میدهد که چرا اپراتورها باید از رابط قدیمی به سمت Profiles و Rotate مهاجرت کنند:
| موضوع | gNOIcert.proto(قدیمی) |
gNSIcertz.proto |
|---|---|---|
| سازمان | شناسه گواهی (Certificate ID) برای هر برگ؛ بهروزرسانیهای بسته CA، یک بسته واحد را بازنویسی میکنند | تمام موارد PKI تحت یک نام گروهبندی شدهاندپروفایل SSL |
| درخواست امضای گواهی (CSR) | عدم وجود SAN در پارامترهای CSR در برخی از استکها | نام جایگزین موضوع (SAN)بخشی ازپارامترهای CSR (CSRParams) |
| سطح RPC | نصب / بارگذاری CA / ابطال به عنوانجداگانهRPCها | یک استریمینگچرخش (Rotate)حمل گواهی، کلید، بسته اعتماد (Trust Bundle) و CRL دردرخواست آپلود (UploadRequest) |
| الگوریتمها | تاریخچه مبتنی بر RSA | RSA, ECDSA, Ed25519پشتیبانی شده |
جهتگیری صنعت، استفاده از gNOIcert.protoرا منسوخ (Deprecated) میداند. در پیادهسازیهای جدید باید از Certz استفاده شود.
پروفایلهای SSL در IOS XR
پروفایل SSL (SSL Profile) چیست؟
پروفایل SSL یک مکان واحد است که روتر (Router) هنگام راهاندازی gRPC، برای یافتن «هر آنچه TLS نیاز دارد» به آن مراجعه میکند:
- مواد احراز هویت (Authentication Material)— گواهینامه (Certificate) برگ و کلید خصوصی (Private Key) آن
- لنگرهای اعتماد (Trust Anchors)— زنجیره گواهی CA که کلاینتها بر اساس آن اعتبارسنجی میکنند
- ابطال (Revocation)— دستههای CRL
- سیاست (Policy)— قلابهای اختیاری برای TLS متقابل (برخی فیلدها مختص پلتفرم باقی میمانند؛ یادداشتهای انتشار (Release Notes) را بررسی کنید)
پروفایل پیشفرض (Default Profile):gNxI
سرور gRPC در IOS XR از شناسه پروفایل (Profile ID)gNxIاستفاده میکند مگر اینکه به شکل دیگری پیکربندی شده باشد. درRotateCertificateRequest, خالی گذاشتنssl_profile_idمعمولاً بهgNxI.
پروفایل متصل به سرور فعال gRPC قابل حذف نیست —DeleteProfileیک خطا برمیگرداند.
ماندگاری روی دیسک (On-disk Persistence)
سیستمعامل IOS XR پروفایلهای SSL Certz را در مسیر زیر ذخیره میکند:
/misc/config/grpc/gnsi/certz/ssl_profiles/<ssl_profile_id>/
متادیتاهایی مانندنسخه (version)وتاریخ ایجاد (created_on)در کنار فایلهای PEM به صورت JSON ذخیره میشوند. همگامسازی (Synchronization) پردازنده رزرو (Standby RP) برای تمامی موارد تحت مسیر/misc/config/grpc/gnsi/از طریق RDSFS انجام میشود. فرآیند تغییر مسیر (Failover) و راهاندازی مجدد EMSd به حفظ یکپارچگی آن درخت دایرکتوری وابسته است.
RPCهای Certz
| RPC | نوع | عملکرد |
|---|---|---|
GetProfileList |
یکطرفه (Unary) | فهرست کردن تمامssl_profile_idموجود روی دستگاه |
AddProfile |
یکطرفه (Unary) | ایجاد یک پوسته پروفایل خالی؛ دادهها از طریقRotate |
CanGenerateCSR |
یکطرفه (Unary) | بررسی اینکه آیاCSRParamsارائه شده پشتیبانی میشوند |
Rotate |
جریان دوطرفه (Bidirectional stream) | تولید اختیاری CSR،UploadRequestبارگذاری دادهها (Payloads)، سپسfinalize_rotation |
DeleteProfile |
یکطرفه (Unary) | حذف پروفایلی که به سرور gRPC فعال متصل نیست |
GetIntegrityManifest |
یکطرفه (Unary) | مانیفست یکپارچگی / RIM (اغلبپیادهسازی نشده (Unimplemented)در نسخههای فعلی IOS XR) |
توجه:توضیح سرویس OpenConfig بیان میکند که در هر لحظه تنها یک RPC از نوع Certz باید اجرا شود. دسترسی را به همان روشی که برای Authz Rotate یا Pathz Rotate انجام میشود، سریالسازی (Serialize) کنید.
در نسخه 25.3.1:
grpcurl … list gnsi.certz.v1.Certzنشان میدهدGetIntegrityManifest، اما یک فراخوانی واقعی برمیگرداندکد: پیادهسازی نشده (Unimplemented). قابلیت بازتاب (Reflection) توصیفگر را تبلیغ میکند؛ اما تضمین نمیکند که EMSd این RPC را پیادهسازی کرده باشد. همیشه با یک فراخوانی واقعی بررسی کنید.
نحوه عملکرد Rotate RPC
مدل تراکنش (Transaction Model)
Rotate یک تراکنش استریمشده برای یک مورد استssl_profile_id:
- جریان (Stream) را برای یک پروفایل (Profile) واحد باز کنید.
- ارسال اختیاری
generate_csr، سپس یک یا چندگواهینامه (Certificates)پیامها (UploadRequestبا مقادیر تکراریEntity)، سپسfinalize_rotation. - تا زمانی که finalize دریافت نشود، متریال جدید به عنوان کاندیدا (Candidate) باقی میماند. برای فعالسازی بازگشت به حالت قبل (Rollback)، جریان را بدون finalize رها کنید.
- استفاده از
force_overwrite: trueبرای جایگزینی یکنسخه (Version)موجود. بدون آن، استفاده مجدد از یک نسخه رد میشود — پروتو (Proto) این مورد راAlreadyExistsنامگذاری میکند، اما در IOS XR 24.4.x به صورتInvalidArgument: certificate: same version sentنمایش داده میشود (مثال کامل در زیر).
رفتار IOS XR (24.4.x)
در ایمیجهای آزمایشگاهی اخیر،هرRotateCertificateRequestدر جریان (Stream) — شامل پیام نهاییسازی (finalize) — به همانsslProfileIdنیاز دارد. حذف آن در مرحله نهاییسازی منجر به خطای زیر میشود:
InvalidArgument: Not expecting rotate RPC for multiple SSL profiles in single stream
لطفاً متن ورودی خود را ارسال کنید تا طبق قوانین و دستورالعملهای تعیینشده، ترجمه آن را انجام دهم.
{"sslProfileId":"lab-profile-1","generateCsr":{...}}
{"sslProfileId":"lab-profile-1","certificates":{...}}
{"sslProfileId":"lab-profile-1","finalizeRotation":{}}
استریمینگ با استفاده از grpcurl
ابزار grpcurl چندین شیء JSON را در ورودی استاندارد (stdin) میپذیرد — یکیRotateCertificateRequestدر هر خط — برای عملیات Rotate:
grpcurl … -d '@' … gnsi.certz.v1.Certz.Rotate <<'EOF'
{... first request...}
{... second request...}
EOF
استفاده-d '@با استفاده از کوتیشنهای تکی تا grpcurl از ورودی استاندارد (stdin) بخواند.
چیستبازنویسی اجباری (force_overwrite)در واقع چه کاری انجام میدهد
توضیح proto در موردforce_overwriteمیگوید استفاده مجدد از یکنسخه (version)بدون آن، خطایAlreadyExistsرا برمیگرداند. در سیستمعامل IOS XR نسخه 24.4.x همین وضعیت به شکل زیر ظاهر میشود:
ERROR:
Code: InvalidArgument
Message: certificate: same version sent
تنظیمforceOverwrite": trueدر هر پیام غیر نهایی (non-finalize) اجازه میدهد تا هماننسخهبدون تغییر مقدار دوباره پخش (replay) شود — که هنگام تلاش مجدد پس از یک خطای گذرا (transient error) در طول بررسی آزمایشگاهی بسیار کاربردی است.
پشتیبانی از IOS XR
| نسخه (Release) | تغییرات |
|---|---|
| 7.8.1 | زیرساخت پروفایل SSL برای Certz معرفی شد. |
| 24.1.1 | چرخش RPC،سرویس grpc gnsi با شناسه پروفایل SSL (ssl-profile-id)رابط خط فرمان (CLI)، قابلیت تنظیم نام دامنه (CN) برای تماس ورودی (dial-in). |
| 24.4.1 | پشتیبانی از TLS 1.3. |
| 25.4.1 | نسخه قدیمی (Legacy)/misc/config/grpcمسیرهای PEM منسوخ شدند — پروفایلهای SSL مسیر آینده هستند. |
پلتفرمها: خانوادههای Cisco 8000، NCS 5500 و ASR 9000. شماره قطعه (SKU) دقیق و PI/SMU را در یادداشتهای انتشار (Release Notes) تأیید کنید.
مرجع رابط خط فرمان (CLI) برای IOS XR
| دستور پیکربندی (Configuration command) | عملکرد دستور |
|---|---|
grpc gnsi service certz ssl-profile-id |
اتصال سرور gRPC به یک پروفایل SSL Certz |
no grpc gnsi service certz ssl-profile-id |
لغو اتصال Certz؛ بازگشت به حالت پیشفرض gNOIcert.protoیا مسیرهای PEM مربوط به trustpoint قدیمی |
| دستور Show / exec | آنچه نمایش میدهد |
|---|---|
show grpc certificate |
موضوع گواهی فعال (Active Certificate)، صادرکننده، تاریخهای اعتبار و زنجیره گواهی |
show gnsi state |
وضعیت زیرسیستم gNSI (رشتههای Certz، Acctz و وضعیت RDSFS) |
show tech-support gnsi |
بسته کامل عیبیابی gNSI (تمامی سرویسها) |
راهاندازی عملی (Hands-on Setup)
پیشنیازها
- روتر IOS XR با قابلیت gRPC فعال (نسخه 24.1.1 یا بالاتر برای Certz)
- grpcurl, jq، و OpenSSL نصب شده
- پروتکلهای OpenConfig gNSI شبیهسازی (Clone) و چیدمان شدهاند به طوری که
$GNSI_IMPORT/certz/certz.protoحل (Resolve) میشود:
git clone https://github.com/openconfig/gnsi.git /tmp/gnsi
mkdir -p./certz-import/certz
cp /tmp/gnsi/certz/certz.proto./certz-import/certz/certz.proto
export GNSI_IMPORT="$PWD/certz-import"
certz.protoفقط importهاgoogle/protobuf/any.proto، کهgrpcurlبه صورت داخلی ارائه میدهد — نیازی به آمادهسازی فایلهای دیگر نیست.
محیط (Environment)
export GNSI_IMPORT="${GNSI_IMPORT:-$PWD/certz-import}"
export XR="${XR:-198.51.100.1:57400}"
export XR_USER="${XR_USER:-cisco}"
export XR_PASS="${XR_PASS:?set XR_PASS for the IOS XR account}"
GRPC_MD=(-H "username:${XR_USER}" -H "password:${XR_PASS}")
PROTO_CERTZ="certz/certz.proto"
${XR_PASS:?…}اگر متغیرXR_PASSصادر (Export) نشده باشد، شل (Shell) را با یک خطای واضح متوقف میکند تا کاربر بهطور تصادفی رمز عبور خالی به دستگاه ارسال نکند.
فقط برای محیط آزمایشگاهی:مثالهای زیر از
-plaintextاستفاده میکنند زیرا هدف آنها یک سرور gRPC است که هنوز هیچ پروفایل گواهی (Certz Profile) به آن متصل نشده است. هنگامی که یک پروفایل فعال و به سرور gRPC متصل شد (grpc gnsi service certz ssl-profile-id)، جایگزین کنید-plaintextبرای-cacert، و اضافه کنید-cert/-keyاگر احراز هویت دوطرفه TLS فعال باشد.
آنچه در این دوره عملی پوشش داده میشود (و آنچه پوشش داده نمیشود)
هر ردیف در زیر مشخص میکند که آیا یک بخش از این تمرین عملی تنها باgrpcurlتکمیل میشود یا به یک کلاینت پیشرفتهتر / مرحله خارج از باند (out-of-band) نیاز دارد:
| بخش | آیا با grpcurl به صورت سرتاسری (End-to-End) کار میکند؟ | یادداشتها |
|---|---|---|
| لیست بازتاب (Reflection list) | بله | هر شش RPC با موفقیت پاسخ دادند |
GetProfileList, AddProfile, DeleteProfile |
بله | پاسخهای خالی و پر هر دو نمایش داده شدند |
CanGenerateCSR |
بله | موفقیت وفقدان CNشکست هر دو نمایش داده شدند |
GetIntegrityManifest |
No | سرور بازمیگرداندUnimplementedدر IOS XR 24.4.x — مستند شده است |
| آزمایشگاه CA + گواهی برگ (Leaf) امضا شده (OpenSSL) | بله | CA دو لایه، گواهی برگ به صورت محلی امضا شده |
جریان B— کلید تولید شده توسط کلاینت + زنجیره تو در توRotate |
بله | زنجیره کامل + نهاییسازی، به همراه موجودیت اختیاری Trust Bundle |
| جریان A— CSR تولید شده توسط هدف (Target) | مرحله CSR بله، Rotate کامل خیر | نمایش یک محدودیت مستند شده درgrpcurlاستفاده در محیط عملیاتی (Production) نیازمند کلاینت Python/Go است |
| Rollback (بستن استریم قبل از نهاییسازی) | بله | کد: Unknown / EOFسیگنال بازگشت (Rollback) است |
forceOverwriteمعناشناسی (Semantics) |
بله | یکساننسخهبا موفقیت دوباره تلاش شد |
| تأیید gNMI (پس از اتصال) | جزئی | شمارندههای Authz همیشه پر هستند؛ زیردرخت وضعیت Certz فقط پس از اتصال CLI |
واژگان PEM، Base64 و CSR
PEM یک پاکت متنی (text envelope) است که-----BEGIN …-----در اطراف یک DER blob قرار میگیرد. درcertz.protoفیلدهای Certificate و CSR از نوعbytesهستند؛ grpcurl این موارد راbytesبه عنوان Base64 استاندارد بر روی بایتهای فایل PEM نمایش میدهد.
دو الگوی CSR در سراسر آن مشاهده میشود:
- CSR تولید شده توسط هدف (Target-generated CSR)— روتر جفتکلید (Key Pair) و CSR را ایجاد میکند. CSR را با یک CA امضا کنید، سپس فقط گواهی (Certificate) امضا شده را بارگذاری کنید. کلید خصوصی (Private Key) روی روتر باقی میماند.
- CSR تولید شده توسط کلاینت (Client-generated CSR)— کلید و CSR را روی یک ایستگاه کاری ایجاد کنید، با یک CA امضا کنید، سپس هم گواهی امضا شده و هم کلید خصوصی را از طریق UploadRequest بارگذاری کنید.
درخواست بارگذاری (UploadRequest).
عملی: فهرست کردن RPCها
فهرست سرویسهای صادر شده (Reflection)
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
"${XR}" list gnsi.certz.v1.Certz
لطفاً متن ورودی خود را برای ترجمه ارسال کنید تا طبق قوانین و دستورالعملهای تعیینشده، ترجمه آن را انجام دهم.
gnsi.certz.v1.Certz.AddProfile
gnsi.certz.v1.Certz.CanGenerateCSR
gnsi.certz.v1.Certz.DeleteProfile
gnsi.certz.v1.Certz.GetIntegrityManifest
gnsi.certz.v1.Certz.GetProfileList
gnsi.certz.v1.Certz.Rotate
فراخوانیهای رویهای از راه دور (RPCs) یکطرفه: پروفایلها، بررسیهای CSR و پاکسازی
دریافت لیست پروفایل (GetProfileList)
تمام شناسههای پروفایل (Profile ID) موجود بر روی دستگاه را بازمیگرداند:
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '{}' \
"${XR}" gnsi.certz.v1.Certz.GetProfileList
هنگامی که هنوز هیچ پروفایلی (Profiles) ایجاد نشده باشد، پاسخ یک شیء خالی است. در برخی از نسخهها، این فراخوانی تا زمانی که درختssl_profilesروی دیسک ایجاد نشود با خطا مواجه میشود؛ اگر خطای داخلی مبنی بر نبود مسیر (Path) ظاهر شد، ابتدا دستورAddProfileرا اجرا کرده و دوباره تلاش کنید.
پاسخ روتر (هنوز پروفایلی وجود ندارد):
{}
پس از چندAddProfileفراخوانی (در ادامه ببینید)، همان RPC لیست تکمیلشده را بازمیگرداند:
{
"sslProfileIds": [
"lab-profile-1",
"lab-temp"
]
}
افزودن پروفایل (AddProfile)
یک پوسته پروفایل (Profile) خالی ایجاد میکند. یک شناسه (ID) مناسب برای مدیر شبکه انتخاب کنید:
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '{"sslProfileId":"lab-profile-1"}' \
"${XR}" gnsi.certz.v1.Certz.AddProfile
پاسخ روتر (موفقیت یک شیء JSON خالی برمیگرداند):
{}
اجرای مجددافزودن پروفایل (AddProfile)برای همان شناسه (ID) نتیجه زیر را برمیگرداند:
ERROR:
Code: InvalidArgument
Message: Profile:lab-profile-1 already exists
بیشتر اسکریپتهای آزمایشگاهی (Lab scripts) دستورAddProfileرا با|| trueپوشش میدهند تا خطای تکراری باعث توقف ادامه گردش کار (Workflow) نشود.
امکان تولید درخواست امضای گواهی (CSR)
پیش از آنکه برای صدور CSR در داخل Rotate به روتر تکیه کنید، بررسیهای لازم را انجام دهید. این کار از باز کردن یک جریان (Stream) که در نهایت مشخص شود مجموعه (Suite) آن پشتیبانی نمیشود، بهصرفهتر است. توجه داشته باشید:commonNameاجباری است — حذف آن منجر به بازگشت خطایInvalidArgument.
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '{
"params": {
"csrSuite": "CSRSUITE_X509_KEY_TYPE_ECDSA_PRIME256V1_SIGNATURE_ALGORITHM_SHA_2_256",
"commonName": "router.example.com",
"organization": "Lab",
"country": "US"
}
}' \
"${XR}" gnsi.certz.v1.Certz.CanGenerateCSR
پاسخ روتر (Router response)
{
"canGenerate": true
}
RSA-2048 / SHA-256همان مقدار را برمیگرداندcanGenerate: trueدر IOS XR 24.4.x. با حذفنام عمومی (commonName)خروجیها:
ERROR:
Code: InvalidArgument
Message: CSR parameters does not have common name
هنگامی کهcanGenerate is false، از مسیر تولید شده توسط کلاینت استفاده کنید: کلید (Key) و CSR را روی یک ایستگاه کاری بسازید و از طریق آن بارگذاری کنیدچرخش (Rotate).
GetIntegrityManifest
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '{}' \
"${XR}" gnsi.certz.v1.Certz.GetIntegrityManifest
چندین نسخه IOS XR بازمیگردانندپیادهسازی نشده (Unimplemented)در اینجا، با وجود اینکه Reflection لیست RPC را نمایش میدهد. در نسخه 24.4.x، پاسخ دقیق به این صورت است:
ERROR:
Code: Unimplemented
Message: unknown method GetIntegrityManifest for service gnsi.certz.v1.Certz
این یک شکاف (Gap) در سمت سرور است، نهgrpcurlپیکربندی نادرست (Misconfiguration).
حذف پروفایل
پروفایلی را حذف میکند کهبهسرور فعال gRPC متصل نیست:
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '{"sslProfileId":"lab-temp"}' \
"${XR}" gnsi.certz.v1.Certz.DeleteProfile
پاسخ روتر در صورت موفقیت:
{}
پاسخهای خطای رایج در IOS XR 24.4.x:
ERROR:
Code: InvalidArgument
Message: Profile: nonexistent-xyz does not exist: <nil>
شناسه پروفایل پیشفرض (Default Profile ID)gNxIتنها زمانی که Certz واقعاً به سرور gRPC متصل (Bound) شده باشد، شناسایی میشود؛ تا پیش از آن، حذف کردن آن همان خطای “does not exist” را برمیگرداند، به جای اینکه پیام توصیفیتر “bound to active server” را نمایش دهد.وجود نداردخطا به جای پیام توصیفیتر “bound to active server”.
کار عملی: چرخش سرتاسری (End to End)
ادامه از محیط راهاندازی عملی (Hands-on Setup) در محیط بالا. بخشهای زیر شما را با مطالب واقعی گواهینامه (Certificate) آشنا میکنند. با یک آزمایشگاه کوچک PKI شروع کنید تا بتوانید CSRها را بدون درگیر کردن یک CA عملیاتی امضا کنید، سپس هر دو سبک چرخش (Rotation) را امتحان کنید.
با کدام جریان (Flow) شروع کنیم:بیشتر اپراتورها کلیدها را روی یک ایستگاه کاری تولید کرده و آنها را از طریق Certz ارسال میکنند — که این همانجریان Bدر زیر است.جریان A(درخواست امضای گواهی یا CSR تولید شده توسط هدف) زمانی مفید است که کلید خصوصی (Private Key) هرگز نباید از روتر خارج شود، اما
grpcurlنمیتواند جریان چند مرحلهای کامل را به صورت تعاملی تکمیل کند — برای استفاده عملیاتی از آن جریان، به یک کلاینت برنامهنویسی شده (Python, Go) نیاز است.
جریان پیام چرخشی (Rotate Message Flow)
| مرحله | فیلد پیام (یکی از rotate_request) |
عملکرد |
|---|---|---|
| 1 (اختیاری) | generate_csr |
هدف تولید میکندکلید + CSR; PEM CSR در جریان پاسخ بازگردانده میشود |
| 2 | گواهیها |
درخواست بارگذاری (UploadRequest): یک یا چند موردموجودیت (Entity)مقادیر (برگ گواهی، بسته اعتماد، CRL،…) |
| آخرین | نهاییسازی چرخش (finalize_rotation) |
تایید (Commit). حذف یا لغو کردن باعث بازگشت به حالت قبل (Rollback) میشود |
هر کدامموجودیتشامل:
نسخه— رشته مبهم (Opaque string) نمایش داده شده در تلهمتری (Telemetry)تاریخ ایجاد— ثانیههای سپری شده از مبدأ یونیکس (Unix epoch seconds)- دقیقاً یک شاخه از موجودیت
یکی از (oneof)(زنجیره گواهی (certificateChain),بسته اعتماد (trustBundle)و غیره)
ایجاد یک Lab CA دو لایه (یکبار برای OpenSSL)
شبکههای سازمانی (Enterprise networks) تقریباً هرگز گواهیهای (Certificates) روتر را مستقیماً با یک ریشه (Root) با طول عمر بالا امضا نمیکنند. آنها یک گواهی میانی (Intermediate) صادر کرده، ریشه (Root) را آفلاین نگه میدارند و اجازه میدهند گواهی میانی (Intermediate) درخواستهای امضای گواهی (CSRs) روزمره را امضا کند. این آزمایشگاه همان الگو را شبیهسازی میکند.
1 — مرجع صدور گواهی ریشه (Root CA) (لنگر اعتماد (Trust Anchor)، خود-امضا (self-signed))
mkdir -p lab-pki/root lab-pki/intermediate
openssl genrsa -out lab-pki/root/root.key 4096
openssl req -new -x509 -key lab-pki/root/root.key -sha256 -days 3650 \
-out lab-pki/root/root.crt \
-subj "/CN=Lab Root CA/O=Lab/C=US" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
2 — گواهی میانی (Intermediate CA) (امضا شده توسط ریشه (Root))
openssl genrsa -out lab-pki/intermediate/intermediate.key 4096
openssl req -new -key lab-pki/intermediate/intermediate.key \
-out lab-pki/intermediate/intermediate.csr \
-subj "/CN=Lab Issuing CA/O=Lab/C=US" \
-addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
openssl x509 -req -in lab-pki/intermediate/intermediate.csr \
-CA lab-pki/root/root.crt -CAkey lab-pki/root/root.key -CAcreateserial \
-out lab-pki/intermediate/intermediate.crt -days 1825 -sha256 \
-copy_extensions copy
3 — تأیید زنجیرههای میانی (Intermediate chains) به سمت ریشه (Root)
openssl verify -CAfile lab-pki/root/root.crt lab-pki/intermediate/intermediate.crt
lab-pki/root/root.keyبه اندازه هر کلید امضای ریشه (Root signing Key) حساس است — با آن مطابق با حساسیتش رفتار کنید.lab-pki/intermediate/intermediate.keyامضاکننده «آنلاین» است؛ با این حال همچنان به دقت از آن محافظت کنید.lab-pki/root/root.crtلنگر اعتماد (Trust Anchor) است که بهopenssl verify.
جریان A — CSR تولید شده توسط هدف (نشاندهنده یک محدودیت در grpcurl)grpcurlمحدودیت (limitation)
آنچه این بخش در واقع نشان میدهد:مراحل 1 تا 3 به درستی کار میکنند —
grpcurlمیتواند روتر را وادار به تولید یک CSR کند و OpenSSL میتواند آن را امضا نماید. سپس مرحله 5 با یک خطای خاص و قابل پیشبینی شکست میخورد، زیراgrpcurlنمیتواند یک جریان چرخش (Rotate stream) را در طول وقفه امضای خارجی که این فرآیند به آن نیاز دارد، باز نگه دارد. راهنمای کامل گنجانده شده است تا اپراتورهایی که «جریان A» (Flow A) را در نظر دارند، دقیقاً ببینندچه چیزی کار میکند, کجا شکست میخورد، وچرا. خوانندگانی که فقط به دنبال یک چرخش (Rotation) عملیاتی هستند، باید به سراغ جریان B (Flow B) — کلید و CSR تولید شده توسط کلاینت بروند.
روتر دارای کلید خصوصی (Private Key) است. از آن یک CSR درخواست کنید، CSR را با Intermediate CA امضا کنید، فقط گواهی امضا شده نهایی (Leaf) را آپلود کنید (بدون کلید خصوصی درUploadRequest) و نهاییسازی (Finalize) را انجام دهید.
مرحله 1 — اطمینان حاصل کنید که پروفایل وجود دارد
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '{"sslProfileId":"lab-profile-1"}' \
"${XR}" gnsi.certz.v1.Certz.AddProfile || true
مرحله 2 — درخواست CSR و دریافت PEM
محدودیت grpcurl:در یک گردش کار عملیاتی (Production Workflow)، مراحل 2 تا 5 در یک جریان (Stream) واحد Rotate رخ میدهند؛ کلاینت دستور
generateCsrرا ارسال میکند، CSR را دریافت کرده، آن را امضا میکند، گواهی برگ (Leaf) امضا شده را بارگذاری کرده و بدون بستن اتصال، فرآیند را نهایی میکند.ابزار grpcurlنمیتواند در میان جریان برای امضای خارجی متوقف شود، بنابراین پس از بازگشت CSR، جریان بسته میشود. دستورات زیر با اجرای دو فراخوانی مجزای Rotate، این محدودیت را دور میزنند. یک کلاینت برنامهنویسی شده (مانند Python یا Go) کل این فرآیند را در یک جریان واحد مدیریت میکند.
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '@' \
"${XR}" gnsi.certz.v1.Certz.Rotate <<'EOF'
{
"sslProfileId": "lab-profile-1",
"forceOverwrite": true,
"generateCsr": {
"params": {
"csrSuite": "CSRSUITE_X509_KEY_TYPE_ECDSA_PRIME256V1_SIGNATURE_ALGORITHM_SHA_2_256",
"commonName": "router.example.com",
"san": { "dns": ["router.example.com"]}
}
}
}
{"sslProfileId": "lab-profile-1", "finalizeRotation": {}}
EOF
پاسخ روتر — مقدار CSR به صورت PEM با کدگذاری Base64 در داخل بازگردانده میشودgeneratedCsr. مقدارcertificateSigningRequestرا درCSR_B64:
{
"generatedCsr": {
"certificateSigningRequest": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"certificateSigningRequest": "LS0tLS1CRUdJTi..."
}
}
}
رمزگشایی و بازرسی (Decode and inspect)
printf '%s' "$CSR_B64" | base64 -d > router.csr.pem
openssl req -in router.csr.pem -noout -text
مرحله 3 — امضای CSR توسط مرجع گواهی میانی (Intermediate CA)
openssl x509 -req -in router.csr.pem \
-CA lab-pki/intermediate/intermediate.crt \
-CAkey lab-pki/intermediate/intermediate.key \
-CAcreateserial \
-out router.crt -days 825 -sha256
مرحله 4 — تبدیل PEM برگِ امضاشده به فرمت Base64
LEAF_B64=$(base64 < router.crt | tr -d '\n')
مرحله 5 — چرخش: برگه امضاشده را بارگذاری کنید، سپس نهایی نمایید
در یک کلاینت تکجریانی (single-stream)، آپلود برگ (leaf upload) روی همان اتصالی قرار میگیرد که بهتازگی CSR را تولید کرده است؛ روتر همچنان کلید کاندید (candidate Key) را در حافظه دارد و فقط برگ (leaf-only) را میپذیردcertificateChain. از آنجایی کهgrpcurlمجبور شد جریان (stream) را پس از مرحله 2 ببندد، کلید کاندید (candidate Key) به همراه تراکنش بازگردانیشده (rolled-back transaction) حذف شد. بنابراین، آپلود مجدد برگ امضا شده در فراخوانی (invocation) دوم با شکست مواجه میشود:grpcurlبنابراین فراخوانی (Invocation) با شکست مواجه میشود:
VER="lab-rotate-$(date +%s)"
CREATED="$(date +%s)"
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d '@' \
"${XR}" gnsi.certz.v1.Certz.Rotate <<EOF
{
"sslProfileId": "lab-profile-1",
"forceOverwrite": true,
"certificates": {
"entities": [{
"version": "${VER}",
"createdOn": ${CREATED},
"certificateChain": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${LEAF_B64}"
}
}
}]
}
}
{"sslProfileId": "lab-profile-1", "finalizeRotation": {}}
EOF
پاسخ روتر (Router) در نسخه IOS XR 24.4.x:
ERROR:
Code: InvalidArgument
Message: No private key found for leaf cert
افزودنkeySource": "KEY_SOURCE_GENERATEDبه گواهی (certificate)برگمشکل جریان (flow) را حل نمیکند — کلید کاندید از بین رفته است، بنابراین روتر همچنان آپلود را با همان خطا رد میکند. این دلیل عملی است که چرا اکثر اپراتورها هنگام کار باgrpcurlاز جریانتولید شده توسط کلاینت (client-generated)(جریان B در زیر) استفاده میکنند. جریان A تنها زمانی به صورت سرتاسری (end-to-end) تکمیل میشود که از یک کلاینت برنامهنویسی شده (Python, Go) استفاده شود که یک استریمRotateرا در طول مراحل CSR / امضا / آپلود / نهاییسازی باز نگه میدارد.چرخش (Rotate)جریان (Stream) باز در مراحل CSR / امضا / بارگذاری / نهاییسازی.
برای الگوی Trust Bundle (مبتنی بر mutual TLS)، مشاهده کنید گام 4b در Flow B — همان چیدمان تو در تو (nested layout) به صورت سرتاسری ازgrpcurl.
Step 6 — Where to go from here
- برای یک عملکرد
grpcurlراهنما، به Flow B در زیر مراجعه کنید. - برای پیادهسازی عملیاتی Flow A، از یک کلاینت برنامهنویسی استفاده کنید. مخزن OpenConfig gNSI شامل یک کلاینت مرجع Go است که جریان Rotate را در طول بازیابی CSR، امضای خارجی، بارگذاری leaf و نهاییسازی باز نگه میدارد.
جریان B — کلید و CSR تولید شده توسط کلاینت (بارگذاری زنجیره کامل)
این جریان با آنچه بسیاری از اپراتورها در حال حاضر با OpenSSL انجام میدهند مطابقت دارد: ایجادserver.key، ساخت یک CSR، امضای آن با Intermediate CA، سپس ارسال leaf، Key و زنجیره صادرکننده (issuer chain) از طریق Certz در یکcertificateChainتودرتو. پس از نهاییسازی، پروفایل را با دستور CLI در IOS XR متصل کرده و با دستورshow grpc certificate.
In certz.proto, certificateChain.certificateشامل گواهی PEM برگ (leaf) به همراهrawPrivateKeyبرای متریال احراز هویت (Authentication) سرور. هر صادرکننده (issuer) در زیرمجموعهparentقرار میگیرد، تا رسیدن به ریشه (Root) که فاقدparentاست. اختیاریtrustBundleموجودیتها از همان ساختار تو در تو برای انتشار متریال CA جهت اعتبارسنجی کلاینتهای متصل (mutual TLS) استفاده مجدد میکنند.
توجه:در محیط عملیاتی (Production)، کلید ریشه (Root Key) به صورت آفلاین باقی میماند؛ تنها کلید میانی (Intermediate) باید گواهیهای نهایی (Leaf Certificates) روزمره را امضا کند.
مرحله 0 — تعیین نام پروفایل
اگر محیط (Environment) بلوک از قبل صادر (Export) شده است، فقط نام پروفایل (Profile name) را اضافه کنید:
export SSL_PROFILE_ID="${SSL_PROFILE_ID:-lab-profile-1}"
مرحله 1 — ایجاد یا استفاده مجدد از پروفایل SSL
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d "{\"sslProfileId\":\"${SSL_PROFILE_ID}\"}" \
"${XR}" gnsi.certz.v1.Certz.AddProfile || true
مرحله 2 — کلید، CSR و گواهی امضاشده روی ایستگاه کاری
ابتدا بخش PKI آزمایشگاه را تکمیل کنید تاlab-pki/intermediate/وlab-pki/root/موجود باشند:
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
-subj "/CN=router.example.com/O=Lab/C=US" \
-addext "subjectAltName=DNS:router.example.com"
openssl x509 -req -in server.csr \
-CA lab-pki/intermediate/intermediate.crt \
-CAkey lab-pki/intermediate/intermediate.key \
-CAcreateserial \
-out server.crt -days 825 -sha256 -copy_extensions copy
تأیید صحت leaf در برابر زنجیره (chain):
openssl verify -CAfile lab-pki/root/root.crt \
-untrusted lab-pki/intermediate/intermediate.crt \
server.crt
If -copy_extensions copyدر نسخههای قدیمیتر OpenSSL در دسترس نیست، از-extfileبه همراه یک قطعه SAN استفاده کنید.
مرحله 3 — تبدیل فایلهای PEM به فرمت Base64 برای استفاده در JSON
CERT_B64=$(base64 < server.crt | tr -d '\n')
KEY_B64=$(base64 < server.key | tr -d '\n')
INT_B64=$(base64 < lab-pki/intermediate/intermediate.crt | tr -d '\n')
ROOT_B64=$(base64 < lab-pki/root/root.crt | tr -d '\n')
VER="lab-chain-$(date +%s)"
CREATED="$(date +%s)"
VER_TRUST="${VER}-trust"
مرحله 4 — چرخش: زنجیره تو در تو را بارگذاری کنید، سپس نهاییسازی نمایید
دو شیء JSON از طریق grpcurl با-d '@: اولی حاملگواهیها (certificates)با یکزنجیره گواهی (certificateChain) تو در تو، دومی نهایی میکند. تکرار کنیدشناسه پروفایل اساسال (sslProfileId)روی هر دو شیء برای نسخههای IOS XR که آن را اعمال میکنند.
Intermediate اولین مورد استوالد (parent)در زیر leaf قرار دارد؛ Root همانوالد (parent)آن Intermediate است. تنها شیء leaf شاملrawPrivateKey است.
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-format json -d '@' \
"${XR}" gnsi.certz.v1.Certz.Rotate <<EOF
{
"sslProfileId": "${SSL_PROFILE_ID}",
"forceOverwrite": true,
"certificates": {
"entities": [{
"version": "${VER}",
"createdOn": ${CREATED},
"certificateChain": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${CERT_B64}",
"rawPrivateKey": "${KEY_B64}"
},
"parent": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${INT_B64}"
},
"parent": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${ROOT_B64}"
}
}
}
}
}]
}
}
{"sslProfileId": "${SSL_PROFILE_ID}", "finalizeRotation": {}}
EOF
پاسخ روتر (Router response)
{
"certificates": {}
}
{}
مرحله 4ب — اختیاری: افزودن یک موجودیت مجموعه اعتماد (Trust Bundle Entity)
این مورد را زمانی اضافه کنید که پروفایل باید برای اعتبارسنجی کلاینتهای متصل، محتوای CA را نیز منتشر کند.VER_TRUSTدر مرحله 3 آماده شد. آرایهentitiesبه دو عنصر تبدیل میشود:
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-format json -d '@' \
"${XR}" gnsi.certz.v1.Certz.Rotate <<EOF
{
"sslProfileId": "${SSL_PROFILE_ID}",
"forceOverwrite": true,
"certificates": {
"entities": [
{
"version": "${VER}",
"createdOn": ${CREATED},
"certificateChain": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${CERT_B64}",
"rawPrivateKey": "${KEY_B64}"
},
"parent": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${INT_B64}"
},
"parent": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${ROOT_B64}"
}
}
}
}
},
{
"version": "${VER_TRUST}",
"createdOn": ${CREATED},
"trustBundle": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${INT_B64}"
},
"parent": {
"certificate": {
"type": "CERTIFICATE_TYPE_X509",
"encoding": "CERTIFICATE_ENCODING_PEM",
"rawCertificate": "${ROOT_B64}"
}
}
}
}
]
}
}
{"sslProfileId": "${SSL_PROFILE_ID}", "finalizeRotation": {}}
EOF
پاسخ روتر (Router response)
{
"certificates": {}
}
{}
اگر خطاهای تو در تو (Nesting errors) همچنان باقی ماند، دستور زیر را اجرا کنید:grpcurl -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" -msg-template describe gnsi.certz.v1.CertificateChainو نام فیلدها را بازتاب دهید. این قالب نامهای منسوخشده پروتو (Proto) را چاپ میکند (certificate, privateKey)؛ نامهای سازگار با سیم (Wire-compatible) که در بالا استفاده شدهاند (rawCertificate, rawPrivateKey) متعلق به انواع مدرن oneof هستند و همان چیزی هستند که تمام نسخههای اخیر IOS XR میپذیرند.
مرحله 5 — فعالسازی پروفایل (IOS XR CLI)
configure
grpc gnsi service certz ssl-profile-id lab-profile-1
commit
end
جایگزینیlab-profile-1برای${SSL_PROFILE_ID}اگر نام متفاوتی صادر شده باشد.
مرحله 6 — تأیید زنجیره و مستندات احراز هویت
show grpc certificate
تأیید موضوع (Subject)، صادرکننده (Issuer)، تاریخهای اعتبار (Validity dates) و اطمینان از اینکه زنجیره گواهی، Intermediate را به عنوان صادرکننده برگ (Leaf issuer) و Root را در لنگر اعتماد (Trust Anchor) نشان میدهد. خروجی نمونه:
RP/0/RP0/CPU0:router# show grpc certificate
Tue Apr 22 18:40:11.218 UTC
SSL Profile: lab-profile-1
Certificate:
Subject: CN=router.example.com, O=Lab, C=US
Issuer: CN=Lab Issuing CA, O=Lab, C=US
Validity:
Not Before: Apr 22 18:32:01 2026 GMT
Not After: Jul 26 18:32:01 2028 GMT
CA chain:
Subject: CN=Lab Issuing CA, O=Lab, C=US
Issuer: CN=Lab Root CA, O=Lab, C=US
Subject: CN=Lab Root CA, O=Lab, C=US
Issuer: CN=Lab Root CA, O=Lab, C=US
هنگامی که پروفایل (Profile) متصل (Bound) شد، زیردرخت وضعیت (State subtree) در gNMI نیز مقداردهی میشود:
gnmic -a "${XR}" --insecure -u "${XR_USER}" -p "${XR_PASS}" -e json_ietf \
get --path "/system/grpc-servers/grpc-server[name=DEFAULT]/state/ssl-profile-id" \
--path "/system/grpc-servers/grpc-server[name=DEFAULT]/state/certificate-version"
پاسخ اکنون شناسه پروفایل (Profile ID) متصل شده ونسخهرشته (string) حاصل از آخرین عملیات موفق Rotate را بازمیگرداند.
مرحله 7 — پاکسازی اختیاری با استفاده از DeleteProfile
grpcurl -plaintext -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
"${GRPC_MD[@]}" \
-d "{\"sslProfileId\":\"${SSL_PROFILE_ID}\"}" \
"${XR}" gnsi.certz.v1.Certz.DeleteProfile
فقط زمانی عملیات پاکسازی (Cleanup) را اجرا کنید که پروفایل (Profile) به سرور زنده gRPC متصل نباشد.
نسخه حداقلی (برگ + فقط کلید) — در این آزمایشگاه اعتبارسنجی نشده است
اگر تمامی همتایان (Peers) از قبل به صادرکنندگان خارج از باند (Out of Band) اعتماد دارند، بارگذاری تنها گره برگ (Leaf) و کلید (Key) درونزنجیره گواهی (certificateChain)بدون هیچگره (Node)والد (Parent) توسط پروتو (Proto) مجاز است. این مقاله به صورت سرتاسری (End-to-End) با چیدمان تو در تو (Nested) از مرحله 4 اعتبارسنجی شده است؛ اگر در محیط عملیاتی (Production) به نسخه حداقلی نیاز دارید، پیش از تکیه بر آن، رفتار دقیق را در نسخه IOS XR هدف تأیید کنید.گره (Node)طرحبندی (Layout) از مرحله 4؛ اگر در محیط عملیاتی (Production) به نسخه حداقلی نیاز دارید، پیش از استفاده، رفتار دقیق آن را در نسخه IOS XR مقصد تأیید کنید.
ابزارهای عیبیابی (Debugging) با grpcurl
The-msg-templateپرچم (flag) ترکیبی باdescribeشکل استاندارد JSON را برای هر پیام چاپ میکند — که هنگام ردیابی خطاهای تو در تو (nesting errors) بسیار کاربردی است:
grpcurl -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
-msg-template describe gnsi.certz.v1.RotateCertificateRequest
grpcurl -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
-msg-template describe gnsi.certz.v1.UploadRequest
grpcurl -import-path "$GNSI_IMPORT" -proto "$PROTO_CERTZ" \
-msg-template describe gnsi.certz.v1.CertificateChain
این قالب از نامهای فیلد منسوخشده (deprecated) در proto استفاده میکند (گواهی (certificate), کلید خصوصی (privateKey)); شاخههای مدرن oneof یعنیگواهی خام (rawCertificate)وکلید خصوصی خام (rawPrivateKey)همان مواردی هستند که نسخههای مدرن IOS XR در شبکه میپذیرند — این همان قالبی است که در سراسر این مقاله استفاده شده است.
تنظیم gRPC روی یک پروفایل Certz (در IOS XR CLI)
از نسخه IOS XR 24.1.1 به بعد، سرور gRPC را به یک پروفایل گواهی (Certz Profile) متصل کنید:
grpc gnsi service certz ssl-profile-id <ssl-profile-name>
اولویت اهمیت دارد: زمانی که Certz فعال نیست، IOS XR به gNOI بازمیگرددcert.proto؛ زمانی که هیچکدام پیکربندی نشده باشند، دادههای trustpoint قدیمی TLS اعمال میشود. جزئیات کامل در راهنمای احراز هویت gRPC — فصل Certz.
show grpc certificate
پایش (Monitoring) با استفاده از YANG Telemetry
هنگامی که یک پروفایل SSL مستقر (Deploy) میشود، مدل OpenConfig YANGopenconfig-gnsi-certz(نسخه 0.5.0) متادیتای اعتبارنامه (Credential) و شمارندههای دستدهی TLS (TLS handshake Counters) را در معرض دید قرار میدهد که تلمتری (Telemetry) میتواند آنها را به صورت بلادرنگ (Real-time) استریم کند.
تمام مسیرهای YANG زیر نسبت به آدرس زیر هستند:/system/grpc-servers/grpc-server[name=.
متادیتای اعتبارنامه (Credential metadata)
| مسیر YANG (نسبت به پایه) | توضیحات |
|---|---|
.../state/certificate-version |
رشته نسخه گواهی (Certificate) فعال |
.../state/certificate-created-on |
زمان نصب گواهی فعال (نانوثانیه از زمان مبدأ) |
.../state/ca-trust-bundle-version |
رشته نسخه بسته اعتماد (Trust Bundle) فعال |
.../state/ca-trust-bundle-created-on |
زمان نصب بسته اعتماد فعال |
.../state/certificate-revocation-list-bundle-version |
رشته نسخه بسته لیست ابطال گواهی (CRL Bundle) فعال |
.../state/certificate-revocation-list-bundle-created-on |
زمان نصب بسته لیست ابطال گواهی فعال |
.../state/authentication-policy-version |
نسخه خطمشی احراز هویت (Authentication Policy) (مبتنی بر TLS متقابل) |
.../state/authentication-policy-created-on |
زمان نصب خطمشی احراز هویت |
.../state/ssl-profile-id |
شناسه پروفایل SSL (SSL Profile ID) مورد استفاده توسط این سرور gRPC |
شمارندههای دستدادن (Handshake) پروتکل TLS:
| مسیر YANG (نسبت به پایه) | توضیحات |
|---|---|
.../state/certz-counters/access-accepts |
مجموع دستدادنهای (Handshake) موفق TLS |
.../state/certz-counters/last-access-accept |
مهر زمانی (Timestamp) آخرین دستدادن موفق |
.../state/certz-counters/access-rejects |
مجموع دستدادنهای ناموفق TLS (کلاینت رد شده) |
.../state/certz-counters/last-access-reject |
مهر زمانی (Timestamp) آخرین رد شدن TLS |
مشترک شوید درaccess-rejectsوlast-access-rejectبرای شناسایی خطاهای احراز هویت (Authentication) در محیط عملیاتی. افزایش ناگهانی در تعداد رد درخواستها (Rejects) پس از عملیات چرخش (Rotate)، معمولاً به این معناست که گواهی (Certificate) یا بسته اعتماد (Trust Bundle) جدید دارای مشکل است — بررسی کنیدcertificate-versionوca-trust-bundle-versionتا با دادههایی که بهتازگی ارسال شدهاند، مطابقت داده شود.
عبارتهای*-versionو*-created-onدر برگهها (leaves) دقیقاً همان رشتههای ارسال شده در هرموجودیت (Entity)در طول فراخوانی Rotate RPC را منعکس میکنند. این بدان معناست که خطلولههای تلهمتری (Telemetry pipelines) میتوانند رفتار gRPC را با همان شناسههای استفاده شده در شبکه (over the wire) مرتبط کنند — بدون نیاز به باز کردن فایلهای PEM روی دیسک.
بررسی سریع تلهمتری (Telemetry) با استفاده از gnmic
در نسخه 25.3.1:زیرشاخه وضعیت Certz تنها پس از اتصال سرور gRPC به یک پروفایل (
grpc gnsi service certz ssl-profile-id) مقداردهی میشود. تا زمانی که این دستور CLI اعمال (Commit) نشود،state/ssl-profile-idوstate/certz-countersمقدارNotFoundرا برمیگردانند و سرور gRPC فعال حتی پس از یک عملیات موفقRotate.
تأیید نسخه فعال گواهی (Certificate) و شمارندههای دستدهی (Handshake) پروتکل TLS با استفاده از یک دستور gNMI Get (gnmic):
gnmic -a "${XR}" --insecure -u "${XR_USER}" -p "${XR_PASS}" -e json_ietf \
get --path "/system/grpc-servers/grpc-server/state/certificate-version" \
--path "/system/grpc-servers/grpc-server/state/ca-trust-bundle-version" \
--path "/system/grpc-servers/grpc-server/state/certz-counters/access-rejects"
شمارندههای AAA برای هر RPC از مدلopenconfig-gnsi-authzبه هر حال پر میشوند و روشی سریع برای تأیید این هستند که آیا ترافیک Certz اصلاً به سرور میرسد یا خیر:
gnmic -a "${XR}" --insecure -u "${XR_USER}" -p "${XR_PASS}" -e json_ietf \
get --path '/system/grpc-servers/grpc-server[name=DEFAULT]'
فیلتر کردن پاسخ باjqفقط برای Certz RPCs:
jq '[.[0].updates[0].values."system/grpc-servers/grpc-server"
."openconfig-gnsi-authz:authz-policy-counters".rpcs.rpc[]
| select(.name | startswith("/gnsi.certz.v1.Certz/"))]'
خروجی مورد انتظار (اعداد نشاندهنده مراحل بررسی آزمایشگاهی هستند):
[
{ "name": "/gnsi.certz.v1.Certz/AddProfile", "state": { "access-accepts": "4",... } },
{ "name": "/gnsi.certz.v1.Certz/CanGenerateCSR", "state": { "access-accepts": "3",... } },
{ "name": "/gnsi.certz.v1.Certz/DeleteProfile", "state": { "access-accepts": "3",... } },
{ "name": "/gnsi.certz.v1.Certz/GetProfileList", "state": { "access-accepts": "4",... } },
{ "name": "/gnsi.certz.v1.Certz/Rotate", "state": { "access-accepts": "11",... } }
]
GetIntegrityManifestاز لیست حذف شده است — IOS XR بازمیگرداندپیادهسازی نشده (Unimplemented)پیش از آنکه شمارنده AAA افزایش یابد، بنابراین RPC به سادگی هرگز در درخت gNMI ظاهر نمیشود.
نکاتی که باید به آنها توجه کرد
- در نسخه IOS XR 24.4.x، تکرار کنید
شناسه پروفایل SSL (sslProfileId)on هرپیام استریم (stream) — شامل نهاییسازی (finalize) — در غیر این صورت سرور درخواست RPC را با این خطا رد میکندانتظار برای RPC چرخش (rotate) برای چندین پروفایل SSL در یک استریم واحد وجود ندارد. - پروفایل متصل بهسرور gRPC فعالقابل حذف نیست.
DeleteProfileبرای آن یک خطا برمیگرداند. GetIntegrityManifestممکن استUnimplemented (پیادهسازی نشده)را در برخی ایمیجها برگرداند. همیشه با یک تماس زنده تست کنید، نه فقط با Reflection.- پس از چرخش (Rotate)، گواهینامه جدید برایجدیداتصالات اعمال میشود. نشستهای (sessions) موجود قطع نمیشوند.
- همیشه با دستور
show grpc certificateپس از اتصال یک پروفایل تأیید کنید — یک چرخش موفق تضمین نمیکند که پروفایل روی سرور gRPC فعال باشد. - جریان A (CSR تولید شده توسط هدف)نمیتواند کامل شودبه صورت سرتاسری (end-to-end) در
grpcurl— بستن استریم پس از بازگشت CSR باعث دور ریختن کلید کاندید میشود و آپلود بعدی با خطایNo private key found for leaf cert (کلید خصوصی برای گواهینامه برگ پیدا نشد)مواجه میشود. برای آن جریان از یک کلاینت برنامهنویسیشده استفاده کنید یا از جریان B استفاده نمایید. - IOS XR برمیگرداند
InvalidArgument: certificate: same version sent (آرگومان نامعتبر: گواهینامه: نسخه مشابه ارسال شد)(نه خطای مستند شده در پروتو یعنیAlreadyExists (از قبل موجود است)) هنگام استفاده مجدد از یکنسخهبدونforceOverwrite (بازنویسی اجباری). مقدارforceOverwrite": trueرا در هر پیام غیر نهایی در طول تلاشهای مجدد تنظیم کنید. - یک استریم چرخش (Rotate) نهایینشده با
ERROR: Code: Unknown / Message: EOFاز دیدگاه سرور بسته میشود. این سیگنال بازگشت به حالت قبل (rollback) است، نه خطایی که نیاز به بررسی داشته باشد. - زیردرخت وضعیت
openconfig-gnsi-certz(state/ssl-profile-id,state/certz-counters) تنها پس از اتصال سرور gRPC به یک پروفایل Certz پر میشود. تا آن زمان، درخواستهای gNMI Get روی این برگها خطایNotFound (یافت نشد) برمیگردانند.
نتیجهگیری
پذیرش gNSI Certz در IOS XR، چرخش TLS در gRPC را با همان مدل مرحلهبندی-اعتبارسنجی-نهاییسازی (stage-validate-finalize) سایر سرویسهای gNSI همسو میکند. قرارداد Protobuf به عمد کوچک طراحی شده است، اما فرمت آپلود گواهیهای تو در تو (nested Certificate) از مزایای آن بهره میبردgrpcurl -msg-templateپیش از خودکارسازی در مقیاس بزرگ. در ترکیب با Authz و Pathz، این پوشش، نشستهای مدیریتی امن و برنامهپذیر (programmable) را به صورت سرتاسری (end to end) در بر میگیرد.
- Certz گروههای مواد احراز هویت TLS، لنگرهای اعتماد (Trust Anchors)، لیستهای ابطال گواهی (CRLs) و سیاستهای اختیاری را در قالبپروفایلهای SSLدر سیستمعامل IOS XR، که توسط EMSd در مسیر
/misc/config/grpc/gnsi/certz/ssl_profiles/. - پشتیبانی میشوند، دستهبندی میکند. فراخوانیهای Unary RPC شامل کشف (
GetProfileList)، ایجاد پروفایل (AddProfile)، بررسی قابلیت CSR (CanGenerateCSR) و حذف (DeleteProfile). ) هستند.Rotateیک تراکنش جریانی (Streamed Transaction) است: شامل موارد اختیاریgenerate_csr، یک یا چندگواهی (Certificates)برای آپلود، و سپسfinalize_rotation- میباشد. برای فعالسازی بازگشت به حالت قبل (Rollback)، جریان را زودتر قطع کنید.
دو جریان عملیاتی وجود دارد: اجازه دهید روتر در زمانی کهcanGenerateصحیح (True) است CSR را تولید کند، یا کلید و CSR را روی یک ایستگاه کاری تولید کرده و زنجیره امضا شده را باrawPrivateKey - روی گره (Leaf) آپلود کنید.
پس از نهاییسازی، پروفایل را با دستورgrpc gnsi service certz ssl-profile-idمتصل کرده و با دستور. - show grpc certificate
تأیید کنید.تلهمتری YANG از طریقopenconfig-gnsi-certzنسخههای گواهی، تازگی بسته اعتماد (Trust Bundle) و شمارندههای دستدادن (Handshake) TLS را استریم میکند — برای شناسایی زودهنگام خطاهای احراز هویت، در
گام بعدی:برای چرخش (Rotate) اعتبارنامههای SSH در کنار gRPC TLS، ادامه دهید با Credentialz. برای افزودن مجوز (Authorization) در سطح سرویس gRPC، مشاهده کنید Authz.
بازگشت / لغو (Undo)
| وضعیت | نحوه بازگشت (Revert) |
|---|---|
| لغو یک Rotate در میانه جریان | ارسال یکگواهینامههاپیام اما بدونfinalizeRotation، سپس بستن جریان grpcurl. در نسخه IOS XR 24.4.x سرور چاپ میکندERROR: Code: Unknown / Message: EOF، کاندیدا (Candidate) کنار گذاشته میشود و متریال قبلی فعال باقی میماند. اثبات: اجرای مجدد همان Rotate (هماننسخه, بدونforceOverwrite) موفقیتآمیز است — که اگر کاندیدا حفظ شده بود، ممکن نبود. |
| بازگشت به یک پروفایل متفاوت | اجرای مجددgrpc gnsi service certz ssl-profile-id در CLI سیستمعامل IOS XR برای هدایت مجدد سرور gRPC. |
| بازگشت به TLS قدیمی (غیر Certz) | حذف خط پیکربندیgrpc gnsi service certzبه طور کامل. سرور gRPC به متریالcert.protoبازمیگردد و سپس به مسیرهای PEM تراستپوینت (Trustpoint) قدیمی. |
| حذف یک پروفایل تست | DeleteProfileRPC — تنها در صورتی کار میکند که پروفایل به سرور gRPC فعال متصل نباشد. |
| جایگزینی متریال گواهینامه معیوب | اجرای یکRotateدیگر باforceOverwrite: trueو متریال اصلاحشده. نیازی به حذف اولیه نیست. |
مراجع
- OpenConfig —
certz.proto,certz/README.md - OpenConfig —
openconfig-gnsi-certzمدل YANG نسخه 0.5.0 - Cisco IOS XR — راهنمای پیکربندی برنامهپذیری (Programmability): احراز هویت gRPC — مدیریت گواهینامهها با استفاده از Certz.proto
- Cisco IOS XR — مرجع دستورات برنامهپذیری (Programmability): دستورات gRPC
- XRdocs — مقدمهای بر gNSI (مجوزدهی یا Authz), PathZ