UKIFY(1) ukify UKIFY(1)

ukify - ترکیب و ساخت تصاویر هسته یکپارچه (Unified Kernel Images - UKI)

ukify [OPTIONS...] build

ukify [OPTIONS...] genkey

ukify [OPTIONS...] inspect FILE...

ukify ابزاری است که هدف اصلی آن ترکیب اجزا (معمولاً یک هسته، یک initrd و استاب UEFI systemd-stub(7)) برای ایجاد یک تصویر هسته یکپارچه UAPI.5 (به انگلیسی: UKI)[1] است — یک فایل باینری PE منفرد که سیستم را بوت می‌کند. هنگامی که UKI اجرا می‌شود، استاب، هسته لینوکس جاسازی‌شده را استخراج کرده و بوت می‌کند. این UKI می‌تواند مستقیماً توسط سفت‌افزار یا از طریق یک بارگذار بوت راه‌اندازی شود. هنگام استفاده با qemu[2]، یک UKI همچنین می‌تواند از طریق «بوت مستقیم هسته» اجرا شود؛ مثال زیر را ببینید.

ukify همچنین می‌تواند برای تولید انواع دیگر تصاویر شبیه UKI، به‌ویژه افزونه‌ها استفاده شود. توضیحات دستور build در زیر را ببینید. ukify همچنین می‌تواند گواهی‌ها و کلیدهایی برای SecureBoot و امضای PCR تولید کند؛ توضیحات دستور genkey در زیر را ببینید. ukify همچنین می‌تواند اطلاعات دقیقی درباره تصاویر هسته یکپارچه چاپ کند؛ توضیحات دستور inspect در زیر را ببینید.

دستورات زیر پشتیبانی می‌شوند:

این دستور یک تصویر هسته یکپارچه ایجاد می‌کند. دو گزینه اصلی که باید برای دستور build مشخص شوند عبارتند از Linux=/--linux= و Initrd=/--initrd=. Initrd= چندین مسیر جداشده با فاصله را می‌پذیرد و --initrd= می‌تواند چندین بار مشخص شود.

بخش‌های اضافی، یا به‌صورت خودکار یا تنها در صورت ارائه گزینه‌ای خاص، در UKI درج خواهند شد. توضیحات مربوط به Microcode=/--microcode=، Cmdline=/--cmdline=، OSRelease=/--os-release=، DeviceTree=/--devicetree=، DeviceTreeAuto=/--devicetree-auto=، HWIDs=/--hwids=، Splash=/--splash=، PCRPKey=/--pcrpkey=، Uname=/--uname=، SBAT=/--sbat= و --section= در زیر را ببینید.

ukify همچنین می‌تواند برای سرهم‌بندی یک باینری PE استفاده شود که قابل اجرا نیست اما حاوی داده‌های کمکی است، برای مثال مدخل‌های اضافی خط فرمان هسته.

اگر کلیدهای امضای PCR از طریق گزینه‌های PCRPrivateKey=/--pcr-private-key= و PCRPublicKey=/--pcr-public-key= یا PCRCertificate=/--pcr-certificate= ارائه شوند، مقادیر PCR که پس از بوت شدن با هسته، initrd و سایر بخش‌های داده‌شده مشاهده خواهند شد، محاسبه، امضا و در UKI جاسازی می‌شوند. systemd-measure(1) برای انجام این محاسبه و امضا استفاده می‌شود.

محاسبه مقادیر PCR برای مسیرهای خاص فاز بوت انجام می‌شود. این مسیرها را می‌توان با گزینه Phases=/--phases= مشخص کرد. در صورت عدم تعیین، مقدار پیش‌فرض ارائه‌شده توسط systemd-measure استفاده می‌شود. همچنین می‌توان آرگومان‌های PCRPrivateKey=/--pcr-private-key=، PCRPublicKey=/--pcr-public-key= یا PCRCertificate=/--pcr-certificate=، و Phases=/--phases= را بیش از یک بار مشخص کرد. در این صورت، امضاها با هر یک از کلیدهای مشخص‌شده انجام می‌شوند. در خط فرمان، هنگامی که هر دو گزینه --phases= و --pcr-private-key= استفاده می‌شوند، باید به تعداد یکسان مشخص شوند، و سپس مجموعه مسیر فاز بوت n-ام با کلید n-ام امضا خواهد شد. این قابلیت را می‌توان برای ساخت خط‌مشی‌های اعتماد متفاوت برای فازهای مختلف بوت استفاده کرد. در فایل پیکربندی، PCRPrivateKey=، PCRPublicKey= و Phases= در بخش‌های جداگانه‌ای گروه‌بندی می‌شوند که فازهای بوت مجزا را توصیف می‌کنند. اگر یکی از گزینه‌های SigningEngine=/--signing-engine= یا SigningProvider=/--signing-provider= مشخص شود، آرگومان‌های کلید خصوصی عیناً به عنوان URI به openssl(1) ارسال می‌شوند، و آرگومان‌های کلید عمومی به عنوان گواهی‌های X.509 بارگذاری خواهند شد، تا امضا بتواند به ترتیب با یک موتور یا ارائه‌دهنده OpenSSL انجام شود.

