پورتال کاج

واژه پرتال به معنی دروازه یا محل ورود به یک شهرمی باشد و تا بحال بیشترین کاربرد را در حوزه IT داشته است. طبق تعاریفی که تا بحال ارائه شده است، پرتال را می توان یک مرکز ارائه خدمات و اطلاعات اینترنتی دانست

لینک های مفید

راهنمای مهندسین برای ادغام ARI در کلاینت‌های ACME موجود


از زمان معرفی آن در مارس ۲۰۲۳، ARI به‌طور چشمگیری به بهبود قابلیت اطمینان و استحکام در فرایند ابطال و تمدید گواهینامه کمک کرده است. برای گسترش این مزایا، لازم است ARI در تعداد بیشتری از کلاینت‌های ACME ادغام شود.

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

اگر مایلید یاد بگیرید که چگونه یک بازه‌ی تمدید پیشنهادی را درخواست کنید، زمان بهینه تمدید را انتخاب کنید و جایگزینی گواهینامه را مشخص نمایید، ادامه‌ی این مطلب را بخوانید!

ادغام ARI در یک کلاینت ACME موجود

در ماه مه ۲۰۲۳، ما یک درخواست تغییر (Pull Request) به کلاینت ACME Lego ارائه دادیم تا از پیش‌نویس draft-ietf-acme-ari-01 پشتیبانی کند. در دسامبر ۲۰۲۳ و فوریه ۲۰۲۴، دو درخواست تغییر دیگر (شماره‌های 2066 و 2114) برای پشتیبانی از تغییرات جدید در draft-ietf-acme-ari-02 و 03 ارائه دادیم.

این تجربیات بینش ارزشمندی درباره‌ی فرایند ادغام ARI در یک کلاینت ACME موجود فراهم کرد. در ادامه، ۶ مرحله‌ی اصلی که از این تجربیات استخراج شده را ارائه می‌کنیم تا برای توسعه‌دهندگان کلاینت‌های ACME مفید باشد.

نکته: قطعه‌کدهای این مقاله به زبان Golang نوشته شده‌اند، اما به‌گونه‌ای ساختاربندی و توضیح داده شده‌اند که بتوانند به راحتی به سایر زبان‌های برنامه‌نویسی نیز تطبیق داده شوند.

مرحله ۱: تشخیص پشتیبانی CA از ARI

از آنجا که بسیاری از کلاینت‌های ACME از چندین مرکز صدور گواهینامه (CA) استفاده می‌کنند، ابتدا باید بررسی کرد که CA مورد نظر از ARI پشتیبانی می‌کند یا خیر. این کار از طریق بررسی وجود نقطه‌ی پایانی (renewalInfo) در شیء دایرکتوری CA انجام می‌شود.

در کلاینت Lego، ما فیلدی به نام renewalInfo را به ساختار Directory اضافه کردیم:

type Directory struct { NewNonceURL string `json:"newNonce"` NewAccountURL string `json:"newAccount"` NewOrderURL string `json:"newOrder"` NewAuthzURL string `json:"newAuthz"` RevokeCertURL string `json:"revokeCert"` KeyChangeURL string `json:"keyChange"` Meta Meta `json:"meta"` RenewalInfo string `json:"renewalInfo"` }

سپس بررسی می‌کنیم که مقدار renewalInfo مقداردهی شده باشد قبل از آنکه از آن استفاده کنیم:

func (c *CertificateService) GetRenewalInfo(certID string) (*http.Response, error) { if c.core.GetDirectory().RenewalInfo == "" { return nil, ErrNoARI } }

مرحله ۲: تعیین جایگاه ARI در چرخه‌ی تمدید گواهینامه

ادغام ARI باید در مناسب‌ترین نقطه از فرایند تمدید کلاینت ACME انجام شود.

در کلاینت Lego، عملیات تمدید معمولاً از طریق یک Job Scheduler مانند Cron اجرا می‌شود، بنابراین ادغام ARI در دستور renew بهترین گزینه بود. به این ترتیب، قبل از اجرای منطق پیش‌فرض تمدید، ابتدا با ARI مشورت می‌شود.

مرحله ۳: ساخت شناسه‌ی گواهینامه ARI (CertID)

شناسه‌ی CertID ترکیبی از شناسه کلید مرجع (AKI) و شماره سریال گواهینامه است که به‌صورت base64url کدگذاری شده و با نقطه (.) جدا می‌شوند.

در Lego، این منطق در تابع MakeARICertID پیاده‌سازی شد:

func MakeARICertID(leaf *x509.Certificate) (string, error) { if leaf == nil { return "", errors.New("leaf certificate is nil") } serial := base64.RawURLEncoding.EncodeToString(leaf.SerialNumber.Bytes()) aki := base64.RawURLEncoding.EncodeToString(leaf.AuthorityKeyId) return fmt.Sprintf("%s.%s", aki, serial), nil }

مرحله ۴: درخواست بازه‌ی تمدید پیشنهادی از ARI

با داشتن CertID، درخواست تمدید را به نقطه‌ی پایانی renewalInfo ارسال می‌کنیم:

GET https://example.com/acme/renewal-info/aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE

پاسخ ARI شامل بازه‌ی زمانی پیشنهادی و در صورت نیاز، یک لینک توضیحی خواهد بود:

{ "suggestedWindow": { "start": "2021-01-03T00:00:00Z", "end": "2021-01-07T00:00:00Z" }, "explanationURL": "https://example.com/docs/ari" }

مرحله ۵: انتخاب زمان مناسب برای تمدید

بر اساس پیشنهاد ARI، زمان تمدید را به‌صورت تصادفی یکنواخت در بازه‌ی پیشنهادی انتخاب می‌کنیم.

go
func (r *RenewalInfoResponse) ShouldRenewAt(now time.Time) *time.Time { start := r.SuggestedWindow.Start.UTC() end := r.SuggestedWindow.End.UTC() window := end.Sub(start) randomDuration := time.Duration(rand.Int63n(int64(window))) rt := start.Add(randomDuration) if rt.Before(now) { return &now } return &rt }

مرحله ۶: مشخص کردن گواهینامه‌ی جایگزین‌شده

هنگام ارسال درخواست جدید ACME Order، مقدار replaces را به CertID گواهینامه‌ی قبلی تنظیم می‌کنیم:

{

"identifiers": [ { "type": "dns", "value": "example.com" } ], "replaces": "aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE" }

جمع‌بندی

ادغام ARI در کلاینت‌های ACME نه‌تنها یک ارتقای فنی محسوب می‌شود، بلکه به تکامل پروتکل ACME کمک کرده و امنیت اینترنت را بهبود می‌بخشد.

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