#!/bin/bash # verify-smbios.sh — Inspect SMBIOS / DMI for MukenVault auth_dna eligibility. # # Read /sys/class/dmi/id/* and check the Tier 1+2 inputs the auth_dna # (issue #26) consumes: # Tier 1 (必須 3): product_uuid, product_serial, primary_mac # Tier 2 (取れたら追記): board_serial, chassis_serial # # Failures detected: # - empty / NONE # - placeholders: "To be filled by O.E.M.", "Default string", # "Not Specified", "Not Available", # "System Serial Number", etc. # - zero UUID: 00000000-0000-0000-0000-000000000000 # - QEMU default MAC: 52:54:00:12:34:56 # # Intended flow (run inside the partner box, after the hypervisor host has # either run fix-libvirt-smbios.sh / fix-proxmox-smbios.sh or applied the # manual settings from /self-managed-vm.html): # # curl -fsSL https://install.mukenvault.com/verify-smbios.sh | sudo bash # # Exit codes: # 0 Tier 1 OK (Tier 2 best-effort) # 1 Tier 1 has missing / placeholder values # 2 /sys/class/dmi/id not present (kernel/platform not DMI-aware) set -euo pipefail IFS=$'\n\t' red() { printf '\033[1;31m%s\033[0m' "$1"; } green() { printf '\033[1;32m%s\033[0m' "$1"; } yellow() { printf '\033[1;33m%s\033[0m' "$1"; } log() { printf '\033[1;36m[verify-smbios]\033[0m %s\n' "$*"; } # Known placeholder strings seen across cloud images / OEM BIOSes. We # compare case-insensitively because OEMs are inconsistent about # capitalization ("Default string" vs "Default String"). PLACEHOLDERS=( "NONE" "To be filled by O.E.M." "To Be Filled By O.E.M." "Default string" "Not Specified" "Not Available" "System Serial Number" "Chassis Serial Number" "Base Board Serial Number" "Board Serial Number" "00000000-0000-0000-0000-000000000000" "OEM" "Not Defined" "Unknown" ) is_placeholder() { local v_lc="${1,,}" [[ -z "${1:-}" ]] && return 0 for p in "${PLACEHOLDERS[@]}"; do if [[ "$v_lc" == "${p,,}" ]]; then return 0; fi done return 1 } read_dmi() { # Strip trailing newline only — DMI values can contain spaces. if [[ -r "$1" ]]; then tr -d '\n' < "$1"; fi } if [[ ! -d /sys/class/dmi/id ]]; then printf '%s /sys/class/dmi/id not found — not a DMI-aware Linux kernel\n' \ "$(red '[verify-smbios] FAIL')" >&2 exit 2 fi product_uuid=$(read_dmi /sys/class/dmi/id/product_uuid 2>/dev/null || true) product_serial=$(read_dmi /sys/class/dmi/id/product_serial 2>/dev/null || true) board_serial=$(read_dmi /sys/class/dmi/id/board_serial 2>/dev/null || true) chassis_serial=$(read_dmi /sys/class/dmi/id/chassis_serial 2>/dev/null || true) # Default-route NIC → MAC. This matches what stable_dna.c / auth_dna.c # pick as primary_mac (so partner sees the same value MukenVault will). default_iface=$(ip -o route get 1.1.1.1 2>/dev/null \ | awk '{for (i=1;i<=NF;i++) if ($i=="dev") {print $(i+1); exit}}' || true) if [[ -n "${default_iface:-}" && -r "/sys/class/net/${default_iface}/address" ]]; then primary_mac=$(cat "/sys/class/net/${default_iface}/address") else primary_mac="" fi # /sys/class/dmi/id/{product,board,chassis}_serial are 0400 root on most # distros. A non-root invocation gets silent empties — warn explicitly so # partners don't chase a "missing serial" that's actually a permission bit. if [[ "$(id -u)" -ne 0 ]]; then log "$(yellow 'note:') not running as root — *_serial fields may show empty" log " even when the BIOS provides them. Re-run with sudo for accurate" log " results: sudo bash verify-smbios.sh" echo fi check() { local label="$1" val="$2" tier="$3" if is_placeholder "$val"; then printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(red 'FAIL')" "$label" "$tier" "${val:-NONE}" return 1 fi printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(green 'OK ')" "$label" "$tier" "$val" return 0 } check_mac() { local val="$1" if [[ -z "$val" ]]; then printf '[verify-smbios] %s %-15s (%s): NONE (no default route found)\n' \ "$(red 'FAIL')" "primary_mac" "Tier 1" return 1 fi if [[ "$val" == "52:54:00:12:34:56" ]]; then printf '[verify-smbios] %s %-15s (%s): %s (QEMU default — shared across all VMs)\n' \ "$(red 'FAIL')" "primary_mac" "Tier 1" "$val" return 1 fi printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(green 'OK ')" "primary_mac" "Tier 1" "$val" return 0 } # Tier 1 fails=0 check "product_uuid" "$product_uuid" "Tier 1" || fails=$((fails+1)) check "product_serial" "$product_serial" "Tier 1" || fails=$((fails+1)) check_mac "$primary_mac" || fails=$((fails+1)) # Tier 2 — informational only, empty values are normal on cloud VMs. t2_have=0 if is_placeholder "$board_serial"; then printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(yellow '· ')" "board_serial" "Tier 2" "NONE (optional — typical on VMs)" else printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(green 'OK ')" "board_serial" "Tier 2" "$board_serial" t2_have=$((t2_have+1)) fi if is_placeholder "$chassis_serial"; then printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(yellow '· ')" "chassis_serial" "Tier 2" "NONE (optional — typical on VMs)" else printf '[verify-smbios] %s %-15s (%s): %s\n' \ "$(green 'OK ')" "chassis_serial" "Tier 2" "$chassis_serial" t2_have=$((t2_have+1)) fi echo if [[ $fails -eq 0 ]]; then log "$(green '✓ Tier 1 全 3 要素 OK') (Tier 2 取得: ${t2_have}/2)" log "auth_dna_collect() が成功する状態です。次のコマンドで partner box の setup に進めます:" cat <<'EOF' curl -fsSL https://install.mukenvault.com/preflight.sh | sudo bash curl -fsSL https://install.mukenvault.com/setup.sh | \ sudo bash -s -- --license YOUR-KEY-HERE EOF exit 0 fi # Tier 1 failure path — guide partner to the hypervisor-host fix tool. log "$(red "✗ Tier 1 の ${fails} 要素が NONE / placeholder です")" cat <<'EOF' これは MukenVault の auth DNA 生成が失敗する状態です。partner box の hypervisor 側で per-VM SMBIOS を設定する必要があります。 自動化スクリプト (hypervisor host 側で root として実行): libvirt: sudo curl -fsSL https://install.mukenvault.com/fix-libvirt-smbios.sh | \ sudo bash -s -- Proxmox: sudo curl -fsSL https://install.mukenvault.com/fix-proxmox-smbios.sh | \ sudo bash -s -- 実行後、partner box を再起動してから本スクリプトをもう一度実行してください。 手動設定 (上記が使えない hypervisor の場合): https://install.mukenvault.com/self-managed-vm.html EOF exit 1