اگر یک کلید امضای SecureBoot از طریق گزینه SecureBootPrivateKey=/--secureboot-private-key= ارائه شود، باینری PE حاصل به‌طور کلی امضا خواهد شد، که به UKI حاصل امکان می‌دهد توسط SecureBoot مورد اعتماد قرار گیرد. همچنین بحث ثبت خودکار در systemd-boot(7) را ببینید.

اگر استاب و/یا هسته حاوی بخش‌های ".sbat" باشند، آن‌ها در UKI ادغام خواهند شد تا به‌روزرسانی‌های ابطال که بر هر یک تأثیر می‌گذارند، هنگام بارگذاری UKI توسط Shim در نظر گرفته شوند. برای اطلاعات بیشتر در مورد SBAT به مستندات Shim[3] مراجعه کنید.

این دستور کلیدها را برای امضای PCR و کلید و گواهی مورداستفاده برای امضای SecureBoot ایجاد می‌کند. همان گزینه‌های پیکربندی که تعیین می‌کنند چه کلیدهایی و در چه مسیرهایی برای امضا هنگام استفاده از build مورد نیاز خواهند بود، در اینجا تعیین می‌کنند که چه کلیدهایی ایجاد شوند. توضیحات مربوط به PCRPrivateKey=/--pcr-private-key=، PCRPublicKey=/--pcr-public-key= و SecureBootPrivateKey=/--secureboot-private-key= در زیر را ببینید.

فایل‌های خروجی نباید از قبل وجود داشته باشند.

نمایش اطلاعات درباره بخش‌های موجود در یک یا چند باینری داده‌شده. اگر --all داده شود، تمام بخش‌ها نشان داده می‌شوند. در غیر این صورت، اگر گزینه --section= حداقل یک بار مشخص شده باشد، تنها همان بخش‌ها نشان داده می‌شوند. در غیر این صورت، بخش‌های شناخته‌شده‌ای که معمولاً در یک UKI گنجانده می‌شوند نشان داده خواهند شد. برای هر بخش، نام، اندازه و خلاصه sha256 آن چاپ می‌شود. برای بخش‌های متنی، محتویات چاپ می‌شود.

همچنین توضیحات مربوط به -j/--json= و --section= را ببینید.

سایر ابزارهایی که ممکن است برای بازرسی UKIها مفید باشند: llvm-objdump(1) -p و pe-inspect.

تنظیمات می‌توانند در فایل‌های پیکربندی (با نحو SomeSetting=value) و در خط فرمان (با نحو --some-setting=value) ظاهر شوند. برای برخی پارامترهای خط فرمان، یک میانبر تک‌حرفی نیز مجاز است. در فایل‌های پیکربندی، تنظیمات باید در بخش مناسب قرار گیرند، از این رو توضیحات در زیر بر اساس بخش‌ها گروه‌بندی شده‌اند. هنگامی که یک تنظیم یکسان هم در فایل پیکربندی و هم در خط فرمان ظاهر می‌شود، به‌طور کلی تنظیم خط فرمان اولویت بالاتری دارد و تنظیم فایل پیکربندی را کاملاً بازنویسی می‌کند. اگر تنظیمی رفتار متفاوتی داشته باشد، در ادامه شرح داده شده است.

اگر هیچ فایل پیکربندی از طریق گزینه --config=PATH ارائه نشود، ukify تلاش خواهد کرد تا یک فایل پیکربندی پیش‌فرض را به این ترتیب در مسیرهای زیر جستجو کند: /etc/systemd/ukify.conf، /run/systemd/ukify.conf، /usr/local/lib/systemd/ukify.conf، و /usr/lib/systemd/ukify.conf، و سپس اولین موردی را که پیدا شد بارگذاری می‌کند. اگر هیچ فایل پیکربندی مشخص نشده باشد و هیچ فایل پیش‌فرضی نیز پیدا نشود، ukify به کار عادی خود ادامه خواهد داد.

آرگومان‌های مکانی LINUX و INITRD، یا تنظیمات معادل Linux= و Initrd=، اختیاری هستند. اگر بیش از یک initrd مشخص شود، همگی در یک بخش PE واحد ترکیب خواهند شد. این امر برای مثال جهت الحاق ریزکد (microcode) قبل از initrd اصلی مفید است.

گزینه‌ها و تنظیمات زیر پشتیبانی می‌شوند:

--config=PATH

پیکربندی را از فایل پیکربندی داده‌شده بارگذاری می‌کند. به‌طور کلی، تنظیمات مشخص‌شده در فایل پیکربندی اولویت کمتری نسبت به تنظیمات مشخص‌شده از طریق گزینه‌ها دارند. مواردی که گزینه خط فرمان به‌طور کامل تنظیم فایل پیکربندی را بازنویسی نمی‌کند، در توضیحات هر گزینه به‌صراحت ذکر شده است.

در نسخه ۲۵۴ اضافه شد.

--measure, --no-measure

فعال یا غیرفعال کردن فراخوانی systemd-measure(1) برای چاپ مقادیر از پیش محاسبه‌شده PCR. به‌طور پیش‌فرض false است.

در نسخه ۲۵۳ اضافه شد.

