signature-protocols(1) دستورات کاربر signature-protocols(1)

signature-protocols - پروتکل‌های دسترسی به امضا برای تصاویر کانتینری

کتابخانه go.podman.io/image/v5 از امضاهایی که به صورت داده‌های دودویی (blobs) «پیوست‌شده به» یک تصویر پیاده‌سازی شده‌اند، پشتیبانی می‌کند. برخی روش‌های انتقال تصویر (قالب‌های ذخیره‌سازی محلی و پروتکل‌های راه دور) این امضاها را به صورت محلی یا به سادگی پیاده‌سازی می‌کنند؛ برای موارد دیگر، افزونه‌های پروتکل که در ادامه شرح داده شده‌اند ضروری هستند.

هر مخزن docker/distribution موجود، چه به صورت پیش‌فرض از امضاها پشتیبانی کند یا خیر، می‌تواند با پیکربندی نشانی اینترنتی (URL) ذخیره‌سازی امضا در ⟨containers-registries.d.md⟩ به یک محل ذخیره امضای جداگانه مجهز شود. می‌توان registries.d را طوری پیکربندی کرد که از یک آدرس ذخیره‌سازی برای کل سرور docker/distribution استفاده کند، یا نشانی‌های اینترنتی جداگانه‌ای را برای فضاهای نام کوچکتری یا مخازن منفرد درون سرور به کار گیرد (این امر برای مثال به سازندگان تصویر اجازه می‌دهد ذخیره‌سازی امضای خود را مدیریت کنند در حالی که تصاویر را در سرور عمومی docker.io منتشر می‌نمایند).

نشانی اینترنتی ذخیره‌سازی امضا، ریشه سلسله‌مراتب مسیر را تعریف می‌کند. این آدرس می‌تواند یک نشانی اینترنتی file:///… باشد که به ساختار دایرکتوری محلی اشاره دارد، یا یک آدرس http/https باشد که به یک سرور راه دور اشاره می‌کند. محل ذخیره امضای file:/// هم قابل خواندن و هم قابل نوشتن است، اما http/https تنها از خواندن پشتیبانی می‌کند.

در هر دو حالت از یک ساختار مسیر مشابه استفاده می‌شود، بنابراین سرور HTTP/HTTPS می‌تواند یک وب‌سرور ایستای ساده باشد که ساختار دایرکتوری ایجادشده از طریق نوشتن در ذخیره‌ساز file:/// را ارائه می‌دهد. (این موضوع البته مانع از پیاده‌سازی‌های دیگر سرور، مانند سرور HTTP که امضاها را از یک پایگاه داده می‌خواند، نخواهد بود).

گردش کار معمول برای تولید و توزیع تصاویر با استفاده از سازوکار ذخیره‌سازی جداگانه این است که مخزن در registries.d با یک نشانی lookaside-staging که به یک ناحیه واسط خصوصی file:/// اشاره دارد و یک نشانی lookaside که به یک سرور وب عمومی اشاره می‌کند، پیکربندی شود. برای انتشار یک تصویر، تولیدکننده تصویر، آن را در صورت نیاز امضا می‌کند (مثلاً با استفاده از skopeo copy) و سپس ساختار دایرکتوری ایجادشده را از ناحیه واسط file:/// به یک زیرشاخه از ریشه وب سرور عمومی کپی می‌کند تا با استفاده از نشانی عمومی lookaside در دسترس باشند. سازنده همچنین به مصرف‌کنندگان تصویر دستورالعمل می‌دهد یا یک فایل پیکربندی registries.d در اختیارشان می‌گذارد تا یک آدرس lookaside که به سرور وب عمومی اشاره دارد تنظیم کنند.

