MACHINE-ID(5) machine-id MACHINE-ID(5)

machine-id - فایل پیکربندی شناسه محلی ماشین

/etc/machine-id

فایل /etc/machine-id حاوی شناسه یکتای ماشین (machine ID) سیستم محلی است که در هنگام نصب یا بوت سیستم تنظیم می‌شود. شناسه ماشین یک رشته هگزادسیمال ۳۲ کاراکتری با حروف کوچک است که به یک خط جدید ختم می‌شود. در صورت رمزگشایی از فرمت هگزادسیمال، معادل یک مقدار ۱۶ بایتی/۱۲۸ بیتی است. این شناسه نمی‌تواند تماماً صفر باشد.

شناسه ماشین معمولاً در طول نصب سیستم یا در نخستین بوت از یک منبع تصادفی تولید می‌شود و در تمام بوت‌های بعدی ثابت می‌ماند. به صورت اختیاری، در سیستم‌های بدون وضعیت (stateless)، در صورت نیاز در مراحل اولیه بوت در زمان اجرا تولید می‌شود.

شناسه ماشین می‌تواند برای مثال هنگام بوت از طریق شبکه، با پارامتر خط فرمان هسته systemd.machine_id= یا با ارسال گزینه --machine-id= به systemd تنظیم شود. شناسه‌ای که به این صورت مشخص شود، اولویت بالاتری دارد و به جای شناسه ذخیره‌شده در /etc/machine-id استفاده خواهد شد.

شناسه ماشین بر اساس پیکربندی محلی یا شبکه تغییر نمی‌کند و با تعویض سخت‌افزار نیز عوض نمی‌شود. به دلیل همین ویژگی و طول بلندتر آن، این شناسه جایگزین بسیار مفیدتری برای فراخوانی gethostid(3) تعیین‌شده توسط استاندارد POSIX است.

این شناسه ماشین از همان قالب و منطق شناسه ماشین D-Bus پیروی می‌کند.

این شناسه به صورت یکتا میزبان را شناسایی می‌کند. باید آن را «محرمانه» در نظر گرفت و نباید در محیط‌های نامطمئن، به‌ویژه در شبکه، افشا شود. اگر برای برنامه‌ای نیاز به یک شناسه یکتا و پایدار وابسته به ماشین باشد، نباید از شناسه ماشین یا هر بخشی از آن به صورت مستقیم استفاده کرد. در عوض، شناسه ماشین باید با استفاده از یک تابع هش رمزنگاری‌شده کلیددار و یک کلید ثابت مخصوص برنامه هش شود. به این ترتیب شناسه کاملاً یکتا بوده و به روشی پایدار از شناسه ماشین مشتق می‌شود، اما امکان بازیابی شناسه اصلی ماشین از روی شناسه اختصاصی برنامه وجود نخواهد داشت. رابط برنامه‌نویسی sd_id128_get_machine_app_specific(3) پیاده‌سازی چنین الگوریتمی را ارائه می‌دهد.

هر ماشین باید در عملکرد عادی یک شناسه غیرخالی داشته باشد. شناسه هر ماشین باید یکتا باشد. برای دستیابی به این اهداف، /etc/machine-id را می‌توان به چند روش مختلف مقداردهی اولیه کرد.

برای نصب‌های عادی سیستم‌عامل، که در آن یک ایمیج سفارشی برای ماشینی خاص ایجاد می‌شود، /etc/machine-id باید در طول نصب مقداردهی شود.

ابزار systemd-machine-id-setup(1) می‌تواند توسط ابزارهای نصب‌کننده برای مقداردهی اولیه شناسه ماشین در زمان نصب استفاده شود، اما /etc/machine-id می‌تواند با هر روش دیگری نیز نوشته شود.

برای ایمیج‌های سیستم‌عامل که یک بار ایجاد شده و در چندین ماشین استفاده می‌شوند (برای مثال برای کانتینرها یا در محیط‌های ابری)، /etc/machine-id باید در ایمیج عمومی سیستم فایل یا وجود نداشته باشد و یا فایلی خالی باشد (تفاوت بین این دو گزینه در بخش «معناشناسی اولین بوت» در زیر توضیح داده شده است). در طول بوت یک شناسه تولید می‌شود و در صورت امکان در این فایل ذخیره می‌گردد. وجود یک فایل خالی توصیه می‌شود زیرا امکان bind-mount کردن یک فایل موقت روی فایل واقعی را فراهم می‌کند، در حالتی که ایمیج به صورت فقط‌خواندنی استفاده شود و /etc در مراحل اولیه بوت به صورت فقط‌خواندنی متصل (mount) شده باشد. همچنین ببینید: Safely Building Images[1].

ابزار systemd-firstboot(1) می‌تواند برای مقداردهی اولیه /etc/machine-id در ایمیج‌های سیستم متصل‌شده (اما بوت‌نشده) استفاده شود.