--policy-digest, --no-policy-digest

فعال یا غیرفعال کردن فراخوانی systemd-measure(1) برای چاپ خلاصه‌های خط‌مشی TPM2 از پیش محاسبه‌شده. برای امضای آفلاین خط‌مشی‌های PCR مفید است. به‌طور پیش‌فرض false است.

در نسخه ۲۵۸ اضافه شد.

--section=NAME:TEXT|@PATH, --section=NAME:text|binary[@PATH]

برای تمام دستورات به جز inspect، نحو اول استفاده می‌شود. یک بخش دلخواه اضافی "NAME" را مشخص می‌کند. آرگومان می‌تواند یک رشته متنی صریح یا "@" به همراه نام یک مسیر باشد. این گزینه می‌تواند بیش از یک بار مشخص شود. هر بخشی که به این روش مشخص شود (به ترتیب) قبل از بخش ".linux" که همیشه آخرین بخش است درج خواهد شد.

برای دستور inspect، نحو دوم استفاده می‌شود. بخش NAME بازرسی خواهد شد (در صورت یافت شدن). اگر آرگومان دوم "text" باشد، محتویات چاپ خواهد شد. اگر آرگومان سوم داده شود، محتویات در فایلی با نام PATH ذخیره خواهد شد.

توجه داشته باشید که نام همان‌گونه که هست استفاده می‌شود، و اگر نام بخش باید با نقطه شروع شود، باید در NAME گنجانده شود.

در نسخه ۲۵۳ اضافه شد.

--join-profile=PATH

مسیری را به یک فایل PE موجود حاوی یک پروفایل اضافی دریافت می‌کند تا به تصویر هسته یکپارچه اضافه شود. پروفایل را می‌توان از قبل با ukify تولید کرد. نیازی نیست که پروفایل امضا شده باشد یا حاوی اندازه‌گیری‌های PCR باشد. تمام بخش‌های PE مربوط به UKI فایل PE مشخص‌شده در UKI تولیدشده کپی می‌شوند. این گزینه برای تولید UKIهای چند پروفایله مفید است. توجه داشته باشید که این کار فقط بخش‌های PE تعریف‌شده توسط مشخصات UKI را کپی می‌کند، و بخش‌های دیگر، مانند ".text" یا موارد مشابه را نادیده می‌گیرد.

در نسخه ۲۵۷ اضافه شد.

--sign-profile=ID

شناسه پروفایلی را دریافت می‌کند که باید برای آن اندازه‌گیری‌های امضاشده PCR توسط ukify تولید شود. این گزینه را می‌توان همراه با --join-profile= هنگام ساخت تصویر نهایی هسته یکپارچه استفاده کرد. اگر مشخص نشود، اندازه‌گیری‌های امضاشده PCR برای تمام پروفایل‌ها اضافه خواهد شد.

در نسخه ۲۵۸ اضافه شد.

--join-pcrsig=PATH, --pcrsig=TEXT|@PATH

گزینه --join-pcrsig= مسیری را به یک فایل PE موجود حاوی یک UKI از پیش ساخته‌شده دریافت می‌کند. --pcrsig= مسیری را به یک حباب JSON مربوط به pcrsig موجود، یا یک حباب درون‌خطی عین کلمه دریافت می‌کند. آن‌ها باید با هم و بدون تعیین هیچ پارامتر بخش UKI دیگری استفاده شوند. ukify حباب JSON مربوط به pcrsig را به UKI پیوست خواهد کرد. این گزینه در ترکیب با --policy-digest برای ایجاد یک UKI و سپس امضای آفلاین خلاصه‌های خط‌مشی TPM2 مفید است.

در نسخه ۲۵۸ اضافه شد.

--tools=DIRS

یک یا چند دایرکتوری حاوی ابزارهای کمکی را مشخص می‌کند. ukify ابتدا ابزارهای کمکی را در آن دایرکتوری‌ها جستجو می‌کند، و اگر پیدا نشدند، تلاش می‌کند تا آن‌ها را طبق معمول از $PATH بارگذاری کند.

در نسخه ۲۵۳ اضافه شد.

--output=FILENAME

نام فایل خروجی. اگر مشخص نشود، نام آرگومان LINUX، با پسوند ".unsigned.efi" یا ".signed.efi" بسته به این که آیا امضا برای SecureBoot انجام شده است یا خیر، استفاده خواهد شد.

در نسخه ۲۵۳ اضافه شد.

--summary

خلاصه‌ای از پیکربندی بارگذاری‌شده را چاپ کرده و خارج می‌شود. این گزینه برای بررسی نحوه ترکیب گزینه‌های فایل پیکربندی و خط فرمان مفید است.

در نسخه ۲۵۴ اضافه شد.

--all

چاپ تمام بخش‌ها (با دستور inspect).

در نسخه ۲۵۵ اضافه شد.

--json