با فرض یک نشانی ذخیره‌سازی امضای base پیکربندی‌شده در registries.d همان‌طور که در بالا ذکر شد، و یک تصویر کانتینر ذخیره‌شده در مخزن docker/distribution با استفاده از نام کامل hostname/namespaces/name{@digest,:tag} (مثلاً برای docker.io/library/busybox:latest، مقدار namespaces برابر با library است، حتی اگر کاربر با نحو کوتاه‌تر busybox:latest به تصویر ارجاع دهد)، امضاها با استفاده از آدرس‌هایی به شکل زیر قابل دسترسی هستند: > base/namespaces/name@digest-algo=digest-value/signature-index

که در آن digest-algo:digest-value یک خلاصه (digest) مانیفست است که برای ارجاع به مانیفست تصویر مربوطه قابل استفاده است (یعنی حتی اگر کاربر با استفاده از تگ به تصویر ارجاع داده باشد، محل ذخیره امضا همیشه با استفاده از مراجع خلاصه تفکیک می‌شود). توجه داشته باشید که در نشانی‌های اینترنتی استفاده‌شده برای امضاها، digest-algo و digest-value با نویسه = از هم جدا می‌شوند، نه با : مانند زمانی که از طریق API مخزن docker/distribution به مانیفست دسترسی پیدا می‌کنید.

درون نشانی اینترنتی، index یک عدد صحیح ده‌دهی (در قالب استاندارد) است که از ۱ شروع می‌شود. امضاها در نشانی‌هایی با مقادیر متوالی index ذخیره می‌شوند؛ برای خواندن همه آن‌ها، از index=1 شروع کنید و خواندن امضاها و افزایش index را تا زمانی که امضاهایی با این مقادیر وجود دارند ادامه دهید. به همین ترتیب، برای افزودن یک امضای دیگر به تصویر، اولین index را که وجود ندارد پیدا کنید و سپس امضای جدید را با استفاده از آن مقدار ذخیره نمایید.

هیچ روشی برای فهرست کردن امضاهای موجود به جز پیمایش در مقادیر متوالی index وجود ندارد، و هیچ راهی برای بارگیری همه امضاها به صورت یکجا نیست.

برای یک تصویر docker/distribution که به صورت busybox@sha256:817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e در دسترس است (یا به عنوان busybox:latest در صورتی که برچسب latest به مانیفستی با همین خلاصه اشاره داشته باشد)، و با پیکربندی registries.d که نشانی lookaside را برابر با https://example.com/lookaside برای همان تصویر تعیین کرده است، برای دانلود تمام امضاها به نشانی‌های اینترنتی زیر دسترسی خواهد شد: > - https://example.com/lookaside/library/busybox@sha256=817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e/signature-1 > - https://example.com/lookaside/library/busybox@sha256=817a12c32a39bbe394944ba49de563e085f1d3c5266eb8e9723256bc4448680e/signature-2 > - …

برای تصویر موجود به عنوان example.com/ns1/ns2/ns3/repo@somedigest:digestvalue و همان نشانی lookaside، امضاها در نشانی زیر در دسترس خواهند بود: > https://example.com/lookaside/ns1/ns2/ns3/repo@somedigest=digestvalue/signature-1

و به همین ترتیب.

مطابق با https://github.com/openshift/origin/pull/12504 ، رجیستری تعبیه‌شده در OpenShift همچنین یک افزونه برای API مخزن docker/distribution ارائه می‌دهد که امکان دسترسی ساده‌تر به امضاها را با استفاده از نقطه پایانی همان API فراهم می‌کند.

این API ذاتاً مختص OpenShift نیست (به عنوان مثال کلاینت نیازی به دانستن نقطه پایانی API در OpenShift ندارد و اطلاعات هویتی کافی برای دسترسی به سرور API مخزن docker/distribution برای دسترسی به امضاها نیز کفایت می‌کند)، و روش ارجح برای پیاده‌سازی ذخیره‌سازی امضا در رجیستری‌ها است.

برای مستندات اصلی بالادستی این API، به آدرس https://github.com/openshift/openshift-docs/pull/3556 مراجعه کنید.

