مقدمه: هویت بهجای نشانی شبکه
در معماریهای ابری و بهویژه Kubernetes، آدرس IP، نام پاد یا محل اجرای یک فرایند، هویت قابل اتکایی برای تصمیم امنیتی نیست. Zero Trust یا «اعتماد صفر» در این مقاله یک تحلیل تحریریه است: تصمیمگیری بر پایه هویت رمزنگاریشده و شواهد قابل اعتبارسنجی، نه اعتماد به شبکه. مستند رسمی SPIRE، آن را پیادهسازی آماده تولید از APIهای SPIFFE معرفی میکند که هویت node و workload را attestation میکند، برای workloadها SVID صادر میکند و SVID سرویسهای دیگر را بررسی میکند. این سازوکار برای Linux و محیطهایی مانند Kubernetes، مبنایی برای احراز هویت سرویسبهسرویس است.
هدف این راهنما توضیح مسیر صدور هویت، مرزهای اعتماد و الزامات X.509-SVID است، بدون افزودن شماره نسخه، CVE، امتیاز CVSS یا تنظیمی که در منابع رسمی بررسیشده نیامده باشد. واقعیتهای قطعی به مشخصات نسبت داده میشوند و پیشنهادهای عملی، تحلیل تحریریهاند.
مدل هویت: Trust Domain و SPIFFE ID
در SPIFFE، دامنه اعتماد یا Trust Domain مرز منطقی صادرکننده و مجموعه هویتهایی است که آن را میشناسند. SPIFFE ID یک URI برای بیان هویت workload است. در X.509-SVID، این شناسه دقیقاً در افزونه Subject Alternative Name یا SAN قرار میگیرد. هر X.509-SVID باید دقیقاً یک URI SAN و در نتیجه دقیقاً یک SPIFFE ID داشته باشد؛ وجود بیش از یک URI SAN باید به رد گواهی منجر شود. گواهی میتواند SANهای دیگری مانند DNS هم داشته باشد، اما این موضوع جای URI یگانه SPIFFE ID را نمیگیرد.
این تفکیک از نام ماشین مهم است: تصمیمگیرنده میتواند به شناسهای مانند spiffe://example.org/ns/payments/sa/api مجوز بدهد، اما این فقط نمونه است، نه مشخصات اجباری نصب. مستندات میگویند گواهی برگ باید مؤلفه مسیر غیرریشهای داشته باشد و طرح URI باید spiffe باشد. تحلیل Kubernetes این است که سیاست مجوزدهی را به workload و زمینه استقرارش پیوند دهیم، نه IP متغیر پاد.
معماری SPIRE: Server، Agent و Workload API
یک استقرار SPIRE از SPIRE Server و یک یا چند SPIRE Agent تشکیل میشود. Server مرجع صدور هویت در trust domain است، registration entryها و کلیدهای امضا را نگه میدارد، agentها را با node attestation احراز میکند و به درخواست agent برای workload، SVID میسازد. pluginها رفتار Server را تعیین میکنند: node attestor برای گره، datastore برای اطلاعات، key manager برای کلید X.509-SVID و JWT-SVID، و upstream authority برای استفاده از CA بیرونی. datastore داخلی میتواند MySQL، SQLite 3 یا PostgreSQL باشد و مقدار پیشفرض آن SQLite 3 است؛ این نکته توصیه عمومی برای همه محیطها نیست.
Agent باید روی هر nodeای باشد که workload شناساییشده در آن اجرا میشود. Agent از Server SVID میگیرد و آن را تا درخواست workload cache میکند، API محلی workload را عرضه میکند، caller را attestation میکند و SVID مناسب را تحویل میدهد. در Unix این API بهصورت Unix Domain Socket ارائه میشود. در تحلیل دفاعی، دسترسی به socket باید فقط به فرایندهای لازم داده شود؛ این توصیه از مدل محلی API نتیجه میشود و جایگزین تنظیمات رسمی پلتفرم نیست.
Registration Entry و کمینهسازی اختیار
Registration entry نگاشتی میان یک SPIFFE ID و مجموعه selectorهاست؛ workload هنگام attestation باید آن ویژگیها را داشته باشد تا هویت را بگیرد. Server entryها را کورکورانه به Agent نمیفرستد: entryهای دارای parent SPIFFE ID agent، ویژگیهای node، entryهای دارای selector متناظر و سپس فرزندانشان را بازگشتی پیدا میکند. حاصل، مجموعه entryهای مجاز همان agent است.
این طراحی دامنه اختیار میسازد: agent یک node نباید برای workloadهای خارج از parent یا selectorهای مجاز هویت صادر کند. در Kubernetes میتوان از selectorهای Service Account یا namespace استفاده کرد؛ برای Unix ویژگیهایی مانند UID، GID و مسیر فایلسیستم مثال زده شده است. ثبت workload باید دقیق باشد. selector کلی مانند «هر فرایند روی node» دامنه خطا را بزرگ میکند؛ selector دقیقتر با اصل کمترین اختیار سازگارتر است.
دو مرحله attestation: گره و workload
Attestation گردآوری ویژگیهای workload و node از مراجع مورد اعتماد و مقایسه آنها با selectorهاست. مرحله نخست، node attestation، هویت ماشینی را بررسی میکند. نمونههای مستند شامل مدرک AWS EC2، هویت مدیریتشده Azure، توکن GCE، توکن Kubernetes Service Account، کلید HSM یا TPM، join token و گواهی X.509 است. نتیجه موفق، SPIFFE ID یکتای agent است و آن شناسه parent workloadهای agent میشود. برخی attestorها selectorهای node مانند شناسه نمونه را نیز برمیگردانند.
مرحله دوم، workload attestation، میپرسد «این process چیست؟». فقط Agent دخالت دارد. Agent شناسه فرایند caller را میگیرد و pluginها از kernel، kubelet یا اجزای محلی ویژگیهایی بهدست میآورند؛ سپس selectorهای کشفشده با entryهای مجاز تطبیق داده میشوند و SVID cacheشده برمیگردد. SPIRE برای Unix، Kubernetes و Docker workload attestor دارد، اما شواهد باید با محیط و registration واقعی همخوان باشد.
گردش صدور SVID و mTLS
در سناریوی مستند AWS، Server آغاز میشود و، مگر آنکه upstream authority تنظیم شده باشد، گواهی self-signed و trust bundle تولید میکند. Agent مدرک node را عرضه میکند، Server آن را بررسی میکند و SVID Agent را میفرستد. Agent با SVID به Server متصل میشود، entryهای مجاز را میگیرد و برای workloadها CSR میفرستد؛ Server آنها را امضا و Agent cache میکند. بعد workload از Workload API درخواست SVID میکند و Agent پس از attestation آن را تحویل میدهد.
در مسیر Agent و Server، سند از TLS دوطرفه یا mTLS سخن میگوید: Agent از SVID خود بهعنوان گواهی client استفاده میکند و Server را با bootstrap bundle میشناسد. این برای Zero Trust مهم است، چون زنجیره گواهی و bundle را وارد تصمیم میکند. بااینحال mTLS بهتنهایی مجوز تجاری صادر نمیکند؛ مصرفکننده باید SPIFFE ID، leaf بودن گواهی و اختیار صادرکننده را نیز بررسی کند.
X.509-SVID: برگ، صادرکننده و محدودیتها
گواهی leaf همان SVIDای است که برای شناسایی caller یا resource به کار میرود. SPIFFE ID برگ باید path component غیرریشهای داشته باشد. signing certificate یک CA است: cA در Basic Constraints باید true و keyCertSign در Key Usage تنظیم باشد. signing certificate برای authentication مجاز نیست و فقط ماده اعتبارسنجی است؛ میتواند در زنجیره X.509 قرار گیرد. این جداسازی مانع پذیرش CA بهعنوان هویت سرویس میشود.
برای همه SVIDها، Key Usage باید وجود داشته و critical باشد. signing certificate باید keyCertSign داشته باشد و میتواند cRLSign داشته باشد. leaf باید digitalSignature داشته باشد و نباید keyCertSign یا cRLSign داشته باشد؛ keyEncipherment و keyAgreement برای leaf اختیاریاند. leaf بهتر است Extended Key Usage داشته باشد و اگر درج شد، id-kp-serverAuth و id-kp-clientAuth باید تنظیم شوند.
Name Constraints میتواند namespace مجاز SPIFFE IDها را محدود کند و دامنه اثر compromise را کاهش دهد. اما مشخصات هشدار میدهد پشتیبانی URI name constraint در کتابخانهها گسترده نیست و ممکن است گواهی رد شود. پس استفاده از آن نیازمند آزمون سازگاری واقعی است؛ این محدودیت interoperability دلیل خاموشکردن اعتبارسنجی نیست.
اعتبارسنجی، bundle و مرزهای اعتماد
اعتبارسنجی مسیر باید RFC 5280 را رعایت کند و leaf بههمراه signing certificateهای CA bundle را بررسی کند. افزون بر path validation، validator باید مطمئن شود گواهی برگ است، cA=false دارد، keyCertSign و cRLSign تنظیم نشدهاند، scheme شناسه spiffe است، path component ریشهای نیست و بیش از یک URI SAN وجود ندارد.
در SPIFFE bundle، CAهای X.509-SVID با entryهای JWK سازگار با RFC 7517 نمایش مییابند. use باید x509-svid باشد، kid نباید تنظیم شود و x5c باید گواهی CA را بهشکل Base64 DER داشته باشد؛ هر entry یک CA certificate را نمایندگی میکند. هنگام مصرف bundle یک trust domain بیگانه، فقط entryهای دارای use=x509-svid بررسی میشوند؛ x5c غایب یا خالی نادیده گرفته میشود و از چند مقدار فقط نخستین استفاده میشود. این امکان پایه trust بین دامنههاست، اما جزئیات کامل federation در منابع این مقاله نیست.
چرخش، تهدید و حریم خصوصی
صفحات بررسیشده از cache شدن SVID و نقش key manager سخن میگویند، اما عمر گواهی، cadence چرخش یا فرمان rotation را تعیین نمیکنند. پس نباید برای این موارد عدد قطعی ساخت. راهنمای دفاعی این است که انقضا و نوسازی را در مستندات و پیکربندی واقعی بررسی، رخدادهای صدور و رد را پایش، و کلیدهای signing و datastore را محدود و محافظت کنید. افشای کلید صادرکننده میتواند به صدور هویت جعلی در trust domain بینجامد؛ name constraint و جداسازی signing از leaf فقط دامنه اثر را کاهش میدهد.
Threat model پیشنهادی شامل agent جعلی، workloadی با دسترسی غیرمجاز به socket، entry بیشازحد باز، datastore افشاشده، CA bundle نادرست و libraryی است که قوانین SVID را کامل بررسی نمیکند. node attestation ادعای Agent را میسنجد، workload attestation فرایند را با شواهد محلی تطبیق میدهد و parent/selector دامنه صدور را محدود میکند. اما compromise شدن kernel، kubelet، توکن Service Account یا مرجع محلی، اعتماد زیربنایی را آسیبپذیر میکند. selectorهایی مانند UID، مسیر فایل، namespace یا شناسه نمونه داده محیطیاند؛ فقط مقدار لازم ثبت و دسترسی به datastore و لاگها محدود شود.
راهنمای عملی استقرار در Linux و Kubernetes
۱. دامنه و نقشها را تعریف کنید. یک trust domain سازمانی تعیین کنید، مرز Server و Agent را روشن کنید و برای هر workload هویت مجزا و path غیرریشهای در نظر بگیرید.
۲. مرجع attestation را انتخاب کنید. در Linux بر شواهد process و در Kubernetes بر شواهد node و Service Account یا namespace تکیه کنید. node attestor سمت Agent و Server باید یک ادعای قابل بررسی بسازد؛ join token را فقط بهعنوان گزینهای که مستندات آن را one-use و دارای انقضای فوری پس از مصرف معرفی میکند، با کنترل عملیاتی مناسب به کار ببرید.
۳. registration entry حداقلی بنویسید. SPIFFE ID، parent و selectorها را دقیق ثبت کنید. رابطه parent را با مسیر واقعی workload تطبیق دهید و selector عمومیای که چند سرویس نامرتبط را یکجا مجاز میکند، کنار بگذارید.
۴. کانال محلی و زنجیره TLS را آزمون کنید. دسترسی workload به Workload API را محدود کنید، bootstrap bundle را امن توزیع کنید و mTLS را از هر دو طرف آزمایش کنید. سپس نمونه SVID را با قواعد leaf، URI SAN یکتا، cA و Key Usage بررسی کنید.
۵. مصرفکننده را مستقل اعتبارسنجی کنید. سرویس گیرنده نباید فقط وجود گواهی معتبر را کافی بداند؛ باید SPIFFE ID مورد انتظار، trust domain و مجوز صادرکننده را با سیاست خود تطبیق دهد. پیش از فعالسازی URI name constraints، سازگاری libraryها را بسنجید.
۶. عملیات و نوسازی را کنترل کنید. cache، key manager، datastore و bundle را پایش کنید. چون این دو منبع زمانبندی rotation را تعیین نمیکنند، چرخه نوسازی را از مستندات اجرایی همان پیادهسازی استخراج و با تست انقضا، قطع Agent و بازیابی Server اعتبارسنجی کنید.
چکلیست انتشار
- [ ] برای هر workload یک SPIFFE ID مشخص و غیرریشهای ثبت شده است.
- [ ] registration entryها selector دقیق و parent درست دارند.
- [ ] node attestation و workload attestation هر دو آزموده شدهاند.
- [ ] دسترسی به Unix Domain Socket یا endpoint محلی حداقلی است.
- [ ] bootstrap bundle و CA bundle از منبع درست و trust domain درست میآیند.
- [ ] validator برگ را از signing certificate جدا میکند.
- [ ] URI SAN دقیقاً یکی، scheme برابر
spiffeوcA=falseاست. - [ ] Key Usage critical و متناسب با نوع SVID است.
- [ ] رفتار libraryها در برابر name constraint و EKU آزمایش شده است.
- [ ] ثبت رویدادها، حفاظت کلید و ملاحظات دادههای selector بازبینی شدهاند.
- [ ] برای rotation و انقضا عدد حدسی در تولید استفاده نشده و runbook واقعی وجود دارد.
پرسش و پاسخ
آیا SPIRE فقط برای Kubernetes است؟ خیر. مستندات از workload attestorهای Unix، Kubernetes و Docker و نیز node attestation در چند محیط نام میبرد. Kubernetes یکی از کاربردهاست، نه تعریف کل سامانه.
تفاوت Server و Agent چیست؟ Server مرجع ثبت، صدور و نگهداری کلیدهای امضا در trust domain است؛ Agent روی node قرار دارد، workload را محلی attestation میکند، با Server ارتباط میگیرد و Workload API را در اختیار فرایند میگذارد.
آیا هر گواهی X.509 برای احراز هویت SPIFFE کافی است؟ خیر. X.509-SVID باید URI SAN یکتای SPIFFE، scheme درست، path مناسب و قیود leaf را داشته باشد؛ CA یا signing certificate نباید بهعنوان caller پذیرفته شود.
آیا این راهنما JWT-SVID را توضیح میدهد؟ فقط در حد مرزبندی. صفحه SPIRE میگوید JWT-SVID مسیر متفاوتی دارد، اما دو منبع انتخابشده جزئیات قالب و اعتبارسنجی JWT را نمیدهند؛ بنابراین نباید برای آنها مشخصهای از این متن استنباط کرد.
نتیجهگیری
SPIFFE هویت را از مکان شبکه جدا میکند و SPIRE با Server، Agent، selector، attestation دو مرحلهای و Workload API آن را به چرخه صدور SVID نزدیک میسازد. X.509-SVID با URI SAN یکتا، تفکیک leaf و signing، Key Usage محدود و اعتبارسنجی مسیر، پایهای برای mTLS و احراز هویت سرویسهاست. ارزش امنیتی واقعی زمانی حاصل میشود که trust domain، parent، selector، socket، bundle و validator کمینه و قابل ممیزی باشند. برای Kubernetes و Linux، این معماری راهی هویتی است؛ اما امنیت آن به سلامت attestation، حفاظت کلید، سازگاری libraryها و انضباط عملیاتی وابسته میماند.