تولید خروجی JSON (با دستور inspect). خروجی یک شیء است که کلیدهای آن نام‌های بخش‌های مشترک بین تمام پروفایل‌ها هستند (یعنی بخش‌های قبل از اولین بخش ".profile")، که هر کدام به شیئی نگاشت می‌شوند که بخش را بر اساس "size" و "sha256" آن، به اضافه یک فیلد "text" برای بخش‌های متنی توصیف می‌کند. بخش‌های UKI که می‌توانند چندین بار (در همان پروفایل) ظاهر شوند به صورت آرایه نشان داده می‌شوند. اگر تصویر حاوی پروفایل‌ها باشد، یک کلید اضافی "_profiles" حاوی آرایه‌ای با یک شیء به ازای هر پروفایل است که هر کدام به همین ترتیب با نام بخش کلیدگذاری شده‌اند (شروع با بخش ".profile" آن).

در نسخه ۲۵۵ اضافه شد.

-h, --help

یک متن راهنمای کوتاه را چاپ کرده و خارج می‌شود.

--version

یک رشته نسخه کوتاه را چاپ کرده و خارج می‌شود.

Linux=LINUX, --linux=LINUX

مسیری به فایل باینری هسته.

در نسخه ۲۵۴ اضافه شد.

OSRelease=TEXT|@PATH, --os-release=TEXT|@PATH

توصیف os-release (بخش ".osrel"). آرگومان می‌تواند یک رشته متنی صریح یا "@" به همراه نام یک مسیر باشد. اگر مشخص نشود، فایل os-release(5) از سیستم میزبان برداشته خواهد شد. اگر صراحتاً روی یک رشته خالی تنظیم شود، بخش ".osrel" از UKI حذف می‌شود (این کار در اغلب موارد توصیه نمی‌شود و باعث می‌شود که خروجی حاصل توسط ابزارهای دیگر مانند kernel-install و bootctl به عنوان یک UKI شناخته نشود).

در نسخه ۲۵۳ اضافه شد.

Cmdline=TEXT|@PATH, --cmdline=TEXT|@PATH

خط فرمان هسته (بخش ".cmdline"). آرگومان می‌تواند یک رشته متنی صریح یا "@" به همراه نام یک مسیر باشد. اگر مشخص نشود، هیچ خط فرمانی جاسازی نخواهد شد.

در نسخه ۲۵۳ اضافه شد.

Initrd=INITRD..., --initrd=LINUX

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

در نسخه ۲۵۴ اضافه شد.

Microcode=UCODE, --microcode=UCODE

مسیر به initrd حاوی به‌روزرسانی‌های ریزکد (microcode). اگر مشخص نشود، این بخش وجود نخواهد داشت.

در نسخه ۲۵۶ اضافه شد.

Splash=PATH, --splash=PATH

تصویری برای نمایش در طول بوت (بخش ".splash"). آرگومان، مسیری به یک فایل BMP است. اگر مشخص نشود، این بخش وجود نخواهد داشت.

در نسخه ۲۵۳ اضافه شد.

DeviceTree=PATH, --devicetree=PATH

توصیف devicetree (بخش ".dtb"). آرگومان، مسیری به یک فایل کامپایل‌شده دودویی DeviceTree است. اگر مشخص نشود، این بخش وجود نخواهد داشت.

در نسخه ۲۵۳ اضافه شد.

DeviceTreeAuto=PATH..., --devicetree-auto=PATH

صفر یا چند فایل DeviceTree با قابلیت انتخاب خودکار. در فایل پیکربندی، موارد با فاصله از هم جدا می‌شوند. هر DeviceTree در یک بخش ".dtbauto" جداگانه قرار خواهد گرفت.

در نسخه ۲۵۷ اضافه شد.

HWIDs=PATH, --hwids=PATH

جدول شناسه سخت‌افزاری دستگاه (بخش ".hwids"). آرگومان، مسیری به یک دایرکتوری حاوی فایل‌های توصیف دستگاه JSON HWID است. هر فایل باید شامل یک شیء JSON واحد با کلیدهای "name"، "compatible" و "hwids" باشد. کلیدهای "name" و "compatible" باید مقادیر رشته‌ای داشته باشند و کلید "hwids" باید لیستی از رشته‌ها به عنوان مقدار داشته باشد، که در آن رشته‌ها باید UUIDهای معتبری باشند که بیانگر CHID/HWID هستند. مثال:
{
    "type": "devicetree",
    "name": "Example Laptop 16 Gen 7",
    "compatible": "example,laptop-16-g7",
    "hwids": [
        "5dc05bf4-01f6-4089-b464-a08c47ea9295",
        "3e3f8f3c-2003-46f2-811c-85554f7d5952"
    ]
}

در اینجا "Example Laptop 16 Gen 7" نام دستگاه "name" (طبق تعریف سازنده) است، "example,laptop-16-g7" مقدار "compatible" (طبق تعریف هسته) است و "hwids" آرایه‌ای از CHIDها/HWIDها است (برای مثال استخراج‌شده از خروجی fwupdtool hwids). اگر مشخص نشود، و دایرکتوری "/usr/lib/systemd/boot/hwids/[EFI_ARCH]/" وجود داشته باشد، آنگاه این بخش به‌طور خودکار از آن دایرکتوری پر خواهد شد (یک رشته خالی را به عنوان پارامتر این گزینه مشخص کنید تا این رفتار غیرفعال شود)، در غیر این صورت وجود نخواهد داشت. توصیه می‌شود در صورتی که قرار است از DeviceTreeهای با قابلیت انتخاب خودکار استفاده شود، این پارامتر مشخص گردد.

