Adds the Blueforce Field OS provisioning stack on top of the existing fleet architecture, without rewriting the working systems (installer, diagnostics, Ansible, WireGuard/SSH/xRDP/RustDesk, Docker policies, monitoring, Docusaurus). ISO build (the previous builder was a skeleton that produced no medium): - boot layout is read from the base ISO at build time via `xorriso -report_el_torito as_mkisofs` and rebuilt with `-as mkisofs`; `-boot_image any replay` cannot work on Ubuntu live ISOs because the GRUB2 MBR lives in the source image's first 16 sectors and the EFI system partition is an appended partition, neither of which is a file in the ISO9660 tree - preflight now asserts El Torito boot metadata positively: xorriso exits 0 on a non-ISO input, which previously let an arbitrary file pass --check - artifact produced and verified: dist/Blueforce-Field-OS-1.0.0-amd64.iso, 6 481 917 952 bytes, SHA256 cb0cc56f...d431296, BIOS+UEFI entries preserved, /autoinstall.yaml at the media root, casper/minimal.squashfs byte-identical to the base - recorded baseline deviation: the verified medium on the build host is the Desktop flavour, so the manifest carries a baseline_deviation block instead of hiding it; Server remains one flag away Offline and identity: - offline APT contract with concrete package requirements, pin format and an audit table; builds fail closed while pins are UNPINNED - autoinstall keeps interactive-sections: [storage]: the operator confirms the target disk, and no automatic wipe is ever performed - firstboot terminal wizard for the 8-digit dealer id, three-state lifecycle (PROVISIONED_OFFLINE -> ENROLLED -> READY) with fail-closed gates, so a missing internet link or WireGuard handshake cannot fail provisioning but can never produce a false READY Fleet and migration: - five read-only Ansible playbooks for Field OS version, provisioning, enrollment, remote channels and offline readiness, all wave-scoped with a separate production override - Windows pre-migration inventory and data export extended to the full brief scope, read-only, never collecting credentials Tests: tests/run-all.sh -> 8/8 pass, exit 0. Boot acceptance (UEFI, Legacy BIOS, Secure Boot), air-gapped install, real enrollment endpoint and Windows rollback remain LAB work and are listed in IMPLEMENTATION-REPORT.md.
9.2 KiB
Enrollment sözleşmesi (Field OS yaşam döngüsü)
Bu dizin sözleşmedir, uç nokta değildir: istemci davranışı, istek/yanıt şemaları ve
güven modeli burada tanımlanır. Merkezi enrollment API'si bu repoda uygulanmaz;
uygulanması ayrı bir güvenlik incelemesi gerektirir (prompt §18, docs/29 §13).
İlgili dosyalar: docs/29-DEVICE-ENROLLMENT.md (karar K-17), docs/26 (K-15),
schemas/enrollment-request.schema.json, schemas/enrollment-response.schema.json.
1. Durum makinesi (ileri yönlü, atlama yok)
(yok) --yerel kurulum--> PROVISIONED_OFFLINE --tek kullanımlık token--> ENROLLED --tüm kanallar doğrulandı--> READY
| Aşama | Ne kanıtlanır | Gerekli kanıt | İnternet |
|---|---|---|---|
PROVISIONED_OFFLINE |
Yerel kurulum tamam; cihaz çevrimdışı işe hazır | bf-check-local: yerel sistem durumu, xRDP, WireGuard anahtar çifti |
Gerekmez |
ENROLLED |
Merkez cihazı tanıdı, WireGuard peer atandı, monitoring/inventory/RustDesk yapılandırması uygulandı | Doğrulanmış enrollment yanıtı + central_verification referansları + yeni WG handshake |
Gerekir |
READY |
Yerel sağlık ve üç merkezi kanal doğrulandı | bf-check-ready: bf-check-local + bf-check-enrollment + bf-remote-status --check |
Gerekir |
Geçiş kuralları (yazıcı ve okuyucu tarafında birlikte uygulanır):
- Geriye dönüş yok.
ENROLLED -> PROVISIONED_OFFLINEveREADY -> ENROLLEDyazılmaz;bf-enrollREADY cihazda çalışmayı reddeder. READY sonrası ciddi kimlik sorunudocs/27akışıyla yeniden provision edilir. - Atlama yok.
PROVISIONED_OFFLINE -> READYdoğrudan yazılamaz. READY yalnızbf-check-readygeçtikten sonra final gate tarafından yazılır; okuma tarafındabf-enrollment-statusböyle bir durumuINVALIDve sıfırdan farklı çıkış kodu ile bildirir (fail-closed). - Atomik yazım. Her geçiş aynı dizinde
tmp + renameile yapılır, dosya modu0600,fsyncuygulanır. Yazıcılar.state.locküzerindeflockile serileştirilir ve geçiş kilit altında yeniden doğrulanır (boot timer ile teknisyen yarışı). - Yetkili yazıcılar.
PROVISIONED_OFFLINEyerel kurulum,ENROLLEDbf-enroll,READYfinal kurulum kapısı. Başka hiçbir araç yaşam döngüsü durumunu değiştirmez:bf-status,bf-enrollment-status,bf-check-*yalnız okur.
Durum dosyası sözleşmesi (/var/lib/blueforce/state.json, chmod 600, BF_STATE_FILE
ile geçersiz kılınabilir): phase, enrollment_status, fleet_status, device_id
(BF-<no>), provisioning_id. Bilinmeyen ek alanlar korunur ve yok sayılır.
2. İstek / yanıt sözleşmesi
İstek (bf-enroll, schemas/enrollment-request.schema.json): device_id,
wireguard_public_key, idempotency_key, hardware, release. İstek gövdesinde
secret yoktur: WireGuard private key, token değeri ve diğer kimlik bilgileri gövdeye
girmez. Tek kullanımlık token Authorization başlığında, argv'ye düşmeyen anonim bir
process-substitution fd'si üzerinden taşınır; başlık dosyaya, state'e veya loga yazılmaz.
Yanıt (schemas/enrollment-response.schema.json): status (accepted), device_id,
idempotency_key (istekle birebir aynı olmalı), isteğe bağlı enrollment_id,
wireguard (hub public key + adres + endpoint + allowed_ips) ve zorunlu
central_verification (status, verification_id ve her biri status +
verification_id taşıyan monitoring, remote, management). Yanıt bütünüyle
doğrulanır: fazla alan, uyuşmayan kimlik ya da idempotency_key tüm yanıtı reddettirir.
Yerel WireGuard yapılandırması yalnız bu doğrulamadan sonra kurulur; private key
merkezden kabul edilmez, cihazda kalır.
central_verification referansları istemci tarafından üretilmez; yalnız doğrulanmış
enrollment yanıtından kalıcılaştırılır. Eksik/biçimsiz kayıt ENROLLED kapısını, pending
kanal ise READY kapısını fail-closed düşürür (cihaz ENROLLED kalır).
3. Güven modeli: alternatifler
| Seçenek | Artı | Eksi | 700 cihaz ölçeği | Sonuç |
|---|---|---|---|---|
| Tek kullanımlık, TTL'li token | Küçük sızıntı alanı; kayıp başına iptal edilebilir; cihaz bağlama (BF-<no>) |
Token üretim/i̇ptal hizmeti gerekir | Cihaz başına ayrı kayıt izi | Seçildi (K-17) |
| İmzalı bootstrap bundle (merkez imzalı dosya, cihaz sadece tüketir) | Çevrimiçi token hizmeti gerekmez; imza ile kimlik doğrulama | İmza anahtarı rotasyonu, bundle dağıtım kanalı ve çevrimdışı "eski bundle" riski; geri çekme zor | Bundle sürüm/iptal yönetimi filo çapında iş yükü | Elendi (V1) |
| Paylaşılan kalıcı bootstrap secret | Kurulumu basit | Tek sızıntı tüm filoyu etkiler; cihaz başına iptal imkânsız | Kabul edilemez blast-radius | Elendi |
| Manuel merkezi kayıt | Ek sistem yok | Denetim izi zayıf, insan hatası | 700 kayıt için sürdürülemez | Elendi |
Hiçbir seçenekte 700 cihaza ortak kalıcı secret konmaz. Karar kaydı: docs/24 K-17,
alternatif analizi docs/29 §5.
3.1 Çevrimdışı → çevrimiçi geçiş (katılım) mekanizması
Teknisyen tokenı cihaz başına bir kez iletir:
# İnternet varken anında enrollment (önerilen):
printf '%s\n' '<tek-kullanımlık-token>' | sudo -E bf-enroll --token-stdin
# İnternet yokken: token'ı cihazda bırakmadan boot denemesine hazırla:
printf '%s\n' '<tek-kullanımlık-token>' | sudo -E bf-enroll-now --stage
--stage gerekçesi: saha cihazı çoğu kez önce çevrimdışı kurulur. İnternet geldiğinde
"kendiliğinden katılma" için tek kullanımlık token'ın cihazda sınırlı ömürlü bir
bekleme dosyasında durması gerekir. Uygulanan sınırlar:
- Dosya
<state dir>/enrollment.token, mod0600, sahibi çalıştıran kullanıcı (root), TTLBF_ENROLLMENT_TOKEN_MAX_AGE(varsayılan 1800 sn, süre sonunda silinir). - Token argv'ye, state dosyasına, support bundle'a ve kurulum medyasına (USB/ISO) hiç yazılmaz; yalnız bu tek dosyada ve yalnız boot denemesi okuyabilir.
- Token başarılı enrollment'ta veya kesin (HTTP 4xx) reddedilmede hemen silinir. Yalnız geçici hata (DNS/TCP/TLS/zaman aşımı) token'ı sınırlı yeniden deneme için korur.
- Support bundle bu dosyayı toplamaz;
--stageyalnız root tarafından kullanılabilir.
Bu mekanizma tek kullanımlık token'ın replay engelini değiştirmez: aynı token merkezde
yalnız bir kez tüketilir, idempotency_key retry'leri birleştirir.
4. Başarısızlık davranışı (reboot loop yok)
- HTTP isteği başarısız: yaşam döngüsü önceki aşamada kalır (
PENDING/PROVISIONED_OFFLINE); hiçbir yapılandırma kurulmaz. - Yanıt doğrulaması başarısız: durum dosyası değişmez, geçici dosyalar silinir.
- WireGuard etkinleştirmesi başarısız: yeni
wg0.confgeri alınır (öncesi varsa eski hali geri yüklenir, yoksa unit devre dışı bırakılır), durum dosyası yazılmaz. - Cihaz reboot edilmez:
blueforce-enroll.serviceRestart=on-failure+RestartSec=5min+StartLimitBurst=6/StartLimitIntervalSec=1hile en fazla saati 6 deneme yapar, sonrasıblueforce-enroll.timerkadansına döner. İnternet yokken agresif deneme yapılmaz; internet gelince cihaz kendiliğinden katılır. - Token yoksa veya durum
READY/kurulmamış ise deneme hiçbir iş yapmadan0ile çıkar (PENDINGmesajı ile): yeniden deneme fırtınası oluşmaz.
5. Araçlar ve aşama kapıları
| Araç / unit | Aşama | Not |
|---|---|---|
bf-check-local |
PROVISIONED_OFFLINE |
İnternet, handshake ve merkez kanıtı gerekmez; eksik wg0.conf yalnız uyarıdır |
bf-enroll |
PROVISIONED_OFFLINE -> ENROLLED |
Token stdin'den ya da sahnelenmiş dosyadan; --check dry-run |
bf-check-enrollment |
ENROLLED |
Merkez kaydı + atanmış peer + canlı tünel + yeni handshake; handshake yokluğu başarısızlık |
bf-check-ready |
READY |
Yerel sağlık + tüm merkezi kanallar; kalıcı READY'a güvenmez |
bf-enrollment-status |
tümü (salt-okunur) | Sözleşme doğrulayıcı; INVALID durumda çıkış kodu ≠ 0 |
bf-status |
tümü (salt-okunur) | Provisioning / Enrollment / Fleet State özet bloğu |
blueforce-enroll.service + blueforce-enroll.timer |
otomatik deneme | Boot +10 dk, sonra günlük; sınırlı Restart= |
blueforce-enrollment.timer ayrıca oluşturulmaz: kurucu modül (17-healthcheck) yalnız
blueforce-enroll.service ve blueforce-enroll.timer dosyalarını cihaza kurar; ikinci bir
timer kurulmadığı için ölü yapılandırma olurdu. Periyodik kadans mevcut timer ve
servisin sınırlı Restart= davranışından gelir.
6. Doğrulama
bash tests/test-field-os-lifecycle.sh # sözleşme, aşama geçişleri, fail-closed davranışı
bash tests/check-provisioning-static.sh # şema/secret/cihaz-kimliği taraması
Şemalar JSON Schema 2020-12'dir ve bf-enroll'in gerçek davranışıyla birebir hizalanır
(zorunlu alanlar, wireguard alt alanları, central_verification biçimi). Endpoint
uygulaması, kimlik doğrulama, imzalama, iptal ve deneme politikası ayrı güvenlik
incelemesi olmadan eklenmeyecektir.