هنگامی که یک ماشین با systemd(1) بوت می‌شود، شناسه ماشین تثبیت خواهد شد. اگر گزینه‌های systemd.machine_id= یا --machine-id= (بخش اول را ببینید) مشخص شده باشند، از این مقدار استفاده می‌شود. در غیر این صورت، مقدار موجود در /etc/machine-id به کار گرفته خواهد شد. اگر این فایل خالی باشد یا وجود نداشته باشد، systemd تلاش می‌کند از شناسه ماشین D-Bus از /var/lib/dbus/machine-id، مقدار گزینه خط فرمان هسته container_uuid، مقدار KVM DMI با نام product_uuid یا devicetree با نام vm,uuid (در سیستم‌های KVM)، شناسه Xen hypervisor با نام uuid، و در نهایت یک UUID تولیدشده به صورت تصادفی استفاده کند. systemd.machine_id=firmware می‌تواند برای تولید شناسه ماشین از فِرم‌ور تنظیم شود.

پس از تثبیت شناسه ماشین، systemd(1) تلاش خواهد کرد آن را در /etc/machine-id ذخیره کند. اگر این کار ناموفق باشد، سعی می‌کند یک فایل موقت را روی /etc/machine-id bind-mount کند. اگر سیستم فایل فقط‌خواندنی باشد و شامل یک فایل (احتمالاً خالی) /etc/machine-id نباشد، خطا رخ می‌دهد.

سرویس systemd-machine-id-commit.service(8) در صورتی که /etc/machine-id یا /etc/ در طول مراحل اولیه بوت فقط‌خواندنی باشند اما بعداً قابل نوشتن شوند، تلاش خواهد کرد شناسه ماشین را در سیستم فایل بنویسد.

فایل /etc/machine-id برای تشخیص اینکه آیا یک بوت، اولین بوت است یا خیر استفاده می‌شود. قوانین به شرح زیر است:

1.آرگومان خط فرمان هسته systemd.condition_first_boot= می‌تواند برای لغو منطق تشخیص خودکار استفاده شود، ببینید: kernel-command-line(7).
2.در غیر این صورت، اگر /etc/machine-id وجود نداشته باشد، این بوت به عنوان اولین بوت در نظر گرفته می‌شود. در طول مراحل اولیه بوت، systemd رشته "uninitialized\n" را در این فایل می‌نویسد و یک فایل موقت حاوی شناسه واقعی ماشین را روی آن mount می‌کند. بعداً (پس از رسیدن به first-boot-complete.target)، شناسه واقعی ماشین روی دیسک ذخیره خواهد شد.
3.اگر /etc/machine-id حاوی رشته "uninitialized" باشد، بوت نیز به عنوان اولین بوت در نظر گرفته می‌شود. همان سازوکار فوق اعمال می‌گردد.
4.اگر /etc/machine-id وجود داشته باشد و خالی باشد، بوت به عنوان اولین بوت در نظر گرفته not می‌شود. با این وجود systemd همچنان فایلی حاوی شناسه واقعی ماشین را روی آن bind-mount کرده و بعداً تلاش می‌کند آن را روی دیسک بنویسد (اگر /etc/ قابل نوشتن باشد).
5.اگر /etc/machine-id از قبل حاوی یک شناسه معتبر ماشین باشد، این یک بوت اولیه نیست.

اگر بر اساس قوانین بالا یک بوت اولیه تشخیص داده شود، واحدهای دارای ConditionFirstBoot=yes اجرا خواهند شد و systemd مراحل مقداردهی اولیه اضافی، به‌ویژه اعمال تنظیمات پیش‌فرض واحدها (presetting units) را انجام می‌دهد.

توجه داشته باشید که از نظر تاریخی، شناسه ماشین یک OSF UUID طبق تعریف RFC 4122[2] یا Microsoft GUID نیست؛ با این حال، از نگارش v30 ابزار systemd به بعد، شناسه‌های تازه تولیدشده ماشین طبق RFC 4122 به عنوان Variant 1 Version 4 UUID شناخته می‌شوند.

به منظور حفظ سازگاری با سیستم‌های نصب‌شده پیشین، برنامه‌ای که به یک UUID کاملاً سازگار با RFC 4122 نیاز دارد باید شناسه ماشین را رمزگشایی کرده و سپس عملیات زیر را به صورت (غیرقابل بازگشت) اعمال کند تا آن را به یک RFC 4122 Variant 1 Version 4 UUID معتبر تبدیل نماید. با فرض اینکه "id" یک آرایه از کاراکترهای بدون علامت (unsigned char) باشد:

/* Set UUID version to 4 --- truly random generation */
id[6] = (id[6] & 0x0F) | 0x40;
/* Set the UUID variant to DCE */
id[8] = (id[8] & 0x3F) | 0x80;

(این کد از "generate_random_uuid()" در drivers/char/random.c از سورس‌های کرنل لینوکس الهام گرفته شده است.)

قالب فایل پیکربندی ساده /etc/machine-id از فایل /var/lib/dbus/machine-id که توسط D-Bus معرفی شد سرچشمه می‌گیرد. در واقع، این فایل دوم ممکن است یک پیوند نمادین (symlink) به /etc/machine-id باشد.

systemd(1)، systemd-machine-id-setup(1)، gethostid(3)، hostname(5)، machine-info(5)، os-release(5)، sd-id128(3)، sd_id128_get_machine(3)، systemd-firstboot(1)

1.
Safely Building Images
2.
RFC 4122
systemd 257.13