در نسخه ۲۵۷ اضافه شد.

Uname=VERSION, --uname=VERSION

مشخص کردن نسخه هسته (همانند uname -r، بخش ".uname"). اگر مشخص نشود، تلاشی برای استخراج رشته نسخه از تصویر هسته صورت خواهد گرفت. توصیه می‌شود در صورت آگاهی، این مقدار صراحتاً ارسال شود، زیرا استخراج بر پایه روش‌های اکتشافی است و چندان قابل اعتماد نیست. اگر مشخص نشود و استخراج با شکست مواجه شود، این بخش وجود نخواهد داشت.

در نسخه ۲۵۳ اضافه شد.

SBAT=TEXT|@PATH, --sbat=TEXT|@PATH

متاداده SBAT مرتبط با UKI یا افزونه. خط‌مشی‌های SBAT برای ابطال کل گروه‌های UKIها یا افزونه‌ها با یک به‌روزرسانی خط‌مشی ایستا که فضایی را در DBX/MOKX اشغال نمی‌کند، مفید هستند. اگر به‌صورت دستی مشخص نشود، یک مدخل متاداده پیش‌فرض متشکل از
uki,1,UKI,uki,1,https://uapi-group.org/specifications/specs/unified_kernel_image

برای UKIها و

uki-addon,1,UKI Addon,addon,1,https://www.freedesktop.org/software/systemd/man/latest/systemd-stub.html

برای افزونه‌ها استفاده خواهد شد، تا اطمینان حاصل شود که ابطال آن‌ها همواره امکان‌پذیر است. برای اطلاعات بیشتر در مورد SBAT به مستندات Shim[3] مراجعه کنید.

در نسخه ۲۵۴ اضافه شد.

PCRPKey=PATH, --pcrpkey=PATH

مسیری به یک کلید عمومی برای جاسازی در بخش ".pcrpkey". اگر مشخص نشود، و دقیقاً یک آرگومان PCRPublicKey=/--pcr-public-key= یا PCRCertificate=/--pcr-certificate= وجود داشته باشد، از آن کلید استفاده خواهد شد. در غیر این صورت، این بخش وجود نخواهد داشت.

در نسخه ۲۵۳ اضافه شد.

Profile=PATH, --profile=PATH

مسیری به یک پروفایل UKI برای قرار دادن در یک بخش ".profile". این گزینه برای ایجاد UKIهای چند پروفایله مفید است، و معمولاً در ترکیب با --join-profile= استفاده می‌شود تا UKI مشخص‌شده با یک پروفایل اضافی گسترش یابد.

در نسخه ۲۵۷ اضافه شد.

PCRBanks=PATH, --pcr-banks=PATH

فهرستی از بانک‌های PCR جداشده با کاما یا فاصله برای امضای یک خط‌مشی. در صورت عدم وجود، تمام بانک‌های شناخته‌شده استفاده خواهند شد ("sha1"، "sha256"، "sha384"، "sha512")، که در صورت عدم پشتیبانی توسط سیستم با شکست مواجه خواهد شد.

در نسخه ۲۵۳ اضافه شد.

SecureBootSigningTool=SIGNER, --signtool=SIGNER

اینکه از "sbsign"، "pesign" یا "systemd-sbsign" استفاده شود. بسته به این انتخاب، پارامترهای متفاوتی برای امضای یک تصویر مورد نیاز است. پیش‌فرض "sbsign" است.

در نسخه ۲۵۴ اضافه شد.

SecureBootPrivateKey=SB_KEY, --secureboot-private-key=SB_KEY

مسیری به یک کلید خصوصی برای استفاده جهت امضای باینری حاصل. اگر گزینه SigningEngine=/--signing-engine= یا SigningProvider=/--signing-provider= استفاده شود، این ممکن است یک نام‌گذاری ویژه موتور یا ارائه‌دهنده نیز باشد. این گزینه توسط SecureBootSigningTool=sbsign/--signtool=sbsign و SecureBootSigningTool=systemd-sbsign/--signtool=systemd-sbsign الزامی است.

در نسخه ۲۵۳ اضافه شد.

SecureBootCertificate=SB_CERT, --secureboot-certificate=SB_CERT

مسیری به یک گواهی برای استفاده جهت امضای باینری حاصل. اگر گزینه SigningEngine=/--signing-engine= یا SigningProvider=/--signing-provider= استفاده شود، این ممکن است یک نام‌گذاری ویژه موتور یا ارائه‌دهنده نیز باشد. این گزینه توسط SecureBootSigningTool=sbsign/--signtool=sbsign و SecureBootSigningTool=systemd-sbsign/--signtool=systemd-sbsign الزامی است.

در نسخه ۲۵۳ اضافه شد.

SecureBootCertificateDir=SB_PATH, --secureboot-certificate-dir=SB_PATH

مسیری به یک دایرکتوری پایگاه‌داده گواهی nss برای استفاده جهت امضای باینری حاصل. هنگامی که SecureBootSigningTool=pesign/--signtool=pesign استفاده می‌شود تأثیر می‌گذارد. پیش‌فرض /etc/pki/pesign است.