برای خواندن امضا، هر کاربری که به تصویر دسترسی دارد می‌تواند از مسیر /extensions/v2/…/signatures/… برای خواندن آرایه‌ای از امضاها استفاده کند. فقط از اشیاء امضایی استفاده کنید که مقدار version آن‌ها برابر با 2 و مقدار type آن‌ها برابر با atomic باشد، و امضا را از فیلد content بخوانید؛ سایر فیلدهای شیء امضا را نادیده بگیرید.

برای افزودن یک امضای منفرد، یک شیء جدید با version برابر با 2، type برابر با atomic و content تنظیم‌شده روی امضا را از طریق متد PUT ارسال کنید. همچنین name را روی یک نام منحصر‌به‌فرد به شکل digest@per-image-name تنظیم نمایید، که در آن digest خلاصه مانیفست تصویر (استفاده‌شده در آدرس اینترنتی) و per-image-name هر شناسه یکتایی است.

برای افزودن بیش از یک امضا، آن‌ها را یک به یک بیفزایید. این API اجازه حذف امضاها را نمی‌دهد.

توجه داشته باشید از آنجا که امضاها درون اشیاء تصویری سطح کلاستر ذخیره می‌شوند (یعنی فضاهای نام مختلف نمی‌توانند مجموعه‌های متفاوتی از امضاها را به همان تصویر مرتبط کنند)، به‌روزرسانی امضاها نیازمند دسترسی در سطح کلاستر به منبع imagesignatures است (که به‌طور پیش‌فرض در اختیار نقش system:image-signer قرار دارد).

رجیستری تعبیه‌شده در OpenShift رابط معمول docker/distribution API را پیاده‌سازی می‌کند و همچنین تصاویر را از طریق REST API اوپن‌شیفت (موجود در سرورهای «API master») ارائه می‌دهد.

توجه: نسخه‌های ۱.۵ و جدیدتر OpenShift از افزونه API مخزن docker/distribution که در بالا توضیح داده شد پشتیبانی می‌کنند، که راه‌اندازی آن آسان‌تر است و معمولاً باید ترجیح داده شود. برای جزئیات در خصوص استفاده از نسخه‌های قدیمی‌تر OpenShift به خواندن ادامه دهید.

مطابق با https://github.com/openshift/origin/pull/9181 ، امضاها از طریق API اوپن‌شیفت ارائه می‌شوند (یعنی برای دسترسی به تصویر کامل، استفاده از هر دو API لازم است، به ویژه دانستن آدرس‌ها برای هر دو نقطه پایانی docker/distribution و OpenShift API master).

برای خواندن امضا، هر کاربری که به تصویر دسترسی دارد می‌تواند از منبع دارای فضای نام imagestreamimages برای خواندن شیء Image و آرایه Signatures آن استفاده کند. فقط از اشیاء ImageSignature که مقدار Type آن‌ها برابر با atomic است استفاده کرده و امضا را از Content بخوانید؛ سایر فیلدهای شیء ImageSignature را نادیده بگیرید.

برای افزودن یا حذف امضاها، از منبع سراسری کلاستر (بدون فضای نام) imagesignatures استفاده کنید، با Type تنظیم‌شده روی atomic و Content تنظیم‌شده روی امضا. نام‌های امضا باید قالبی به شکل digest@per-image-name داشته باشند که در آن digest خلاصه مانیفست تصویر (در نام‌گذاری OpenShift به عنوان «image name») و per-image-name هر شناسه یکتا است.

توجه داشته باشید از آنجا که امضاها درون اشیاء تصویری سطح کلاستر ذخیره می‌شوند (یعنی فضاهای نام مختلف نمی‌توانند مجموعه‌های متفاوتی از امضاها را به همان تصویر مرتبط کنند)، به‌روزرسانی امضاها نیازمند دسترسی در سطح کلاستر به منبع imagesignatures است (که به‌طور پیش‌فرض در اختیار نقش system:image-signer قرار دارد)، و حذف امضاها به شدت نهی شده است (زیرا امضا را از تمامی فضاهای نامی که شامل همان تصویر هستند حذف می‌کند).