У Льоні сьогодні

Залежність UUID від MAC-адреси

Виявив істерично смішну дивину з UUID на AWS ECS. Дивився на UUID в базі та помітив, що всі вони мають однакове закінчення. Що трапилось? Розібрався.

  • UUID версії 1 складається з відбитка часу та імені машини. За специфікацією, імʼя машини — це її MAC адреса. Має бути зрозумілим, що в глобально унікальному ідентифікаторі саме імʼя машини прибирає можливість збігу; бо MAC адреса є унікальною (принаймні в теорії), та в межах машини досить легко не видавати один UUID двічі.

  • Власне, на Linux для того є сервіс uuidd. Він централізовано роздає UUID всім споживачам. Ось вам код, де він читає MAC адресу.

  • Але навіть якщо хтось генерує UUID сам, а не лізе в uuidd, то теж зазвичай бере MAC адресу, наприклад, дуже популярний Go-пакет github.com/google/uuid.

  • Памʼятаєте, як я казав, що MAC адреса теоретично унікальна? Ну, не знаю, як там у фізичних пристроях (на моєму Odroid U3 за замовчуванням вона призначається випадково при старті.) Але я точно знаю, що в Docker вам так не повезе. Docker просто будує MAC адресу з IP адреси. Ой… Адреси віртуальних мереж збігаються, та досить часто.

  • Так що якщо ви генеруєте UUID версії 1 з Docker, то шанси бути реально унікальним ID в них стрімко падають. Щоб цього уникнути, простіше за все не використати в якості Node ID MAC адресу, а взяти щось інше — бажано з зарезервованого діапазону MAC адрес. Та, також, краще не користуватись uuidd в Докері зовсім — якщо є такий вибір.

  • Але це ще не найсмішніше. Бо наша MAC адреса не збігається з докерівською. Покопав далі, знайшов, що всі контейнери AWS ECS Fargate отримують однакову MAC адресу. Однакову! Можете самі запустити ifconfig в будь-якому контейнері та підтвердити. Міняти MAC адресу в Fargate поки не можна. Це значить, що всі UUID, згенеровані на AWS Fargate стандартним шляхом, ділять один простір відбитків часу. Та дійсно, такі UUID легко знайти у вільному Інтернеті.

Наскільки це погано? Таймстемп в UUID має роздільну здатність 100 наносекунд. За формулою збігу величин, для 1% ймовірності збігу потрібно 450 паралельних генераторів. Але це 1% шанс щосекунди! Для 1% шансу збігу щогодини достатньо 8 машин. З двома машинами можна очікувати збігу кожні 14 годин. Так що, достатньо погано, щоб негайно припинити вживати “стандартні” UUID v1.