در نسخه ۲۵۴ اضافه شد.

SecureBootCertificateName=SB_CERTNAME, --secureboot-certificate-name=SB_CERTNAME

نام مدخل پایگاه‌داده گواهی nss برای استفاده جهت امضای باینری حاصل. این گزینه توسط SecureBootSigningTool=pesign/--signtool=pesign الزامی است.

در نسخه ۲۵۴ اضافه شد.

SecureBootCertificateValidity=DAYS, --secureboot-certificate-validity=DAYS

مدت اعتبار (به روز) برای یک گواهی ایجادشده توسط genkey. پیش‌فرض ۳۶۵۰، یعنی ۱۰ سال است.

در نسخه ۲۵۴ اضافه شد.

SigningEngine=ENGINE, --signing-engine=ENGINE

یک موتور OpenSSL برای استفاده جهت امضای باینری حاصل و اندازه‌گیری‌های PCR؛ به openssl-engine(1) مراجعه کنید.

در نسخه ۲۵۳ اضافه شد.

SigningProvider=PROVIDER, --signing-provider=PROVIDER

یک ارائه‌دهنده OpenSSL برای استفاده جهت امضای باینری حاصل و اندازه‌گیری‌های PCR؛ به provider(7) مراجعه کنید. این گزینه فقط زمانی می‌تواند استفاده شود که systemd-sbsign به عنوان ابزار امضا استفاده شود.

در نسخه ۲۵۷ اضافه شد.

CertificateProvider=PROVIDER, --certificate-provider=PROVIDER

یک ارائه‌دهنده OpenSSL برای استفاده جهت بارگذاری گواهی مورد استفاده برای امضای باینری حاصل و اندازه‌گیری‌های PCR؛ به provider(7) مراجعه کنید. این گزینه فقط زمانی می‌تواند استفاده شود که systemd-sbsign به عنوان ابزار امضا استفاده شود.

در نسخه ۲۵۷ اضافه شد.

SignKernel=BOOL, --sign-kernel, --no-sign-kernel

نادیده گرفتن تشخیص خودکار این که آیا خود باینری لینوکس قبل از جاسازی در تصویر ترکیبی امضا شود یا خیر. اگر مشخص نشود، در صورتی که یک کلید امضای SecureBoot از طریق گزینه SecureBootPrivateKey=/--secureboot-private-key= ارائه شود و باینری قبلاً امضا نشده باشد، امضا خواهد شد. اگر SignKernel=/--sign-kernel روی true باشد، و باینری قبلاً امضا شده باشد، امضا در هر حال ضمیمه خواهد شد.

در نسخه ۲۵۳ اضافه شد.

در فایل پیکربندی، این گزینه‌ها بر اساس بخش گروه‌بندی می‌شوند. در خط فرمان، آن‌ها باید به همان ترتیب مشخص شوند. بخش‌های مشخص‌شده در هر دو منبع ترکیب می‌شوند.

PCRPrivateKey=PATH, --pcr-private-key=PATH

یک کلید خصوصی برای استفاده جهت امضای خط‌مشی‌های PCR. در خط فرمان، این گزینه ممکن است بیش از یک بار مشخص شود، که در این صورت امضاهای متعددی ایجاد خواهد شد.

در نسخه ۲۵۳ اضافه شد.

PCRPublicKey=PATH, --pcr-public-key=PATH

یک کلید عمومی برای استفاده جهت امضای خط‌مشی‌های PCR.

در خط فرمان، این گزینه ممکن است بیش از یک بار مشخص شود، مشابه با گزینه --pcr-private-key=. اگر وجود نداشته باشد، کلیدهای عمومی از کلیدهای خصوصی استخراج خواهند شد. در خط فرمان، در صورت وجود، این گزینه باید به تعداد یکسان با گزینه --pcr-private-key= مشخص شود. در صورت استفاده از --pcr-certificate= نمی‌تواند مشخص شود.

در نسخه ۲۵۳ اضافه شد.

PCRCertificate=PATH, --pcr-certificate=PATH

یک گواهی X.509 برای استفاده جهت امضای خط‌مشی‌های PCR.

در خط فرمان، این گزینه ممکن است بیش از یک بار مشخص شود، مشابه با گزینه --pcr-private-key=. اگر وجود نداشته باشد، کلیدهای عمومی از کلیدهای خصوصی استخراج خواهند شد. در خط فرمان، در صورت وجود، این گزینه باید به تعداد یکسان با گزینه --pcr-private-key= مشخص شود. در صورت استفاده از --pcr-public-key= نمی‌تواند مشخص شود.

در نسخه ۲۵۸ اضافه شد.

Phases=LIST, --phases=LIST

فهرستی از مسیرهای فاز جداشده با دو نقطه، تفکیک‌شده با کاما یا فاصله برای امضای خط‌مشی. هر مجموعه از مسیرهای فاز بوت با کلید خصوصی متناظر امضا خواهد شد. در صورت عدم وجود، مقدار پیش‌فرض systemd-measure(1) استفاده خواهد شد.

در خط فرمان، هنگامی که این آرگومان وجود دارد، باید به تعداد یکسان با گزینه --pcr-private-key= ظاهر شود.

در نسخه ۲۵۳ اضافه شد.

مثال ۱. فراخوانی کمینه

$ ukify build \
      --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
      --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
      --cmdline='quiet rw'

این دستور یک UKI امضانشده به نام ./vmlinuz.unsigned.efi ایجاد می‌کند.

مثال ۲. بوت مستقیم هسته در یک ماشین مجازی

هنگام استفاده از qemu[2] با OVMF[4] (سفت‌افزار UEFI برای ماشین‌های مجازی) می‌توان از سوییچ -kernel مستقیماً همراه با یک UKI استفاده کرد. مثال:

qemu-kvm -drive if=pflash,format=qcow2,readonly=on,file=/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2 -kernel ./vmlinuz.unsigned.efi [ ... ]

(مسیر فایل سفت‌افزار ممکن است بسته به توزیع نیاز به تنظیم داشته باشد.) معمولاً یک آرگومان دیگر -drive برای اتصال یک ایمیج دیسک واقعی استفاده می‌شود، اما این کار اجباری نیست.

مثال ۳. تمامی ویژگی‌ها و امکانات

$ ukify build \
      --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
      --initrd=early_cpio \
      --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
      --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
      uki.author.myimage,1,UKI for System,uki.author.myimage,1,https://uapi-group.org/specifications/specs/unified_kernel_image' \
      --pcr-private-key=tpm2-pcr-initrd-private-key.pem \
      --pcr-public-key=tpm2-pcr-initrd-public-key.pem \
      --phases='enter-initrd' \
      --pcr-private-key=tpm2-pcr-private-key-system.pem \
      --pcr-public-key=tpm2-pcr-public-key-system.pem \
      --phases='enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit \
                enter-initrd:leave-initrd:sysinit:ready' \
      --pcr-banks=sha384,sha512 \
      --secureboot-private-key=secureboot-private-key.pem \
      --secureboot-certificate=secureboot-certificate.pem \
      --sign-kernel \
      --cmdline='quiet rw rhgb'

این دستور یک UKI امضاشده به نام ./vmlinuz.signed.efi ایجاد می‌کند. بخش initrd شامل دو بخش به هم پیوسته است: early_cpio و initramfs-6.0.9-300.fc37.x86_64.img. خط‌مشی جاسازی‌شده در بخش ".pcrsig" برای initrd (فاز enter-initrd) با کلید tpm2-pcr-initrd-private-key.pem، و برای سیستم اصلی (فازهای leave-initrd، sysinit، ready) با کلید tpm2-pcr-private-key-system.pem امضا خواهد شد. باینری لینوکس و تصویر ترکیبی حاصل با کلید SecureBoot به نام secureboot-private-key.pem امضا خواهند شد.

مثال ۴. تمامی ویژگی‌ها و امکانات از طریق یک فایل پیکربندی

این همان مثال قبلی است، اما این بار پیکربندی در یک فایل ذخیره شده است:

$ cat ukify.conf
[UKI]
Initrd=early_cpio
Cmdline=quiet rw rhgb
SecureBootPrivateKey=secureboot-private-key.pem
SecureBootCertificate=secureboot-certificate.pem
SignKernel=yes
PCRBanks=sha384,sha512
[PCRSignature:initrd]
PCRPrivateKey=tpm2-pcr-initrd-private-key.pem
PCRPublicKey=tpm2-pcr-initrd-public-key.pem
Phases=enter-initrd
[PCRSignature:system]
PCRPrivateKey=tpm2-pcr-private-key-system.pem
PCRPublicKey=tpm2-pcr-public-key-system.pem
Phases=enter-initrd:leave-initrd
       enter-initrd:leave-initrd:sysinit
       enter-initrd:leave-initrd:sysinit:ready
$ ukify -c ukify.conf build \
        --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
        --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img

یک "initrd" (با نام early_cpio) در فایل پیکربندی مشخص شده است، و initrd دیگر (با نام initramfs-6.0.9-300.fc37.x86_64.img) در خط فرمان مشخص شده است. این امر برای مثال زمانی مفید است که اولین initrd حاوی ریزکد (microcode) برای پردازنده باشد و برخلاف initrd واقعی، با تغییر نسخه هسته نیازی به به‌روزرسانی نداشته باشد.

مثال ۵. افزونه PE خط فرمان هسته

ukify build \
      --secureboot-private-key=secureboot-private-key.pem \
      --secureboot-certificate=secureboot-certificate.pem \
      --cmdline='debug' \
      --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
      uki-addon.author,1,UKI Addon for System,uki-addon.author,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html'
      --output=debug.addon.efi

این دستور یک باینری PE امضاشده ایجاد می‌کند که حاوی پارامتر خط فرمان اضافی هسته یعنی "debug" همراه با متاداده SBAT ارجاع‌دهنده به مالک افزونه است.

مثال ۶. تصمیم‌گیری درباره خط‌مشی امضا، و ایجاد گواهی و کلیدها

ابتدا، بیایید یک فایل پیکربندی ایجاد کنیم که مشخص می‌کند چه امضاهایی باید انجام شوند:

# cat >/etc/kernel/uki.conf <<EOF
[UKI]
SecureBootPrivateKey=/etc/kernel/secureboot-private-key.pem
SecureBootCertificate=/etc/kernel/secureboot-certificate.pem
[PCRSignature:initrd]
Phases=enter-initrd
PCRPrivateKey=/etc/systemd/tpm2-pcr-initrd-private-key.pem
PCRPublicKey=/etc/systemd/tpm2-pcr-initrd-public-key.pem
[PCRSignature:system]
Phases=enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit
       enter-initrd:leave-initrd:sysinit:ready
PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key-system.pem
PCRPublicKey=/etc/systemd/tpm2-pcr-public-key-system.pem
EOF

سپس، می‌توانیم گواهی و کلیدها را تولید کنیم:

# ukify genkey --config=/etc/kernel/uki.conf
Writing SecureBoot private key to /etc/kernel/secureboot-private-key.pem
Writing SecureBoot certificate to /etc/kernel/secureboot-certificate.pem
Writing private key for PCR signing to /etc/systemd/tpm2-pcr-initrd-private-key.pem
Writing public key for PCR signing to /etc/systemd/tpm2-pcr-initrd-public-key.pem
Writing private key for PCR signing to /etc/systemd/tpm2-pcr-private-key-system.pem
Writing public key for PCR signing to /etc/systemd/tpm2-pcr-public-key-system.pem

(هر دو عملیات باید به عنوان ریشه انجام شوند تا دسترسی نوشتن به /etc/kernel/ مجاز باشد.)

فراخوانی‌های بعدی با استفاده از فایل پیکربندی (ukify build --config=/etc/kernel/uki.conf) از این فایل‌های گواهی و کلید استفاده خواهند کرد. توجه داشته باشید که افزونه kernel-install(8) به نام 60-ukify.install به‌طور پیش‌فرض از /etc/kernel/uki.conf استفاده می‌کند، بنابراین پس از ایجاد این فایل، نصب هسته‌هایی که با استفاده از kernel-install یک UKI روی ماشین محلی ایجاد می‌کنند، با استفاده از این پیکربندی امضا را انجام خواهند داد.

مثال ۷. تصویر هسته یکپارچه با چند پروفایل (Multi-Profile UKI)

ابتدا چند پروفایل ایجاد کنید:

$ ukify build \
      --profile='TITLE=Base' \
      --output=profile0.efi

یک پروفایل دوم اضافه کنید (@1):

$ ukify build \
      --profile='TITLE=Boot into Storage Target Mode
ID=storagetm' \
      --cmdline='quiet rw rd.systemd.unit=storage-target-mode.target' \
      --output=profile1.efi

یک پروفایل سوم اضافه کنید (@2):

$ ukify build \
      --profile='TITLE=Factory Reset
ID=factory-reset' \
      --cmdline='quiet rw systemd.unit=factory-reset.target' \
      --output=profile2.efi

سپس، یک UKI ایجاد کرده و تمام پروفایل‌های تولیدشده را در آن بگنجانید:

$ ukify build \
      --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
      --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
      --cmdline='quiet rw' \
      --join-profile=profile0.efi \
      --join-profile=profile1.efi \
      --join-profile=profile2.efi \
      --output=base.efi

تصویر UKI حاصل به نام base-with-profile-0-1-2.efi اکنون شامل سه پروفایل خواهد بود.

مثال ۸. امضای آفلاین بخش pcrsig

ابتدا یک UKI ایجاد کرده و حباب JSON مربوط به PCR را ذخیره کنید:

$ ukify build \
      --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
      --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
      --cmdline='quiet rw' \
      --pcr-public-key=tpm2-pcr-initrd-public-key.pem \
      --policy-digest \
      --json=short \
      --output=base.efi >base.pcrs

سپس، خلاصه‌های PCR را به‌صورت آفلاین امضا کرده و در حباب JSON درج کنید:

#!/usr/bin/python3
import base64, json, subprocess
priv_key = '/home/zbyszek/src/systemd/tpm2-pcr-private.pem'
base_file = 'base.pcrs'
base = json.load(open(base_file))
for bank,policies in base.items():
    for policy in policies:
        pol = base64.b16decode(policy['pol'].upper())
        call = subprocess.run(['openssl', 'dgst', f'-{bank}', '-sign', priv_key],
                              input=pol,
                              check=True,
                              capture_output=True)
        sig = base64.b64encode(call.stdout).decode()
        policy['sig'] = sig
print(json.dumps(base))

در نهایت، حباب به‌روزشده JSON را به UKI پیوست کنید:

$ ukify build \
      --join-pcrsig=base.efi \
      --pcrsig=@base.pcrs \
      --json=short \
      --output=base-signed.efi

تصویر UKI حاصل به نام base-signed.efi اکنون شامل خلاصه‌های امضاشده PCR خواهد بود.

systemd(1), systemd-stub(7), systemd-boot(7), systemd-measure(1), systemd-pcrphase.service(8)

1.
UAPI.5 Unified Kernel Image (UKI)
2.
qemu
3.
Shim documentation
4.
OVMF
systemd 261.3