docs: Blueforce 700-device fleet architecture (TR) - GNOME baseline

This commit is contained in:
emirhanmamak-blueforce 2026-09-15 17:03:02 +03:00
parent 6402e85b32
commit 0b5664949a
50 changed files with 5284 additions and 0 deletions

View file

@ -0,0 +1,248 @@
# Blueforce 700 Cihaz Linux Filo Mimari + Dokümantasyon Implementation Plan
> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task.
**Goal:** 700 AdBlue saha PC'si için %100 ücretsiz/self-hosted Linux filo mimarisini araştırıp karar vererek, başka bir DevOps mühendisinin sıfırdan kurabileceği 26 Türkçe Markdown dokümanını üretmek.
**Architecture:** Markdown-first Git repo (`blueforce-industrial-linux/`): `docs/` (26 dosya) + `SUMMARY.md` + iskelet `scripts/`, `ansible/`, `config/`, `monitoring/`, `rustdesk/`, `docs-site/`, `tests/`. Önce kaynak doğrulama (resmi docs/GitHub), sonra kararlar, sonra dokümanlar parti parti yazılır.
**Tech Stack:** Ubuntu LTS (26.04 doğrulanacak), WireGuard, RustDesk OSS self-hosted (hbbs/hbbr), xRDP + XFCE/GNOME (karar verilecek), Ansible + Semaphore UI Community, Docker, Prometheus/Node Exporter/Grafana OSS/Uptime Kuma (karşılaştırılacak), Docusaurus (aday docs platformu).
---
## Current Context / Assumptions
- Çalışma dizini: `/home/emirhanmamak/_Work/AMC/Blueforce-Linux` — **boş repo** (sadece `.gitignore` + `.git`). Plan sonunda önerilen repo yapısı sıfırdan kurulacak.
- Şartname kaynağı: kullanıcının yapıştırdığı 28 bölümlük Türkçe şartname (pasted_content_2026-09-15). Implementasyon YOK — sadece araştırma + karar + plan + `.md` üretimi.
- Cihaz kimliği standardı sabit: 8 haneli bayi no → `BF-<no>` (Device ID), `bf-<no>` (hostname). Tüm sistemlerde aynı ID.
- Maliyet kuralı: %100 ücretsiz/self-hosted hedef. Ücretli her araç açıkça işaretlenip alternatifi önerilecek. AnyDesk varsayım yapılmadan resmi kaynaktan doğrulanacak.
- Update politikası: onaysız update yasak (apt, release, Docker, MEG dahil). LAB(2) → PILOT-1(5) → PILOT-2(20) → WAVE-1(50) → WAVE-2(100) → PRODUCTION rollout.
- Basitlik: Kubernetes/microservice/gereksiz agent/DB/cloud yok. Öncelik: kesintisiz çalışma > veri kaybı yok > erişim > bakım kolaylığı.
- Her dokümanda yapı: Amaç, Kapsam, Kararlar, Neden, Alternatifler, Avantaj/Dezavantaj, Riskler, Uygulama Planı, Test Planı, Rollback, Kontrol Listesi, Açık Sorular + uygun yerde Mermaid. Her teknik karar için KARAR/GEREKÇE/ALTERNATİF/RİSK/MALİYET/LİSANS bloğu.
- Çıktı dili Türkçe; komut/dosya/service/terimler İngilizce kalabilir.
## Proposed Approach
1. **Faz 0 — Repo iskeleti:** README + docs/ + önerilen klasör yapısı + docs-site iskeleti. Boş dosya değil, şablonlu başlıklarla.
2. **Faz 1 — Kaynak doğrulama (tahmin yok):** Resmi docs + GitHub üzerinden 10 kritik konuda (Ubuntu 26.04, xRDP/GNOME/XFCE, WireGuard, RustDesk OSS, AnyDesk lisansı, Docker, Ansible, Semaphore Community, Docusaurus/Wiki.js/TriliumNext) doğrulama notları. Her bulgu URL + sürüm + tarih ile kaydedilir.
3. **Faz 2 — Mimari kararlar:** OS/GUI, 4. erişim yöntemi, fleet mgmt, monitoring, docs platformu, golden image yöntemi için karar matrisleri. Sadelik kuralı uygulanır.
4. **Faz 3 — Doküman üretimi (4 parti):** Her parti bağımsız yazılabilir ama karar tutarlılığı için sırayla. Her dosya yukarıdaki şablona uyar.
5. **Faz 4 — QA + eleştiri:** Tutarlılık denetimi (isimlendirme, karar çelişkisi, ücretli sızıntı), SUMMARY.md'deki 27 sorunun cevabı var mı kontrolü, "5 yılda en büyük 10 operasyonel risk" analizi.
6. Paralelleştirme: Faz 1 araştırmaları `delegate_task` ile bağımsız doğrulanabilir; Faz 3 partileri tek yazarda tutulmalı (tutarlılık için) veya sıkı karar günlüğüyle paralel.
## Files Likely to Change (hedef repo yapısı)
```
blueforce-industrial-linux/
├── README.md
├── SUMMARY.md
├── docs/
│ ├── 00-MASTER-PLAN.md
│ ├── 01-ARCHITECTURE.md
│ ├── 02-DEVICE-NAMING-AND-INVENTORY.md
│ ├── 03-UBUNTU-BASELINE.md
│ ├── 04-GOLDEN-IMAGE-AND-PROVISIONING.md
│ ├── 05-ONE-CLICK-INSTALLER.md
│ ├── 06-USERS-SSH-AND-PERMISSIONS.md
│ ├── 07-REMOTE-ACCESS.md
│ ├── 08-WIREGUARD-AND-NETWORK.md
│ ├── 09-FLEET-MANAGEMENT.md
│ ├── 10-UPDATE-AND-ROLLBACK-POLICY.md
│ ├── 11-SECURITY-HARDENING.md
│ ├── 12-DOCKER-OPERATIONS.md
│ ├── 13-MEG-LINUX-ACCEPTANCE.md
│ ├── 14-MONITORING-AND-HEALTH.md
│ ├── 15-LOGGING.md
│ ├── 16-POWER-LOSS-AND-AUTO-RECOVERY.md
│ ├── 17-BACKUP-RECOVERY-AND-REINSTALL.md
│ ├── 18-PILOT-AND-700-DEVICE-ROLLOUT.md
│ ├── 19-TROUBLESHOOTING.md
│ ├── 20-FIELD-TECHNICIAN-RUNBOOK.md
│ ├── 21-CENTRAL-ADMIN-RUNBOOK.md
│ ├── 22-DOCUMENTATION-PLATFORM.md
│ ├── 23-SECURITY-AND-LICENSE-AUDIT.md
│ ├── 24-DECISION-LOG.md
│ └── 25-IMPLEMENTATION-ROADMAP.md
├── scripts/ (install/, maintenance/, diagnostics/, recovery/ — Faz 3'te sadece sözleşme/imza, kod Faz-sonrası)
├── ansible/ (inventory/, playbooks/, roles/)
├── config/ (ssh/, wireguard/, firewall/, docker/, systemd/)
├── monitoring/ | rustdesk/ | docs-site/ | tests/
```
## Step-by-Step Plan
### Task 1: Repo iskeleti + doküman şablonu + karar bloğu standardı
**Objective:** Boş repoya hedef klasör yapısı ve her doc'un uyacağı şablon konur.
**Files:**
- Create: `README.md`, `docs/_TEMPLATE.md`, klasörler `docs/ scripts/{install,maintenance,diagnostics,recovery} ansible/{inventory,playbooks,roles} config/{ssh,wireguard,firewall,docker,systemd} monitoring/ rustdesk/ docs-site/ tests/`
**Step 1:** `README.md` yaz — amaç, 700 cihaz özeti, docs haritası, maliyet kuralı, isimlendirme örneği (BF-12010193).
**Step 2:** `docs/_TEMPLATE.md` yaz — 12 başlık (Amaç…Açık Sorular) + KARAR/GEREKÇE/ALTERNATİF/RİSK/MALİYET/LİSANS bloğu + Mermaid örneği.
**Step 3:** Klasörleri oluştur, `git status` ile doğrula.
**Step 4:** Commit: `docs: repo skeleton and doc template`.
**Verify:** `ls docs/ scripts ansible config` beklenen ağacı verir; şablon 12 başlığı içerir.
### Task 2: Kaynak doğrulama paketi A — OS/GUI/RDP + WireGuard + Docker
**Objective:** Tahmine dayalı kararları engellemek için resmi kaynak bulguları toplanır.
**Files:**
- Create: `docs/24-DECISION-LOG.md` (taslak, sadece Faz-1 bulguları bölümü) — veya geçici `research/A.md` sonra taşınır. Öneri: doğrudan 24'e işle, kaynak URL + sürüm + tarih ile.
**Doğrulanacaklar (resmi docs/GitHub, web_search + web_extract):**
1. Ubuntu 26.04 LTS var mı / saha için uygun mu; minimal+GUI vs Server+XFCE/GNOME davranışları; `unattended-upgrades` varsayılanı (update yasağı için kritik).
2. xRDP + GNOME vs XFCE: RAM/CPU, RDP uyumluluğu, 700 ölçeği. `bf-gui-on/off` için dayanak (target/DM servisi).
3. WireGuard: otomatik reconnect davranışı (PersistentKeepalive, systemd restart), Turkcell NAT arkası notları.
4. Docker: UFW bypass senaryosu + güvenli çözüm; log rotation; `unless-stopped` vs `always`; `latest` yasağı dayanağı; Watchtower kullanılmaması gerekçesi.
**Verify:** Her bulguda en az 1 resmi URL; "ücretsiz" iddiası lisans metniyle destekli. Çıktı 24-DECISION-LOG'a işlenir.
### Task 3: Kaynak doğrulama paketi B — RustDesk OSS + AnyDesk lisansı + 4. erişim
**Objective:** 4-kanallı erişim mimarisinin lisans ve teknik dayanağı netleşir.
**Files:**
- Modify: `docs/24-DECISION-LOG.md` (B bulguları ekle)
**Doğrulanacaklar:**
1. RustDesk OSS self-hosted: hbbs/hbbr VDS kurulumu, Pro gerektirmeyen özellikler, WireGuard çökerse çalışmaya devam eder mi (bağımsız kanal analizi).
2. AnyDesk ticari lisans şartları (resmi fiyat/lisans sayfası): 700 kurumsal cihazda ücretsiz kullanım yasal mı? Sonuç EVET/HAYIR + URL. HAYIR ise mimariden çıkar, sadece opsiyonel installer modülü olarak kalır.
3. 4. bağımsız ücretsiz erişim adayı: MeshCentral / SSH-over-WireGuard / Tailscale-freesiz? — Tailscale gibi freemium tuzaklarına düşmeden gerçek OSS/self-hosted seç (şartname: SSH, RDP, RustDesk + 1 daha).
**Verify:** AnyDesk kararı tek cümle + resmi URL ile 07-REMOTE-ACCESS ve 23'e taşınmaya hazır.
### Task 4: Kaynak doğrulama paketi C — Fleet (Ansible/Semaphore/AWX/Salt/Rudder/MeshCentral) + Monitoring + Docs platformu
**Objective:** Fleet, monitoring ve docs platformu kararlarının dayanağı toplanır.
**Files:**
- Modify: `docs/24-DECISION-LOG.md` (C bulguları ekle)
**Doğrulanacaklar:**
1. Semaphore UI Community: yalnız free/OSS özellikleri listele, Pro/Enterprise bağımlılığı yok. Ansible CLI, AWX, Salt, Rudder Community, MeshCentral ile karşılaştırma (700 cihaz sadeliği).
2. Monitoring: Prometheus+Node Exporter+Grafana OSS vs Netdata Community vs Uptime Kuma — 700 cihazda karmaşıklık/maliyet. Minimum metrik listesi (online/offline … last seen) hangi çözümde nasıl toplanır.
3. Docs: Docusaurus vs MkDocs vs Wiki.js vs TriliumNext — ücretsiz/OSS/self-hosted/Git/Markdown/AI-güncellenebilirlik/search/sidebar/kod/Mermaid/koyu tema/intranet kriterlerine göre tek öneri.
**Verify:** Her kategoride "tek öneri + gerekçe + alternatif" cümlesi hazır.
### Task 5: Mimari kararları kilitle — 24-DECISION-LOG + 01-ARCHITECTURE
**Objective:** Tüm kritik kararlar tek dosyada kilitlenir, mimari diyagram çizilir.
**Files:**
- Modify: `docs/24-DECISION-LOG.md` (nihai karar tablosu), Create: `docs/01-ARCHITECTURE.md`
**Kararlar (her biri KARAR/GEREKÇE/ALTERNATİF/RİSK/MALİYET/LİSANS):**
Ubuntu sürümü/varyantı, GNOME/XFCE, boot=terminal + bf-gui-on/off, SSH/RDP/RustDesk/4.yöntem, WireGuard modeli, fleet çözümü, monitoring, docs platformu, golden image yöntemi, Docker restart politikası.
**Mermaid (01'e):** Internet → WireGuard → SSH/RDP/Mgmt akışı; power boot zinciri (Power→BIOS→Ubuntu→Network→WireGuard→Docker→MEG→Blueforce→Remote→Monitoring); update onay akışı (bulundu→rapor→onay→LAB→PILOT→WAVE→PROD).
**Verify:** SUMMARY.md'deki 27 sorunun her biri en az bir karara izlenebilir.
### Task 6: Parti 1 dokümanlar — isimlendirme, Ubuntu, golden image, installer
**Objective:** Saha kurulumunun çekirdek 4 dosyası yazılır.
**Files:**
- Create: `docs/00-MASTER-PLAN.md`, `docs/02-DEVICE-NAMING-AND-INVENTORY.md`, `docs/03-UBUNTU-BASELINE.md`, `docs/04-GOLDEN-IMAGE-AND-PROVISIONING.md`, `docs/05-ONE-CLICK-INSTALLER.md`
**Notlar:**
- 02: `BF-<8hane>` / `bf-<8hane>` standardı + kullanıldığı 9 sistem listesi + `bf-hardware-inventory.sh` sözleşmesi (JSON+Markdown çıktı alanları: Manufacturer…Temperatures).
- 03: BIOS `Restore on AC Power Loss = Power On`, boot servisleri, GUI on/off tasarımı, GNOME/XFCE kararı.
- 04: Clonezilla/autoinstall/cloud-init/custom ISO/Packer/Ansible karşılaştırması; hedef: USB→Ubuntu→tek script→bayi no→READY.
- 05: `sudo ./blueforce-install.sh` akışı, `^[0-9]{8}$` doğrulama, modül listesi (01-precheck…18-final-check) değerlendirilmiş/geliştirilmiş hali, idempotency kuralı.
**Verify:** Her dosya 12 başlıklı şablona uyar; 05'teki modül listesi 01-precheck…18-final-check ile birebir eşleşir veya sapma gerekçelendirilir.
### Task 7: Parti 2 — erişim, ağ, filo, update
**Objective:** Kritik operasyon 4 dosyası yazılır.
**Files:**
- Create: `docs/06-USERS-SSH-AND-PERMISSIONS.md`, `docs/07-REMOTE-ACCESS.md`, `docs/08-WIREGUARD-AND-NETWORK.md`, `docs/09-FLEET-MANAGEMENT.md`, `docs/10-UPDATE-AND-ROLLBACK-POLICY.md`
**Notlar:**
- 06: `blueforce` kullanıcısı, root SSH kapalı, password SSH kapalı, key zorunlu, sudo kontrollü, servisler ayrı system user; 700 cihazda tek private key riski + doğru auth mimarisi (host başına key / CA önerisi).
- 07: SSH+RDP+RustDesk+dördüncü yöntem; boot otostart; RDP/SSH dışa kapalı, WireGuard arkası; WireGuard çökerse RustDesk analizi.
- 08: peer isimlendirme = bayi ID, PersistentKeepalive, otomatik reconnect, Turkcell paket bitimi/dönüşü senaryosu.
- 09: tek/grup/pilot/tüm-filo işlemleri (ping…GUI OFF listedeki 15 komut), Semaphore Community sınırları içinde.
- 10: onaysız update yasağı + unattended-upgrades kapatma + LAB→…→PROD dalgaları + durdurma/rollback + security update öncelik işareti.
**Verify:** 09'daki 15 işlemin her biri Ansible/Semaphore karşılığına izlenir; 10'daki dalga sayıları LAB(2)/P1(5)/P2(20)/W1(50)/W2(100)/PROD ile eşleşir.
### Task 8: Parti 3 — güvenlik, Docker, MEG, monitoring, log, power
**Objective:** Dayanıklılık 6 dosyası yazılır.
**Files:**
- Create: `docs/11-SECURITY-HARDENING.md`, `docs/12-DOCKER-OPERATIONS.md`, `docs/13-MEG-LINUX-ACCEPTANCE.md`, `docs/14-MONITORING-AND-HEALTH.md`, `docs/15-LOGGING.md`, `docs/16-POWER-LOSS-AND-AUTO-RECOVERY.md`
**Notlar:**
- 11: UFW default DENY, WG arayüzü izinleri, Docker-UFW bypass çözümü, personel yetkisizliği.
- 12: otostart, restart policy, pinli image, `latest` yasağı, log rotation, Watchtower yok.
- 13: MEG ACCEPTANCE TEST checklist (Ubuntu sürümü…package update davranışı — 16 madde), paket detayı varsayılmadan.
- 14: minimum 17 metrik (online…last seen) + dashboard mimarisi + `bf-status` örnek çıktısı + `bf-diagnostics`/`bf-support-bundle` (secret sızdırmaz) sözleşmesi.
- 15: journald/Docker/RustDesk/WG/MEG/Blueforce/installer/update-history limitleri.
- 16: boot zinciri systemd bağımlılıkları, race condition önlemleri.
**Verify:** 14'teki örnek `bf-status` çıktısı şartnamedeki 16 satırlı formata uyar; support-bundle'da secret dışlama kuralı yazılı.
### Task 9: Parti 4 — recovery, rollout, runbook'lar, docs platformu, audit, roadmap
**Objective:** Son 8 dosya + tutarlılık kapanışı.
**Files:**
- Create: `docs/17-BACKUP-RECOVERY-AND-REINSTALL.md`, `docs/18-PILOT-AND-700-DEVICE-ROLLOUT.md`, `docs/19-TROUBLESHOOTING.md`, `docs/20-FIELD-TECHNICIAN-RUNBOOK.md`, `docs/21-CENTRAL-ADMIN-RUNBOOK.md`, `docs/22-DOCUMENTATION-PLATFORM.md`, `docs/23-SECURITY-AND-LICENSE-AUDIT.md`, `docs/25-IMPLEMENTATION-ROADMAP.md`
**Notlar:**
- 17: LEVEL 1…9 recovery (service→…→golden image reinstall), her seviyede merkezi+yerel prosedür.
- 18: donanım bilinmediği için önce `bf-hardware-inventory.sh` taraması, sonra dalgalı rollout.
- 20: teknisyen diliyle sade (USB→kur→bayi no→READY), 21: merkezi admin (onay yetkisi kimde, update'i kim başlatır).
- 23: her ücretli aday için ÜCRETLİ işareti + ücretsiz alternatif; AnyDesk hükmü.
- 25: FAZ'lı yol haritası; unattended provisioning ayrı FAZ.
**Verify:** LEVEL sayısı 9; 20 saha diliyle, 21 merkez diliyle ayrışır.
### Task 10: SUMMARY.md + 10 risk eleştirisi + final QA
**Objective:** Teslim kapanışı ve mimari öz-eleştirisi.
**Files:**
- Create: `SUMMARY.md` (repo kökü), Modify: gerekirse tutarlılık düzeltmeleri
**SUMMARY.md içeriği:** 27 sorunun kesin cevabı (hangi Ubuntu…hangi platform — her cevap ilgili doc'a linkli) + "Bu sistem 700 istasyonda 5 yıl çalışacak olsa en büyük 10 operasyonel risk" (her risk + önlem) + gerçekten tamamen ücretsiz olanların listesi.
**Final QA checklist:**
- [ ] 26 dosya var, hepsi Türkçe, şablonlu, Mermaid yerinde.
- [ ] Cihaz adı `BF-…`/hostname `bf-…` her doc'ta tutarlı.
- [ ] Ücretli hiçbir araç zorunlu mimaride değil; AnyDesk hükmü resmi URL'li.
- [ ] Onaysız update'e giden hiçbir varsayılan açık değil (unattended-upgrades dahil).
- [ ] 27 sorunun cevabı SUMMARY'den doc'lara izlenebilir.
- [ ] Commit: `docs: complete fleet documentation v1`.
## Tests / Validation
- `ls docs/ | wc -l` = 26 (+ `_TEMPLATE.md`).
- `grep -r "AnyDesk" docs/23-SECURITY-AND-LICENSE-AUDIT.md` lisans hükmü + resmi URL içerir.
- `grep -ri "unattended" docs/10-UPDATE-AND-ROLLBACK-POLICY.md docs/03-UBUNTU-BASELINE.md` kapatma adımı içerir.
- Her doc'ta 12 başlığın varlığı: `for f in docs/*.md; do grep -c "^## " $f; done` — eksik başlık yok.
- Mermaid blok sayısı: `grep -r '```mermaid' docs/ | wc -l` ≥ 4 (mimari, ağ, update, power).
- Tutarlılık: `grep -rho "BF-[0-9]\{8\}" docs/ | sort -u` örnekleri ve `bf-gui-on|bf-status|bf-diagnostics|bf-support-bundle|bf-hardware-inventory` adları tüm doc'larda aynı.
## Risks, Tradeoffs, Open Questions
- **Ubuntu 26.04 (2026 itibarıyla):** Şartname 26.04 diyor; doğrulamada mevcut değilse/uygun değilse 24.04 LTS'e düşme kararı + gerekçesi gerekir. [AÇIK]
- **Donanım bilinmiyor:** amd64/arm64, serial/RS232/USB, GPU karışık olabilir → golden image tek imajda çalışmayabilir; önce inventory taraması şart. [RİSK]
- **MEG .deb detayları yok:** Acceptance testi varsayımsız yazılacak; paket gelince 13 numaralı doc revize edilir. [AÇIK]
- **Turkcell NAT/kota:** WireGuard keepalive + kotasız yönetim trafiği minimizasyonu (monitoring aralığı) dengesi. [RİSK]
- **Tek private SSH key:** 700 cihaza yayılırsa sızıntı blast-radius'u büyük → ev sahibi CA / per-admin key önerisi. [RİSK]
- **Semaphore Community sınırları:** Pro özelliğine yaslanılırsa maliyet kuralı delinir; her playbook Community ile test edilmeli. [RİSK]
- **Tradeoff — sadelik vs gözetlenebilirlik:** 700 cihazda full Prometheus yerine hafif push + Uptime Kuma kombinasyonu seçilebilir; Faz 2'de kilitlenir.
- **Kapsam dışı (bu planda YOK):** Script kodlarının implementasyonu, VDS kurulumu, gerçek cihaz testi — bunlar 25-ROADMAP'in sonraki FAZ'ları.
---
**Kaynak:** Kullanıcı şartnamesi (28 bölüm, 1042 satır, pasted_content_2026-09-15). Maliyet/lisans/karar kuralları şartnameden birebir alınmıştır.

116
README.md Normal file
View file

@ -0,0 +1,116 @@
# Blueforce Linux Filo — 700 Saha Cihazı
> %100 ücretsiz / self-hosted Linux filo mimarisi: başka bir DevOps mühendisinin sıfırdan kurabileceği 26 Türkçe dokümanın ana reposu.
## Amaç
AdBlue saha otomasyonundaki ~700 Windows mini PC'yi, lisans maliyeti olmayan, merkezi yönetilebilir, kesintisiz çalışan bir Linux filosuna taşımak.
Bu repo üç şeyi tek yerde toplar:
1. **Kararlar** — her teknik seçim için gerekçe, alternatif, risk, maliyet ve lisans notu.
2. **Kurulum ve işletme dokümanları** — `docs/` altında 26 Türkçe Markdown dosyası.
3. **Uygulanabilir iskelet** — `scripts/`, `ansible/`, `config/`, `monitoring/`, `rustdesk/` klasörleri (kod ve config Faz 3'te dolar).
Öncelik sırası: **kesintisiz çalışma > veri kaybı yok > uzaktan erişim > bakım kolaylığı.**
## 700 Cihaz Özeti
| Konu | Özet |
|---|---|
| Cihaz sayısı | ~700 saha PC'si (bayi/istasyon yanında) |
| Cihaz kimliği | 8 haneli bayi no → Device ID `BF-<no>`, hostname `bf-<no>` (ör. `BF-12010193` / `bf-12010193`). Tüm sistemlerde aynı ID kullanılır. |
| Hedef OS | Ubuntu LTS (sürüm Faz 1'de resmi kaynaktan doğrulanacak) |
| Ağ | Turkcell modem arkası, CGNAT/NAT varsayımı; merkezle bağlantı WireGuard tüneli üzerinden |
| Uzaktan erişim | RustDesk OSS self-hosted (hbbs/hbbr) ana yol; SSH + WireGuard yedek yol; RDP/GUI ihtiyaca göre |
| Filo yönetimi | Ansible + Semaphore UI Community (aday; Faz 2'de karar) |
| İzleme | Prometheus/Node Exporter/Grafana OSS veya Uptime Kuma (Faz 2'de karşılaştırılacak) |
| Güncelleme politikası | **Onaysız update yasak** (apt, release upgrade, Docker image, MEG dahil). Rollout: LAB(2) → PILOT-1(5) → PILOT-2(20) → WAVE-1(50) → WAVE-2(100) → PRODUCTION |
| Doküman dili | Türkçe; komut, dosya, servis ve terim adları İngilizce kalır |
## Docs Haritası (26 dosya)
Tüm dokümanlar `docs/` altındadır ve `docs/_TEMPLATE.md` şablonuna uyar.
| No | Dosya | Konu |
|---|---|---|
| 00 | `00-MASTER-PLAN.md` | Genel plan, fazlar, kapsam |
| 01 | `01-ARCHITECTURE.md` | Uçtan uca mimari |
| 02 | `02-DEVICE-NAMING-AND-INVENTORY.md` | `BF-<no>` / `bf-<no>` isimlendirme ve envanter |
| 03 | `03-UBUNTU-BASELINE.md` | Ubuntu taban kurulum |
| 04 | `04-GOLDEN-IMAGE-AND-PROVISIONING.md` | Golden image ve ilk kurulum |
| 05 | `05-ONE-CLICK-INSTALLER.md` | Tek-tık kurucu |
| 06 | `06-USERS-SSH-AND-PERMISSIONS.md` | Kullanıcılar, SSH, yetkiler |
| 07 | `07-REMOTE-ACCESS.md` | RustDesk + SSH + RDP erişim yolları |
| 08 | `08-WIREGUARD-AND-NETWORK.md` | WireGuard ve ağ |
| 09 | `09-FLEET-MANAGEMENT.md` | Ansible/Semaphore filo yönetimi |
| 10 | `10-UPDATE-AND-ROLLBACK-POLICY.md` | Güncelleme ve geri alma politikası |
| 11 | `11-SECURITY-HARDENING.md` | Güvenlik sertleştirme |
| 12 | `12-DOCKER-OPERATIONS.md` | Docker işletimi |
| 13 | `13-MEG-LINUX-ACCEPTANCE.md` | MEG Linux kabul kriterleri |
| 14 | `14-MONITORING-AND-HEALTH.md` | İzleme ve sağlık |
| 15 | `15-LOGGING.md` | Log toplama ve saklama |
| 16 | `16-POWER-LOSS-AND-AUTO-RECOVERY.md` | Elektrik kesintisi ve otomatik kurtarma |
| 17 | `17-BACKUP-RECOVERY-AND-REINSTALL.md` | Yedekleme, kurtarma, yeniden kurulum |
| 18 | `18-PILOT-AND-700-DEVICE-ROLLOUT.md` | Pilot ve 700 cihaz rollout |
| 19 | `19-TROUBLESHOOTING.md` | Sorun giderme |
| 20 | `20-FIELD-TECHNICIAN-RUNBOOK.md` | Saha teknisyeni runbook |
| 21 | `21-CENTRAL-ADMIN-RUNBOOK.md` | Merkezi yönetici runbook |
| 22 | `22-DOCUMENTATION-PLATFORM.md` | Doküman platformu (Docusaurus adayı) |
| 23 | `23-SECURITY-AND-LICENSE-AUDIT.md` | Güvenlik ve lisans denetimi |
| 24 | `24-DECISION-LOG.md` | Karar günlüğü (kaynak URL + sürüm + tarih ile) |
| 25 | `25-IMPLEMENTATION-ROADMAP.md` | Uygulama yol haritası |
Şablon: `docs/_TEMPLATE.md`. Karar günlüğü: `docs/24-DECISION-LOG.md`.
## Maliyet Kuralı
- Hedef **%100 ücretsiz / self-hosted**'dir.
- Ücretli veya lisans kısıtlı her araç dokümanda açıkça işaretlenir ve **ücretsiz alternatifi** ile birlikte verilir.
- Varsayıma dayalı lisans kararı verilmez; resmi kaynak (resmi docs, GitHub, fiyat sayfası) URL + sürüm + tarih ile kaydedilir.
- Örnek: AnyDesk kararı resmi kaynaktan doğrulanmadan yazılmaz.
## İsimlendirme Örneği
Bayi no `12010193` için:
- Device ID: `BF-12010193`
- Hostname: `bf-12010193`
- WireGuard peer adı, RustDesk ID etiketi, Ansible inventory adı, monitoring etiketi: hepsi aynı ID'yi kullanır.
## Klasör Yapısı
```
.
├── README.md
├── SUMMARY.md # Faz 4'te üretilecek
├── docs/ # 26 doküman (00–25) + _TEMPLATE.md
├── scripts/
│ ├── install/ # ilk kurulum scriptleri (Faz 3'te sözleşme/imza)
│ ├── maintenance/ # bakım scriptleri
│ ├── diagnostics/ # tanı scriptleri
│ └── recovery/ # kurtarma scriptleri
├── ansible/
│ ├── inventory/
│ ├── playbooks/
│ └── roles/
├── config/
│ ├── ssh/
│ ├── wireguard/
│ ├── firewall/
│ ├── docker/
│ └── systemd/
├── monitoring/ # izleme config ve panoları
├── rustdesk/ # hbbs/hbbr self-hosted config
├── docs-site/ # doküman sitesi iskeleti (Docusaurus adayı)
├── tests/ # doğrulama testleri
└── research/ # Faz 1 kaynak doğrulama notları
```
## Durum
- [x] Faz 0: repo iskeleti + şablon
- [ ] Faz 1: kaynak doğrulama (resmi docs/GitHub, 10 kritik konu)
- [ ] Faz 2: mimari kararlar
- [ ] Faz 3: 26 dokümanın parti parti yazımı
- [ ] Faz 4: QA, tutarlılık denetimi, SUMMARY.md

146
SUMMARY.md Normal file
View file

@ -0,0 +1,146 @@
# Blueforce Linux — Yönetici Özeti (SUMMARY)
> 700 saha cihazlık filonun kesin kararları, en büyük 10 operasyonel riski ve ücretsiz-bileşen listesi.
> Ayrıntı `docs/` dosyalarındadır; her cevap ilgili dokümana linklenir. Kararların kilit kaynağı
> [`docs/24-DECISION-LOG.md`](docs/24-DECISION-LOG.md) (K-01…K-14), izlenebilirlik tablosu Ek B'dedir (S-01…S-27).
> Mimari tek bakış: [`docs/01-ARCHITECTURE.md`](docs/01-ARCHITECTURE.md). Commit yok, FREE sürümler baz.
---
## 1. Şartnamedeki 27 Sorunun Kesin Cevabı
1. **Hangi Ubuntu? Server mı Desktop mı?** — Ubuntu **Server 26.04.1+ LTS**, GUI'siz minimal kurulum.
Desktop ISO'sunun 6 GB RAM şartı saha bütçesini zorlar; GUI sonradan eklenir. → [`03`](docs/03-UBUNTU-BASELINE.md) (K-01)
2. **GNOME mu XFCE mi?** — Cevap **GNOME** (Ubuntu Desktop standardı, kullanıcı kararı); XFCE elendi.
→ [`03`](docs/03-UBUNTU-BASELINE.md) (K-02)
3. **Normal boot GUI mi terminal mi?** — Cihazlar **terminale** (`multi-user.target`) boot eder;
kapalı GUI = düşük RAM, düşük saldırı yüzeyi, öngörülebilir boot. → [`03`](docs/03-UBUNTU-BASELINE.md), [`16`](docs/16-POWER-LOSS-AND-AUTO-RECOVERY.md) (K-03)
4. **GUI nasıl açılıp kapatılacak?** — `sudo bf-gui-on` / `sudo bf-gui-off` ile systemd üzerinden
(display-manager + `xrdp`/`xrdp-sesman`); varsayılan kapalıdır. → [`03`](docs/03-UBUNTU-BASELINE.md), [`07`](docs/07-REMOTE-ACCESS.md) (K-03)
5. **Cihaz isimlendirme standardı?** — 8 haneli bayi no → insan arayüzünde `BF-<no>` (büyük),
makine adında `bf-<no>` (küçük); 9 sistemde (hostname, WireGuard peer, RustDesk, MeshCentral,
Ansible, Prometheus, log, envanter, runbook) join anahtarıdır. Örn. `BF-12010193` / `bf-12010193`. → [`02`](docs/02-DEVICE-NAMING-AND-INVENTORY.md) (K-12)
6. **İlk PC hazırlığı nasıl?** — İmaj dondurulmadan **önce** `bf-hardware-inventory.sh` ile donanım
taraması (CPU/RAM/disk/NIC/GPU profilleri); profilsiz imaj sahada rastgele kırılır. → [`18`](docs/18-PILOT-AND-700-DEVICE-ROLLOUT.md), [`02`](docs/02-DEVICE-NAMING-AND-INVENTORY.md) (K-09)
7. **Yeni PC kurulumu kaç adım?** — Teknisyen için **4 adım**: USB tak → Ubuntu kur →
`blueforce-install.sh` + 8 haneli bayi no → `bf-status` ile READY gör, çık (<15 dk aktif iş). → [`20`](docs/20-FIELD-TECHNICIAN-RUNBOOK.md), [`04`](docs/04-GOLDEN-IMAGE-AND-PROVISIONING.md) (K-09)
8. **Installer nasıl çalışacak?** — Tek giriş `blueforce-install.sh --dealer-id <8hane>`; **18 idempotent
modül** (precheck → dealer-id → paketler → GNOME → xRDP → SSH → WireGuard → Docker → MEG → RustDesk →
MeshCentral → monitoring → firewall → envanter → logging → boot → bootstrap → final-check),
çıkış kodu 0 = READY, format kapısı + onay ekranlı. → [`05`](docs/05-ONE-CLICK-INSTALLER.md) (K-09)
9. **WireGuard mimarisi?** — **Hub-spoke**: merkez hub (`10.8.0.1`), her cihaz spoke (peer adı `bf-<no>`,
sabit `/32`); istemcide `PersistentKeepalive = 25` + `wg-quick@wg0` enable; SSH/RDP yalnızca tünel
içinden, dış dünyaya kapalı. → [`08`](docs/08-WIREGUARD-AND-NETWORK.md) (K-05)
10. **SSH güvenliği nasıl?** — `blueforce` bakım kullanıcısı + **anahtar zorunlu**, password auth kapalı,
root SSH kapalı; 700 cihaza tek private key **yayılmaz** — admin başına anahtar, Ansible ile merkezi
`authorized_keys` dağıtımı, uzun vadede SSH CA hedefi. → [`06`](docs/06-USERS-SSH-AND-PERMISSIONS.md) (K-13)
11. **RDP nasıl?** — **xRDP + GNOME**, yalnızca WireGuard üzerinden; internete açık RDP portu yoktur.
Grafik katman kapalıyken RDP açılmaz (`bf-gui-on` gerekir). → [`07`](docs/07-REMOTE-ACCESS.md) (K-03/K-05)
12. **RustDesk self-host neyi kapsar?** — **RustDesk OSS** istemci + `hbbs`/`hbbr` kendi VDS'imizde;
sınırsız istemci, E2E şifreli oturum, dosya transferi, katılımsız erişim — hepsi ücretsiz. İstemci VDS
genel adresine doğrudan çıktığı için **WireGuard çökse bile** kanal ayaktadır. → [`07`](docs/07-REMOTE-ACCESS.md) (K-04)
13. **AnyDesk ücretsiz kullanılabilir mi?** — **HAYIR.** Free sürüm yalnızca kişisel kullanımı kapsar;
700 kurumsal cihaz ticari kullanımdır, lisanssız kullanım sözleşme ihlalidir. Mimari dışıdır; yalnızca
müşteride zaten ticari lisans varsa opsiyonel `--with-anydesk` modülü. → [`07`](docs/07-REMOTE-ACCESS.md), [`23`](docs/23-SECURITY-AND-LICENSE-AUDIT.md) (K-04)
14. **4. erişim kanalı ne?** — **MeshCentral** (self-hosted, Apache-2.0): ikincil yönetim düzlemi
(terminal/dosya/envanter), RustDesk gibi WireGuard-bağımsız. 4 kanal = SSH-over-WG, xRDP, RustDesk, MeshCentral. → [`07`](docs/07-REMOTE-ACCESS.md) (K-04)
15. **Fleet yönetimi ne?** — Birincil **Ansible CLI** (SSH, agent'sız); **15 standart işlem**
(`bf-ping`, `bf-status`, `bf-gui-on/off`, `reboot`…) playbook + Semaphore task şablonu olarak tanımlı;
serbest komut yalnızca acil prosedürle; hedefleme tek → grup → pilot → tüm-filo. → [`09`](docs/09-FLEET-MANAGEMENT.md) (K-06)
16. **Semaphore kullanmalı mıyız?** — Evet, **Semaphore UI Community** (self-hosted, MIT, $0) operatör
arayüzü olarak; Semaphore çökse Ansible CLI bağımsız çalışır. **Pro gerekmez** (zaten 500 node
sınırıyla 700 cihaza yetmez). Community'de OIDC/2FA/Vault yoktur → yalnızca WireGuard arkasından erişim. → [`09`](docs/09-FLEET-MANAGEMENT.md) (K-06)
17. **Monitoring ne?** — Birincil **Prometheus + Node Exporter + Grafana OSS** (17 metriğin tamamı,
özel metrikler textfile `.prom` ile); tamamlayıcı **Uptime Kuma** (teknisyen dostu UP/DOWN + Push
"last seen" + bildirim). Netdata Cloud Free 5 node kotasıyla elendi. → [`14`](docs/14-MONITORING-AND-HEALTH.md) (K-07)
18. **Update onayı nasıl, kim başlatır, başarısız olursa ne olur?** — **Onaysız update yasaktır.**
Başlatma yetkisi yalnızca **merkezi yöneticide** (asıl + vekil); her dalga Semaphore onay kapısından
geçer: LAB(2) → P1(5) → P2(20) → W1(50) → W2(100) → PROD(~523). Başarısız dalga bir sonrakine geçmez,
yayılım durur, etkilenmiş dalga rollback zinciriyle geri alınır; acil yamalar da aynı zincirden
(kısaltılmış bekleme, kapılar kalkmaz) geçer. → [`10`](docs/10-UPDATE-AND-ROLLBACK-POLICY.md), [`21`](docs/21-CENTRAL-ADMIN-RUNBOOK.md) (K-11)
19. **`unattended-upgrades` ne olacak?** — Golden image'da **kapalı** (`20auto-upgrades` değerleri `0` +
`apt-daily*.timer` maskeleme); kapatılmazsa Ubuntu varsayılanı 700 cihazı ilk açılışta güncellemeye
kalkar. Kilit, kurucu final-check + monitoring metriğiyle denetlenir. → [`03`](docs/03-UBUNTU-BASELINE.md), [`10`](docs/10-UPDATE-AND-ROLLBACK-POLICY.md) (K-11)
20. **Docker politikası ne?** — Restart `unless-stopped`; **`latest` yasak** (sabit tag, digest P2'de
değerlendirilir); **Watchtower yasak**; log rotasyonu `daemon.json`'da zorunlu; yayımlanan portlar
UFW bypass'a karşı **`127.0.0.1`**'e bağlanır. → [`12`](docs/12-DOCKER-OPERATIONS.md), [`11`](docs/11-SECURITY-HARDENING.md) (K-10)
21. **Log disiplini + disk dolması engeli?** — journald kalıcı + tavanlı (`SystemMaxUse`/`MaxFileSec`),
Docker `json-file` rotasyonlu, 7 kaynak standardı + `bf-status`/`bf-diagnostics`/`bf-support-bundle`
(secret sızdırmaz); merkezi Loki/ELK ilk fazda yok (Faz-sonrası hedef). Rotasyonsuz log = kilitlenen
cihaz kuralıyla disk taşması mimari düzeyde engellenir. → [`15`](docs/15-LOGGING.md), [`12`](docs/12-DOCKER-OPERATIONS.md) (K-14/K-10)
22. **Elektrik kesintisi ve dönüşü?** — BIOS `Restore on AC Power Loss = Power On` ile cihaz kendiliğinden
açılır; systemd sıralı boot zinciri (network → `wg-quick` → docker → MEG → agent'lar) + `unless-stopped`
ile her katman kendiliğinden toparlanır, ek kurtarma servisi yoktur. → [`16`](docs/16-POWER-LOSS-AND-AUTO-RECOVERY.md) (K-03/K-10)
23. **İnternet paketi bitimi ve dönüşü?** — Kota bitince tünel sessizce ölür (arıza değil, "çevrimdışı"
görünür; Kuma "last seen" alarmı + bayiye bildirim); kota dönüşünde `wg-quick` + keepalive **kendiliğinden**
yeniden handshake eder, ek işlem gerekmez. Kota-dostu keepalive (25 sn, PİLOT verisiyle ayarlanır). → [`08`](docs/08-WIREGUARD-AND-NETWORK.md) (K-05)
24. **PC bozulunca teknisyen ne yapar?** — **9 seviyeli kurtarma merdiveni** (L1 servis restart → … →
L8 USB ile sıfırdan imaj → L9 merkez inşası); cihaz "değiştirilebilir" sayılır, kimlik + config merkezden
yeniden basılır, cihaz-başı veri yedeği yoktur. Çoğu arıza 4 kanaldan biriyle uzaktan çözülür, sahaya
gidilmez. → [`17`](docs/17-BACKUP-RECOVERY-AND-REINSTALL.md), [`20`](docs/20-FIELD-TECHNICIAN-RUNBOOK.md)
25. **Golden image yöntemi ne?** — Kimliksiz zemin (Server 26.04.1+ minimal + update kapalı + kurucu) USB/autoinstall
ile kurulur; cihaz-spesifik kimlik (`bf-<no>`) imajda **değil ilk açılışta** enjekte edilir. Clonezilla
bit-kopya yalnızca yedek yöntemdir (donanım-fragil). → [`04`](docs/04-GOLDEN-IMAGE-AND-PROVISIONING.md), [`05`](docs/05-ONE-CLICK-INSTALLER.md) (K-09)
26. **700 cihaz rollout nasıl?** — Üstel dalgalar: LAB(2) → P1(5) → P2(20) → W1(50) → W2(100) → PROD(~523);
hiçbir dalga önceki çıkış kriterini sağlamadan başlamaz; halt kuralları (≥2 kritik arıza / >%10 çevrimdışı /
2× kurulum süresi) yayılımı durdurur. → [`18`](docs/18-PILOT-AND-700-DEVICE-ROLLOUT.md) (K-11)
27. **Docs platformu ne?** — **Docusaurus**; kaynak `docs/*.md` tek-kaynaktır, site CI'da derlenir, siteye
elle yazma yasaktır. Yedek: MkDocs + Material. → [`22`](docs/22-DOCUMENTATION-PLATFORM.md) (K-08)
---
## 2. 700 İstasyonda 5 Yıllık En Büyük 10 Operasyonel Risk
| # | Risk | Önlem |
|---|---|---|
| 1 | **Onaysız update kaçağı** — tek imajda `unattended-upgrades` açık unutulur, 700 cihaz kendiliğinden güncellenir. | Kurucu `18-final-check` kapısı + monitoring'de `unattended_upgrade_active` metriği (1 = ihlal alarmı); K-11 kilidi üç dosyada (03/10/12) denetlenir. |
| 2 | **Tek VDS ortak arıza noktası** — hub + hbbs/hbbr + MeshCentral aynı makinede; VDS giderse 2 bağımsız kanal da gider. | Yedek VDS planı + üç ayda bir "boş VDS'e sıfırdan kur" L9 tatbikatı; IaC Git'te, veriler günlük dosya yedeğinde ([`17`](docs/17-BACKUP-RECOVERY-AND-REINSTALL.md)). |
| 3 | **Heterojen/yeni-parti donanım imajı kırar** — 5 yılda donanım partileri değişir, sürücü eksiği sahada patlar. | Her yeni parti LAB profil matrisine girer; imaj, envanter taraması olmadan dondurulmaz ([`18`](docs/18-PILOT-AND-700-DEVICE-ROLLOUT.md), [`04`](docs/04-GOLDEN-IMAGE-AND-PROVISIONING.md)). |
| 4 | **Semaphore kapı bypass'ı** — acil bahanesiyle CLI'dan onaysız PROD run, dalga disiplini kağıtta kalır. | Semaphore dışı PROD run'ı yasak + denetim logu izlenir; onaysız run testi merkez test planında ([`21`](docs/21-CENTRAL-ADMIN-RUNBOOK.md)). |
| 5 | **Prometheus kardinalite/retention şişmesi** — 700 node × 5 yıl metrik ve log hacmi merkez diskini ve sorguları yorar. | 60 sn scrape, 30–90 gün retention, `BF-<no>` etiket disiplini; PİLOT hacim ölçümüyle donanım siparişi, federasyon hedefi ([`14`](docs/14-MONITORING-AND-HEALTH.md)). |
| 6 | **Teknisyen hatası ölçeklenir** — yanlış bayi no (kimlik çakışması), READY görülmeden çıkış, eski USB ile kurulum. | Kurucuda format kapısı + sesli onay ekranı; kontrol listesi imzalanmadan iş kapanmaz; USB sürüm etiketi ([`20`](docs/20-FIELD-TECHNICIAN-RUNBOOK.md), [`02`](docs/02-DEVICE-NAMING-AND-INVENTORY.md)). |
| 7 | **Turkcell hat/kota davranış değişimi** — CGNAT eşleme süresi veya kota politikası değişir, tüneller toplu düşer. | P1 7/24 kopma sayacıyla keepalive saha verisine bağlanır; Kuma "last seen" + paket-bitim bildirim akışı ([`08`](docs/08-WIREGUARD-AND-NETWORK.md)). |
| 8 | **Upstream lisans/kapsam daralması** — RustDesk/Grafana/Semaphore free kapsamı 5 yıl içinde değişebilir. | Yıllık lisans gözden geçirme + her ücretli-adayın ücretsiz karşılığı tabloda hazır; değişiklik 24-PR ile işletilir ([`23`](docs/23-SECURITY-AND-LICENSE-AUDIT.md)). |
| 9 | **SSH anahtar sızıntısı** — tek private key 700 cihazı açar; ayrılan personelin anahtarı unutulur. | Per-admin anahtar + Ansible merkezi dağıtım/iptal, paylaşılan key politikada yasak + denetim scripti; SSH CA Faz-sonrası hedef ([`06`](docs/06-USERS-SSH-AND-PERMISSIONS.md)). |
| 10 | **IaC drift + denenmemiş kurtarma** — Git'teki playbook gerçek merkezden sapar, L9 günü çalışmaz. | Üç aylık L9 tatbikatı + aylık yedek-doğrulama job'ı (açılabilirlik + hash); sonuç monitoring'e işlenir ([`17`](docs/17-BACKUP-RECOVERY-AND-REINSTALL.md)). |
---
## 3. Gerçekten Tamamen Ücretsiz Olanlar (FREE katman, lisans bedeli $0)
> Kapsam: yazılım lisansları. Merkezi VDS kirası altyapı maliyetidir, lisans değildir.
| Bileşen | Sürüm/katman | Lisans | Kaynak |
|---|---|---|---|
| Ubuntu Server LTS | 26.04.1+ (ESM'e bel bağlanmaz) | Açık kaynak | [`03`](docs/03-UBUNTU-BASELINE.md) |
| GNOME | saha standardı (Ubuntu Desktop) | GPL/LGPL bileşenler | [`03`](docs/03-UBUNTU-BASELINE.md) |
| xRDP | v0.10.6.1 | Apache-2.0 | [`03`](docs/03-UBUNTU-BASELINE.md) |
| WireGuard + wg-quick | wireguard-tools 1.0.20250521-1ubuntu1 | OSS | [`08`](docs/08-WIREGUARD-AND-NETWORK.md) |
| OpenSSH / UFW | sistem paketleri | BSD / GPL bileşenler | [`06`](docs/06-USERS-SSH-AND-PERMISSIONS.md), [`11`](docs/11-SECURITY-HARDENING.md) |
| Docker CE | (Business/Scout mimaride yok) | Ücretsiz | [`12`](docs/12-DOCKER-OPERATIONS.md) |
| RustDesk istemci + sunucu (hbbs/hbbr) | 1.4.9 / 1.1.16, OSS | AGPL-3.0 | [`07`](docs/07-REMOTE-ACCESS.md) |
| MeshCentral | 1.2.5 | Apache-2.0 | [`07`](docs/07-REMOTE-ACCESS.md) |
| Ansible | CLI, agent'sız | GPL-3.0 | [`09`](docs/09-FLEET-MANAGEMENT.md) |
| Semaphore UI | Community ($0, free forever) | MIT | [`09`](docs/09-FLEET-MANAGEMENT.md) |
| Prometheus + Node Exporter | kotasız self-host | Apache-2.0 | [`14`](docs/14-MONITORING-AND-HEALTH.md) |
| Grafana | OSS (değişikliksiz self-host) | AGPL-3.0 | [`14`](docs/14-MONITORING-AND-HEALTH.md) |
| Uptime Kuma | tek konteyner | MIT | [`14`](docs/14-MONITORING-AND-HEALTH.md) |
| Docusaurus | statik site | MIT | [`22`](docs/22-DOCUMENTATION-PLATFORM.md) |
| systemd / journald | log + servis zinciri | LGPL bileşenler | [`15`](docs/15-LOGGING.md), [`16`](docs/16-POWER-LOSS-AND-AUTO-RECOVERY.md) |
**Ücretsiz DEĞİL / mimaride YOK (kullanılırsa lisans gerekir):** AnyDesk Free (ticari kullanımda ihlal) → [`23`](docs/23-SECURITY-AND-LICENSE-AUDIT.md);
RustDesk Pro (gerekmez); Semaphore Pro/Enterprise (500 node sınırı + ücretli); Netdata Cloud Free (5 node kotası);
Tailscale/ZeroTier ücretli kademeler; Ubuntu Pro/ESM (bel bağlanmaz). Tam hüküm tablosu [`23 §9`](docs/23-SECURITY-AND-LICENSE-AUDIT.md),
kaynak URL'ler [`24 Ek A`](docs/24-DECISION-LOG.md).
---
## Ek: QA Doğrulama (2026-09-15)
- **26 dosya mevcut:** `docs/00` … `docs/25` tamamı var (+ `_TEMPLATE.md`).
- **13 başlık:** 26 dosyanın tamamında §1–§13 sıralı ve eksiksiz.
- **Mermaid:** 26/26 dosyada ≥1 diyagram (03/19/21/23/24'e bu özetle birlikte eklendi).
- **BF-/bf- tutarlılığı:** insan arayüzü `BF-<no>`, makine adı `bf-<no>`; aykırı kullanım yok.
- **Ücretli sızıntı:** yok — ücretli geçen her satır elendi/hüküm/denetim bağlamında.
- **Onaysız-update kapısı:** yok — `unattended-upgrades`/`latest`/Watchtower yasakları 03/10/12'de ve
K-11'de kilitli; acil yama bile onay + rollback testinden geçer.

View file

View file

0
ansible/roles/.gitkeep Normal file
View file

0
config/docker/.gitkeep Normal file
View file

0
config/firewall/.gitkeep Normal file
View file

0
config/ssh/.gitkeep Normal file
View file

0
config/systemd/.gitkeep Normal file
View file

View file

0
docs-site/.gitkeep Normal file
View file

135
docs/00-MASTER-PLAN.md Normal file
View file

@ -0,0 +1,135 @@
# 00 — Ana Plan (Master Plan)
> Kısa özet: 700 cihazlık Blueforce Linux filosunun uçtan uca planı: hangi doküman neyi kapsar, fazlar nasıl ilerler, tüm işler hangi kararlara dayanır. Projeye yeni katılan herkes önce bu dosyayı okur.
- Dosya: `docs/00-MASTER-PLAN.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-01…K-14` (tüm fazlar bu kararlara dayanır)
- Durum: [x] Onaylı (Faz 2 kilidi)
---
## 1. Amaç
700 saha PC'sinin Ubuntu tabanlı standardize filoya dönüşümünü tek planda toplamak: kapsam, fazlar, doküman haritası ve başarı kriterleri. Parça işlerin (imaj, kurucu, ağ, filo, monitoring) birbirine nasıl bağlandığı bu dosyadan izlenir.
## 2. Kapsam
- Kapsam içi: faz planı (LAB → PİLOT → WAVE → PROD), doküman haritası (00…24), karar bağımlılıkları (K-01…K-14), dalga boyutları ve kapı kriterleri.
- Kapsam dışı: kurulum komutları (03/04/05), playbook ve metrik detayları (09/14), VDS kurulum adımları (07/08) — ilgili dokümanlara havale.
## 3. Kararlar
```text
KARAR: Proje Faz 2'de kilitlenen 14 karara (K-01…K-14) göre yürütülür; karar değişikliği yalnızca 24-DECISION-LOG PR'ı ile yapılır.
GEREKÇE: 700 cihazda tutarlılığın tek dayanağı yazılı karardır; her doküman kararlara linklenir, varsayıma dayalı seçim bırakılmaz.
ALTERNATİF: Doküman başına bağımsız karar — çelişki ve tekrara yol açtığı için elendi.
RİSK: Karar kilidi gelişmeyi yavaşlatabilir; azaltma: LAB/PİLOT bulguları PR ile hızlı işletilir.
MALİYET: Ücretsiz (süreç kararı).
LİSANS: Yok (yöntem kararı).
```
```text
KARAR: Dağıtım dalgaları: LAB(2) → PİLOT-1(5) → PİLOT-2(20) → WAVE-1(50) → WAVE-2(100) → PROD (kalan ~523).
GEREKÇE: Onaysız update yasağı (K-11) gereği her değişiklik küçük dalgada kanıtlanmadan büyüğe geçmez; blast-radius üstten sınırlanır.
ALTERNATİF: Tek seferde tüm filo — tek hatanın 700 cihaza yayılması nedeniyle elendi.
RİSK: Dalga disiplini atlanırsa hata büyür; azaltma: Semaphore'da onay adımı + 10-UPDATE kapı kriterleri.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Öncelik sırası (kesintisiz çalışma > veri kaybı yok > uzaktan erişim > bakım kolaylığı) planı şekillendirdi. Tüm kararlarda üç filtre uygulandı: (1) %100 ücretsiz/self-hosted, (2) sadelik (K8s, gereksiz agent/DB/cloud yok), (3) onaysız update yasağı. 700 ölçeğinde her küçük varsayılan filo-çapı arızaya dönüşür; fazlar bu çarpanı küçültür.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Big-bang dağıtım | Hızlı | Tek hata = 700 cihaz arızası | Elendi |
| K8s-orkestrasyonlu saha | Esnek ölçek | 700 mini PC'de gereksiz yük | Elendi |
| Cloud-merkezli yönetim | Hızlı kurulum | Kota/lisans maliyeti, veri egemenliği | Elendi |
## 6. Avantajlar
- Tek kimlik (`BF-<no>`/`bf-<no>`) tüm katmanlarda join anahtarı — envanterden monitoring'e aynı ad.
- Her fazın giriş/çıkış kriteri yazılı; "hazır" demek ölçülebilir.
- Hiçbir faz ücretli lisansa dayanmaz (FREE sürümler baz).
## 7. Dezavantajlar
- Faz disiplini ilk kurulumu yavaşlatır (LAB+PİLOT ölçümleri beklenir).
- Merkez servis sayısı ilk kurulumda tek VDS'e sığsa da yük testinden geçmeli (sahibi: 25-ROADMAP).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Faz atlanarak sahaya çıkılması | Orta | Yüksek | Kapı kriterleri + Semaphore onay adımı |
| Merkez VDS kesintisi | Düşük | Yüksek | Hızlı yeniden kurulum + yedek VDS planı (17) |
| Heterojen donanımda imaj kırılması | Orta | Orta | Envanter taraması + LAB profil testi (04) |
## 9. Uygulama Planı
1. Faz 1 (Zemin): karar kilidi (24) + mimari (01) + bu plan — tamamlandı.
2. Faz 2 (İmaj+Kurucu): 02-03-04-05 dokümanları + `blueforce-install.sh` + LAB(2) imaj testi.
3. Faz 3 (Merkez): WireGuard hub → hbbs/hbbr → MeshCentral → Semaphore → Prometheus/Grafana/Kuma (07/08/09/14).
4. Faz 4 (PİLOT): P1(5)+P2(20) cihazda 7/24 sayaçlar (kopma, log hacmi, metrik kardinalitesi).
5. Faz 5 (WAVE+PROD): W1(50) → W2(100) → PROD (~523), her dalgada 10-UPDATE onay zinciri.
```bash
# kapı örneği: LAB'dan P1'e geçiş koşulu
./scripts/install/blueforce-install.sh --check # exit 0 olmadan dalga büyümez
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Her dokümanın karar linkleri | Tüm karar blokları 24'teki K-no'ya bağlı | Repo CI (markdown-link-check) |
| LAB(2) uçtan uca akış | Erişim + boot + update zinciri çalışır | LAB(2) |
| Dalga kapı kriterleri | Kriter sağlanmadan sonraki dalga açılmaz | P1/P2/W1/W2 |
## 11. Rollback
1. Plan değişikliği 24-DECISION-LOG PR'ı ile yapılır; bağımlı dokümanlar aynı PR'da güncellenir.
2. Sahaya sürülmüş dalga hatalıysa 10-UPDATE rollback zinciri işletilir.
3. Son çare: karar öncesi imaj sürümüne dönüş (17-RECOVERY LEVEL 9).
## 12. Kontrol Listesi
- [ ] 14 kararın her biri ≥1 dokümana ve faza bağlı.
- [ ] Dalga boyutları tüm dokümanlarda tutarlı (2/5/20/50/100/~523).
- [ ] FREE sürüm kuralı tüm fazlarda korunuyor.
- [ ] `SUMMARY.md` Faz 4'te 27 soru → karar izlenebilirliğiyle üretilecek.
## 13. Açık Sorular
- [ ] Merkez servislerin tek VDS'e sığıp sığmadığı — LAB yük testi (sahibi: 25-ROADMAP).
- [ ] Faz takviminin bayi rollout kapasitesine göre netleşmesi (sahibi: 18-ROLLOUT).
---
## Ek: Doküman Haritası
```mermaid
flowchart LR
P0["00 Master Plan<br/>(bu dosya)"] --> ARCH["01 Mimari<br/>24 Karar Log"]
ARCH --> ZEMIN["02 Kimlik + Envanter<br/>03 Ubuntu Baseline<br/>04 Golden Image<br/>05 Tek-Kurucu"]
ZEMIN --> MERKEZ["06 SSH 07 Erişim 08 WireGuard<br/>09 Filo 11 Hardening"]
MERKEZ --> OPS["10 Update 12 Docker<br/>14 Monitoring 15 Logging 16 Boot<br/>17 Recovery 18 Rollout"]
OPS --> GOV["19 Test 20 Runbook 21 CI<br/>22 Docs 23 Lisans"]
```
| Doküman | Konu | Dayandığı karar |
|---|---|---|
| 01 | Sistem mimarisi | K-01…K-14 |
| 02 | Cihaz adlandırma + envanter | K-12 |
| 03 | Ubuntu baseline | K-01, K-02, K-03, K-11 |
| 04 | Golden image + provisioning | K-09 |
| 05 | Tek-tık kurucu | K-09, K-11, K-12 |
| 06–09 | SSH, erişim, WireGuard, filo | K-13, K-04, K-05, K-06 |
| 10–12 | Update, hardening, Docker | K-11, K-10 |
| 13–16 | MEG, monitoring, logging, boot | K-02, K-07, K-14, K-03 |
| 17–18 | Recovery, rollout | K-04, K-09 |
| 19–23 | Test, runbook, CI, docs, lisans | K-08 + tümü |
| 24 | Karar günlüğü | Kilit kaynak |

154
docs/01-ARCHITECTURE.md Normal file
View file

@ -0,0 +1,154 @@
# 01 — Sistem Mimarisi
> Kısa özet: 700 saha cihazlı Blueforce filosunun uçtan uca mimarisi: saha PC'si, WireGuard ağı, 4 erişim kanalı, filo otomasyonu, monitoring ve update zinciri tek bakışta. Kararların görsel karşılığıdır.
>
> - Dosya: `docs/01-ARCHITECTURE.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-01…K-14` (tüm mimari bu kararlara dayanır)
> - Durum: [x] Onaylı (Faz 2 kilidi)
---
## 1. Amaç
Başka bir DevOps mühendisinin filoyu tek dosyadan anlayıp kurmaya başlayabilmesi: hangi bileşen nerede koşar, trafik nasıl akar, cihaz nasıl boot eder, update nasıl yayılır.
## 2. Kapsam
- Kapsam içi: saha cihazı katmanları, merkez (VDS) servisleri, ağ/erişim akışı, boot zinciri, update onay akışı.
- Kapsam dışı: kurulum komutları (03/04/05), playbook detayları (09), metrik listesi detayı (14) — ilgili dokümanlara havale.
## 3. Kararlar
```text
KARAR: Filo mimarisi: saha = Ubuntu Server 26.04.1+ GNOME + Docker(MEG) + WireGuard spoke; merkez = WireGuard hub + RustDesk hbbs/hbbr + MeshCentral + Ansible/Semaphore + Prometheus/Grafana + Uptime Kuma (hepsi self-hosted, ücretsiz katman).
GEREKÇE: 24-DECISION-LOG K-01…K-08'in birleşimi; hareketli parça en aza indirildi (agent'sız filo, tek Go binary UI, tek konteyner uptime), iki WireGuard-bağımsız erişim kanalıyla tek-nokta körlüğü engellendi.
ALTERNATİF: K8s-tabanlı yönetim / Cloud-merkezli monitoring — sadelik kuralını bozduğu için elendi (bkz. 24 §4).
RİSK: Merkez VDS tek fiziksel nokta; azaltma: yedekleme + hızlı yeniden kurulum (17-RECOVERY), kritik kanalların ayrı VDS'e taşınabilirliği.
MALİYET: Ücretsiz (lisans $0; VDS kira bedeli altyapı maliyetidir).
LİSANS: Bileşen lisansları için 24-DECISION-LOG Ek A'ya bakılır.
```
## 4. Neden Bu Karar?
Öncelik sırası (kesintisiz çalışma > veri kaybı yok > uzaktan erişim > bakım kolaylığı) mimariyi şekillendirdi: boot zinciri her katmanda otomatik toparlanır (systemd + `unless-stopped` + `wg-quick` enable), erişim 4 kanalla yedeklenir (ikisi WireGuard-bağımsız), update'ler onay zincirinden geçmeden sahaya inmez. Hiçbir katman ücretli lisansa dayanmaz.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Tek kanal (yalnızca SSH) | En sade | Tünel çökerse körlük | Elendi |
| Cloud monitoring (Netdata Cloud vb.) | Hızlı kurulum | 5 node free kotası, 700 cihaz ücretli | Elendi |
| K8s-orkestrasyonlu saha | Ölçek esnekliği | 700 mini PC'de gereksiz yük | Elendi |
## 6. Avantajlar
- Tek kimlik (`BF-<no>`/`bf-<no>`) tüm katmanlarda join anahtarı — envanterden monitoring'e aynı ad.
- Her akış (erişim/boot/update) diyagramla sabit; runbook'lar bu diyagramlara prosedür yazar.
## 7. Dezavantajlar
- Merkez servis sayısı (hub + 2 erişim + fleet + 2 monitoring + docs) ilk kurulumda tek VDS'e sığsa da yük testinden geçmeli.
- Diyagramlar sözleşmedir: bileşen değişirse 3 Mermaid de aynı PR'da güncellenmeli.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Merkez VDS kesintisi | Düşük | Yüksek | Hızlı yeniden kurulum + yedek VDS planı (17) |
| Boot zincirinde race (Docker WG'den önce kalkar) | Orta | Orta | systemd bağımlılıkları + After= kuralları (16) |
| Onaysız update zinciri bypass eder | Düşük | Yüksek | K-11 kilitleri + Semaphore'da onay adımı (10) |
## 9. Uygulama Planı
1. Merkez VDS: WireGuard hub → hbbs/hbbr → MeshCentral → Semaphore → Prometheus/Grafana/Kuma sırasıyla kurulur.
2. Saha imajı: Ubuntu Server → GNOME → Docker → WireGuard spoke → RustDesk/MeshCentral agent → Node Exporter.
3. İlk 2 LAB cihazı bu mimariye göre uca eklenir, 3 akış (erişim/boot/update) testlenir.
```bash
# örnek: cihaz kimliği standardı (K-12)
hostnamectl set-hostname bf-12010193
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| 3 Mermaid'deki her ok için bağlantı testi | Uçtan uca akış çalışır | LAB(2) |
| VDS down simülasyonu (hbbs kapalı) | SSH-over-WG + MeshCentral ayakta | P1(5) |
| Güç kesintisi simülasyonu | Boot zinciri sırayla toparlanır | LAB(2) |
## 11. Rollback
Mimari değişikliği 24-DECISION-LOG PR'ı ile yapılır; bu dosyanın diyagramları aynı PR'da güncellenir. Yanlış bileşen seçimi sahaya yayılmadan LAB'da geri alınır (10-UPDATE rollback zinciri).
## 12. Kontrol Listesi
- [ ] 3 Mermaid bloğu render oluyor (Docusaurus + GitHub preview).
- [ ] Her bileşen adının kararı 24'te var (K-01…K-14).
- [ ] `bf-<no>` / `BF-<no>` adlandırması diyagramlarda tutarlı.
## 13. Açık Sorular
- [ ] Merkez servislerin tek VDS'e sığıp sığmadığı — LAB yük testi (sahibi: 25-ROADMAP).
- [ ] Prometheus federasyonu gerekip gerekmediği — 700 node ölçümü (sahibi: 14-MONITORING).
---
## Ek: Mermaid — 1. Erişim ve yönetim akışı (Internet → WireGuard → SSH/RDP/Mgmt)
```mermaid
flowchart LR
subgraph SAHA["Saha (bf-<no>)"]
PC["Ubuntu Server 26.04.1<br/>GNOME + Docker/MEG"]
end
subgraph MERKEZ["Merkez VDS"]
WG["WireGuard hub"]
SEM["Ansible/Semaphore"]
MON["Prometheus/Grafana<br/>Uptime Kuma"]
RD["RustDesk hbbs/hbbr"]
MC["MeshCentral"]
end
PC -->|Internet: WG tüneli<br/>PersistentKeepalive=25| WG
WG --> SEM
WG --> MON
WG -->|SSH 22, RDP 3389<br/>yalnızca tünel içi| PC
PC -->|Internet doğrudan<br/>VDS genel adresi| RD
PC -->|Internet doğrudan<br/>VDS genel adresi| MC
RD -.->|WG çökse bile<br/>ayakta| PC
MC -.->|WG çökse bile<br/>ayakta| PC
```
## Ek: Mermaid — 2. Power boot zinciri
```mermaid
flowchart TB
PWR["Power ON<br/>(BIOS: Restore on AC Power Loss = Power On)"] --> BIOS["BIOS/UEFI"]
BIOS --> UB["Ubuntu Server 26.04.1<br/>multi-user terminal boot"]
UB --> NET["Network<br/>(NetworkManager/systemd-networkd)"]
NET --> WGV["WireGuard<br/>(wg-quick@wg0 enable)"]
WGV --> DKR["Docker daemon<br/>(log rotasyonlu)"]
DKR --> MEG["MEG konteyneri<br/>(unless-stopped)"]
MEG --> BF["Blueforce servisleri"]
BF --> REM["Remote: SSH + xRDP +<br/>RustDesk + MeshCentral agent"]
REM --> MON["Monitoring:<br/>Node Exporter + Uptime Push"]
```
## Ek: Mermaid — 3. Update onay akışı
```mermaid
flowchart LR
F["Bulundu<br/>(güvenlik bülteni / MEG sürümü)"] --> R["Rapor<br/>(etki + geri alma planı)"]
R --> O{"Onay<br/>(merkezi admin)"}
O -->|Red| F
O -->|Onay| LAB["LAB 2 cihaz"]
LAB -->|Başarılı| P1["PILOT-1 5 cihaz"]
P1 -->|Başarılı| P2["PILOT-2 20 cihaz"]
P2 -->|Başarılı| W1["WAVE-1 50 cihaz"]
W1 -->|Başarılı| W2["WAVE-2 100 cihaz"]
W2 -->|Başarılı| PROD["PRODUCTION<br/>kalan ~523 cihaz"]
LAB -->|Başarısız| RB["Rollback<br/>(10-UPDATE zinciri)"]
P1 -->|Başarısız| RB
P2 -->|Başarısız| RB
W1 -->|Başarısız| RB
W2 -->|Başarısız| RB
```

View file

@ -0,0 +1,165 @@
# 02 — Cihaz Adlandırma ve Envanter
> Kısa özet: 8 haneli bayi numarasından türetilen tek cihaz kimliği (`BF-<no>`/`bf-<no>`) standardı ve 9 sistemde kullanımı; donanım taraması yapan `bf-hardware-inventory.sh` sözleşmesi. Filoda join anahtarıdır.
- Dosya: `docs/02-DEVICE-NAMING-AND-INVENTORY.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-12` (cihaz kimliği), `K-09` (envanter önce, imaj sonra)
- Durum: [ ] Taslak
---
## 1. Amaç
700 cihazda tek, okunabilir, çakışmasız kimlik standardı kurmak ve bu kimliğin 9 sistemde birebir aynı değeri taşımasını sağlamak. Bayi numarası değişirse ne yapılacağı da bu dosyanın prosedürüdür.
## 2. Kapsam
- Kapsam içi: `BF-<no>`/`bf-<no>` formatı, doğrulama kuralı, 9 sistemdeki kullanım tablosu, `bf-hardware-inventory.sh` JSON+Markdown sözleşmesi, yeniden-numaralandırma prosedürü.
- Kapsam dışı: hostname atama komut akışı detayı (05-ONE-CLICK-INSTALLER), Ansible inventory şeması detayı (09-FLEET), monitoring etiket şeması detayı (14-MONITORING).
## 3. Kararlar
```text
KARAR: 8 haneli bayi no → Device ID `BF-<no>` (büyük, insan arayüzü) + hostname `bf-<no>` (küçük, makine adı); WireGuard peer adı, RustDesk etiketi, Ansible inventory adı, monitoring etiketi hepsi aynı ID'yi kullanır.
GEREKÇE: Tek kimlik 9 sistemde join anahtarıdır; büyük/küçük ayrımı insan-makine karışıklığını önler (insan `BF-`, makine `bf-`). Örnek: `BF-12010193` / `bf-12010193`.
ALTERNATİF: Rastgele UUID / MAC-tabanlı ad — saha teknisyeni için okunamaz, bayi eşleşmesi manuel olur → elendi.
RİSK: Bayi no değişirse kimlik çakışması; azaltma: §9'daki yeniden-no prosedürü + envanter benzersizlik kontrolü.
MALİYET: Ücretsiz.
LİSANS: Yok (isimlendirme standardı).
```
```text
KARAR: Donanım taraması `bf-hardware-inventory.sh` ile yapılır; çıktı hem JSON (makine) hem Markdown (insan) üretir; zorunlu alanlar §9'daki sözleşmededir.
GEREKÇE: Heterojen saha donanımı bilinmeden golden image dondurulamaz (K-09); tarama LAB/PİLOT öncesi her profili belgeler, imaj test matrisine girer.
ALTERNATİF: Manuel envanter tablosu — 700 cihazda eksik/hatalı veri riski nedeniyle elendi.
RİSK: Script farklı donanımda alan boş bırakır; azaltma: §10'daki şema doğrulama testi.
MALİYET: Ücretsiz.
LİSANS: Yok (şirket içi script).
```
## 4. Neden Bu Karar?
Bayi numarası sahada zaten bilinen tek anahtardır; yeni bir numara üretmek eşleşme maliyeti doğurur. 8 hane sabit uzunluk (`^[0-9]{8}$`) yazım hatasını format düzeyinde yakalar. 9 sistemde aynı adın kullanılması, arıza anında "hangi cihaz?" sorusunu tek cevaba indirir: `BF-12010193` denen cihaz her panelde aynı cihazdır.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| UUID | Çakışmasız | Okunamaz, bayi eşleşmesi manuel | Elendi |
| MAC-tabanlı ad | Donanıma bağlı benzersiz | Ağ kartı değişince ad değişir, okunamaz | Elendi |
| Seri-no tabanlı ad | Üretici garantili | Format üreticiye göre değişir, 9 sistemde normalize gerekir | Elendi |
## 6. Avantajlar
- Tek format kuralı (`^[0-9]{8}$`) tüm giriş noktalarında (kurucu, Ansible, envanter) aynı regex ile doğrulanır.
- Büyük/küçük ayrımı log aramalarında ve etiketlerde karışıklığı önler.
- Envanter JSON'u monitoring ve Ansible'a doğrudan beslenebilir.
## 7. Dezavantajlar
- Bayi no değişimi 9 sistemde atomik güncelleme gerektirir (prosedür §9).
- 8 hane dışı gerçek no'lar (kısa/uzun) sıfır-dolgu kuralına ihtiyaç duyar — kural: soldan sıfırla 8 haneye tamamlanır.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Yinelenen bayi no (çift kayıt) | Düşük | Yüksek | Merkezi envanterde benzersizlik kontrolü, kurucu kaydı reddeder |
| Bayi no değişiminde eski adın artıkları | Orta | Orta | Yeniden-no prosedürü (§9) + eski adın 30 gün alias tutulması |
| Envanter JSON şema kayması | Düşük | Orta | Şema sürümü (`schema_version`) + CI doğrulama |
## 9. Uygulama Planı
1. Bayi no doğrulama kuralı: `^[0-9]{8}$` — uymayan girdi reddedilir, kurucu devam etmez (05'teki akış).
2. 9 sistemde kimlik kullanımı:
| # | Sistem | Kullanılan değer | Örnek |
|---|---|---|---|
| 1 | DNS / hostname | `bf-<no>` | `bf-12010193` |
| 2 | WireGuard peer adı | `bf-<no>` | `bf-12010193` |
| 3 | RustDesk cihaz etiketi | `BF-<no>` | `BF-12010193` |
| 4 | MeshCentral cihaz adı | `BF-<no>` | `BF-12010193` |
| 5 | Ansible inventory adı | `bf-<no>` | `bf-12010193` |
| 6 | Prometheus/Grafana etiketi (`device_id`) | `BF-<no>` | `BF-12010193` |
| 7 | Log alanı (`device_id`) | `BF-<no>` | `BF-12010193` |
| 8 | Merkezi envanter kaydı (anahtar) | `BF-<no>` | `BF-12010193` |
| 9 | Runbook/arıza kaydı başlığı | `BF-<no>` | `BF-12010193` |
3. `bf-hardware-inventory.sh` sözleşmesi — çalıştırma ve çıktılar:
```bash
# saha PC'sinde (kurucu öncesi veya bağımsız tarama)
sudo ./bf-hardware-inventory.sh --dealer-id 12010193 --out-dir /var/lib/blueforce/inventory
# çıktılar:
# /var/lib/blueforce/inventory/BF-12010193.json
# /var/lib/blueforce/inventory/BF-12010193.md
```
JSON zorunlu alanları (`schema_version: 1`):
```json
{
"schema_version": 1,
"device_id": "BF-12010193",
"hostname": "bf-12010193",
"dealer_id": "12010193",
"collected_at": "2026-09-15T10:00:00+03:00",
"cpu": {"model": "...", "cores": 4, "arch": "x86_64"},
"memory_mb": 8192,
"disks": [{"name": "sda", "size_gb": 256, "type": "ssd"}],
"network": {"macs": ["..."], "wireless": true},
"gpu": {"model": "..."},
"bios": {"vendor": "...", "version": "...", "ac_restore": "Power On"},
"os": {"distro": "Ubuntu", "version": "26.04.1"},
"notes": ""
}
```
Markdown çıktısı aynı alanların insan-okunur tablosudur (başlık: `# Donanım Envanteri — BF-12010193`, her bölüm tablo satırı).
4. Yeniden-numaralandırma prosedürü (bayi no değişirse):
1. Eski `BF-<eski>` kaydı envanterde `retired` işaretlenir, 30 gün alias tutulur.
2. Yeni no ile kurucu yeniden koşar (`blueforce-install.sh --dealer-id <yeni>`).
3. WireGuard peer, RustDesk etiketi, MeshCentral adı, Ansible inventory, monitoring etiketi yeni ID'ye taşınır; eski peer anahtarı iptal edilir.
4. Alias süresi dolunca eski kayıt arşivlenir.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `^[0-9]{8}$` dışı girdi (7/9 hane, harf) | Kurucu reddeder, exit ≠ 0 | LAB(2) |
| JSON şema doğrulama (`schema_version`, zorunlu alanlar) | Eksik alan = hata | LAB(2) |
| Yinelenen no ile kayıt | Merkezi envanter reddeder | LAB(2) |
| 9 sistemde ad tutarlılığı | Tümü aynı no'yu taşır | P1(5) |
## 11. Rollback
1. Yanlış no ile kurulan cihaz: `blueforce-install.sh --dealer-id <doğru>` idempotent yeniden koşar, hostname + peer + etiketler düzelir.
2. Envanter kaydı hatalıysa JSON yeniden üretilir, merkezi kayıt güncellenir; eski sürüm arşivde tutulur.
## 12. Kontrol Listesi
- [ ] Format regex'i kurucu + envanter + Ansible'da aynı (`^[0-9]{8}$`).
- [ ] JSON zorunlu alan listesi script ile eşleşiyor.
- [ ] 9 sistem tablosundaki her satırın sahibi doküman linkli (06/07/08/09/14/15/20).
- [ ] Yeniden-no prosedürü runbook'a işlendi.
## 13. Açık Sorular
- [ ] 8 haneden kısa/uzun gerçek no var mı — saha listesiyle doğrulanacak (sahibi: 18-ROLLOUT).
- [ ] Merkezi envanterin fiziksel konumu (VDS'de dosya mı, Semaphore Key Store mu) (sahibi: 09-FLEET yazarı).
---
## Ek: Kimlik Akışı
```mermaid
flowchart LR
BAYI["Bayi no<br/>12010193"] -->|^[0-9]8$| KURUCU["blueforce-install.sh"]
KURUCU --> H["hostname<br/>bf-12010193"]
KURUCU --> WG["WireGuard peer<br/>bf-12010193"]
KURUCU --> ENV["Envanter JSON/MD<br/>BF-12010193"]
ENV --> ANS["Ansible inventory"]
ENV --> MON["Prometheus etiketi"]
ENV --> RD["RustDesk / MeshCentral"]
```

167
docs/03-UBUNTU-BASELINE.md Normal file
View file

@ -0,0 +1,167 @@
# 03 — Ubuntu Baseline
> Kısa özet: Saha PC'lerinin standart zemini: Ubuntu Server 26.04.1+ LTS minimal kurulum, GNOME sonradan eklenir, terminale boot edilir, `unattended-upgrades` kapalıdır. BIOS güç-kurtarma ayarı ve GUI aç/kapa anahtarları bu dosyadadır.
- Dosya: `docs/03-UBUNTU-BASELINE.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-01` (OS/sürüm), `K-02` (GNOME), `K-03` (boot + bf-gui), `K-11` (otomatik update kapalı)
- Durum: [ ] Taslak
---
## 1. Amaç
Her saha PC'sinin aynı minimal zeminden başlamasını garanti etmek: hangi ISO, hangi masaüstü, hangi boot hedefi, hangi servisler açık/kapalı. Bu zemin 04'teki imajın ve 05'teki kurucunun varsayımıdır.
## 2. Kapsam
- Kapsam içi: ISO seçimi, BIOS güç-kurtarma ayarı, boot hedefi (multi-user), GUI katmanı (GNOME + xRDP + `bf-gui-*`), `unattended-upgrades` kapatma, açılışta koşan servis listesi.
- Kapsam dışı: imaj üretim yöntemi (04), kurucu modül detayları (05), WireGuard/SSH sertleştirme (06/08/11).
## 3. Kararlar
```text
KARAR: Saha standardı Ubuntu Server 26.04.1+ LTS'tir (GUI'siz minimal kurulum; GNOME sonradan eklenir).
GEREKÇE: 26.04.1 LTS resmi indirme sayfasında yayında (kod adı Resolute Raccoon); Server ISO'su varsayılan olarak GUI kurmaz, minimal zemin + ihtiyaca göre GUI standart yoldur. Noktasürüm (.1+) baz alınır çünkü ilk .0 dalgasındaki kurulumcu hataları genelde .1'de toplanır.
ALTERNATİF: Ubuntu 24.04 LTS — 26.04 doğrulanamasaydı yedekti; doğrulandığı için yedekte bekler. Ubuntu Desktop 26.04 (6 GB RAM şartı) saha bütçesini zorladığı için elendi.
RİSK: 26.04.x noktasürümlerinde donanım sürücü farkı; azaltma: golden image LAB(2)'de her saha donanım profilinde test edilir.
MALİYET: Ücretsiz.
LİSANS: Ubuntu LTS ücretsiz (ESM kapsamına bel bağlanmaz) — https://releases.ubuntu.com/ (26.04.1, doğrulanma: 2026-09-15) + https://ubuntu.com/download/desktop (sistem gereksinimi, doğrulanma: 2026-09-15).
```
```text
KARAR: Saha masaüstü ortamı GNOME'dur (Ubuntu Desktop standardı); XFCE elendi.
GEREKÇE: Kullanıcı kararı + Ubuntu Desktop standardı: tanıdık modern masaüstü, teknisyen akışıyla birebir uyum.
ALTERNATİF: XFCE — hafif ve düşük kaynak tüketimine rağmen kullanıcı kararıyla elendi; yedekte tutulmaz.
RİSK: xRDP+GNOME kombinasyonu ek ayar isteyebilir (uyarı: GNOME oturumu RDP'de ek yapılandırma gerektirebilir); azaltma: 13-MEG-LINUX-ACCEPTANCE testi GNOME üzerinde koşar, `bf-gui-*` LAB'da 26.04.1 imajında doğrulanmadan dondurulmaz.
MALİYET: Ücretsiz.
LİSANS: GNOME (GPL/LGPL bileşenler), ücretsiz — https://www.gnome.org/ (doğrulanma: 2026-09-15).
```
```text
KARAR: Cihazlar terminale (multi-user) boot eder; grafik katman `bf-gui-on` / `bf-gui-off` ile systemd üzerinden açılıp kapatılır.
GEREKÇE: xRDP mimarisi oturum yöneticisi (sesman) + systemd servis birimleri (`xrdp`, `xrdp-sesman`) üzerine kuruludur; GUI, display-manager + xRDP servisleri üzerinden yönetilebilir bir katman olarak modellenir. Varsayılan kapalı GUI = düşük RAM, düşük saldırı yüzeyi, öngörülebilir boot.
ALTERNATİF: Her zaman grafik boot — kaynak israfı ve 700 cihazda gereksiz hata yüzeyi nedeniyle elendi.
RİSK: Kesin birim adları ve GNOME oturum başlatma satırı 26.04.1'e göre değişebilir; azaltma: LAB'da 26.04.1 imajında doğrulanmadan `bf-gui-*` dondurulmaz.
MALİYET: Ücretsiz.
LİSANS: xRDP Apache-2.0, ücretsiz — https://github.com/neutrinolabs/xrdp (v0.10.6.1, 2026-07-07; doğrulanma: 2026-09-15).
```
```text
KARAR: Golden image'da `unattended-upgrades` kapatılır (`/etc/apt/apt.conf.d/20auto-upgrades` değerleri `0` + `apt-daily*.timer` maskeleme).
GEREKÇE: `unattended-upgrades` Ubuntu Server'da varsayılan kurulu ve etkindir, günde bir kez çalışır; kapatılmazsa 700 cihaz ilk açılışta güncellemeye kalkar ("onaysız update yasak" ilkesi delinir).
ALTERNATİF: Otomatik security update'e izin verme — eşzamanlı indirme + onaysız değişim riski nedeniyle elendi.
RİSK: Kapatma adımı imajda atlanırsa filo kendiliğinden güncellenir; azaltma: kurucu final-check + monitoring metriği.
MALİYET: Ücretsiz.
LİSANS: Yok (OS yapılandırması) — https://ubuntu.com/server/docs/how-to/software/automatic-updates/ (doğrulanma: 2026-09-15).
```
## 4. Neden Bu Karar?
Server minimal kurulum + sonradan GNOME (Ubuntu Desktop standardı, kullanıcı kararı). Terminale boot, 700 cihazın varsayılan durumunu en öngörülebilir hale getirir; grafik yalnızca bakım penceresinde açılır. Otomatik update'in kapatılması, update zincirinin (10-UPDATE) "onay olmadan değişim yok" ilkesinin teknik kilididir.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Ubuntu 24.04 LTS | Olgun donanım desteği | Daha kısa destek penceresi | Yedek |
| Ubuntu Desktop 26.04 | Tek adımda GUI | 6 GB RAM şartı, şişkin zemin | Elendi |
| XFCE | Hafif, düşük kaynak | Kullanıcı kararıyla elendi (saha standardı GNOME) | Elendi |
| Her zaman grafik boot | Teknisyen rahatlığı | Kaynak israfı, geniş hata yüzeyi | Elendi |
## 6. Avantajlar
- Minimal zemin = küçük imaj, hızlı kurulum, az saldırı yüzeyi.
- Kapalı GUI varsayılanı = düşük RAM + öngörülebilir boot 700 cihazda çarpan etkisi yapar.
- Kapalı otomatik update = filo sürüm determinizmi.
## 7. Dezavantajlar
- GNOME oturum başlatma satırı ve display-manager birim adları 26.04.1'e göre LAB'da doğrulanmadan dondurulamaz.
- Teknisyen grafik istediğinde ek komut (`bf-gui-on`) gerekir — runbook'a işlenir.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| 26.04.x sürücü farkı heterojen donanımda | Orta | Orta | LAB profil testi (04) |
| `bf-gui-*` birim adları 26.04.1'de farklı | Orta | Düşük | LAB doğrulaması, §13 açık soru |
| `unattended-upgrades` açık unutulur | Orta | Yüksek | final-check + monitoring metriği |
## 9. Uygulama Planı
1. BIOS ayarı (her saha PC'sinde, elektrik kesintisi sonrası otomatik açılış için):
- `Restore on AC Power Loss = Power On` (üretici menüsünde `After Power Loss: Power On` / `AC Recovery: Power On` adlarıyla da geçer; teknisyen imaj öncesi menüden doğrular).
2. Ubuntu Server 26.04.1+ minimal kurulum (GUI seçilmez).
3. Boot hedefi terminale sabitlenir:
```bash
sudo systemctl set-default multi-user.target
systemctl get-default # multi-user.target beklenir
```
4. GNOME + xRDP katmanı kurulur (kurucu 05 üzerinden):
```bash
sudo apt install -y ubuntu-desktop-minimal xrdp
sudo systemctl enable xrdp xrdp-sesman
# GNOME oturumu varsayılan yapılır (LAB'da 26.04.1'e göre doğrulanacak satır):
echo "gnome-session" > ~/.xsession
```
5. GUI aç/kapa anahtarları (kurucu tarafından `/usr/local/bin/` altına yazılır):
```bash
sudo bf-gui-on # display-manager + xrdp/xrdp-sesman başlatılır, RDP oturumu açılır
sudo bf-gui-off # grafik katman durdurulur, cihaz terminale döner
```
6. Otomatik update kapatılır:
```bash
# /etc/apt/apt.conf.d/20auto-upgrades içinde her iki değer 0:
# APT::Periodic::Update-Package-Lists "0";
# APT::Periodic::Unattended-Upgrade "0";
sudo systemctl mask apt-daily.timer apt-daily-upgrade.timer
```
7. Açılışta koşması beklenen servisler (final-check bunları denetler): `NetworkManager` (veya `systemd-networkd`), `wg-quick@wg0`, `docker`, `xrdp`+`xrdp-sesman` (yalnızca GUI-açık modda), `node_exporter`, RustDesk/MeshCentral agent, `bf-health-push.timer`.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `get-default` | `multi-user.target` | LAB(2) |
| Güç kesintisi simülasyonu | BIOS ayarı ile cihaz kendiliğinden açılır | LAB(2) |
| `bf-gui-on/off` sonrası RDP | GNOME oturumu açılır/kapanır | LAB(2) |
| `20auto-upgrades` değerleri `0`, timer'lar maskeli | Otomatik apt çalışmaz | LAB(2) imaj denetimi |
## 11. Rollback
1. Yanlış boot hedefi: `sudo systemctl set-default multi-user.target` ile geri alınır.
2. Bozuk GNOME/xRDP katmanı: `bf-gui-off` + paket yeniden kurulumu; son çare imajdan yeniden kurulum (04).
3. Otomatik update yanlışlıkla açıldıysa §9 adım 6 yeniden uygulanır, `apt-daily*` timer durumu denetlenir.
## 12. Kontrol Listesi
- [ ] ISO sürümü 26.04.1+ (LAB'da `lsb_release -a` çıktısı kayıtlı).
- [ ] BIOS `Restore on AC Power Loss = Power On` her profilde doğrulandı.
- [ ] `get-default` = `multi-user.target`.
- [ ] `bf-gui-on/off` LAB 26.04.1 imajında test edildi.
- [ ] `unattended-upgrades` kapalı + timer'lar maskeli.
## 13. Açık Sorular
- [ ] GNOME oturum başlatma satırı + `bf-gui-*` kesin birim listesi — LAB 26.04.1 imajında (sahibi: Faz 3).
- [ ] `NetworkManager` vs `systemd-networkd` seçimi — netplan profiliyle birlikte LAB'da netleşecek (sahibi: Faz 3, 08 yazarı).
---
## Ek: Zemin Katmanları
```mermaid
flowchart TB
ISO["Ubuntu Server 26.04.1+ ISO<br/>(GUI'siz minimal)"] --> BOOT["Boot hedefi: multi-user.target<br/>(terminale boot)"]
BOOT --> GUI["GUI katmanı (kapalı varsayılan)<br/>GNOME + xRDP + bf-gui-on/off"]
GUI --> KILIT["Update kilidi<br/>unattended-upgrades kapalı + timer maskeli"]
KILIT --> SERVIS["Açılış servisleri<br/>wg-quick + docker + node_exporter + agent'lar"]
```

View file

@ -0,0 +1,129 @@
# 04 — Golden Image ve Provisioning
> Kısa özet: Saha imajının nasıl üretildiği ve cihaza nasıl basıldığı: autoinstall-tabanlı Ubuntu zemini + ilk açılışta kimlik enjeksiyonu. Hedef akış: USB → Ubuntu → tek script → bayi no → READY.
- Dosya: `docs/04-GOLDEN-IMAGE-AND-PROVISIONING.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-09` (golden image yöntemi), `K-01` (OS), `K-11` (update kapalı), `K-12` (kimlik imajda değil, ilk boot'ta)
- Durum: [ ] Taslak
---
## 1. Amaç
Heterojen 700 saha PC'sinde aynı zemini tekrarlanabilir şekilde kurmak: imajın ne içerdiği, ne içermediği (cihaz kimliği), hangi araçla üretildiği ve sahada hangi akışla basıldığı.
## 2. Kapsam
- Kapsam içi: yöntem seçimi (karşılaştırma tablosu), imaj içeriği, autoinstall rolü, USB basım akışı, kimlik enjeksiyonu, LAB test matrisi.
- Kapsam dışı: kurucu modül detayları (05), BIOS ayarı detayı (03), rollout lojistiği (18-RECOVERY/18-ROLLOUT).
## 3. Kararlar
```text
KARAR: Golden image = Ubuntu Server 26.04.1+ minimal + `unattended-upgrades` kapalı + `blueforce-install.sh` tek kurucu (bayi no → READY); imaj, preseed/autoinstall dosyasıyla üretilir, cihaz-spesifik kimlik (`bf-<no>`) imajda DEĞİL ilk açılışta verilir.
GEREKÇE: Donanım heterojenliği bilinmediği için bit-kopya klon (Clonezilla) tek imajda kırılgandır; autoinstall + idempotent kurulum scripti her donanım profilinde aynı zemini kurar, kimlik ilk boot'ta enjekte edilir. Hedef akış: USB → Ubuntu → tek script → bayi no → READY.
ALTERNATİF: Clonezilla bit-kopya (hızlı ama donanım-fragil → yedek yöntem olarak tutulur); Packer/custom ISO (ek derleme hattı yükü → elendi); cloud-init (autoinstall'a göre saha-USB akışına daha az uygun → elendi).
RİSK: İlk imaj heterojen donanımda sürücü eksiltebilir; azaltma: önce `bf-hardware-inventory.sh` taraması (18-ROLLOUT), LAB'da her profilde test.
MALİYET: Ücretsiz.
LİSANS: Ubuntu autoinstall/subiquity (ücretsiz, Ubuntu lisans seti içinde) — https://releases.ubuntu.com/26.04/ (doğrulanma: 2026-09-15). NOT: resmi autoinstall sözdizimi LAB çıktısıyla kesinleşir.
```
## 4. Neden Bu Karar?
Bit-kopya klon, kaynak makinenin sürücü setini dondurur; farklı anakart/ağ kartı olan sahada açılmayan cihaz üretir. Autoinstall her makinede donanıma göre kurulum yapar, ardından aynı kurucu script aynı zemini kurar — sonuç donanımdan bağımsız deterministik zemin + ilk boot'ta enjekte edilen benzersiz kimliktir. Custom ISO/Packer ek derleme hattı (imzalı ISO, build sunucusu, sürüm takibi) getirir; sadelik kuralını bozar.
## 5. Alternatifler
| Yöntem | Artı | Eksi | Sonuç |
|---|---|---|---|
| Ubuntu autoinstall (user-data) | Resmi yol, donanım-bağımsız, USB'den katılımsız | Sözdizimi LAB'da doğrulanmalı | **Seçildi** |
| Clonezilla bit-kopya | Çok hızlı klon, basit | Donanım-fragil, kimlik çakışması riski | Yedek yöntem |
| cloud-init (NoCloud USB) | Esnek ilk-boot yapılandırma | Saha-USB akışına autoinstall kadar uygun değil, ek katman | Elendi |
| Custom ISO (cubic/live-build) | Her şey gömülü tek ISO | Derleme hattı + imza + sürüm yükü | Elendi |
| Packer + QEMU build | Tekrarlanabilir build | Ek altyapı, öğrenme eğrisi, 700 PC için aşırı | Elendi |
| Ansible-only (kurulu OS üstüne) | İmaja gerek yok | Temel OS kurulumu yine manuel/USB gerektirir | Tamamlayıcı (kurucu sonrası filo) |
## 6. Avantajlar
- İmaj kimliksizdir: tek USB tüm sahada kullanılır, yanlış kimlikli cihaz çıkmaz.
- Kurucu idempotent olduğu için yarım kalan kurulum kaldığı yerden tamamlanır.
- Yedek yöntem (Clonezilla) hazırda bekler; autoinstall bir profilde takılırsa sahada blokaj olmaz.
## 7. Dezavantajlar
- Autoinstall sözdizimi Faz 1'de resmi-doğrulamalı değil; LAB çıktısı beklenir.
- İlk kurulum Clonezilla'ya göre daha yavaştır (paket kurulumu her cihazda tekrarlanır).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Heterojen donanımda sürücü eksikliği | Orta | Orta | Envanter taraması + LAB profil matrisi |
| Autoinstall sözdizimi sürüm farkı | Orta | Düşük | LAB 26.04.1 çıktısı dondurulur, dosyası repo'da sürümlenir |
| USB medyası bozuk/eskimiş | Düşük | Düşük | Çift USB + SHA256 doğrulama |
## 9. Uygulama Planı
1. İmaj içeriği (kimliksiz zemin):
- Ubuntu Server 26.04.1+ minimal (GUI yok).
- `unattended-upgrades` kapalı (03 §9 adım 6).
- `blueforce-install.sh` + modüller USB'de `/opt/blueforce-installer/` altında (veya ilk boot'ta merkezi depodan çekilir — LAB'da netleşir).
- Bootstrap SSH anahtarı (ilk Ansible run'ında rotasyon, K-13).
2. Saha akışı (hedef: teknisyen başına <15 dk aktif iş):
```text
USB tak → Ubuntu Server kur (autoinstall, katılımsız)
→ ilk açılışta: sudo ./blueforce-install.sh --dealer-id <8hane>
→ script bitince: bf-status → READY
→ USB çıkar, cihaz sahaya alınır
```
```bash
# sahada tek komut (kimlik ilk kez burada verilir)
sudo ./blueforce-install.sh --dealer-id 12010193
```
3. Kimlik enjeksiyonu ilk boot'ta olur: hostname + WireGuard peer + envanter kaydı kurucu tarafından yazılır; imajda hiçbir `bf-<no>` artığı bulunmaz (final-check denetler).
4. LAB test matrisi: envanterde çıkan her donanım profili × (kurulum + güç-kesintisi + `bf-gui-on/off` + final-check) — matris dolmadan WAVE açılmaz.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Aynı USB ile 2 farklı donanım profili | İkisi de READY | LAB(2) |
| İmajda kimlik artığı taraması (`bf-*`, peer key) | Hiçbir cihaz-spesifik değer yok | LAB(2) |
| Yarım kesilen kurulumun tekrarı | İkinci koşu tamamlar, exit 0 | LAB(2) |
| Clonezilla yedek yöntemi | Autoinstall takılan profilde READY | LAB(2) |
## 11. Rollback
1. Bozuk imaj: önceki USB sürümüne dönüş (USB'ler sürüm etiketli saklanır).
2. Kurulum sonrası hata: kurucu idempotent yeniden koşar; düzelmezse 17-RECOVERY LEVEL 9 (imajdan temiz kurulum).
3. Autoinstall dosyası hatalıysa düzeltme repo PR'ı ile sürümlenir, SHA256 yeniden yayımlanır.
## 12. Kontrol Listesi
- [ ] Autoinstall dosyası repo'da sürümlü + LAB çıktısıyla doğrulanmış.
- [ ] USB SHA256 değeri yayımlanmış ve sahada doğrulanıyor.
- [ ] İmajda kimlik artığı yok (otomatik tarama).
- [ ] Her donanım profili LAB matrisinde READY almış.
- [ ] Clonezilla yedek prosedürü yazılı ve test edilmiş.
## 13. Açık Sorular
- [ ] Kurucu USB'de mi taşınacak, ilk boot'ta merkezden mi çekilecek (saha interneti varsayımı) (sahibi: Faz 3).
- [ ] Autoinstall kesin direktif seti — LAB 26.04.1 çıktısı (sahibi: Faz 3, bu dosyanın yazarı).
- [ ] USB hazırlama standardı (Ventoy vs dd vs Balena) (sahibi: Faz 3).
---
## Ek: Provisioning Akışı
```mermaid
flowchart LR
USB["USB<br/>(autoinstall + kurucu)"] --> KUR["Ubuntu Server 26.04.1<br/>katılımsız kurulum"]
KUR --> TEK["sudo ./blueforce-install.sh<br/>--dealer-id <8hane>"]
TEK --> KIMLIK["Kimlik enjeksiyonu<br/>bf-<no> + peer + envanter"]
KIMLIK --> HAZIR["bf-status → READY"]
HAZIR --> SAHA["Sahaya alım"]
```

View file

@ -0,0 +1,153 @@
# 05 — Tek-Tık Kurucu (One-Click Installer)
> Kısa özet: Sahada tek komutla cihazı READY yapan `blueforce-install.sh`: bayi no doğrulaması, 18 modül, idempotent yeniden-koşu ve final-check kapısı. Teknisyenin çalıştırdığı tek şeydir.
- Dosya: `docs/05-ONE-CLICK-INSTALLER.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-09` (tek kurucu), `K-11` (update kapalı), `K-12` (kimlik formatı), `K-03` (bf-gui), `K-10` (Docker disiplini)
- Durum: [ ] Taslak
---
## 1. Amaç
Saha teknisyeninin uzmanlık gerektirmeden cihazı standarda getirmesi: tek komut, tek girdi (bayi no), net sonuç (READY / hata + log yolu). Yarım kalan veya hatalı kurulumun güvenli tekrarı.
## 2. Kapsam
- Kapsam içi: komut arayüzü, bayi-no doğrulama, 18 modül listesi ve sırası, idempotency kuralları, log/bundle çıktısı, çıkış kodları.
- Kapsam dışı: modül iç kodları (repo `scripts/install/`), imaj üretim yöntemi (04), filo-side yapılandırma (09).
## 3. Kararlar
```text
KARAR: Saha kurulumu tek giriş noktasıdır: `sudo ./blueforce-install.sh --dealer-id <8hane>`; bayi no `^[0-9]{8}$` ile doğrulanır, uymayan girdi kurucuyu başlatmaz.
GEREKÇE: Tek komut teknisyen hatasını en aza indirir; format kapısı yanlış kimliğin 9 sisteme yayılmasını baştan engeller (K-12).
ALTERNATİF: Çok scriptli kurulum (ağ.sh, gui.sh, …) — sıra hatası ve atlanan adım riski nedeniyle elendi.
RİSK: Tek dosya büyüdükçe bakımı zorlaşır; azaltma: 18 bağımsız modül + ana orkestratör ayrımı.
MALİYET: Ücretsiz.
LİSANS: Yok (şirket içi script).
```
```text
KARAR: Kurucu 18 modülden oluşur (`01-precheck` … `18-final-check`); her modül idempotenttir — yeniden koşu güvenli ve kaldığı yerden tamamlayıcıdır.
GEREKÇE: Saha elektriği/kesintisi yarım kurulum üretir; idempotency olmadan her kesinti temiz-kurulum demektir. Final-check kapısı (modül 18) exit 0 vermeden cihaz READY sayılmaz.
ALTERNATİF: Tek seferlik (non-idempotent) script — kesinti durumunda belirsiz ara durum nedeniyle elendi.
RİSK: Modülün idempotent yazılmaması (çift kayıt, çift key); azaltma: §10'daki çift-koşu testi her modül için zorunlu.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
700 cihaz × teknisyen başına değişen beceri = kurulumun "tek komut + tek soru" olması şarttır. 18 modül, her kararın (update-kapalı, Docker-disiplini, GUI-anahtarı, kimlik, servisler) ayrı denetlenebilir adımdır; modül numarası log satırında görünür, arıza hangi adımda kaldıysa oradan devam edilir.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Çok scriptli kurulum | Küçük dosyalar | Sıra/atlama hatası | Elendi |
| Non-idempotent tek script | Daha basit kod | Kesintide temiz-kurulum zorunluluğu | Elendi |
| İnteraktif sihirbaz (çok sorulu) | Esnek | Teknisyen hatası, otomasyona kapalı | Elendi |
## 6. Avantajlar
- Tek komut = eğitim maliyeti minimum, runbook tek sayfa.
- Idempotency = kesinti korkusu yok, "bir daha koş" her sorunun ilk cevabı.
- Final-check = READY iddiası ölçülebilir, dalga kapılarına bağlanır.
## 7. Dezavantajlar
- 18 modülün her biri için idempotency testi yazma maliyeti.
- Tek giriş noktası, modül-atlama (debug) ihtiyacında `--from/--only` bayraklarını zorunlu kılar.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Modül idempotent değil (çift kayıt) | Orta | Orta | Çift-koşu testi (§10) + code review kuralı |
| Teknisyen yanlış no girer | Orta | Orta | Format kapısı + onay ekranı (`BF-xxxx, onaylıyor musunuz?`) |
| Kurucu yarıda kesilir, cihaz ara durumda sahaya alınır | Düşük | Yüksek | Final-check exit 0 olmadan READY yok; `bf-status` bunu gösterir |
## 9. Uygulama Planı
1. Komut arayüzü:
```bash
sudo ./blueforce-install.sh --dealer-id 12010193 [--from 07] [--only 18-final-check] [--check]
# --check: değişiklik yapmadan denetim (final-check + modül durumları)
# --from: belirtilen modülden devam et | --only: tek modül koş
```
2. Bayi-no doğrulama: `^[0-9]{8}$`; uymazsa exit 2 + kullanım mesajı. Geçerse onay ekranı (`BF-12010193` + hostname `bf-12010193` gösterilir).
3. 18 modül (sıra sözleşmedir, yeri `scripts/install/`):
| # | Modül | İşlev (dayandığı karar) |
|---|---|---|
| 01 | `01-precheck` | OS sürümü (26.04.1+), disk/RAM minimumu, root yetkisi, internet kontrolü |
| 02 | `02-dealer-id` | No doğrulama + hostname `bf-<no>` atama (K-12) |
| 03 | `03-base-packages` | Temel paketler + `unattended-upgrades` kapatma (K-11) |
| 04 | `04-gnome` | GNOME kurulumu (K-02) |
| 05 | `05-xrdp` | xRDP + sesman + `bf-gui-on/off` yazımı (K-03) |
| 06 | `06-ssh-hardening` | `blueforce` kullanıcısı, key-auth, root/password kapalı (K-13) |
| 07 | `07-wireguard` | Spoke config, peer `bf-<no>`, keepalive 25, `wg-quick@wg0` enable (K-05) |
| 08 | `08-docker` | Docker CE + `unless-stopped` + log rotasyonu + localhost-bind (K-10) |
| 09 | `09-meg` | MEG konteyneri (sabit tag, `latest` yok) (K-10) |
| 10 | `10-rustdesk` | RustDesk istemci + VDS adresi + `BF-<no>` etiketi (K-04) |
| 11 | `11-meshcentral` | MeshCentral agent + `BF-<no>` adı (K-04) |
| 12 | `12-monitoring` | Node Exporter + textfile + Uptime Push (K-07) |
| 13 | `13-firewall` | UFW profili (SSH/RDP yalnızca WG) (K-05) |
| 14 | `14-inventory` | `bf-hardware-inventory.sh` koşusu, JSON+MD üretimi (02) |
| 15 | `15-logging` | journald + Docker rotasyon + `bf-status/bf-diagnostics` (K-14) |
| 16 | `16-boot` | multi-user default + BIOS notu + servis enable denetimi (K-03) |
| 17 | `17-ansible-bootstrap` | Bootstrap SSH key + ilk pull/Ansible kaydı (K-06/K-13) |
| 18 | `18-final-check` | Tüm kapılar: kimlik, servisler, update-kapalı, Docker politikası, READY damgası |
4. Idempotency kuralları (her modül için zorunlu):
- Varlık kontrolü önce (`id blueforce`, `dpkg -l`, `systemctl is-enabled`): varsa atla, yoksa kur.
- Dosya yazımları atomik (tmp + rename) ve tekrarlanabilir (aynı girdi → aynı çıktı).
- Anahtar/secret üretimi bir kez (`/var/lib/blueforce/.modül-done` damgası); `--force` olmadan yeniden üretilmez.
- Her modül `/var/log/blueforce-install.log` dosyasına `MODÜL-NO + OK/SKIP/FAIL` satırı yazar.
5. Çıkış kodları: `0` READY, `1` modül hatası (no logda), `2` argüman/format hatası.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Geçersiz no (7/9 hane, harf, boş) | exit 2, kurulum başlamaz | LAB(2) |
| Her modülün çift-koşusu | İkinci koşu exit 0, durum değişmez (diff boş) | LAB(2) |
| Elektrik-kesintisi simülasyonu (modül 09 ortasında kill) | `--from 09` ile tamamlanır, final exit 0 | LAB(2) |
| `18-final-check` tüm kapıları | Eksik adımda FAIL + modül nosu, READY yok | LAB(2) |
| `--check` kuru koşusu | Değişiklik yapmaz, rapor üretir | P1(5) |
## 11. Rollback
1. Modül hatası: logdaki modül nosundan `--from <no>` ile devam edilir.
2. Yanlış no: doğru no ile tam yeniden koşu (idempotent, kimlik modülü üzerine yazar).
3. Düzelmeyen cihaz: 17-RECOVERY LEVEL 9 (temiz imaj + kurucu).
## 12. Kontrol Listesi
- [ ] 18 modül dosyası `scripts/install/` altında numaralı ve çalışır durumda.
- [ ] Her modülde varlık-kontrolü + damga + log satırı var.
- [ ] Format regex'i 02 ile aynı (`^[0-9]{8}$`).
- [ ] `18-final-check` K-10/K-11 kapılarını denetliyor (unless-stopped, latest yok, update kapalı).
- [ ] `--check/--from/--only` bayrakları çalışıyor.
## 13. Açık Sorular
- [ ] Kurucu USB'de mi, merkezden `curl` ile mi alınacak (saha interneti varsayımı) (sahibi: Faz 3, 04 yazarı ile ortak).
- [ ] MEG sabit tag'inin kim tarafından, hangi onay ile güncelleneceği (sahibi: 10-UPDATE / 12-DOCKER yazarları).
---
## Ek: Kurucu Akış
```mermaid
flowchart TB
CMD["sudo ./blueforce-install.sh<br/>--dealer-id <8hane>"] --> FMT{"^[0-9]8$ ?"}
FMT -->|Hayır| EXIT2["exit 2<br/>kullanım mesajı"]
FMT -->|Evet| M01["01-precheck … 17-bootstrap<br/>(idempotent modüller)"]
M01 --> M18["18-final-check"]
M18 -->|Tümü OK| READY["READY damgası<br/>bf-status yeşil"]
M18 -->|FAIL| LOG["modül nosu + log yolu<br/>--from ile devam"]
```

View file

@ -0,0 +1,139 @@
# 06 — Kullanıcılar, SSH ve Yetkiler
> Kısa özet: Saha cihazlarındaki kullanıcı modeli (`blueforce` bakım kullanıcısı), SSH kimlik doğrulama mimarisi (anahtar zorunlu, password kapalı, root kapalı) ve tek private key riskine karşı per-admin anahtar + SSH CA hedefi. 700 cihazda güvenli ve iptal edilebilir erişimin sözleşmesidir.
- Dosya: `docs/06-USERS-SSH-AND-PERMISSIONS.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-13` (SSH mimarisi), `K-05` (SSH yalnızca WireGuard arkası), `K-12` (cihaz kimliği)
- Durum: [ ] Taslak
---
## 1. Amaç
700 saha cihazına kimlerin, hangi kullanıcıyla, nasıl bağlanacağını sabitlemek: tek bakım kullanıcısı, anahtar-zorunlu SSH, kapalı root/password, sızıntıda blast-radius'u sınırlayan anahtar dağıtım modeli.
## 2. Kapsam
- Kapsam içi: `blueforce` kullanıcısı, servis kullanıcıları, sudo politikası, `sshd_config` kilitleri, per-admin anahtar dağıtımı (Ansible), anahtar iptal prosedürü, SSH CA hedefi.
- Kapsam dışı: WireGuard tünel kurulumu (08), Ansible playbook detayları (09), UFW/firewall kuralları (11).
## 3. Kararlar
```text
KARAR: Saha cihazlarında tek insan bakım kullanıcısı `blueforce`'tur; servisler ayrı systemsız-login kullanıcılarla çalışır, sudo kontrollüdür.
GEREKÇE: Tek bakım kimliği = 9 sistemde (02-NAMING, WireGuard, Ansible, monitoring) join anahtarı; servislerin ayrı kullanıcıyla çalışması bir servisin ele geçirilmesinin bakım yetkisine sıçramasını engeller.
ALTERNATİF: Kişi başına ayrı login — 700 cihaz × N teknisyen authorized_keys kaosu nedeniyle elendi; ayrım SSH anahtarı seviyesinde (per-admin key) yapılır, kullanıcı seviyesinde değil.
RİSK: Tek kullanıcı adı hedefli saldırıya odaklanır; azaltma: password kapalı + yalnızca WireGuard arayüzünden SSH (08).
MALİYET: Ücretsiz.
LİSANS: OpenSSH (BSD-lisanslı), ücretsiz.
```
```text
KARAR: Root SSH girişi kapalıdır (`PermitRootLogin no`); password ile SSH kapalıdır (`PasswordAuthentication no`); anahtar zorunludur (`PubkeyAuthentication yes`).
GEREKÇE: Kaba-kuvvet yüzeyi root+password ikilisinden gelir; ikisi de kapatılınca uzaktan giriş yalnızca dağıtılmış anahtarlarla mümkündür. Root yetkisi yalnızca `sudo` ile, denetim izi bırakarak alınır.
ALTERNATİF: Password auth açık tutma — 700 internete çıkabilen cihazda kaba-kuvvet + zayıf parola riski nedeniyle elendi.
RİSK: Anahtarını kaybeden admin erişemez; azaltma: bootstrap anahtarı + acil erişim prosedürü (§9) + RustDesk/MeshCentral yedek kanalı (07).
MALİYET: Ücretsiz.
LİSANS: OpenSSH (BSD-lisanslı), ücretsiz.
```
```text
KARAR: 700 cihaza tek private key YAYILMAZ — her adminin kendi anahtar çifti vardır; cihazlardaki `authorized_keys` Ansible ile merkezi dağıtılır; uzun vadede SSH CA (sertifika tabanlı giriş) hedeflenir.
GEREKÇE: Tek private key'in sızıntı blast-radius'u 700 cihazdır; per-admin anahtar + merkezi dağıtım, sızıntıyı tek anahtarın iptali + tek Ansible run'ına indirger. SSH CA hedefi anahtar dağıtım gecikmesini ortadan kaldırır (kısa ömürlü sertifika).
ALTERNATİF: Tek paylaşılan private key — basit ama 700 cihazlık blast-radius nedeniyle elendi.
RİSK: Anahtar dağıtım gecikmesi yeni cihazda erişimsizlik; azaltma: golden image'da bootstrap anahtarı + ilk Ansible run'ında rotasyon (04-GOLDEN-IMAGE).
MALİYET: Ücretsiz.
LİSANS: OpenSSH (BSD-lisanslı), ücretsiz.
```
## 4. Neden Bu Karar?
Savunma katmanları üst üste biner: (1) SSH yalnızca WireGuard arayüzüne bağlıdır (08), internetten port 22 görünmez; (2) o dar kapıda bile password/root kapalıdır; (3) anahtarlar kişi bazlıdır, çalınan tek anahtar tek komutla iptal edilir. Tek paylaşılan key, 700 cihazda "bir sızıntı = filo kaybı" demektir; bu risk, per-admin anahtarın getirdiği küçük dağıtım yükünden ağır basar.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Tek paylaşılan private key | Dağıtım çok basit | 700 cihazlık blast-radius | Elendi |
| Password auth açık | Acil girişte kolay | Kaba-kuvvet yüzeyi | Elendi |
| Kişi başına ayrı login | Denetimde ad bazlı iz | 700 cihazda kullanıcı kaosu | Elendi |
| SSH CA (hemen) | En temiz iptal/rotasyon | Kurulum + Faz 1 yükü | Hedef (ileride) |
## 6. Avantajlar
- Sızıntıda iptal tek Ansible run'ı ile filoya yayılır.
- Root'un doğrudan girişi olmadığı için tüm yetkili işlem `sudo` log'unda iz bırakır.
- Servis/servis-dışı ayrımı, MEG veya agent zafiyetinin bakım yetkisine sıçramasını engeller.
## 7. Dezavantajlar
- Yeni admin için anahtar üret + dağıt + test döngüsü gerekir (runbook'a işlenir).
- SSH CA kurulana kadar `authorized_keys` dağıtım gecikmesi yaşanabilir (bootstrap anahtarı ile kapatılır).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Tek private key sızıntısı (yasak ihlali) | Düşük | Yüksek (700 cihaz) | Politika + denetim (§12); sızıntıda tüm filo rotasyonu (17-RECOVERY) |
| Admin anahtar kaybı | Orta | Düşük | Bootstrap anahtarı kasada; acil erişim prosedürü (§9) |
| `authorized_keys` senkron kayması | Orta | Orta | Ansible run sonunda `ssh -i` doğrulama testi (09) |
| SSH CA'ye hiç geçilememesi | Orta | Düşük | Per-admin model CA'sız da sürdürülebilir; CA Faz-sonrası hedef |
## 9. Uygulama Planı
1. Golden image: `blueforce` kullanıcısı + bootstrap `authorized_keys` + kilitli `sshd_config` ile gelir (04).
2. Her admin kendi anahtar çiftini üretir, public key merkez envantere işlenir.
3. Ansible `users/ssh` rolü `authorized_keys`'i dağıtır, bootstrap anahtarını ilk run'da rotasyona sokar (09).
4. Sızıntı/ayrılışta ilgili public key envanterden çıkarılır, playbook tüm filoya koşar.
5. Faz-sonrası: SSH CA kurulumu değerlendirilir (CA private key merkezde, host sertifikaları ilk boot'ta).
```bash
# örnek: sshd kilitleri (hedef durum)
grep -E '^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication)' /etc/ssh/sshd_config
# beklenen: PermitRootLogin no / PasswordAuthentication no / PubkeyAuthentication yes
# örnek: acil erişim testi (merkezden, WireGuard üzerinden)
ssh -i ~/.ssh/admin-emirhan -o BatchMode=yes blueforce@10.8.0.15 echo OK
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `ssh root@<wg-ip>` | Red (Permission denied) | LAB(2) |
| Parola ile giriş denemesi | Red | LAB(2) |
| Geçerli admin anahtarı ile giriş | Başarılı | LAB(2) |
| İptal edilen anahtar ile giriş | Red (dağıtım sonrası) | LAB(2) |
| `sudo -l` çıktısı | Yalnızca tanımlı komutlar | LAB(2) |
## 11. Rollback
1. Hatalı `sshd_config` dağıtımında önceki sürüm Ansible ile geri basılır (`sshd -t` doğrulamalı).
2. Yanlışlıkla silinen geçerli anahtar, bootstrap anahtarı veya yedek kanaldan (RustDesk/MeshCentral, 07) girilip geri eklenir.
3. Son çare: cihaz 17-RECOVERY prosedürüyle yeniden imajlanır.
## 12. Kontrol Listesi
- [ ] `PermitRootLogin no`, `PasswordAuthentication no` tüm saha cihazlarında doğrulandı.
- [ ] Hiçbir cihazda paylaşılan/ortak private key yok (denetim scripti 11'de).
- [ ] Her admin anahtarı envanterde kayıtlı, ayrılanlarınki çıkarılmış.
- [ ] Bootstrap anahtarı fiziksel kasada + erişim log'lu.
- [ ] SSH yalnızca WireGuard arayüzünde dinliyor (08 ile birlikte test).
## 13. Açık Sorular
- [ ] SSH CA için zaman çizelgesi ve CA altyapısı (sahibi: Faz-sonrası plan, 25-ROADMAP).
- [ ] `sudo` komut beyaz listesinin kesin içeriği — LAB'da bakım akışlarıyla netleşecek (sahibi: 11-SECURITY yazarı).
---
## Ek: Mermaid — anahtar yaşam döngüsü
```mermaid
flowchart LR
GEN["Admin anahtar üretir<br/>(public key envantere)"] --> DIST["Ansible authorized_keys<br/>dağıtımı"]
DIST --> USE["SSH-over-WG<br/>günlük kullanım"]
USE --> REV["Ayrılış/sızıntı:<br/>key envanterden çıkar"]
REV --> REDIST["Playbook tüm filoya<br/>yeniden koşar"]
REDIST --> VER["İptal testi:<br/>eski key reddedilir"]
```

154
docs/07-REMOTE-ACCESS.md Normal file
View file

@ -0,0 +1,154 @@
# 07 — Uzaktan Erişim (4 Kanal)
> Kısa özet: Saha cihazlarına 4 bağımsız erişim kanalı: SSH-over-WireGuard, xRDP + GNOME, RustDesk OSS self-hosted (birincil grafik), MeshCentral self-hosted (ikincil yönetim). AnyDesk mimariden çıkarılmıştır; yalnızca müşteri sahasında zaten lisanslıysa opsiyonel modül olarak kurulur.
- Dosya: `docs/07-REMOTE-ACCESS.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-04` (4 kanal + AnyDesk hükmü), `K-03` (xRDP + bf-gui), `K-05` (WireGuard arkası), `K-02` (GNOME)
- Durum: [ ] Taslak
---
## 1. Amaç
WireGuard çökse bile sahaya erişimi sürdürecek yedekli uzak-erişim mimarisini sabitlemek: hangi kanal ne için kullanılır, hangisi hangi arızada ayakta kalır, AnyDesk neden yoktur.
## 2. Kapsam
- Kapsam içi: 4 kanalın rolü/kurulumu/boot davranışı, WG-çöküşü analizi, AnyDesk hükmü + opsiyonel modül notu, kanal seçim matrisi.
- Kapsam dışı: WireGuard tünel kurulumu (08), SSH anahtar politikası (06), filo otomasyonu (09).
## 3. Kararlar
```text
KARAR: Dört erişim kanalı: (1) SSH-over-WireGuard (yönetim/otomasyon), (2) xRDP + GNOME (grafik bakım), (3) RustDesk OSS self-hosted hbbs/hbbr (birincil grafik uzak erişim, WireGuard-bağımsız), (4) MeshCentral self-hosted (ikincil yönetim: terminal/dosya/envanter, WireGuard-bağımsız). AnyDesk mimariden ÇIKARILDI.
GEREKÇE: RustDesk OSS sınırsız istemci, kendi ID+röle altyapısı, E2E şifreli oturum, dosya transferi ve katılımsız erişimi ücretsiz verir; istemcide VDS genel adresi kullanıldığında WireGuard çökse bile kanal ayakta kalır. MeshCentral Apache-2.0 ile ikinci bağımsız düzlemi sağlar. AnyDesk ücretsiz sürümü yalnızca kişisel kullanımı kapsar; 700 kurumsal cihaz ticari kullanımdır ve lisanssız kullanım ihlal olur.
ALTERNATİF: AnyDesk (lisans maliyeti + kapalı kaynak + self-hosted yalnızca en üst planda → elendi; yalnızca müşteri sahasında zaten lisanslıysa opsiyonel installer modülü). Tailscale/ZeroTier (freemium, merkezi kimlik → elendi).
RİSK: İki VDS-bağımlı kanalın tek ortak noktası VDS + genel internet; azaltma: hbbs/hbbr + MeshCentral health monitörü (Uptime Kuma) + yedek VDS planı 17-RECOVERY'de.
MALİYET: Ücretsiz (kendi VDS'i üzerinde; VDS kira bedeli hariç — altyapı maliyeti, lisans değil).
LİSANS: RustDesk istemci+sunucu AGPL-3.0 (1.4.9 / 1.1.16) — https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/ + https://rustdesk.com/docs/en/self-host/client-deployment/ (doğrulanma: 2026-09-15); MeshCentral Apache-2.0 (1.2.5) — https://github.com/Ylianst/MeshCentral (doğrulanma: 2026-09-15); AnyDesk hükmü — https://support.anydesk.com/docs/anydesk-licenses.md (doğrulanma: 2026-09-15) + https://anydesk.com/en/pricing.
```
```text
KARAR: xRDP grafik bakımı verir (GNOME oturumu), yalnızca WireGuard arkasında dinler; GUI varsayılan kapalıdır, bakım penceresinde `bf-gui-on` ile açılır.
GEREKÇE: xRDP systemd servis birimleri (`xrdp`, `xrdp-sesman`) üzerinden yönetilebilir bir katmandır; WG-arkası dinleme RDP'yi internet taramasından gizler, kapalı GUI varsayılanı RAM'i korur.
ALTERNATİF: RDP'yi doğrudan internete açma — tarama + kaba-kuvvet riski nedeniyle elendi.
RİSK: Kesin birim adları ve GNOME oturum satırı 26.04.1'de değişebilir; azaltma: LAB doğrulaması olmadan `bf-gui-*` dondurulmaz (03).
MALİYET: Ücretsiz.
LİSANS: xRDP Apache-2.0, ücretsiz — https://github.com/neutrinolabs/xrdp (v0.10.6.1, 2026-07-07; doğrulanma: 2026-09-15).
```
```text
KARAR: Dört kanalın agent/servisleri boot'ta otomatik başlar (systemd enable): `wg-quick@wg0`, `rustdesk` katılımsız servis, MeshCentral agent, xRDP servisleri (GUI kapalı olsa da sesman hazır).
GEREKÇE: Elektrik kesintisi sonrası cihaz açılınca VPN + yedek kanallar kendiliğinden gelir; 16-POWER-LOSS boot zincirinin varsayımıdır.
ALTERNATİF: Manuel başlatma — 700 dokunulmaz cihazda her kesintide saha ziyareti demek → elendi.
RİSK: Boot race (agent ağdan önce kalkar); azaltma: systemd `After=network-online.target` + yeniden deneme, LAB güç-kesinti testiyle doğrulanır.
MALİYET: Ücretsiz.
LİSANS: Yok (OS yapılandırması).
```
## 4. Neden Bu Karar?
Tek tünel körlüğü engellenir: SSH ve RDP WireGuard'a bağımlıdır (güvenlik için), RustDesk ve MeshCentral ise VDS genel adresine doğrudan çıkar (erişilebilirlik için). RustDesk birincil grafiktir çünkü katılımsız erişim + dosya transferini OSS'te verir; MeshCentral ikinci düzlemdir çünkü terminal/dosya/envanter sunar ve RustDesk arızasında devreye girer. AnyDesk'in ücretsiz katmanı ticari kullanımı kapsamadığı için 700 cihazda lisans ihlali doğurur — bu hukuki risk teknik kolaylığa ağır basar.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| AnyDesk (ücretsiz) | Tanınmış, kolay | Ticari kullanımda lisans ihlali | Elendi |
| AnyDesk (lisanslı) | Kurumsal destek | 700 cihaz lisans bedeli + kapalı kaynak | Opsiyonel modül (bkz. §9) |
| Tailscale/ZeroTier | Kolay mesh | Freemium, merkezi kimlik | Elendi |
| Tek kanal (yalnızca SSH) | En sade | Tünel çökerse körlük | Elendi |
| VNC doğrudan | Basit | Şifresiz/zayıf varyantlar, WG-dışı risk | Elendi |
## 6. Avantajlar
- WireGuard çökse bile 2 kanal (RustDesk, MeshCentral) ayakta — filo kör kalmaz.
- Tüm kanallar ücretsiz/self-hosted; veri üçüncü parti buluta çıkmaz.
- Kanal başına rol ayrımı (otomasyon / grafik bakım / grafik erişim / envanter) runbook'ları sadeleştirir.
## 7. Dezavantajlar
- 4 kanal = 4 agent/servis bakımı, 4 izleme hedefi (14-MONITORING'e yük).
- RustDesk + MeshCentral aynı VDS'teyse ortak arıza noktası (yedek VDS planı gerekir).
- Teknisyenin hangi kanalı ne zaman kullanacağı eğitim gerektirir (kanal matrisi §9).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| WireGuard çöküşü (istemci/saha tarafı) | Orta | Orta | RustDesk/MeshCentral bağımsız kanallar (§9 analizi) |
| VDS kesintisi (hbbs+hbbr+MeshCentral) | Düşük | Yüksek | Health monitörü + yedek VDS planı (17) |
| RustDesk ID çakışması / key sızıntısı | Düşük | Orta | Self-hosted key, `bf-<no>` etiketi, key rotasyon prosedürü |
| xRDP + GNOME ek ayar ihtiyacı (26.04.1) | Orta | Orta | LAB'da `bf-gui-*` doğrulaması (03) |
## 9. Uygulama Planı
1. Merkez VDS: `hbbs`/`hbbr` (`--net=host` önerilir) + MeshCentral kurulumu, health monitörü (Uptime Kuma) bağlanır.
2. Golden image: RustDesk istemcisi (self-hosted key + VDS adresi gömülü) + MeshCentral agent + xRDP kurulu gelir; dördü de systemd enable.
3. Cihaz kimliği (`bf-<no>`, 02) RustDesk etiketi + MeshCentral adı + Ansible inventory adı olarak aynı yazılır.
4. Opsiyonel AnyDesk modülü: SADECE müşterinin sahasında geçerli ticari AnyDesk lisansı varsa, `blueforce-install.sh --with-anydesk` bayrağıyla kurulur; lisans anahtarı müşteri tarafından sağlanır, AMC lisans sağlamaz. Lisanssız cihaza kurulmaz.
```bash
# örnek: kanal durum denetimi (saha cihazında)
systemctl is-active wg-quick@wg0 xrdp rustdesk meshcentral 2>/dev/null
ss -tlnp | grep -E ':(22|3389)' # yalnızca WG arayüzünde dinlemeli
```
### Kanal seçim matrisi
| Durum | Kullanılacak kanal |
|---|---|
| Normal bakım (komut/config) | SSH-over-WireGuard |
| Grafik bakım (teknisyen) | xRDP + GNOME (WG üzerinden) |
| WireGuard çöktü, grafik lazım | RustDesk OSS (birincil yedek) |
| WireGuard + RustDesk çöktü | MeshCentral terminal/dosya |
| Otomasyon (filo) | Ansible-over-SSH (09), kanal değil araç |
### WG çökerse RustDesk analizi
RustDesk istemcisi tünele değil VDS genel adresine (`hbbs`/`hbbr` portları) doğrudan internetten çıkar; WireGuard arayüzü down olsa bile `eth0/wlan0` üzerinden röle/ID sunucusuna ulaşır. Bu bağımsızlığın iki önkoşulu vardır: (1) saha interneti ayaktadır (elektrik + ISS), (2) VDS ayaktadır. İkisi de varsa teknisyen RustDesk'ten girip `wg-quick@wg0`'ı onarır — yani RustDesk hem yedek kanal hem WG kurtarma aracıdır. Tek ortak arıza: saha internet kesintisi (o zaman hiçbir uzaktan kanal çalışmaz, 16/17 prosedürleri) veya VDS kesintisi (o zaman MeshCentral da gider; yedek VDS planı 17'de).
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| 4 kanalın normal durumda erişilebilirliği | Tümü OK | LAB(2) |
| `wg-quick@wg0` stop → RustDesk oturumu | Bağlantı kurulur | LAB(2) |
| WG down + RustDesk kapalı → MeshCentral terminal | Komut çalışır | P1(5) |
| Güç kesintisi → 4 kanalın otomatik dönüşü | Tümü 5 dk içinde OK | LAB(2) |
| RDP portu internetten tarama | Kapalı (yalnızca WG) | LAB(2) |
## 11. Rollback
1. Arızalı kanalın önceki agent sürümüne dönüşü 10-UPDATE dalga zinciriyle yapılır.
2. RustDesk key değişikliğinde eski key geçiş süresi boyunca tutulur, sonra iptal edilir.
3. Son çare: kanal agent'ı kaldırılıp kalan 3 kanalla işletim sürdürülür (17-RECOVERY).
## 12. Kontrol Listesi
- [ ] hbbs/hbbr + MeshCentral VDS'te ayakta, Uptime Kuma izliyor.
- [ ] 4 servisin tamamı boot-enable, güç-kesinti testinden geçti.
- [ ] SSH/RDP yalnızca WG arayüzünde dinliyor.
- [ ] RustDesk etiketleri `bf-<no>` ile eşleşiyor.
- [ ] AnyDesk hiçbir lisanssız cihaza kurulu değil.
## 13. Açık Sorular
- [ ] hbbs/hbbr ile MeshCentral aynı VDS'te mi, ayrı mı — yük testiyle karar (sahibi: 25-ROADMAP).
- [ ] RustDesk self-hosted key rotasyon sıklığı (sahibi: 11-SECURITY yazarı).
---
## Ek: Mermaid — kanal bağımsızlığı
```mermaid
flowchart LR
PC["Saha bf-<no>"] -->|WG tüneli| WG["WireGuard hub"]
WG --> SSH["SSH / Ansible"]
WG --> RDP["xRDP + GNOME"]
PC -->|doğrudan internet<br/>VDS genel adresi| RD["RustDesk hbbs/hbbr"]
PC -->|doğrudan internet<br/>VDS genel adresi| MC["MeshCentral"]
WG -.->|çökerse| DOWN{"WG down?"}
DOWN -->|evet| RD
DOWN -->|evet| MC
```

View file

@ -0,0 +1,141 @@
# 08 — WireGuard Ağı ve Network
> Kısa özet: Hub-spoke WireGuard topolojisi: merkez hub, her saha cihazı `bf-<8hane>` peer'ı, `PersistentKeepalive = 25`, boot'ta otomatik tünel. SSH/RDP yalnızca tünel içinden erişilir; saha internetindeki Turkcell paket bitimi/dönüşü etkileri bu dosyadadır.
- Dosya: `docs/08-WIREGUARD-AND-NETWORK.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-05` (hub-spoke + keepalive + otomatik reconnect), `K-12` (peer adı = cihaz kimliği), `K-04` (WG çökerse yedek kanallar)
- Durum: [ ] Taslak
---
## 1. Amaç
700 cihazlık VPN topolojisini, peer adlandırma sözleşmesini, NAT arkasında tüneli ayakta tutan keepalive değerini ve saha interneti (Turkcell mobil veri) gerçekleriyle başa çıkma planını sabitlemek.
## 2. Kapsam
- Kapsam içi: hub-spoke topoloji, peer = bayi ID eşleşmesi, keepalive, `wg-quick@wg0` otostart, subnet/IP planı, SSH/RDP'nin WG-arkası kuralı, Turkcell paket bitimi/dönüşü notu.
- Kapsam dışı: SSH anahtar politikası (06), RustDesk/MeshCentral kurulumu (07), firewall detayları (11).
## 3. Kararlar
```text
KARAR: Hub-spoke WireGuard: merkez sunucu hub, her saha cihazı spoke (peer adı = `bf-<8hane>`); istemcide `PersistentKeepalive = 25` + `wg-quick@wg0` systemd enable; RDP/SSH dış dünyaya kapalı, yalnızca WireGuard arkasında.
GEREKÇE: Resmi QuickStart NAT arkasındaki eş için 25 sn keepalive'i "geniş güvenlik-duvarı yelpazesiyle çalışan makul aralık" olarak verir; `wg-quick@.service` Ubuntu paketinden gelir, enable = açılışta otomatik VPN. Elektrik kesintisi sonrası cihaz açılınca VPN kendiliğinden gelir.
ALTERNATİF: Keepalive kapalı / agresif 10 sn — kapalı NAT eşlemesini düşürür, agresif değer saha verisi olmadan yazılmaz; PİLOT-1 kopma sayacına göre ayarlanır.
RİSK: Turkcell CGNAT davranışı resmi kaynaktan doğrulanamaz (operatör bilgisi); azaltma: PİLOT-1'de 7/24 kopma sayacı, aralık saha verisiyle ayarlanır.
MALİYET: Ücretsiz.
LİSANS: WireGuard OSS (Ubuntu paketi `wireguard-tools 1.0.20250521-1ubuntu1`) — https://www.wireguard.com/quickstart/ + https://packages.ubuntu.com/resolute/wireguard-tools (doğrulanma: 2026-09-15).
```
```text
KARAR: Her WireGuard peer adı cihaz kimliğine eşittir (`bf-<8hane>` = hostname = Ansible inventory adı = monitoring etiketi); hub tarafında peer başına sabit tünel IP'si atanır.
GEREKÇE: Tek kimlik (K-12) 9 sistemde join anahtarıdır; peer adı farklı olsaydı WG log'undan cihaz bulmak manuel eşleştirme gerektirirdi. Sabit IP = envanterde `bf-<no> → 10.x` haritası, runbook ve monitoring sorguları deterministik olur.
ALTERNATİF: Rastgele peer adı / dinamik IP — okunamaz, izlenemez → elendi.
RİSK: Bayi no değişirse peer yeniden adlandırılmalı; azaltma: 02-NAMING yeniden-no prosedürü.
MALİYET: Ücretsiz.
LİSANS: Yok (isimlendirme standardı).
```
## 4. Neden Bu Karar?
Saha cihazları NAT/CGNAT arkasındadır; merkez onlara ulaşamaz, onlar merkeze çıkar. Hub-spoke bu gerçeğe uyar: spoke keepalive ile NAT eşlemesini canlı tutar, hub yalnızca dinler. 25 sn, resmi dokümanın "makul aralık" değeridir — saha ölçümü olmadan daha agresif yazmak veri israfı, kapatmak kopma demektir. Peer = bayi ID kuralı, 700 peer'lı hub config'ini insan tarafından okunabilir tutar.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Keepalive kapalı | Az trafik | NAT eşlemesi düşer, tünel ölür | Elendi |
| Keepalive 10 sn | Daha canlı eşleme | Saha verisi olmadan veri israfı | Yedek (PİLOT-1 verisine göre) |
| Full-mesh | Spoke'lar arası doğrudan | 700 cihazda key/config patlaması | Elendi |
| Tailscale/ZeroTier | Kolay | Freemium, merkezi kimlik | Elendi (K-04) |
## 6. Avantajlar
- Kernel-seviyesi VPN: düşük CPU, düşük gecikme, mini PC dostu.
- Otostart: elektrik kesintisi sonrası teknisyen müdahalesi gerekmez.
- Sabit IP + peer adı = monitoring ve Ansible'da doğrudan adresleme.
## 7. Dezavantajlar
- Hub tek darboğaz: 700 eşin handshake + trafiği tek VDS'ten geçer (yük testi gerekir).
- CGNAT davranışları (özellikle mobil) resmi kaynaktan doğrulanamaz; ayar saha verisine bağımlıdır.
- Peer ekleme/çıkarma merkez config'inde yapılır; otomasyonsuz 700 peer yönetilemez (09'a bağımlılık).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Turkcell CGNAT NAT eşlemesini erken düşürür | Orta | Orta | PİLOT-1 7/24 kopma sayacı; aralık saha verisiyle ayarlanır |
| Turkcell paket bitimi → veri durur | Orta | Yüksek | Paket izleme + bitim alarmı (bkz. §9); kota-dostu keepalive |
| Hub VDS darboğazı (700 eş) | Orta | Yüksek | Yük testi + peer başına trafik limiti; gerekirse 2. hub |
| Peer private key sızıntısı | Düşük | Orta | Peer bazlı iptal (tek peer silinir, filo etkilenmez) |
## 9. Uygulama Planı
1. Merkez hub kurulur, subnet planı dondurulur (ör. `10.8.0.0/16`, hub `10.8.0.1`, cihazlara sabit `/32`).
2. Her cihaz için peer üretilir: adı `bf-<8hane>`, tünel IP'si envanter haritasından.
3. İstemci config'i (`/etc/wireguard/wg0.conf`): hub endpoint + `PersistentKeepalive = 25` + `wg-quick@wg0 enable`.
4. Peer ekleme/çıkarma Ansible rolüyle yapılır (09); hub config'i Git'te sürümlenir.
5. PİLOT-1'de kopma sayacı koşar (handshake yaşı metriği 14'te), keepalive saha verisiyle ayarlanır.
```bash
# örnek: istemci konfigürasyonu (değerler envanterden gelir)
# /etc/wireguard/wg0.conf
# [Interface] PrivateKey = <cihaz-özel> / Address = 10.8.0.15/32
# [Peer] PublicKey = <hub-genel> / Endpoint = <hub>:51820
# PersistentKeepalive = 25 / AllowedIPs = 10.8.0.0/16
sudo systemctl enable --now wg-quick@wg0
sudo wg show wg0 latest-handshakes # kopma sayacı girdisi
```
### Turkcell paket bitimi / dönüşü notu
Saha bağlantısı Turkcell mobil veri ise iki gerçek vardır: (1) hat CGNAT arkasındadır — merkez cihaza ulaşamaz, keepalive'lı giden tünel zorunludur; (2) kota bitiminde veri durur veya hız düşer — tünel sessizce ölür, cihaz "çevrimdışı" görünür ama arıza değildir. Önlemler: kota-dostu keepalive (25 sn varsayılan, PİLOT verisiyle ayarlanır; gereksiz agresif değer kotayı eritir), paket bitimine Uptime Kuma "last seen" alarmı + sorumlu bayiye bildirim akışı (14), kota dönüşünde tünelin kendiliğinden toparlanması (`wg-quick` + keepalive yeniden handshake eder, ek işlem gerekmez). Paket yenileme/dönüş prosedürü (hat sahibi, yenileme adımı) 18-ROLLOUT runbook'una yazılır — bu dosya yalnızca teknik davranışı sabitler.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Boot sonrası `wg show` handshake | 3 dk içinde güncel handshake | LAB(2) |
| NAT arkasında 24 saat tünel | Kopma yok (sayaç temiz) | P1(5) |
| Kota simülasyonu (veri kes) → geri ver | Tünel kendiliğinden toparlanır | LAB(2) |
| SSH/RDP internetten tarama | Kapalı; yalnızca `10.8.0.0/16` içinden açık | LAB(2) |
| 700 eş yük projeksiyonu | Hub CPU/bant genişliği sınırlar içinde | Yük testi |
## 11. Rollback
1. Hatalı hub config'i Git'teki önceki sürüme döndürülür, `systemctl reload wg-quick@wg0`.
2. Keepalive değişikliği sorun çıkarırsa önceki değere Ansible ile toplu dönüş (10-UPDATE dalga sırası).
3. Son çare: WG down iken RustDesk/MeshCentral (07) ile cihaza girilip config elle düzeltilir.
## 12. Kontrol Listesi
- [ ] Peer adları `bf-<8hane>` ile birebir, envanterle eşleşiyor.
- [ ] Tüm istemcilerde `PersistentKeepalive = 25` (veya PİLOT-onaylı değer).
- [ ] `wg-quick@wg0` tüm sahada enable.
- [ ] SSH/RDP yalnızca WG arayüzünde dinliyor.
- [ ] PİLOT-1 kopma sayacı koşuyor, sonuç 24-DECISION-LOG'a işlenecek.
## 13. Açık Sorular
- [ ] Keepalive'ın PİLOT-1 verisine göre 25 sn'de kalıp kalmayacağı (sahibi: 08 yazarı, P1 sonrası).
- [ ] Hub'un 700 eşi tek VDS'te taşıyıp taşımayacağı — yük testi (sahibi: 25-ROADMAP).
- [ ] Turkcell kota/bitim prosedürünün işletme sahibi (sahibi: 18-ROLLOUT yazarı).
---
## Ek: Mermaid — hub-spoke + keepalive
```mermaid
flowchart TB
subgraph SAHA["Saha (NAT/CGNAT arkası)"]
S1["bf-12010193<br/>10.8.0.15"]
S2["bf-12010194<br/>10.8.0.16"]
end
HUB["WireGuard hub<br/>10.8.0.1:51820"]
S1 -->|handshake + keepalive 25sn<br/>giden bağlantı| HUB
S2 -->|handshake + keepalive 25sn<br/>giden bağlantı| HUB
HUB -->|SSH/RDP yalnızca<br/>tünel içi| S1
```

181
docs/09-FLEET-MANAGEMENT.md Normal file
View file

@ -0,0 +1,181 @@
# 09 — Filo Yönetimi (Ansible + Semaphore)
> Kısa özet: 700 cihazın otomasyonu Ansible CLI (agent'sız, SSH) ile yapılır; operatör arayüzü Semaphore UI Community'dir (self-hosted, MIT). 15 standart işlem, tek/grup/pilot/tüm-filo hedefleme ve Semaphore Community sınırları bu dosyadadır.
- Dosya: `docs/09-FLEET-MANAGEMENT.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-06` (Ansible + Semaphore Community), `K-13` (SSH anahtar dağıtımı), `K-12` (inventory adı = `bf-<no>`), `K-11` (dalgalı yayılım)
- Durum: [ ] Taslak
---
## 1. Amaç
700 cihaza komut/config güncellemesini güvenli, tekrarlanabilir ve onaylı yaymanın yolunu sabitlemek: hangi araç, hangi 15 standart işlem, hangi hedefleme seviyeleri, Community sürümünün sınırlarında nasıl çalışılır.
## 2. Kapsam
- Kapsam içi: Ansible rolü/inventory düzeni, 15 standart işlem, hedefleme seviyeleri (tek/grup/pilot/tüm-filo), Semaphore kurulumu + Community sınırları, Semaphore-down yedeği.
- Kapsam dışı: monitoring (14), update onay zinciri detayı (10), SSH anahtar politikası (06).
## 3. Kararlar
```text
KARAR: Birincil filo otomasyonu Ansible CLI (SSH, agent'sız); operatör arayüzü Semaphore UI Community (self-hosted, MIT). Hiçbir playbook Pro/Enterprise özelliğine bağlanmaz.
GEREKÇE: En düşük hareketli parça (SSH + YAML + tek Go binary); 700 cihazda ek agent/master/K8s maliyeti yok. Community ücretsizliği resmi fiyat sayfasıyla kanıtlı ("$0, free forever"); Pro en fazla 500 managed node desteklediği için 700 cihazda ücretli yol zaten kapalı.
ALTERNATİF: AWX (K8s yükü + release'ler refactoring nedeniyle duraklatıldı → elendi); Salt (minion agent + master PKI → elendi); Rudder Community (relay/Enterprise modülleri + öğrenme eğrisi → elendi); MeshCentral (erişim aracı, filo otomasyonu değil → bu rolde elendi).
RİSK: Semaphore tek nokta arızası → Ansible CLI bağımsız çalışır (UI çökse filo durmaz). Community'de OIDC/2FA/Vault yok → Semaphore yalnızca WireGuard arkasında, erişim VPN + SSH anahtarı ile; gizliler yerleşik şifreli Key Store'da.
MALİYET: Ücretsiz (kendi VDS'i üzerinde).
LİSANS: Ansible GPL-3.0 — https://github.com/ansible/ansible; Semaphore Community MIT — https://github.com/semaphoreui/semaphore + https://semaphoreui.com/pricing (doğrulanma: 2026-09-15).
```
```text
KARAR: Tüm filo işlemleri 15 standart işlemden biri olarak Semaphore task şablonu + Ansible playbook/rolüyle tanımlanır; serbest komut yalnızca acil kır cam prosedürüyle koşar.
GEREKÇE: 15 sabit işlem = denetlenebilir, test edilebilir, rollback'i tanımlı yüzey; serbest komut 700 cihazda yazım hatasını filo arızasına çevirir.
ALTERNATİF: Serbest ad-hoc komut serbestliği — insan hatası blast-radius'u nedeniyle elendi.
RİSK: 16. ihtiyaçta şablon dışı kalma; azaltma: yeni işlem teklifi PR ile 15 listesine eklenir (§13).
MALİYET: Ücretsiz.
LİSANS: Yok (operasyon standardı).
```
```text
KARAR: Hedefleme 4 seviyelidir: tek cihaz → grup → pilot dalga → tüm filo; tüm-filoya çıkış yalnızca pilot dalga başarısından sonra, onay adımlı Semaphore pipeline ile yapılır.
GEREKÇE: 10-UPDATE dalga zincirinin (LAB/P1/P2/W1/W2/PROD) filo-operasyon karşılığıdır; playbook hatası LAB(2)'de yakalanır, 700 cihaza yayılmaz.
ALTERNATİF: Doğrudan tüm-filo çalıştırma — tek hatanın 700 katı etki nedeniyle elendi.
RİSK: Yanlış grup etiketi yanlış hedefe koşar; azaltma: `--limit` + `--check` kuru koşu zorunlu ön adım.
MALİYET: Ücretsiz.
LİSANS: Yok (operasyon standardı).
```
## 4. Neden Bu Karar?
700 cihazda ajanlı mimariler (Salt minion, Rudder agent, AWX+K8s) her cihaza bir ek yük ve merkeze bir ek servis bindirir. Ansible'da ajan yoktur: SSH varsa filo vardır. Semaphore, CLI bilgisi olmayan operatörün (saha sorumlusu) güvenli düğmelere basmasını sağlar; CLI ise Semaphore çöktüğünde bağımsız yedektir. Pro sürüm 500 node ile sınırlı olduğundan 700 cihazda zaten kullanılamaz — Community sınırı bir eksik değil, mimari sabittir.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| AWX | Güçlü UI, RBAC | K8s zorunlu, release'ler duraklatıldı | Elendi |
| Salt | Ölçeklenir | Minion agent + master PKI | Elendi |
| Rudder Community | Politika motoru | Relay/Enterprise modülleri, öğrenme eğrisi | Elendi |
| Semaphore Pro | Ek özellikler | 500 node limiti (700'e yetmez) + ücret | Elendi |
| MeshCentral (filo rolü) | Zaten kurulu | Toplu config/rollback disiplini yok | Bu rolde elendi |
## 6. Avantajlar
- Agent'sız: saha imajına ek yük yok, yeni cihaz envantere girer girmez yönetilir.
- Semaphore down olsa filo durmaz (Ansible CLI bağımsız).
- 15 sabit işlem + 4 hedefleme seviyesi = hata yüzeyi küçük, denetim izi tam.
## 7. Dezavantajlar
- Community'de OIDC/2FA/Vault yok — erişim disiplini (WG-arkası + Key Store) manuel korunmalı.
- Eşzamanlı 700 SSH bağlantısı Semaphore/Ansible fork ayar + hub bant genişliği ister (yük testi §13).
- Windows-odaklı teknisyen için YAML/playbook eşiği (Semaphore düğmeleriyle kapatılır).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Playbook hatası filoya yayılır | Orta | Yüksek | Dalgalı yayılım + `--check` kuru koşu + LAB zorunluluğu |
| Semaphore çöker | Düşük | Orta | Ansible CLI bağımsız çalışır (K-06) |
| Community'de kimlik disiplini bozulur | Orta | Yüksek | WG-arkası erişim + per-admin SSH key + Key Store; denetim (§12) |
| 700 eşzamanlı SSH hub'ı yorar | Orta | Orta | Fork/batch limitleri + dalga yayılımı; yük testi |
## 9. Uygulama Planı
1. Merkez: Semaphore Community (tek binary, WG-arkası) + Ansible CLI + Git-sürümlü playbook deposu kurulur.
2. Inventory: `bf-<no>` adları, grup etiketleri (bölge/pilot-dalga/donanım-profili), `ansible_user=blueforce`, per-admin key (06).
3. 15 standart işlem playbook/rol + Semaphore task şablonu olarak yazılır, LAB(2)'de test edilir.
4. Hedefleme boru hattı: tek → grup → pilot → tüm-filo; son adıma onay kapısı konur.
5. Semaphore-down tatbikatı: CLI ile aynı playbook'un koştuğu kanıtlanır (10-Test).
```bash
# örnek: kuru koşu + sınırlı hedef (zorunlu ön adım)
ansible-playbook -i inventory/prod.yml playbooks/bf-gui-off.yml --limit 'pilot1' --check
ansible-playbook -i inventory/prod.yml playbooks/bf-gui-off.yml --limit 'pilot1'
# örnek: tek cihaz teşhisi
ansible -i inventory/prod.yml 'bf-12010193' -m ping
```
### 15 standart işlem
| # | İşlem | Playbook/rol (ad) |
|---|---|---|
| 1 | ping (erişilebilirlik yoklaması) | `bf-ping.yml` |
| 2 | status (bf-status çıktısı toplama) | `bf-status.yml` |
| 3 | diagnostics (bf-diagnostics + bundle) | `bf-diagnostics.yml` |
| 4 | gui-on (grafik katmanı aç) | `bf-gui-on.yml` |
| 5 | gui-off (grafik katmanı kapat) | `bf-gui-off.yml` |
| 6 | reboot (kontrollü yeniden başlatma) | `bf-reboot.yml` |
| 7 | shutdown (kontrollü kapatma) | `bf-shutdown.yml` |
| 8 | ssh-keys (authorized_keys dağıtım/rotasyon) | `bf-ssh-keys.yml` |
| 9 | wg-rekey (WireGuard peer anahtar yenileme) | `bf-wg-rekey.yml` |
| 10 | docker-restart (MEG konteyner yeniden başlatma) | `bf-docker-restart.yml` |
| 11 | docker-update (sabit tag'e onaylı imaj geçişi) | `bf-docker-update.yml` |
| 12 | apt-update (onaylı paket güncellemesi, dalgalı) | `bf-apt-update.yml` |
| 13 | config-push (dosya/şablon dağıtımı) | `bf-config-push.yml` |
| 14 | log-collect (journald/destek paketi toplama) | `bf-log-collect.yml` |
| 15 | decommission (envanter + peer + key temizliği) | `bf-decommission.yml` |
### Hedefleme seviyeleri
| Seviye | Hedef | Onay |
|---|---|---|
| Tek | `bf-<no>` (arıza/teşhis) | Gerekmez (loglanır) |
| Grup | bölge / donanım profili etiketi | Grup sorumlusu |
| Pilot | P1(5) → P2(20) dalgaları | Merkezi admin |
| Tüm-filo | kalan cihazlar (W1/W2/PROD sırasıyla) | Merkezi admin + değişiklik kaydı (10) |
### Semaphore Community sınırları (çalışma kuralları)
- OIDC/SSO yok → kullanıcılar Semaphore yerel hesabı, erişim yalnızca WireGuard arkasından.
- 2FA yok → parola politikası + VPN zorunluluğu bu açığı kapatır; admin hesapları envanterde kayıtlı.
- Harici Vault entegrasyonu yok → gizliler Semaphore yerleşik şifreli Key Store'da; prod secret'ları playbook'a gömülmez.
- Global Runner / yüksek eşzamanlılık sınırları → 700 node yük testi yapılır; gerekirse runner sayısı + fork/batch ayarlanır (§13 açık soru).
- Hiçbir iş akışı Pro özelliğine bağlanmaz (Community'de çalışmayan şablon yazılmaz).
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| 15 işlemin her biri LAB(2)'de | Başarılı + log'lu | LAB(2) |
| `--check` kuru koşu, değişimsiz playbook | "changed=0" | LAB(2) |
| Yanlış `--limit` denemesi | Onay kapısında durur / hedef dışı etkilenmez | LAB(2) |
| Semaphore kapalı → CLI run | Playbook başarıyla koşar | LAB(2) |
| Pilot dalga → tüm-filo boru hattı | Onay adımları çalışır | P1(5) |
## 11. Rollback
1. Her işlemin geri alma adımı playbook'ta tanımlıdır (config-push önceki sürümü basar, docker-update önceki tag'e döner).
2. Yayılım ortasında arıza: dalga durdurulur, etkilenmiş dalga 10-UPDATE rollback zinciriyle geri alınır.
3. Semaphore veritabanı bozulursa playbook deposu (Git) + inventory'den CLI ile işletim sürer; Semaphore yeniden kurulur.
## 12. Kontrol Listesi
- [ ] 15 işlemin playbook + Semaphore şablonu LAB-onaylı.
- [ ] Inventory adları `bf-<no>`, grup etiketleri güncel.
- [ ] `--check` ön adımı tüm şablonlarda zorunlu.
- [ ] Semaphore yalnızca WG arkasından erişilebilir.
- [ ] CLI yedeği tatbikatla kanıtlandı.
- [ ] Hiçbir şablon Pro/Enterprise özelliği kullanmıyor.
## 13. Açık Sorular
- [ ] Semaphore Global Runner sayısı + eşzamanlılık (fork/batch) — 700 node yük testi (sahibi: 25-ROADMAP).
- [ ] 16. standart işlem teklifi süreci (PR şablonu) (sahibi: 09 yazarı).
- [ ] Inventory kaynak gerçeği (statik dosya mı, API mi) (sahibi: 02-NAMING yazarı).
---
## Ek: Mermaid — dalgalı yayılım
```mermaid
flowchart LR
DEV["Playbook PR<br/>(Git review)"] --> LAB["LAB 2<br/>--check + run"]
LAB --> P1["PILOT-1 5"]
P1 --> P2["PILOT-2 20"]
P2 --> W["W1 50 → W2 100"]
W --> PROD["PROD kalan"]
LAB -->|hata| FIX["Düzelt +<br/>yeniden LAB"]
```

View file

@ -0,0 +1,162 @@
# 10 — Update ve Rollback Politikası
> Kısa özet: Sahaya onaysız update yasaktır: `unattended-upgrades` kapalıdır, her değişiklik LAB(2) → P1(5) → P2(20) → W1(50) → W2(100) → PROD dalgalarından ve merkezi onaydan geçer. Her dalganın geri alma planı yayından önce tanımlıdır.
- Dosya: `docs/10-UPDATE-AND-ROLLBACK-POLICY.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-11` (otomatik update yasağı + dalgalar), `K-10` (`latest`/Watchtower yasakları), `K-09` (imaj bağı)
- Durum: [ ] Taslak
---
## 1. Amaç
700 cihazda "kendiliğinden değişen hiçbir şey olmasın" ilkesini teknik ve prosedürel kilitlerle garanti etmek: otomatik updater'ların kapatılması, onay zinciri, dalga planı ve rollback sözleşmesi.
## 2. Kapsam
- Kapsam içi: onaysız update yasağı, `unattended-upgrades` kapatma, dalga tanımı ve geçiş kriterleri, onay rolleri, rollback zinciri.
- Kapsam dışı: playbook yazım detayları (09), imaj üretim adımları (04), Docker tag disiplini detayı (12).
## 3. Kararlar
```text
KARAR: Golden image'da `unattended-upgrades` kapatılır (`/etc/apt/apt.conf.d/20auto-upgrades` değerleri `0` + `apt-daily*.timer` maskeleme); tüm güncellemeler LAB→PİLOT→WAVE→PROD onay zincirinden geçer (dalgalar: LAB(2)/P1(5)/P2(20)/W1(50)/W2(100)/PROD).
GEREKÇE: `unattended-upgrades` Ubuntu Server'da varsayılan kurulu ve etkindir, günde bir kez çalışır; kapatılmazsa 700 cihaz ilk açılışta güncellemeye kalkar ("onaysız update yasak" ilkesi delinir). Kaçan timer makine açılışında hemen tetiklenir (`Persistent=true` davranışı) — saha PC'leri sık kapanan makinelerdir.
ALTERNATİF: Otomatik security update'e izin verme — 700 cihazda eşzamanlı indirme + onaysız değişim riski nedeniyle elendi; security update'ler öncelik işaretli onaylı dalga ile çıkar.
RİSK: Kapatma adımı imajda atlanırsa filo kendiliğinden güncellenir; azaltma: `blueforce-install.sh` final-check + monitoring'de `Unattended-Upgrade` durumu metriği.
MALİYET: Ücretsiz.
LİSANS: Yok (işletim sistemi yapılandırması) — https://ubuntu.com/server/docs/how-to/software/automatic-updates/ + https://manpages.ubuntu.com/manpages/resolute/en/man8/unattended-upgrade.8.html (doğrulanma: 2026-09-15).
```
```text
KARAR: Onaysız update yasaktır: sahaya inen her değişiklik (OS paketi, Docker imajı, config, agent sürümü) değişiklik kaydı + merkezi admin onayı + dalga planı olmadan uygulanmaz; `latest` etiketi ve Watchtower gibi otomatik updater'lar yasaktır.
GEREKÇE: 700 ölçeğinde her "küçük varsayılan" (günlük otomatik update, hareketli etiket, otomatik imaj çekme) filo-çapı arızaya dönüşür; determinizm yalnızca sabit sürüm + onaylı yayılımla korunur.
ALTERNATİF: Güvenlik güncellemelerine otomatik izin — eşzamanlı indirme fırtınası + onaysız değişim riski nedeniyle elendi; acil güvenlik yaması "hızlandırılmış dalga" prosedürüyle (aynı zincir, kısaltılmış bekleme) çıkar.
RİSK: Onay kuyruğu kritik yamayı geciktirir; azaltma: security dalgasına öncelik SLA'sı (§9).
MALİYET: Ücretsiz.
LİSANS: Yok (politika) — Docker yasak dayanağı için 12-DOCKER ve K-10'a bakılır.
```
```text
KARAR: Rollback her yayının parçasıdır: dalgaya çıkmadan önce geri alma adımı (önceki paket sürümü / önceki imaj tag'i / önceki config) tanımlanır ve LAB'da geri dönüş testi yapılır; başarısız dalga bir sonrakine geçmez, etkilenmiş dalga geri alınır.
GEREKÇE: Geri alması test edilmemiş yayın, 700 cihazda tek yönlü kapıdır; LAB'da kanıtlanan rollback, PROD'da gece yarısı kurtarma prosedürüne dönüşür.
ALTERNATİF: "Gerekirse bakarız" yaklaşımı — arıza anında doğaçlama riski nedeniyle elendi.
RİSK: Geri alma adımı da bozuk çıkabilir; azaltma: son çare 17-RECOVERY yeniden-imaj prosedürü.
MALİYET: Ücretsiz.
LİSANS: Yok (operasyon standardı).
```
## 4. Neden Bu Karar?
Üç yasak tek ilkeden doğar: `unattended-upgrades` (işletim sistemi kendi kendine değişmesin), `latest` (hangi sürümün koştuğu her cihazda aynı bilinsin), Watchtower (hiçbir daemon izinsiz imaj çekmesin). Dalgalar (2 → 5 → 20 → 50 → 100 → ~523) hatanın blast-radius'unu geometrik olarak sınırlar: LAB'da yakalanan hata 2 cihazı etkiler, PROD'a sızan hata ancak 5 dalga kapısından geçmiş demektir.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Otomatik security update | Hızlı yama | Eşzamanlı indirme + onaysız değişim | Elendi (hızlandırılmış dalga ile karşılanır) |
| Doğrudan tüm-filo yayın | Hızlı | Tek hatanın 700 katı | Elendi |
| Watchtower ile oto-imaj | Eforsuz güncellik | Politika ihlali + upstream arşivli | Elendi (K-10) |
| `latest` etiketi | Kolay | Determinizm kaybı | Elendi (K-10) |
## 6. Avantajlar
- Filo sürüm determinizmi: her cihazın ne koşturduğu envanterde bilinir.
- Hata erken dalgada yakalanır; PROD'a ulaşan değişiklik 5 kez kanıtlanmıştır.
- Acil yama da aynı zincirden geçer — hız, disiplinsizlikle değil kısaltılmış beklemeyle kazanılır.
## 7. Dezavantajlar
- Yayın döngüsü yavaştır (özellikle PROD'a tam yayılım günler sürebilir).
- Onay kuyruğu ve dalga beklemeleri operasyonel disiplin ister.
- Her yayın için rollback testi yazma maliyeti.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| `unattended-upgrades` imajda açık unutulur | Orta | Yüksek | install.sh final-check + monitoring metriği (K-11) |
| Onay kuyruğu kritik yamayı geciktirir | Orta | Yüksek | Security dalgasına öncelik SLA'sı (§9) |
| Dalga atlama ("acil" bahanesiyle) | Orta | Yüksek | Semaphore onay kapısı + değişiklik kaydı zorunluluğu |
| Rollback adımı da bozuk | Düşük | Yüksek | LAB geri-dönüş testi + 17-RECOVERY son çare |
## 9. Uygulama Planı
1. Golden image: `20auto-upgrades` değerleri `0`, `apt-daily*.timer` maskeli, final-check'te doğrulamalı (04).
2. Değişiklik kaydı açılır: kapsam (paket/imaj/config), etkilenen sürümler, geri alma adımı, dalga takvimi.
3. Merkezi admin onaylar; yayın Semaphore pipeline ile dalga sırasına girer (09).
4. Her dalgada sağlık kapısı: monitoring (14) + `bf-status` örneklemesi temizse sonraki dalga açılır.
5. Başarısız dalga: yayılım durdurulur, etkilenmiş dalga rollback zinciriyle geri alınır, kök neden kayda işlenir.
```bash
# örnek: otomatik update kilit denetimi (saha cihazında)
cat /etc/apt/apt.conf.d/20auto-upgrades # iki değer de 0 olmalı
systemctl status apt-daily.timer apt-daily-upgrade.timer # maskeli/inactive
```
### Dalga tanımı ve geçiş kriterleri
| Dalga | Büyüklük | Geçiş kriteri (sonraki dalgaya) |
|---|---|---|
| LAB | 2 cihaz | Fonksiyonel test + rollback testi geçti |
| P1 (PİLOT-1) | 5 cihaz | 24–48 saat sorunsuz + metrikler temiz |
| P2 (PİLOT-2) | 20 cihaz | 48–72 saat sorunsuz + saha geri bildirimi |
| W1 (WAVE-1) | 50 cihaz | Sağlık kapısı + onay yenileme |
| W2 (WAVE-2) | 100 cihaz | Sağlık kapısı + onay yenileme |
| PROD | kalan ~523 cihaz | W2 temizliği + final onay |
### Security yaması öncelik SLA'sı
Kritik güvenlik bülteninde aynı zincir kısaltılmış beklemeyle koşar (LAB saatler içinde, P1 aynı gün); bekleme kısaltılır, kapılar kaldırılmaz — onay ve rollback testi security dalgasında da zorunludur.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `20auto-upgrades` değerleri + timer durumu | `0` / maskeli, 24 saatte otomatik apt yok | LAB(2) imaj denetimi |
| Kuru yayın (tüm dalgalar `--check`) | Değişim öngörüsü kayıtla eşleşir | LAB(2) |
| LAB rollback testi | Önceki sürüme dönüş + servis ayakta | LAB(2) |
| P1 48 saat gözlem | Metrik anomalisi yok | P1(5) |
| Dalga-durdurma tatbikatı | Yayılım durur, P1 geri alınır | P1(5) |
## 11. Rollback
1. Etkilenmiş dalga, değişiklik kaydındaki geri alma adımıyla önceki sürüme döndürülür (paket downgrade / önceki imaj tag'i / önceki config).
2. Geri alma sonrası sağlık kapısı (monitoring + `bf-status`) doğrulanır, kayda işlenir.
3. Geri alma da başarısızsa: cihaz 17-RECOVERY prosedürüyle önceki golden image'a döndürülür (LEVEL 9 son çare).
4. Kök neden bulunmadan yayına devam edilmez; zincir başa (LAB) sarar.
## 12. Kontrol Listesi
- [ ] `unattended-upgrades` tüm sahada kapalı (monitoring metriğiyle sürekli denetim).
- [ ] `latest`/`Watchtower` hiçbir saha cihazında yok (12 ile birlikte denetim).
- [ ] Her yayının değişiklik kaydı + onayı + rollback adımı var.
- [ ] Dalga kapıları atlanmadan işletildi (Semaphore log'uyla kanıtlı).
- [ ] Security SLA'sı runbook'ta yazılı, sorumlusu belli.
## 13. Açık Sorular
- [ ] Dalga bekleme sürelerinin (24–72 saat) PİLOT verisine göre kalibrasyonu (sahibi: 10 yazarı, P2 sonrası).
- [ ] Paket/imaj aynası (yerel mirror) gerekip gerekmediği — 700 cihazın eşzamanlı indirme yükü (sahibi: 25-ROADMAP).
---
## Ek: Mermaid — update onay akışı
```mermaid
flowchart LR
F["Bulundu<br/>(bülten / MEG sürümü)"] --> R["Kayıt<br/>(etki + rollback planı)"]
R --> O{"Onay<br/>(merkezi admin)"}
O -->|Red| F
O -->|Onay| LAB["LAB 2"]
LAB -->|Başarılı| P1["P1 5"]
P1 -->|Başarılı| P2["P2 20"]
P2 -->|Başarılı| W1["W1 50"]
W1 -->|Başarılı| W2["W2 100"]
W2 -->|Başarılı| PROD["PROD ~523"]
LAB -->|Başarısız| RB["Rollback +<br/>kök neden"]
P1 -->|Başarısız| RB
P2 -->|Başarısız| RB
W1 -->|Başarısız| RB
W2 -->|Başarısız| RB
```

View file

@ -0,0 +1,154 @@
# 11 — Güvenlik Sertleştirme (Security Hardening)
> Kısa özet: saha cihazının güvenlik tabanı: UFW default DENY, WireGuard arayüz izinleri, Docker-UFW bypass çözümü, SSH sertleştirme. Teknik ekip ve denetim içindir.
>
> - Dosya: `docs/11-SECURITY-HARDENING.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-05`, `#K-10`, `#K-13`
> - Durum: [ ] Taslak
---
## 1. Amaç
700 saha cihazında varsayılan-kapalı ağ + en az ayrıcalık ilkesiyle saldırı yüzeyini küçültmek; Docker'ın UFW'yi baypas etme davranışını standart çözüme bağlamak.
## 2. Kapsam
- Kapsam içi: UFW politikası, WireGuard arayüz kuralları, Docker bypass çözümü, SSH/userspace sertleştirme, denetim komutları.
- Kapsam dışı: WireGuard kurulum detayı (08), Docker işletimi (12), kullanıcı/anahtar dağıtımı (06).
## 3. Kararlar
```text
KARAR: UFW varsayılan politika: incoming DENY, outgoing ALLOW; izinler tek tek açılır.
GEREKÇE: Varsayılan-kapalı, unutulan portu dışa kapatır; 700 cihazda en güvenli varsayılan budur.
ALTERNATİF: Varsayılan ALLOW + kara liste — unutulan servis dışa açılır, elendi.
RİSK: Kural unutulursa meşru trafik kesilir; azaltma: LAB'da kural seti test edilir, bf-status denetler.
MALİYET: Ücretsiz.
LİSANS: UFW (Ubuntu paketi, GPL bileşenler) — https://manpages.ubuntu.com/manpages/resolute/en/man8/ufw.8.html (doğrulanma: 2026-09-15).
```
```text
KARAR: SSH (22) ve RDP (3389) yalnızca WireGuard arayüzünden (`wg0`) kabul edilir; herkese açık internete kapalıdır.
GEREKÇE: K-05 gereği yönetim düzlemi tünel arkasındadır; dış taramada port görünmez.
ALTERNATİF: İnternete açık SSH + fail2ban — kaba-kuvvet yüzeyini gereksiz büyütür, elendi.
RİSK: WireGuard çökerse SSH erişimi kesilir; azaltma: RustDesk/MeshCentral bağımsız kanallar (K-04).
MALİYET: Ücretsiz.
LİSANS: Yok (yapılandırma).
```
```text
KARAR: Docker-UFW bypass sorununun çözümü: yayımlanan tüm saha portları `127.0.0.1`'e bağlanır; `iptables:false` varsayılan çözüm değildir.
GEREKÇE: Docker, yayımlanan portlarda UFW kurallarını baypas eder (resmi belgeli); localhost-bind, servisi dış arayüzden görünmez kılar, erişim WireGuard üzerinden olur.
ALTERNATİF: `iptables:false` — resmi doküman "çoğu kullanıcı için uygun değil" diye uyarır; yedek seçenek olarak tutulur.
RİSK: Yanlış bind ile port dışa açılır; azaltma: `docker ps` + `ss -tlnp` denetimi imaj final-check'te.
MALİYET: Ücretsiz (Docker CE).
LİSANS: Docker CE ücretsiz — https://docs.docker.com/engine/network/packet-filtering-firewalls/ (doğrulanma: 2026-09-15).
```
```text
KARAR: SSH sertleştirme: `blueforce` bakım kullanıcısı + anahtar zorunlu, password auth kapalı, root SSH kapalı (K-13 uygulanır).
GEREKÇE: Kaba-kuvvet ve tek-key blast-radius riskini kapatır.
ALTERNATİF: Password auth — saldırı yüzeyi nedeniyle elendi.
RİSK: Anahtar kaybı erişimsizlik; azaltma: per-admin anahtar + Ansible ile merkezi dağıtım.
MALİYET: Ücretsiz.
LİSANS: OpenSSH (BSD-lisanslı), ücretsiz.
```
## 4. Neden Bu Karar?
Üç filtre: (1) varsayılan-kapalı (UFW DENY + WG-arkası yönetim), (2) Docker gerçeğine uyum (bypass inkâr edilmez, localhost-bind ile etkisizleştirilir), (3) ücretsiz katman (ek güvenlik ürünü yok).
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Varsayılan ALLOW + kara liste | Kolay | Unutulan port dışa açılır | Elendi |
| İnternete açık SSH + fail2ban | Basit | Kaba-kuvvet yüzeyi | Elendi |
| `iptables:false` | Bypass'ı kökten keser | Docker ağ işlevlerini bozar, resmi uyarı var | Yedek |
| Ücretli EDR/host güvenlik ajanı | Merkezi konsol | Lisans maliyeti, sadelik ihlali | Elendi |
## 6. Avantajlar
- Tek standart kural seti 700 cihaza aynen uygulanır; denetimi Ansible ile otomatik.
- Docker bypass'ı mimari düzeyde çözülür, kural-dışı port açığı kalmaz.
## 7. Dezavantajlar
- localhost-bind, konteyner portunu doğrudan LAN'dan kullanılamaz kılar (erişim WG üzerinden olur — bilinçli tercih).
- UFW kural değişikliği hatalı playbook ile filoya yayılabilir; önce LAB(2).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Bypass yüzünden MEG portu dışa açılır | Orta | Yüksek | localhost-bind + final-check denetimi |
| Kural hatası WG trafiğini keser | Düşük | Yüksek | LAB testi + `ufw --dry-run` + konsol erişimi |
| Semaphore Community'de 2FA yok | Orta | Orta | Semaphore yalnızca WG arkasında |
## 9. Uygulama Planı
1. UFW varsayılanları ve taban kuralları uygulanır.
2. WireGuard arayüzüne SSH/RDP izni, dış dünyaya ret yazılır.
3. Docker portları `127.0.0.1` bind ile doğrulanır.
4. SSH sertleştirme (`PasswordAuthentication no`, `PermitRootLogin no`) uygulanır.
```bash
# UFW taban politikası
ufw default deny incoming
ufw default allow outgoing
ufw allow in on wg0 to any port 22 proto tcp
ufw allow in on wg0 to any port 3389 proto tcp
ufw allow 51820/udp
ufw enable
# durum denetimi
ufw status verbose
ss -tlnp | grep -v '127\.0\.0\.1'
```
```bash
# SSH sertleştirme denetimi
sshd -T | grep -Ei 'passwordauthentication|permitrootlogin'
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `ufw status verbose` | default DENY incoming | LAB(2) |
| Dış taramada 22/3389 | Kapalı (filtreli) | P1(5) |
| `ss -tlnp` bind denetimi | `0.0.0.0` bind yok | LAB(2) |
| Password ile SSH denemesi | Red | LAB(2) |
| WG down iken dış SSH | Bağlantı yok | P1(5) |
## 11. Rollback
1. Hatalı kuralda önceki UFW profili geri yüklenir (`ufw reset` + bilinen-iyi kural seti Ansible'dan).
2. SSH kilitlenmesinde konsol/RustDesk üzerinden düzeltilir.
3. Son çare: golden image yeniden kurulumu (17-RECOVERY).
## 12. Kontrol Listesi
- [ ] `ufw default deny incoming` tüm sahada aktif.
- [ ] 22/3389 yalnızca `wg0` üzerinden erişilebilir.
- [ ] Docker `0.0.0.0` bind yok.
- [ ] `PasswordAuthentication no`, `PermitRootLogin no` doğrulandı.
## 13. Açık Sorular
- [ ] WireGuard port numarası standardı (51820 varsayılan mı?) — 08 yazarı + LAB (sahibi: Faz 3).
- [ ] Ek UFW log seviyesi/rate-limit değerleri — PİLOT ölçümü (sahibi: 11 yazarı).
---
## Ek: Mermaid — Güvenlik katmanları
```mermaid
flowchart LR
INT["Internet"] --> UFW["UFW<br/>default DENY in"]
UFW -->|51820/udp| WG["WireGuard wg0"]
WG -->|22, 3389| MGMT["SSH/RDP"]
UFW -->|RustDesk/MeshCentral<br/>giden| RD["Bağımsız kanallar"]
DKR["Docker<br/>127.0.0.1 bind"] -.->|dışa kapalı| UFW
```

View file

@ -0,0 +1,165 @@
# 12 — Docker Operasyonları
> Kısa özet: saha Docker disiplini: otostart, `unless-stopped`, pinli imaj, `latest` yasağı, log rotasyonu, Watchtower yok. Konteyner işleten teknik ekip içindir.
>
> - Dosya: `docs/12-DOCKER-OPERATIONS.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-10`
> - Durum: [ ] Taslak
---
## 1. Amaç
Elektrik kesintisi sonrası konteynerlerin kendiliğinden ve doğru sürümle ayağa kalkması; disiplinsiz imaj/log davranışının 700 cihazda filo arızasına dönüşmesini engellemek.
## 2. Kapsam
- Kapsam içi: restart politikası, imaj pinleme, `latest`/Watchtower yasakları, log rotasyonu, port bind kuralı, otostart denetimi.
- Kapsam dışı: MEG kabul testleri (13), log içerik politikası (15), boot zinciri systemd sırası (16).
## 3. Kararlar
```text
KARAR: Tüm saha konteynerlerinde restart politikası `unless-stopped` kullanılır; Docker daemon açılışta otomatik başlar.
GEREKÇE: `unless-stopped`, teknisyenin bakım için durdurduğunu reboot sonrası sürpriz çalıştırmaz; elektrik kesintisi "manuel stop" sayılmadığı için kurtarma aynen çalışır. Daemon enable olmadan otostart anlamsızdır.
ALTERNATİF: `always` — bakım-stop'u reboot'ta deler, elendi. `on-failure`/`no` — kesinti kurtarması sağlamaz, elendi.
RİSK: Yanlış politikayla kritik konteyner kalkmaz; azaltma: `docker inspect` final-check'te.
MALİYET: Ücretsiz (Docker CE).
LİSANS: Docker CE ücretsiz — https://docs.docker.com/engine/containers/start-containers-automatically/ (doğrulanma: 2026-09-15).
```
```text
KARAR: `latest` etiketi yasaktır; her imaj sabit tag ile pinlenir (örn. `meg:1.2.3`); digest pinleme (`@sha256`) PİLOT-2'de değerlendirilir.
GEREKÇE: Hareketli `latest` 700 cihazda determinizmi bozar; "onaysız update yasak" ilkesi sabit tag gerektirir.
ALTERNATİF: `latest` + periyodik pull — onaysız değişim riski, elendi.
RİSK: Tag yeniden yazılırsa (mutable tag) pinleme delinir; azaltma: PİLOT-2'de digest kararı.
MALİYET: Ücretsiz.
LİSANS: Yok (operasyon politikası).
```
```text
KARAR: Watchtower (veya eşdeğeri otomatik güncelleyici) sahada yasaktır ve kurulmaz.
GEREKÇE: Hem "onaysız update yasak" ilkesini ihlal eder hem upstream'de arşivlenmiştir.
ALTERNATİF: Programlı otomatik pull — politika ihlali, elendi.
RİSK: Manuel update gecikmesi; azaltma: 10-UPDATE dalga zinciri.
MALİYET: Ücretsiz.
LİSANS: Watchtower arşiv durumu — https://github.com/containrrr/watchtower (doğrulanma: 2026-09-15).
```
```text
KARAR: Log rotasyonu `daemon.json`'da zorunludur (`json-file`: `max-size` + `max-file`); rotasyonsuz log ile cihaz sahaya çıkmaz.
GEREKÇE: Docker varsayılan `json-file` logu rotasyon yapmaz; dolan disk = kilitlenen cihaz (700 katı etki).
ALTERNATİF: Rotasyonsuz + periyodik manuel temizlik — unutulur, elendi.
RİSK: Değerler MEG hacmine göre yanlışsa log kaybolur veya disk dolar; azaltma: PİLOT'ta hacim ölçülür, değer sabitlenir.
MALİYET: Ücretsiz.
LİSANS: Docker CE ücretsiz — https://docs.docker.com/engine/logging/configure/ (doğrulanma: 2026-09-15).
```
```text
KARAR: Yayımlanan portlar `127.0.0.1`'e bağlanır (UFW bypass'a karşı); kural 11-HARDENING ile birlikte denetlenir.
GEREKÇE: Docker yayımlanan portlarda UFW'yi baypas eder (resmi belgeli); localhost-bind dışa açılmayı kapatır.
ALTERNATİF: `iptables:false` — resmi uyarı nedeniyle varsayılan değil, yedek.
RİSK: Hatalı compose ile `0.0.0.0` bind; azaltma: final-check'te `ss -tlnp` denetimi.
MALİYET: Ücretsiz.
LİSANS: Docker CE ücretsiz — https://docs.docker.com/engine/network/packet-filtering-firewalls/ (doğrulanma: 2026-09-15).
```
## 4. Neden Bu Karar?
Tek ilke — öngörülebilir filo: cihaz neyle kapandıysa onunla açılır (unless-stopped), hangi sürüm onaylandıysa o çalışır (pinli tag), disk logla dolmaz (rotasyon), hiçbir şey kendiliğinden güncellenmez (Watchtower yok).
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| `always` | Her koşulda ayakta | Bakım davranışını bozar | Elendi |
| `latest` serbest | Kolay pull | Determinizm yok | Elendi |
| Watchtower | Otomatik güncellik | Politika ihlali + arşivli | Elendi |
| `iptables:false` (varsayılan) | Bypass'ı keser | Resmi "çoğu kullanıcı için uygun değil" uyarısı | Yedek |
## 6. Avantajlar
- Kesinti kurtarma ile bakım öngörülebilirliği aynı politikada birleşir.
- Deterministik sürüm + rotasyonlu log = uzaktan tanı güvenilirliği.
## 7. Dezavantajlar
- Sabit tag disiplini update prosedürüne yük bindirir (10-UPDATE ile işletilir).
- Rotasyon değerleri PİLOT ölçümüne kadar kesinleşmez.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| `max-size/max-file` yanlış ayar | Orta | Orta | PİLOT hacim ölçümü |
| Mutable tag yeniden yazımı | Düşük | Yüksek | Digest pinleme değerlendirmesi (PİLOT-2) |
| Daemon enable unutulur | Düşük | Yüksek | install.sh final-check |
## 9. Uygulama Planı
1. `daemon.json` yazılır (log rotasyonu), daemon enable edilir.
2. Compose dosyalarında restart + sabit tag + localhost bind uygulanır.
3. Final-check ile `docker inspect` / `ss` denetimi yapılır.
```bash
# daemon.json (örnek — boyut değerleri PİLOT ölçümüyle kesinleşir)
cat /etc/docker/daemon.json
# {"log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"3"}}
systemctl enable --now docker
# compose parçası (örnek)
# ports: ["127.0.0.1:8080:8080"]
# restart: unless-stopped
# image: meg:1.2.3 # latest YASAK
```
```bash
# denetim
docker inspect --format '{{.HostConfig.RestartPolicy.Name}} {{.Config.Image}}' $(docker ps -aq)
docker info --format '{{json .LoggingDriver}}'
ss -tlnp | grep -v '127\.0\.0\.1'
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `docker inspect` restart | `unless-stopped` tamamında | LAB(2) |
| İmaj tag denetimi | `latest` yok, sabit tag var | LAB(2) |
| Güç kesintisi simülasyonu | Konteynerler otomatik kalkar | LAB(2) |
| Manuel stop + reboot | Durdurulan kalkmaz | LAB(2) |
| Log boyutu denetimi | `max-size/max-file` aşımı yok | P1(5) |
## 11. Rollback
1. Yanlış imajda önceki pinli tag'e dönüş (`docker compose pull/pull + up -d` onaylı sürümle).
2. Bozuk daemon.json'da bilinen-iyi dosya + `systemctl restart docker`.
3. Son çare: 10-UPDATE rollback zinciri.
## 12. Kontrol Listesi
- [ ] `systemctl is-enabled docker` → enabled.
- [ ] Tüm saha konteynerleri `unless-stopped`.
- [ ] `latest` yok, sabit tag var.
- [ ] Watchtower kurulu değil.
- [ ] `daemon.json` rotasyon aktif.
- [ ] `0.0.0.0` bind yok.
## 13. Açık Sorular
- [ ] `max-size/max-file` kesin değerleri — PİLOT hacim ölçümü (sahibi: 12 yazarı).
- [ ] Digest pinleme (`@sha256`) kararı — PİLOT-2 (sahibi: 12 yazarı).
---
## Ek: Mermaid — Konteyner yaşam döngüsü
```mermaid
flowchart TB
BOOT["Boot: docker enable"] --> UP["unless-stopped<br/>otomatik kalkış"]
UP --> PIN["Pinli tag<br/>(latest yok)"]
PIN --> LOG["Rotasyonlu log<br/>daemon.json"]
LOG --> BIND["127.0.0.1 bind<br/>(UFW bypass kapalı)"]
STOP["Manuel stop<br/>(bakım)"] -.->|reboot sonrası kalkmaz| UP
```

View file

@ -0,0 +1,138 @@
# 13 — MEG Linux Kabul Kriterleri (Acceptance)
> Kısa özet: MEG'in saha Linux'unda çalışır sayılması için 16 maddelik kabul listesi; paket içyapısı varsayılmaz, yalnızca gözlenebilir davranış test edilir. Kabul ekibi ve LAB sorumlusu içindir.
>
> - Dosya: `docs/13-MEG-LINUX-ACCEPTANCE.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-02`, `#K-10`, `#K-14`
> - Durum: [ ] Taslak
---
## 1. Amaç
"Çalışıyor" iddiasını denetlenebilir eşiğe bağlamak: MEG sürümü, GNOME + Docker zemininde 16 maddeyi geçmeden PİLOT dalgasına alınmaz.
## 2. Kapsam
- Kapsam içi: kurulum/çalışma/sağlık/log/kurtarma gözlemleri (16 madde).
- Kapsam dışı: MEG paket içyapısı, kaynak kodu, lisans koşulları (varsayılmaz; satıcı dokümanına havale).
## 3. Kararlar
```text
KARAR: MEG kabulü 16 maddelik davranış listesidir; paket detayı varsayılmaz, her madde PASS/FAIL ile kapatılır.
GEREKÇE: İçyapı varsayımı her satıcı sürümünde kırılır; gözlenebilir davranış (kurulur, kalkar, yanıt verir, log üretir, kurtarır) sürümler arası sabittir.
ALTERNATİF: Paket-içi dosya yolu kontrolü — satıcı değişikliğinde test çöp olur, elendi.
RİSK: Davranış testleri içsel bozulmayı geç fark eder; azaltma: metrik + log izleme (14/15) tamamlayıcıdır.
MALİYET: Ücretsiz (test emeği).
LİSANS: Yok (kabul prosedürü).
```
```text
KARAR: Kabul GNOME + `unless-stopped` + pinli tag zemininde koşar; `latest` ile kabul geçersizdir.
GEREKÇE: K-02/K-10 zemini dışında geçen test saha gerçeğini temsil etmez.
ALTERNATİF: XFCE/latest zeminde kabul — saha dışı, elendi.
RİSK: Yok (zemin standardı 03/12'de kilitli).
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
MEG satıcı bağımlılığının en kırılgan noktasıdır; kabul listesi satıcının ne dağıttığına değil cihazın ne gösterdiğine bakar. Böylece sürüm değişse bile liste yaşar.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Paket-içi yol kontrolü | Hızlı | Sürümde kırılır | Elendi |
| Tek "açılıyor mu" testi | Çok kolay | Kurtarma/log körlüğü | Elendi |
| Satıcı beyanıyla kabul | Emeksiz | Doğrulanmamış | Elendi |
## 6. Avantajlar
- 16 madde tek sayfada denetlenir; LAB(2) sonucu PİLOT kapısı olur.
- Satıcı sürümü değişse liste değişmez.
## 7. Dezavantajlar
- Liste, MEG işlevsel doğruluğunu (iş mantığı) test etmez; yalnızca platform uyumunu test eder.
- 16 maddenin tamamı her sürümde yeniden koşulmalıdır.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| GNOME grafik bağımlılığı/ek ayar eksik | Orta | Yüksek | Madde 9–10 erken yakalar |
| Log hacmi diski doldurur | Orta | Orta | Madde 12 + 12-DOCKER rotasyonu |
| Kesinti sonrası MEG kalkmaz | Düşük | Yüksek | Madde 13–14 |
## 9. Uygulama Planı
Kabul, LAB(2) cihazında pinli tag ile koşar; her madde PASS/FAIL işlenir, sonuç kabul tutanağına yazılır.
```bash
# kabul öncesi zemin denetimi
docker inspect --format '{{.HostConfig.RestartPolicy.Name}} {{.Config.Image}}' <meg-container>
systemctl is-enabled docker
ufw status verbose
```
### MEG ACCEPTANCE — 16 madde
| # | Madde | Nasıl bakılır | PASS eşiği |
|---|---|---|---|
| 1 | Kurulum tamamlanır | Onaylı prosedürle kurulum uca kadar gider | Hatasız tamamlanır |
| 2 | Sabit sürüm kimliği | Sürüm/etiket sorgulanır | `latest` yok, sürüm okunur ve tutanakla eşleşir |
| 3 | Konteyner/servis ayakta | `docker ps` / servis durumu | Çalışıyor (restart döngüsü yok) |
| 4 | Restart politikası | `docker inspect` | `unless-stopped` |
| 5 | Port bind | `ss -tlnp` | Dışa açık `0.0.0.0` bind yok |
| 6 | Sağlık yanıtı | Sağlık endpoint'i/komutu (varsa) veya süreç canlılığı | Yanıt veriyor / süreç yaşıyor |
| 7 | Temel işlev duman testi | Tanımlı en küçük iş akışı uçtan uca | Hatasız tamamlanır |
| 8 | Yeniden başlatmada toparlanma | Konteyner restart edilir | ≤ tanımlı sürede sağlığa döner |
| 9 | GNOME uyumu | GNOME oturumunda grafik gereksinim (varsa) açılır | Görüntü/oturum hatasız |
| 10 | RDP üzerinden erişim | xRDP + GNOME ile uzaktan oturum | Oturum açılır, kritik hata yok |
| 11 | Log üretimi | Log çıktısı gözlenir | Tanımlı olaylar logda görülür |
| 12 | Log rotasyonu altında çalışma | Rotasyon aktifken 24 saat çalışma | Disk taşması yok, log kaybı kritik değil |
| 13 | Güç kesintisi kurtarması | Güç kesintisi simülasyonu | Boot sonrası kendiliğinden sağlığa döner |
| 14 | WireGuard yokluğunda çalışma | WG down edilir | Yerel işlev sürer (bağımlılık varsa tutanağa yazılır) |
| 15 | Monitoring görünürlüğü | Prometheus/Grafana + Kuma | Cihaz ve MEG sağlığı panoda görünür |
| 16 | Destek paketi üretimi | `bf-support-bundle` çalıştırılır | Secret sızdırmadan paket üretilir |
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| 16 maddenin tamamı LAB(2)'de | Tümü PASS | LAB(2) |
| Başarısız maddede sürüm reddi | PİLOT'a alınmaz, satıcıya iade | LAB(2) |
| PASS sürümün P1(5) tekrarı | 1,3,6,8,13,15 yeniden PASS | P1(5) |
## 11. Rollback
1. Kabulü geçemeyen sürüm sahaya sürülmez; önceki kabul görmüş pinli tag sahada kalır.
2. Yanlışlıkla sürülen sürüm 10-UPDATE rollback zinciriyle geri alınır.
## 12. Kontrol Listesi
- [ ] 16 maddenin PASS/FAIL kaydı tutanakta var.
- [ ] Sürüm kimliği tutanakla eşleşiyor.
- [ ] `latest` kullanılmadı.
- [ ] Başarısız madde varsa PİLOT onayı verilmedi.
## 13. Açık Sorular
- [ ] Madde 8/13 için süre eşiği (örn. ≤5 dk) — PİLOT ölçümüyle sabitlenecek (sahibi: 13 yazarı).
- [ ] Madde 7 duman testinin kapsamı — MEG işlev sahibiyle tanımlanacak (sahibi: Faz 3).
---
## Ek: Mermaid — Kabul kapısı
```mermaid
flowchart LR
VER["MEG sürümü"] --> LAB["LAB 2: 16 madde"]
LAB -->|Tümü PASS| P1["PILOT-1 5: kritik 6 madde"]
LAB -->|Herhangi FAIL| REJ["RED: sahaya alınmaz"]
P1 -->|PASS| WAVE["Dalgalar (10-UPDATE)"]
P1 -->|FAIL| REJ
```

View file

@ -0,0 +1,193 @@
# 14 — İzleme ve Sağlık (Monitoring & Health)
> Kısa özet: 17 metrik + Prometheus/Node Exporter/Grafana OSS + Uptime Kuma + `bf-status`/`bf-diagnostics`/`bf-support-bundle` sözleşmeleri. Monitoring operatörü ve saha teknisyeni içindir.
>
> - Dosya: `docs/14-MONITORING-AND-HEALTH.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-07`, `#K-14`
> - Durum: [ ] Taslak
---
## 1. Amaç
700 cihazda "hangisi ölü, hangisi hasta, hangisi sağlıklı" sorusuna iki perdede cevap: mühendis için metrik (Prometheus), teknisyen için UP/DOWN + last-seen (Uptime Kuma).
## 2. Kapsam
- Kapsam içi: 17 metrik listesi, Prometheus/Node Exporter/Grafana OSS/Uptime Kuma rolleri, scrape/retention ilkeleri, 3 saha komutu sözleşmesi.
- Kapsam dışı: log içerik politikası (15), alarm bildirim hedefleri detayı (kurulum dokümanına havale), merkez donanım siparişi.
## 3. Kararlar
```text
KARAR: Birincil metrik yığını Prometheus + Node Exporter + Grafana OSS'tir; 17 metriğin tamamı burada toplanır.
GEREKÇE: 17 metriğin tamamı yalnızca bu yığında ücretsiz ve kotasız toplanır (WireGuard/Docker/MEG sağlığı textfile collector ile).
ALTERNATİF: Netdata Cloud — Free 5 node kotası 700 cihazda ücrete düşer, elendi. Yalnızca Kuma — metrik körlüğü, elendi.
RİSK: 700 node kardinalite/saklama yükü; azaltma: 60 sn scrape, 30–90 gün retention, `BF-<no>` etiket şeması.
MALİYET: Ücretsiz.
LİSANS: Prometheus/Node Exporter Apache-2.0 — https://github.com/prometheus/prometheus + https://prometheus.io/docs/guides/node-exporter/ (2026-09-15); Grafana OSS AGPL-3.0 — https://grafana.com/oss/ (2026-09-15).
```
```text
KARAR: Tamamlayıcı olarak Uptime Kuma: saha-teknisyeni dostu UP/DOWN panosu + Push "last seen" + bildirimler.
GEREKÇE: Metrik bilmeyen teknisyene en basit çevrimdışı alarmını verir (20 sn aralık, 90+ bildirim servisi, tek konteyner).
ALTERNATİF: Yalnızca Grafana alarmı — teknisyen için karmaşık, elendi.
RİSK: Kuma metrik vermez; azaltma: Prometheus ile birlikte koşar, rol çakışması yok.
MALİYET: Ücretsiz.
LİSANS: Uptime Kuma MIT — https://github.com/louislam/uptime-kuma (2026-09-15).
```
```text
KARAR: Özel metrikler (WireGuard handshake, Docker, MEG) Node Exporter textfile collector `.prom` dosyalarıyla verilir.
GEREKÇE: Standart Prometheus yolu; özel exporter yazma yükü yok.
ALTERNATİF: Özel exporter geliştirme — bakım yükü, elendi.
RİSK: `.prom` yazım hatası scrape'i bozar; azaltma: cron/systemd timer çıktısı atomik yazılır.
MALİYET: Ücretsiz.
LİSANS: Node Exporter Apache-2.0 — https://github.com/prometheus/node_exporter (2026-09-15).
```
```text
KARAR: Saha sağlık sözleşmeleri: `bf-status` (hızlı bakış), `bf-diagnostics` (derin tanı), `bf-support-bundle` (secret sızdırmaz paket).
GEREKÇE: 700 dokunulmaz cihazda logsuz metrik kör, metriksiz log sağırdır; bundle secret dışlama kuralıyla güvenli uzaktan tanı sağlar.
ALTERNATİF: Harici log platformu (Loki/ELK) ilk fazda — ek servis yükü, elendi (Faz-sonrası hedef).
RİSK: Bundle'a secret kaçması; azaltma: dışlama listesi + üreticide maskeleme testi.
MALİYET: Ücretsiz.
LİSANS: systemd-journald / textfile (Apache-2.0) — https://github.com/prometheus/node_exporter (2026-09-15).
```
## 4. Neden Bu Karar?
İki kullanıcı, iki hız: mühendis kök nedeni metrikten bulur, teknisyen kesintiyi Kuma'dan görür. Scrape 60 sn + retention 30–90 gün, 700 node'da merkez yükünü taşınabilir tutar.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Yalnızca Uptime Kuma | Çok kolay | Metrik körlüğü | Elendi |
| Netdata Cloud | Zengin agent | Free 5 node kotası | Elendi |
| Netdata Parent self-hosted | Zengin | Merkezi tasarım yükü + kota riski | Elendi |
| Loki/ELK ilk fazda | Güçlü log | Ek servis yükü, sadelik ihlali | Faz-sonrasına ertelendi |
## 6. Avantajlar
- Tamamı ücretsiz ve kotasız; 700 cihaz lisans duvarına çarpmaz.
- Tek kimlik (`BF-<no>`) metrikten loga join anahtarıdır.
## 7. Dezavantajlar
- Prometheus 700 node işletme bilgisi ister; retention LAB ölçümü olmadan donanım siparişi verilmemeli.
- Kuma + Prometheus çift kurulum merkezde iki servis demektir.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Kardinalite patlaması | Orta | Orta | 60 sn scrape, etiket disiplini, federasyon hedefi |
| Retention şişmesi | Orta | Orta | 30–90 gün, PİLOT hacim ölçümü |
| Bundle secret sızıntısı | Düşük | Yüksek | Dışlama listesi + maskeleme testi |
## 9. Uygulama Planı
1. Merkez: Prometheus + Grafana OSS + Uptime Kuma kurulur.
2. Saha: Node Exporter + textfile cron/timer + Kuma Push kurulur.
3. Etiket şeması `device_id="BF-<no>"` tüm metriklerde uygulanır.
4. `bf-status` / `bf-diagnostics` / `bf-support-bundle` sahaya dağıtılır.
```bash
# saha: Node Exporter + textfile dizini (örnek)
systemctl enable --now node_exporter
ls /var/lib/node_exporter/textfile/ # *.prom buraya atomik yazılır
# WireGuard handshake örneği (üretici script özeti)
# wg show wg0 latest-handshakes > /var/lib/node_exporter/textfile/wireguard.prom.tmp \
# && mv .../wireguard.prom.tmp .../wireguard.prom
```
### 17 metrik listesi
| # | Metrik | Kaynak | Ne için |
|---|---|---|---|
| 1 | `up` | Prometheus scrape | Cihaz scrape edilebilir mi (ölü/diri) |
| 2 | `node_cpu_seconds_total` | Node Exporter | CPU yükü |
| 3 | `node_memory_MemAvailable_bytes` | Node Exporter | RAM baskısı |
| 4 | `node_filesystem_avail_bytes` | Node Exporter | Disk dolumu |
| 5 | `node_load1/5/15` | Node Exporter | Yük ortalaması |
| 6 | `node_network_receive/transmit_bytes_total` | Node Exporter | Ağ trafiği |
| 7 | `node_systemd_unit_state` | Node Exporter (systemd) | Kritik servis ayakta mı |
| 8 | `node_timex_offset_seconds` | Node Exporter | Saat kayması (TLS/WG için kritik) |
| 9 | `node_boot_time_seconds` | Node Exporter | Beklenmedik reboot tespiti |
| 10 | `wireguard_last_handshake_seconds` | textfile | Tünel canlılığı (stale = kopuk) |
| 11 | `wireguard_transfer_bytes` | textfile | Tünel trafiği |
| 12 | `docker_container_running` | textfile | MEG/yan konteyner ayakta mı |
| 13 | `docker_container_restart_count` | textfile | Crash-loop tespiti |
| 14 | `meg_up` | textfile | MEG sağlığı (kabul madde 6 ile aynı kaynaktan) |
| 15 | `meg_last_success_timestamp` | textfile | MEG iş yapıyor mu (stale = takılı) |
| 16 | `unattended_upgrade_active` | textfile | K-11 kilidi delinmiş mi (1 = ihlal) |
| 17 | `kuma_push_last_seen` | Uptime Kuma Push | Teknisyen "last seen" görünümü |
Scrape: 60 sn. Retention: 30–90 gün (LAB ölçümüyle kesinleşir).
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Scrape + 17 metrik | Grafana panosu dolu | P1(5) |
| WG down simülasyonu | Metrik 10 stale + Kuma DOWN | P1(5) |
| Konteyner kill | Metrik 12/13 alarm | LAB(2) |
| `unattended-upgrade` açma | Metrik 16 = 1 alarm | LAB(2) |
| Kuma Push kesintisi | last-seen bayatlar | P1(5) |
## 11. Rollback
1. Bozuk exporter/push, önceki sürüme Ansible ile geri alınır.
2. Prometheus config hatasında önceki config + `promtool check config` ile dönüş.
3. Son çare: monitoring'siz işletim (erişim kanalları bağımsızdır — 01).
## 12. Kontrol Listesi
- [ ] 17 metriğin tamamı Grafana'da görünüyor.
- [ ] Kuma UP/DOWN + Push last-seen çalışıyor.
- [ ] Etiket şeması `BF-<no>` tutarlı.
- [ ] Scrape 60 sn, retention 30–90 gün aralığında.
### `bf-status` örnek çıktısı (16 satır sözleşmesi)
```text
BF-12010193 2026-09-15 12:00 +03 OK
uptime: 6d 4h 12m | load: 0.31 0.28 0.22
cpu: 8% | mem: 1.1/3.8G (29%) | disk /: 9.2/28G (33%)
net: wg0 UP, handshake 12s ago | rx 41M tx 18M
docker: daemon UP | meg:1.2.3 running 6d (restarts 0)
meg: UP, last success 40s ago
systemd: docker OK | wg-quick@wg0 OK | xrdp OFF | node_exporter OK
unattended-upgrades: DISABLED (timer masked)
ufw: active, default DENY in | 22/3389 wg0-only
gui: OFF (multi-user) | rdp sessions: 0
kuma push: OK 30s ago | prometheus scrape: OK 45s ago
rustdesk: online | meshcentral: online
boot: 2026-09-09 07:48 (power-loss recovery OK)
alerts: 0 critical, 1 warning (disk trend)
next: support bundle: bf-support-bundle
```
`bf-diagnostics`: yukarıdakinin detaylı sürümü (servis log kuyrukları + `ss` + `df -i` + textfile içerikleri). `bf-support-bundle`: aynı paketin tarball'ı; WireGuard private key, RustDesk şifresi, SSH private key ve `authorized_keys` dışı secret'lar ASLA pakete girmez (üretici maskeleme testinden geçer).
## 13. Açık Sorular
- [ ] Prometheus retention/kardinalite hesabı (700 × 60 sn) — LAB ölçümü (sahibi: 14 yazarı).
- [ ] Bildirim hedefleri (SMS/e-posta/webhook) — merkez kurulumunda netleşecek (sahibi: Faz 3).
- [ ] Federasyon gerekip gerekmediği — 700 node ölçümü (sahibi: 14 yazarı).
---
## Ek: Mermaid — Metrik akışı
```mermaid
flowchart LR
SAHA["Saha bf-<no><br/>Node Exporter + textfile"] -->|scrape 60sn| PROM["Prometheus"]
PROM --> GRAF["Grafana OSS"]
SAHA -->|Push last-seen| KUMA["Uptime Kuma"]
KUMA --> TECH["Teknisyen panosu"]
GRAF --> ENG["Mühendis panosu"]
SAHA -->|bf-status| CONSOLE["Saha konsolu"]
```

153
docs/15-LOGGING.md Normal file
View file

@ -0,0 +1,153 @@
# 15 — Loglama (Logging)
> Kısa özet: 7 log kaynağı (journald/Docker/RustDesk/WG/MEG/Blueforce/installer/update-history) için yer, rotasyon ve saklama limitleri. Tanı koyan mühendis ve denetçi içindir.
>
> - Dosya: `docs/15-LOGGING.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-10`, `#K-14`
> - Durum: [ ] Taslak
---
## 1. Amaç
Disk doldurmayan ama tanı koydurmaya yeten log disiplini: her kaynağın nerede tutulduğu, ne kadar büyüyebileceği ve ne zaman silineceği bellidir.
## 2. Kapsam
- Kapsam içi: 7 kaynağın konumu + rotasyon + saklama limiti; secret maskeleme kuralı.
- Kapsam dışı: metrik tanımları (14), merkezi log platformu (Faz-sonrası hedef), log içeriklerinin iş anlamı.
## 3. Kararlar
```text
KARAR: journald kalıcı + boyut sınırlı tutulur (`SystemMaxUse`/`MaxFileSec` ile); sınırsız journal yasaktır.
GEREKÇE: Sınırsız journal saha diskini sessizce doldurur; sınırlı journal boot sonrası tanıya yetecek kadar geçmişi korur.
ALTERNATİF: Volatil journal (RAM'de) — reboot sonrası tanı kaybolur, elendi.
RİSK: Limit küçükse kesinti kök nedeni silinir; azaltma: PİLOT hacim ölçümü.
MALİYET: Ücretsiz.
LİSANS: systemd-journald (LGPL bileşenler), ücretsiz.
```
```text
KARAR: Docker `json-file` rotasyonu (`max-size`/`max-file`) tüm saha konteynerlerinde zorunludur (K-10).
GEREKÇE: Rotasyonsuz Docker logu disk doldurur = kilitlenen cihaz.
ALTERNATİF: Rotasyonsuz + manuel temizlik — unutulur, elendi.
RİSK: Değerler MEG hacmine göre ayarlanmazsa kayıp/taşma; azaltma: PİLOT ölçümü (12 ile ortak).
MALİYET: Ücretsiz.
LİSANS: Docker CE ücretsiz — https://docs.docker.com/engine/logging/configure/ (doğrulanma: 2026-09-15).
```
```text
KARAR: Harici log platformu (Loki/ELK) ilk fazda kurulmaz; Faz-sonrası hedef olarak izlenir.
GEREKÇE: Ek servis yükü sadelik kuralını bozar; 7 kaynak + bundle ilk faz tanısı için yeterlidir.
ALTERNATİF: İlk fazda merkezi log — merkez yükü + işletme maliyeti, ertelendi.
RİSK: Filo-çapı log araması ilk fazda yoktur; azaltma: Ansible ile hedefli log toplama.
MALİYET: Ücretsiz (erteleme).
LİSANS: Yok.
```
## 4. Neden Bu Karar?
700 cihaz × sınırsız log = 700 dolu disk. Her kaynağa tavan konur; tavanlar PİLOT'ta ölçülen gerçek hacimle sabitlenir. Merkezi platform yokluğunda tanı, cihaz-üzeri komutlar + hedefli toplama ile yapılır.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Sınırsız journal | Kayıpsız geçmiş | Disk taşması | Elendi |
| Volatil journal | Disk dostu | Reboot sonrası körlük | Elendi |
| İlk fazda Loki/ELK | Merkezi arama | Servis yükü | Ertelendi |
| Rotasyonsuz Docker log | Sıfır ayar | Kilitlenen cihaz | Elendi |
## 6. Avantajlar
- Tanı için yeterli geçmiş, disk için güvenli tavan aynı tabloda.
- 7 kaynak standardı `bf-support-bundle` ile birebir eşleşir.
## 7. Dezavantajlar
- Merkezi arama yok; filo-çapı örüntü avı Ansible hedefli toplamayla sınırlı.
- Limitler PİLOT ölçümüne kadar taslak değerlerdir.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Limit küçük → kök neden silinir | Orta | Orta | PİLOT hacim ölçümü + kritik olayda bundle |
| MEG log patlaması | Orta | Yüksek | Rotasyon + metrik 13 alarmı |
| Secret loga yazılır | Düşük | Yüksek | Maskeleme kuralı + bundle dışlama listesi |
## 9. Uygulama Planı
1. journald limitleri yazılır, kalıcı depolama açılır.
2. `daemon.json` rotasyonu uygulanır (12 ile ortak).
3. Uygulama log dizinleri + logrotate kurulur.
4. Update-history append-only tutulur.
```bash
# journald (taslak değerler — PİLOT ölçümüyle kesinleşir)
# /etc/systemd/journald.conf.d/blueforce.conf
# [Journal]
# Storage=persistent
# SystemMaxUse=500M
# MaxFileSec=14day
systemctl restart systemd-journald
journalctl --disk-usage
# Docker rotasyon denetimi (12 ile ortak)
cat /etc/docker/daemon.json
```
### 7 kaynak — yer ve limit tablosu
| # | Kaynak | Yer | Rotasyon/limit (taslak) |
|---|---|---|---|
| 1 | journald (sistem + servisler) | `/var/log/journal/` | `SystemMaxUse=500M`, `MaxFileSec=14day` |
| 2 | Docker konteyner logları | `json-file` (daemon.json) | `max-size=10m`, `max-file=3` (PİLOT ile kesinleşir) |
| 3 | RustDesk istemci | `~/.config/RustDesk/logs/` + journald | 50M tavan, 14 gün (istemci varsayılanını aşmayacak şekilde) |
| 4 | WireGuard | journald (`wg-quick@wg0`) + textfile sayaç | journald limitine tabi; handshake sayacı metrikte (14) |
| 5 | MEG | Konteyner logu (json-file) + varsa `/var/log/meg/` | Docker rotasyonuna tabi; dosya logu varsa logrotate 7×10M |
| 6 | Blueforce servisleri | journald + `/var/log/blueforce/` | logrotate 7×10M, 30 gün |
| 7 | installer + update-history | `/var/log/blueforce/install.log`, `/var/log/blueforce/update-history.log` | Append-only, rotasyonsuz saklanır (denetim izi); 50M üstünde arşivlenir, silinmez |
Secret kuralı: private key, parola, token loga ve bundle'a ASLA yazılmaz; tanı için gereken kimlik yalnızca `BF-<no>` etiketidir.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `journalctl --disk-usage` | Tavan altında | LAB(2) |
| 7 gün çalışma sonrası disk | Taşma yok | P1(5) |
| Logrotate kuru çalıştırma | Hatasız döner | LAB(2) |
| Bundle secret taraması | Secret yok | LAB(2) |
| update-history append | Silinmemiş, sıralı | LAB(2) |
## 11. Rollback
1. Hatalı journald/logrotate config'de önceki dosya geri yüklenir, servis restart edilir.
2. Aşırı agresif rotasyonda limit genişletilir, PİLOT ölçümü yenilenir.
## 12. Kontrol Listesi
- [ ] journald kalıcı + tavanlı.
- [ ] Docker rotasyonu aktif (12 ile ortak denetim).
- [ ] 7 kaynağın tamamı bundle'a dahil veya bilerek hariç.
- [ ] Secret taraması temiz.
- [ ] update-history append-only.
## 13. Açık Sorular
- [ ] journald/Docker/MEG kesin limitleri — PİLOT hacim ölçümü (sahibi: 15 yazarı, 12 ile ortak).
- [ ] Merkezi log platformu (Loki) Faz-sonrası eşiği — 700 node ölçümü (sahibi: 14 yazarı).
---
## Ek: Mermaid — Log akışı
```mermaid
flowchart LR
J["journald<br/>sistem + servisler"] --> B["bf-support-bundle<br/>(secret sızdırmaz)"]
D["Docker json-file<br/>rotasyonlu"] --> B
A["/var/log/blueforce/<br/>+ update-history"] --> B
B --> T["Merkez tanı<br/>(Ansible hedefli toplama)"]
```

View file

@ -0,0 +1,156 @@
# 16 — Elektrik Kesintisi ve Otomatik Kurtarma
> Kısa özet: güç geldikten sonra cihazın dokunulmadan işe dönmesi: BIOS ayarı, boot zinciri, systemd bağımlılıkları, kurtarma doğrulaması. Saha ve LAB ekibi içindir.
>
> - Dosya: `docs/16-POWER-LOSS-AND-AUTO-RECOVERY.md`
> - İlgili kararlar: `24-DECISION-LOG.md#K-03`, `#K-05`, `#K-10`
> - Durum: [ ] Taslak
---
## 1. Amaç
Elektrik kesintisini sıradan olay haline getirmek: güç gelir, cihaz açılır, VPN kurulur, konteynerler kalkar, MEG işe döner — teknisyen dokunmaz.
## 2. Kapsam
- Kapsam içi: BIOS güç ayarı, boot hedefi, systemd sıralaması ve bağımlılıkları, kurtarma testi.
- Kapsam dışı: UPS yatırımı, veri yedekleme (17), update rollback (10).
## 3. Kararlar
```text
KARAR: BIOS "Restore on AC Power Loss = Power On" tüm sahada standarttır; cihaz terminale (multi-user) boot eder.
GEREKÇE: Güç gelince açılmayan cihaz kurtarma zincirine hiç giremez; terminal boot en düşük kaynakla en öngörülebilir zemindir (K-03).
ALTERNATİF: Grafik boot / manuel açma — kaynak israfı + saha ziyareti, elendi.
RİSK: Heterojen BIOS menülerinde ayar adı farklı olabilir; azaltma: donanım profil başına LAB kaydı.
MALİYET: Ücretsiz.
LİSANS: Yok (donanım ayarı).
```
```text
KARAR: Boot zinciri systemd bağımlılıklarıyla sıralanır: network → `wg-quick@wg0` → `docker.service` → MEG/uygulama birimleri → remote/monitoring ajanları.
GEREKÇE: Sırasız boot race üretir (Docker WG'den önce kalkar, MEG ağ bulamaz); `After=`/`Wants=` zinciri her açılışta aynı sırayı garanti eder.
ALTERNATİF: Bağımlılıksız "hepsi enable" — açılışta rastgele sıra, elendi.
RİSK: Birim adları 26.04.1'e göre değişebilir; azaltma: LAB imajında doğrulanmadan dondurulmaz (K-03 riski).
MALİYET: Ücretsiz.
LİSANS: Yok (systemd yapılandırması).
```
```text
KARAR: Kurtarma `unless-stopped` + `wg-quick enable` + daemon enable üzerine kurulur; kesinti "manuel stop" sayılmaz.
GEREKÇE: K-10 gereği kesinti sonrası konteynerler kendiliğinden kalkar; K-05 gereği VPN kendiliğinden gelir. Ek kurtarma servisi gerekmez.
ALTERNATİF: Özel kurtarma scripti/cron — hareketli parça artar, elendi.
RİSK: Yanlışlıkla stop edilen kritik konteyner kalkmaz (tasarlanan davranış); azaltma: `bf-status` ile görünürlük.
MALİYET: Ücretsiz.
LİSANS: Docker CE ücretsiz — https://docs.docker.com/engine/containers/start-containers-automatically/ (doğrulanma: 2026-09-15).
```
## 4. Neden Bu Karar?
Kurtarma, ek yazılımla değil sıralamayla çözülür: her katman bir öncekinin hazır olduğuna bakarak kalkar. Sadelik kuralı burada en literally uygulanır — zincirde özel bileşen yok.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| UPS ile kesintiyi önleme | Kesinti yaşanmaz | 700 cihazda donanım maliyeti | Saha kararına bırakıldı (bu dokümanın dışı) |
| Özel kurtarma servisi | Esnek | Ek bakım yükü | Elendi |
| Grafik boot | Teknisyene tanıdık | Kaynak + hata yüzeyi | Elendi |
## 6. Avantajlar
- Kurtarma testi tek komutla tekrarlanır (fişi çek / reboot); sonuç deterministiktir.
- Zincirdeki her halka standart systemd mekanizmasıdır, özel bilgi gerektirmez.
## 7. Dezavantajlar
- Uzun kesintide saat kayması olabilir; NTP senkronu zincire dahildir ama ilk WG handshake gecikebilir.
- Bozuk diskte (kirli filesystem) boot fsck'e takılabilir; journal + ext4 varsayılanı bu riski küçültür.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Boot race (sıra bozuk) | Orta | Orta | `After=` zinciri + LAB güç testi |
| BIOS ayarı profilde yok | Düşük | Yüksek | Profil başına LAB kaydı |
| Saat kaymasıyla WG/TLS gecikmesi | Orta | Düşük | NTP bekleme + handshake metriği (14) |
## 9. Uygulama Planı
1. BIOS güç ayarı profillere işlenir.
2. Boot hedefi multi-user yapılır; GUI kapalı standarttır.
3. systemd bağımlılıkları yazılır, enable zinciri kurulur.
4. Güç kesintisi simülasyonuyla doğrulanır.
```bash
# boot hedefi (terminal standart)
systemctl set-default multi-user.target
systemctl get-default
# enable zinciri
systemctl enable wg-quick@wg0 docker node_exporter
# MEG/uygulama birimleri docker sonrası kalkar:
# /etc/systemd/system/meg-app.service.d/override.conf
# [Unit]
# After=docker.service wg-quick@wg0.service network-online.target
# Wants=network-online.target
# [Install]
# WantedBy=multi-user.target
# zincir denetimi
systemd-analyze critical-chain docker.service
systemd-analyze critical-chain wg-quick@wg0.service
```
```bash
# kurtarma doğrulaması (güç testi sonrası)
uptime -s
systemctl is-active wg-quick@wg0 docker
docker ps --format '{{.Names}} {{.Status}}'
bf-status
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Fiş çekme simülasyonu (güç kesintisi) | Müdahalesiz tam zincir kalkar | LAB(2) |
| Reboot sonrası sıra | network → WG → Docker → MEG | LAB(2) |
| Manuel stop + reboot | Durdurulan kalkmaz (tasarlanan) | LAB(2) |
| 10 ardışık güç döngüsü | 10/10 kurtarma | P1(5) |
| WG handshake süresi | Metrik 10 makul aralıkta tazelenir | P1(5) |
## 11. Rollback
1. Bozuk bağımlılıkta override dosyası kaldırılır, daemon-reload + reboot ile önceki sıra geri gelir.
2. Boot hedefine takılmada konsoldan `systemctl set-default` düzeltilir.
3. Son çare: golden image yeniden kurulumu (17-RECOVERY LEVEL 9).
## 12. Kontrol Listesi
- [ ] BIOS güç ayarı profilde kayıtlı.
- [ ] Boot hedefi multi-user.
- [ ] `wg-quick@wg0`, `docker`, ajanlar enable.
- [ ] `After=` zinciri dosyada ve LAB'da doğrulandı.
- [ ] Güç testi 10/10 geçti (P1).
## 13. Açık Sorular
- [ ] Kesin birim adları + GNOME oturum satırı — LAB 26.04.1 imajı (sahibi: Faz 3, 03/04 yazarları).
- [ ] NTP bekleme süresi eşiği — P1 ölçümü (sahibi: 16 yazarı).
---
## Ek: Mermaid — Boot zinciri ve systemd bağımlılıkları
```mermaid
flowchart TB
PWR["Power ON<br/>(BIOS Power On)"] --> TGT["multi-user.target<br/>(terminal boot)"]
TGT --> NET["network-online.target"]
NET --> WG["wg-quick@wg0<br/>After network-online"]
WG --> DKR["docker.service<br/>After network"]
DKR --> MEG["MEG / uygulama birimleri<br/>After docker + wg-quick"]
MEG --> AGT["RustDesk + MeshCentral<br/>+ node_exporter + Kuma Push"]
AGT --> BF["bf-status OK"]
```

View file

@ -0,0 +1,159 @@
# 17 — Yedekleme, Kurtarma ve Yeniden Kurulum (Backup, Recovery & Reinstall)
> Kısa özet: 9 seviyeli kurtarma merdiveni (LEVEL 1…9): servis yeniden başlatmadan merkez VDS'in sıfırdan inşasına kadar her seviyede merkezi prosedür + saha/yerel prosedür. Saha teknisyeni ve merkezi admin için ortak başvuru noktasıdır.
- Dosya: `docs/17-BACKUP-RECOVERY-AND-REINSTALL.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-04` (kanal bağımsızlığı), `#K-05` (WireGuard), `#K-06` (Ansible/Semaphore), `#K-09` (golden image), `#K-10` (unless-stopped), `#K-11` (onaysız update yasağı), `#K-12` (cihaz kimliği), `#K-14` (support bundle)
- Durum: [ ] Taslak
---
## 1. Amaç
700 cihazlı filoda her arızanın boyuna uygun, önceden tanımlı bir kurtarma yolu olması. Küçük arıza küçük müdahaleyle (servis restart), büyük arıza büyük müdahaleyle (yeniden imaj) çözülür; teknisyen "ne yapsam?" diye doğaçlama yapmaz, LEVEL tablosuna bakar.
## 2. Kapsam
- Kapsam içi: saha cihazı LEVEL 1…8 kurtarma, merkez VDS yedeği ve yeniden inşası (LEVEL 9), her seviyede merkezi (uzaktan) + yerel (sahada) prosedür, yedeklenecek veri listesi, yedek sıklığı.
- Kapsam dışı: update dalgalarının onay akışı (10-UPDATE), MEG uygulama verisi yedeği detayı (13-MEG-ACCEPTANCE'a havale), elektrik kesintisi sonrası otomatik toparlanma zinciri (16-POWER-LOSS).
## 3. Kararlar
```text
KARAR: Kurtarma 9 seviyeli merdivenle işletilir: L1 servis restart → L2 reboot → L3 son değişikliği geri alma → L4 WireGuard/RustDesk/MeshCentral kanalıyla uzaktan onarım → L5 yedekten config geri yükleme → L6 Docker/MEG yeniden kurulum → L7 OS onarımı → L8 USB ile sıfırdan imaj → L9 merkez VDS yeniden inşası.
GEREKÇE: Merdiven, en ucuz müdahaleyi önce dener; gereksiz yeniden imaj (veri kaybı + teknisyen saati) ve gereksiz VDS müdahalesi önlenir. Her seviyenin "merkezi" ve "yerel" kolu vardır, erişim durumuna göre yol seçilir.
ALTERNATİF: Tek "USB ile sıfırla" prosedürü — her arızada saha ziyareti gerektirir, 700 cihazda sürdürülemez; elendi.
RİSK: Yanlış seviye seçimi (L8 gerekirken L1'de oyalanma); azaltma: her seviyede "bir üst seviyeye geç" kriteri yazılıdır.
MALİYET: Ücretsiz (yerleşik araçlar + Ansible).
LİSANS: Yok (işletim prosedürü; araç lisansları 24-DECISION-LOG Ek A).
```
```text
KARAR: Merkez VDS'ler dosya-seviyesi yedek + IaC (Ansible playbook + compose dosyaları Git'te) ile kurtarılır; blok-imaj yedeği zorunlu değildir.
GEREKÇE: Servislerin tamamı kodla yeniden kurulabilir durumda tutulur (playbook/compose Git'te); veri (envanter DB, Prometheus verisi, Semaphore DB) dosya yedeğiyle alınır. Blok imaj hem pahalı hem VDS sağlayıcıya bağımlıdır.
ALTERNATİF: Sağlayıcı snapshot'ına bel bağlama — taşınabilir değil, ikinci VDS'e geçemez; yedek yöntem olarak tutulur, birincil yapılmaz.
RİSK: Git'teki IaC ile gerçek VDS drift eder; azaltma: üç ayda bir "boş VDS'e sıfırdan kur" tatbikatı (L9 testi).
MALİYET: Ücretsiz (VDS kira + varsa snapshot ücreti hariç).
LİSANS: Yok.
```
```text
KARAR: Saha cihazında kullanıcı verisi yedeği alınmaz; cihaz "değiştirilebilir" (disposable) sayılır — kimlik (`bf-<no>`) + config merkezden yeniden basılır.
GEREKÇE: Tek kimlik standardı (K-12) sayesinde cihazın tüm kişiliği merkezde tanımlıdır; yeniden imaj + kimlik enjeksiyonu cihazı eşdeğerine döndürür. 700 cihazda tek tek veri yedeği işletilemez.
ALTERNATİF: Cihaz-başı tam yedek — bant genişliği ve operasyon yükü nedeniyle elendi.
RİSK: MEG yerel verisi kaybolur; azaltma: MEG verisi gerekiyorsa merkezi yedek hedefi 13-MEG-ACCEPTANCE'ta tanımlanır, teknisyen L8 öncesi uyarılır.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Kurtarma merdiveni üç ilkeye dayanır: (1) erişim varsa sahaya gidilmez — 4 erişim kanalından (K-04) en az biri ayaktaysa onarım uzaktan yapılır; (2) config kodludur — IaC Git'te olduğu sürece merkez de saha da yeniden üretilebilir; (3) cihaz disposable'dır — veri cihazda değil merkezde yaşar. LEVEL 9 (merkez inşası) bu yüzden dosya yedeği + playbook ikilisine dayanır, pahalı imaj altyapısına değil.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Tek-seviye "sıfırla" | Basit anlatım | Her arızada saha ziyareti, veri kaybı | Elendi |
| Sağlayıcı snapshot birincil | Hızlı geri dönüş | Taşınabilir değil, sağlayıcı kilidi | Yedek |
| Cihaz-başı tam yedek (Borg/restic per-node) | Veri korunur | 700 cihazda bant/işletme yükü | Elendi (MEG verisi ayrı ele alınır) |
| Clonezilla ile bit-kopya geri yükleme | Hızlı | Donanım-fragil (K-09) | Yedek yöntem |
## 6. Avantajlar
- Her arızada "hangi seviye" sorusunun cevabı tabloda hazır; teknisyen doğaçlama yapmaz.
- Merkezi kol sayesinde çoğu arıza saha ziyaretsiz çözülür.
- L9 tatbikatı merkezin gerçekten yeniden kurulabildiğini kanıtlar (kağıt üstünde kalmaz).
## 7. Dezavantajlar
- Merdiven disiplini eğitim ister; acemi teknisyen L1'i atlayıp doğrudan L8'e koşabilir.
- IaC drift'i (Git ≠ gerçek) L9'u yavaşlatır; periyodik tatbikat şarttır.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Yanlış seviye seçimi, arızayı büyütür | Orta | Orta | Her seviyede "yükseltme kriteri" + runbook yönlendirmesi (20/21) |
| Yedek alınmıyor ama alınıyor sanılıyor | Orta | Yüksek | Yedek doğrulama job'ı + Uptime Kuma/Prometheus alarmı |
| L8'de bayi no yanlış girilir, kimlik çakışır | Düşük | Yüksek | 02-NAMING benzersizlik kontrolü + kurucu script onayı |
| Merkez yedeği şifresiz saklanır | Düşük | Yüksek | Yedek şifreleme + erişim yalnızca merkezi admin (21) |
## 9. Uygulama Planı
### LEVEL tablosu (her seviyede Merkezi + Yerel kol)
| LEVEL | Ad | Merkezi prosedür (uzaktan) | Yerel prosedür (sahada) | Üst seviyeye geç kriteri |
|---|---|---|---|---|
| L1 | Servis restart | Ansible/Semaphore ile `systemctl restart` (Docker, xrdp, wg-quick, agent) | `sudo systemctl restart <servis>` | Servis 2 restartta ayağa kalkmıyorsa → L2 |
| L2 | Reboot | `reboot` (Semaphore job veya SSH); boot zinciri izlenir (16) | Güç düğmesi / fiş-çek-tak (tek sefer) | Boot sonrası aynı arıza sürüyorsa → L3 |
| L3 | Son değişikliği geri alma | 10-UPDATE rollback zinciri (önceki config/imaj) | Teknisyen değişikliği yaptıysa manuel geri alma (20) | Geri alma sonrası düzelmiyorsa → L4 |
| L4 | Alternatif kanaldan onarım | WG çöktüyse RustDesk/MeshCentral ile bağlan, WG config'ini düzelt; tersi durumda SSH-over-WG ile agent düzelt | Teknisyen telefonla merkezden komut alır, uygular | Hiçbir kanaldan erişilemiyorsa → L5/L8 hazırlığı |
| L5 | Config geri yükleme | Ansible ile bilinen-iyi config'i bas (sshd, wg0, daemon.json, exporter) | USB'deki `config/` klasöründen kopyalama (kurucu medyasında) | Config doğru ama servis kalkmıyorsa → L6 |
| L6 | Docker/MEG yeniden kurulum | Playbook ile Docker + MEG stack yeniden kurulumu | `blueforce-install.sh --only-docker-meg` (varsa) | İmaj bozulmuş görünüyorsa → L7/L8 |
| L7 | OS onarımı | Kırık paket/çekirdek onarımı (`apt --fix-broken`, eski çekirdekle boot) | Recovery mod + teknisyen adımları (20) | Kök dosya sistemi hasarlıysa → L8 |
| L8 | USB ile sıfırdan imaj | Merkez L8 kararı verir, teknisyeni yönlendirir (21) | USB → Ubuntu → `blueforce-install.sh` → bayi no → READY (20) | Cihaz donanımsal arızalıysa → donanım değişimi; donanım sağlamsa L8 son duraktır |
| L9 | Merkez VDS yeniden inşası | Boş VDS'e playbook/compose + dosya yedeğiyle kurulum; DNS/kimlikler güncellenir | — (teknisyen işi değil) | — |
### Yedeklenecekler ve sıklık
1. Merkez dosya yedeği (günlük, otomatik): Ansible inventory + `host_vars`/`group_vars`, WireGuard anahtarları (şifreli), Semaphore DB dump, Prometheus config + kurallar, Grafana dashboard JSON'ları, compose dosyaları, RustDesk keypair, MeshCentral config/DB.
2. IaC Git deposu (her değişiklikte commit+push): playbook'lar, roller, compose'lar, autoinstall/preseed, `blueforce-install.sh`.
3. Yedek doğrulama (aylık): en yeni yedeğin açılabilirliği + kritik dosya hash kontrolü; sonuç monitoring'e işlenir.
```bash
# örnek: saha cihazı hızlı durum (L1 öncesi tanı)
bf-status
# örnek: tanılama paketi (secret sızdırmaz)
bf-support-bundle --out /tmp/bf-12010193-bundle.tar.gz
# örnek: merkezden tek cihazda servis restart (Ansible)
ansible-playbook playbooks/restart.yml --limit bf-12010193
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| L1→L2 merdiven tatbikatı (servis kill) | L1 çözer, kayıt düşer | LAB(2) |
| WG config bozma → L4 (RustDesk ile onarım) | Tünel uzaktan onarılır | P1(5) |
| L8 tam yeniden imaj + bayi no | READY < hedef süre | LAB(2) |
| L9 boş VDS'e sıfırdan kurulum tatbikatı | Tüm servisler ayağa kalkar | İzole VDS |
| Yedekten geri yükleme (Semaphore DB) | İş geçmişi ve envanter döner | Merkez test |
## 11. Rollback
1. Kurtarma müdahalesi arızayı büyütürse bir üst LEVEL'e geçilir, geri dönülmez (merdiven tek yönlüdür).
2. L3 geri alması yanlışsa 10-UPDATE zincirindeki önceki-önceki sürüme geçilir.
3. L9 inşası başarısızsa eski VDS (kapatılmadıysa) ayakta tutulur; DNS geri alınır.
## 12. Kontrol Listesi
- [ ] L1…L9 tablosu 20 (teknisyen) ve 21 (merkez) runbook'larına linkli.
- [ ] Yedek listesi + sıklığı merkezde job'a bağlı, doğrulaması alarmlı.
- [ ] IaC deposu güncel; son L9 tatbikat tarihi yazılı.
- [ ] `bf-support-bundle` secret dışlama kuralı testli (K-14).
## 13. Açık Sorular
- [ ] Yedek saklama süresi ve şifreleme anahtarının kasası (sahibi: merkezi admin, 21).
- [ ] MEG yerel veri yedeği gerekli mi — 13-MEG kararı bekleniyor (sahibi: Faz 3).
- [ ] L9 tatbikat periyodu (öneri: 3 ay) onayı (sahibi: 25-ROADMAP).
---
## Ek: Mermaid — kurtarma merdiveni
```mermaid
flowchart TB
F["Arıza bildirimi<br/>(teknisyen / monitoring)"] --> L1["L1 servis restart"]
L1 -->|düzelmedi| L2["L2 reboot"]
L2 -->|düzelmedi| L3["L3 son değişikliği geri al"]
L3 -->|düzelmedi| L4["L4 alternatif kanaldan onarım<br/>(WG ↔ RustDesk/MeshCentral)"]
L4 -->|erişim yok| L8["L8 USB ile sıfırdan imaj"]
L4 -->|erişim var, config bozuk| L5["L5 config geri yükleme"]
L5 -->|düzelmedi| L6["L6 Docker/MEG yeniden kurulum"]
L6 -->|düzelmedi| L7["L7 OS onarımı"]
L7 -->|düzelmedi| L8
L8 --> OK["READY"]
L9["L9 merkez VDS inşası<br/>(ayrı tetikleyici)"] --> OKC["Merkez servisler ayakta"]
```

View file

@ -0,0 +1,153 @@
# 18 — Pilot ve 700 Cihaz Yayılımı (Pilot & Rollout)
> Kısa özet: Yayılımın ilk adımı `bf-hardware-inventory.sh` donanım taramasıdır; imaj dondurulmadan önce saha heterojenliği ölçülür. Sonra LAB(2) → P1(5) → P2(20) → W1(50) → W2(100) → PROD dalgaları, her dalgada giriş/çıkış kriteriyle ilerler.
- Dosya: `docs/18-PILOT-AND-700-DEVICE-ROLLOUT.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-01` (donanım profili), `#K-09` (önce envanter, sonra imaj), `#K-11` (dalga zinciri), `#K-12` (cihaz kimliği)
- Durum: [ ] Taslak
---
## 1. Amaç
700 cihazı "bir gecede" değil, ölçülebilir dalgalarla üretime almak. Her dalga bir öncekinin kanıtı üzerine kurulur; bir dalga batarsa filo değil, o dalga etkilenir.
## 2. Kapsam
- Kapsam içi: donanım envanter taraması, dalga tanımı ve sayıları, her dalganın giriş/çıkış kriterleri, dalga başına izlenecek metrikler, durdurma (halt) kuralları.
- Kapsam dışı: update'lerin dalga zinciri (10-UPDATE — aynı dalga isimlerini kullanır ama tetikleyici farklıdır), tek cihaz kurulum adımları (20-FIELD-RUNBOOK).
## 3. Kararlar
```text
KARAR: İmaj dondurulmadan ÖNCE `bf-hardware-inventory.sh` ile saha donanım taraması yapılır; CPU/RAM/disk/NIC/GPU profilleri çıkarılmadan golden image dondurulmaz.
GEREKÇE: K-09'un en büyük riski heterojen donanımda sürücü eksiğidir; tarama olmadan üretilen tek imaj sahada rastgele kırılır. Profil listesi LAB test matrisini belirler.
ALTERNATİF: Taramasız "standart PC varsayımı" — ilk dalgada sürpriz donanımla çakışır; elendi.
RİSK: Tarama örneklemi yanlı olur (kolay ulaşılan bayiler); azaltma: bölge başına kota + en az %10 örneklem hedefi.
MALİYET: Ücretsiz (script + Ansible).
LİSANS: Yok.
```
```text
KARAR: Dalgalar: LAB(2) → P1/PILOT-1(5) → P2/PILOT-2(20) → W1/WAVE-1(50) → W2/WAVE-2(100) → PROD (kalan ~523). Hiçbir dalga, önceki dalganın çıkış kriterini sağlamadan başlamaz.
GEREKÇE: K-11'in onay zinciri; üstel büyüme (2→5→20→50→100→523) riski kademeli taşır, her adımda gözetim süresi vardır.
ALTERNATİF: Tek seferde toplu kurulum — geri dönüşü olmayan filo-çapı hata riski; elendi.
RİSK: Takvim baskısıyla kriter atlanır; azaltma: dalga geçişi merkezi admin onayı gerektirir (21), Semaphore'da kapı adımı.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Önce ölç (envanter), sonra dondur (imaj), sonra büyüt (dalgalar). Bu sıra, 700 cihazda "bilinmeyen donanım" ve "bilinmeyen ölçek" risklerini birbirinden ayırır: donanım riski LAB'da, ölçek riski dalgalarda eritilir. Dalga sayıları (2/5/20/50/100) hem K-11'deki update zinciriyle aynıdır hem de teknisyen kapasitesine uyar (erken dalgalar az cihazla çok öğrenme).
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Taramasız imaj | Hızlı başlangıç | Sahada sürücü sürprizi | Elendi |
| Tek dalga (big-bang) | Hızlı | Filo-çapı geri dönüşsüz hata | Elendi |
| Daha fazla küçük dalga (10+) | Çok güvenli | Takvim ve teknisyen yorgunluğu | Elendi (6 dalga yeterli) |
## 6. Avantajlar
- Her dalga, sonraki dalganın eğitim verisidir (süre, hata tipi, destek yükü ölçülür).
- Durdurma kuralları sayesinde kötü imaj 5 cihazdan öteye geçemez.
- Envanter taraması aynı zamanda 02-INVENTORY'nin veri kaynağıdır (iki iş bir taş).
## 7. Dezavantajlar
- Dalgalar takvimi uzatır; yönetim "neden hepsi birden değil" diye sorar (bu doküman cevaptır).
- Erken dalga bayileri pilot yükü taşır; iletişim ve destek planı gerekir.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Envanter örneklemi yanlı | Orta | Yüksek | Bölge kotası + %10 hedefi |
| Kriter atlanarak dalga atlama | Orta | Yüksek | Merkezi admin onayı zorunlu (21) |
| Pilot bayilerde destek yığılması | Orta | Orta | Dalga başına teknisyen kapasite planı (25) |
| Donanım profili imajı kırar (yeni parti PC) | Orta | Orta | Her yeni donanım partisi LAB'a girer |
## 9. Uygulama Planı
### FAZ 0 — Donanım taraması (her şeyden önce)
1. `bf-hardware-inventory.sh` mevcut/örnek cihazlarda çalıştırılır (CPU, RAM, disk, NIC, GPU, BIOS modu, mevcut OS).
2. Çıktılar merkezde toplanır, donanım profilleri çıkarılır (örn. Profil-A: i3/4GB/120GB, Profil-B: i5/8GB/256GB…).
3. Profil listesi 04-GOLDEN-IMAGE'a girer; LAB test matrisi = her profilden ≥1 cihaz.
4. Profil başına sürücü notu düşülür (Wi-Fi çipi, ekran kartı, yazıcı).
```bash
# örnek: envanter taraması (sahada veya Ansible ile)
sudo ./bf-hardware-inventory.sh --out /tmp/inv-$(hostname).json
# örnek: merkezde toplama
ansible all -m fetch -a "src=/tmp/inv-{{ inventory_hostname }}.json dest=inventory/hw/ flat=yes"
```
### Dalga planı
| Dalga | Cihaz | Amaç | Gözetim süresi | Çıkış kriteri (hepsi şart) |
|---|---|---|---|---|
| LAB | 2 | İmaj + 3 akış doğrulama (erişim/boot/update) | 1 hafta | 3 akış yeşil, support-bundle temiz, rollback denendi |
| P1 (PILOT-1) | 5 | Gerçek saha + WG kopma sayacı + teknisyen akışı | 2 hafta | Kopma sayacı toplandı, teknisyen USB→READY'yi desteksiz yaptı, kritik hata yok |
| P2 (PILOT-2) | 20 | Ölçek provası + digest pinleme değerlendirmesi + destek yükü ölçümü | 2–3 hafta | Cihaz-başı kurulum süresi hedefte, destek bileti/cihaz eşiği altında, monitoring 17 metrik dolu |
| W1 (WAVE-1) | 50 | Bölge-ölçeği yayılım, envanter disiplini | 3 hafta | Envanter %100 eşleşiyor, halt kuralı tetiklenmedi |
| W2 (WAVE-2) | 100 | Üretim-öncesi son prova, paralel ekip çalışması | 3–4 hafta | İki ekip paralel kurulum yapabiliyor, geri alma zinciri canlı denendi |
| PROD | ~523 | Kalan filo | planlı | W2 çıkış kriterleri + yönetim onayı |
### Halt (durdurma) kuralları
1. Dalga içinde aynı kök-nedenle ≥2 kritik arıza → dalga durur, 17-RECOVERY L3 işletilir.
2. Monitoring'de dalga cihazlarının >%10'u 24 saatte çevrimdışı → yayılım durur, ağ/VPN incelenir.
3. Teknisyen kurulum süresi hedefin 2× üstünde → eğitim/runbook (20) revize edilmeden devam edilmez.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Envanter scripti 3 farklı donanımda | Profil JSON'u eksiksiz | LAB + örnek saha |
| LAB 3-akış testi | Erişim + boot + update yeşil | LAB(2) |
| P1 kopma sayacı 7/24 | Keepalive ayarı için veri | P1(5) |
| Dalga geçiş kapısı (Semaphore) | Onaysız geçiş engellenir | Merkez test |
## 11. Rollback
1. Dalga içi arızada etkilenen cihazlar 17-RECOVERY merdiveniyle (L3/L8) önceki-iyi duruma alınır.
2. İmaj-köklü arızada dalga durdurulur, imaj revize edilir, dalga baştan başlar (ilerideki dalgalar etkilenmez).
3. PROD'da imaj sorunu çıkarsa 10-UPDATE rollback zinciri işletilir.
## 12. Kontrol Listesi
- [ ] Envanter taraması tamam, profil listesi 04'e işlendi.
- [ ] Her dalganın giriş/çıkış kriteri + gözetim süresi yazılı ve onaylı.
- [ ] Halt kuralları 21 (merkez) runbook'una işlendi.
- [ ] Dalga cihaz listeleri envanterde (`BF-<no>`) ayrıldı.
## 13. Açık Sorular
- [ ] Örneklem hedefi (%10) ve bölge kotaları onayı (sahibi: merkezi admin).
- [ ] Pilot bayi seçimi + iletişim planı (sahibi: 25-ROADMAP).
- [ ] Cihaz-başı kurulum süresi hedefi (öneri P2'de ölçülüp sabitlenecek).
---
## Ek: Mermaid — dalga akışı
```mermaid
flowchart LR
INV["Donanım taraması<br/>bf-hardware-inventory.sh"] --> PROF["Profil listesi"]
PROF --> IMG["Golden image<br/>(04)"]
IMG --> LAB["LAB 2"]
LAB -->|çıkış kriteri| P1["P1 5"]
P1 -->|çıkış kriteri| P2["P2 20"]
P2 -->|çıkış kriteri| W1["W1 50"]
W1 -->|çıkış kriteri| W2["W2 100"]
W2 -->|çıkış + onay| PROD["PROD ~523"]
LAB -->|halt| FIX["Düzelt +<br/>tekrar"]
P1 -->|halt| FIX
P2 -->|halt| FIX
W1 -->|halt| FIX
W2 -->|halt| FIX
FIX --> LAB
```

192
docs/19-TROUBLESHOOTING.md Normal file
View file

@ -0,0 +1,192 @@
# 19 — Sorun Giderme (Troubleshooting)
> Kısa özet: Sahada ve merkezde en sık görülen arızaların belirti → neden → komut → çözüm tablosu. 17-RECOVERY "hangi seviye" sorusunu, bu doküman "o seviyede hangi komut" sorusunu cevaplar.
- Dosya: `docs/19-TROUBLESHOOTING.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-03` (xRDP/GUI), `#K-04` (erişim kanalları), `#K-05` (WireGuard), `#K-10` (Docker), `#K-14` (`bf-status`, support-bundle)
- Durum: [ ] Taslak
---
## 1. Amaç
Tekrar eden arızalarda teşhisi hızlandırmak: belirtiyi bulan teknisyen/admin, tabloya bakıp ilk komutu 30 saniyede çalıştırır. Her girdide "ne zaman üst seviyeye çık" notu vardır.
## 2. Kapsam
- Kapsam içi: boot, ağ/VPN, SSH, RDP/GUI, RustDesk, MeshCentral, Docker/MEG, disk, monitoring belirti tabloları.
- Kapsam dışı: seviye kararları (17), adım-adım kurulum (20), merkez onay akışı (21).
## 3. Kararlar
```text
KARAR: Her arıza girdisi aynı formatta yazılır: Belirti → Olası nedenler (olasılık sırasıyla) → Tanı komutları → Çözüm → Yükseltme kriteri.
GEREKÇE: Standart format, acemi teknisyenin bile doğru sırayla (tanıdan önce çözüm yok) ilerlemesini sağlar; her çözüm denenebilir komutla verilir.
ALTERNATİF: Serbest-anlatım sorun listesi — komutlar dağınık kalır, otomasyona çevrilemez; elendi.
RİSK: Tablo eskirse yanlış yönlendirir; azaltma: her PİLOT dalgası sonrası tablo gözden geçirilir.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Sorun giderme, kurtarma merdiveninin (17) "içini" doldurur: 17 hangi LEVEL, 19 o LEVEL'de hangi komut. Olasılık sırası önemlidir — en yaygın neden önce yazılır, teknisyen zamanı boşa harcanmaz. Yükseltme kriteri her girdinin sigortasıdır (inatla aynı komutu tekrarlamak yasak).
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Harici bilgi tabanı (Wiki araması) | Aranabilir | Çevrimdışı sahada erişilemez, Git akışı yok | Elendi (22'de Docusaurus içinde bu dosya zaten aranabilir) |
| Her arıza için ayrı sayfa | Detaylı | 700 cihazda 100 sayfa yönetilemez | Elendi (gerekirse Ek'e taşınır) |
## 6. Avantajlar
- Tek dosya, çevrimdışı da okunur (USB'de veya basılı).
- Komutlar kopyala-yapıştırılabilir; açıklamalar Türkçe, komut adları İngilizce orijinal.
## 7. Dezavantajlar
- 26.04.1'e özgü çıktı farkları LAB'da güncellenmelidir (kesin servis adları, log yolları).
- MEG'e özgü arızalar 13-MEG-ACCEPTANCE'tan beslenmelidir; bu dosya iskelettir.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Eski komut (servis adı değişti) | Orta | Orta | LAB'da her komut çalıştırılıp doğrulanır |
| Secret'lı komut geçmişe düşer | Düşük | Yüksek | Support-bundle kuralı (K-14); komutlarda secret yazılmaz |
## 9. Uygulama Planı
Önce genel tanı (her arızada ilk 60 saniye):
```bash
bf-status
systemctl --failed
ip -brief addr; ip route show default
wg show wg0 2>&1 | head -20
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.RestartPolicy}}'
df -h / /var/lib/docker | cat
```
### T-1 — Cihaz açılmıyor / ekranda hiçbir şey yok
| # | Neden (olasılık sırası) | Tanı | Çözüm |
|---|---|---|---|
| 1 | Elektrik yok / BIOS güç ayarı | Priz, adaptör, güç LED'i | BIOS "Restore on AC Power Loss = Power On" (16) |
| 2 | Monitör/kablo | Başka kablo/ekran dene | Değiştir |
| 3 | Disk ölmüş | BIOS diski görmüyor | Donanım değişimi → L8 yeni diskte |
Yükseltme: donanım sağlamsa ama OS açılmıyorsa T-2'ye geç.
### T-2 — Boot terminale düşmüyor / servisler kalkmıyor
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | Failed servis var | `systemctl --failed`, `journalctl -xb -p err` | İlgili servis girdisine git (T-3…T-6) |
| 2 | Disk dolu | `df -h /` | Docker log temizliği + rotasyon kontrolü (T-7) |
| 3 | Bozuk çekirdek/paket | `dpkg --audit`, `apt --fix-broken install` | 17-L7; olmazsa L8 |
### T-3 — WireGuard tüneli yok (`wg show` boş / handshake eski)
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | Servis inaktif | `systemctl status wg-quick@wg0` | `sudo systemctl enable --now wg-quick@wg0` |
| 2 | Anahtar/config hatası | `journalctl -u wg-quick@wg0 --no-pager`, `wg show wg0 latest-handshakes` | Config'i merkezden yeniden bas (17-L5); peer adı `bf-<no>` mi kontrol et |
| 3 | Saha interneti yok / CGNAT | `ping -c3 8.8.8.8`, modem arayüzü | Yerel ağ düzeltilir; kopma sayacı not edilir (P1 görevi) |
| 4 | Merkez hub down | Başka cihazdan hub'a bak | 17-L9 kolu işletilir |
Yükseltme: WG kalkmıyorsa RustDesk/MeshCentral ile devam (17-L4); onlar de yoksa saha ziyareti.
### T-4 — SSH bağlanmıyor (WG ayaktayken)
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | sshd down / anahtar eşleşmiyor | `systemctl status ssh`, `ssh -vvv blueforce@bf-<no>` | Anahtarı merkezden yeniden dağıt (K-13); password denemesi YOK |
| 2 | Yanlış IP/hostname | `ip -brief addr`, envanter karşılaştır | 02-NAMING'e göre düzelt |
| 3 | Güvenlik duvarı | `sudo ufw status`, `ss -tlnp` | 11-HARDENING standardına döndür |
### T-5 — RDP açılmıyor / siyah ekran / hemen kopuyor
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | GUI katmanı kapalı | `systemctl status display-manager xrdp xrdp-sesman` | `bf-gui-on`, tekrar dene |
| 2 | Oturum çakışması (yerel + RDP aynı kullanıcı) | `who`, `loginctl list-sessions` | Ayrı kullanıcı/oturum; eski oturumu kapat |
| 3 | xRDP config bozulmuş | `journalctl -u xrdp --no-pager` | Bilinen-iyi config'i bas (17-L5) |
### T-6 — RustDesk bağlanmıyor
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | İstemci servis/uygulama kapalı | RustDesk durumu, ID görünüyor mu | Servisi başlat; ID+röle adresi merkez değerlerle aynı mı |
| 2 | Key uyuşmazlığı | İstemci key vs hbbs key | Merkezi key'i yeniden bas (07-REMOTE-ACCESS) |
| 3 | hbbs/hbbr down | Merkezden konteyner/servis durumu | Merkez tarafını ayağa kaldır; health monitörü (Kuma) ne diyor |
### T-7 — Docker/MEG kalkmıyor veya sürekli restart
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | Restart loop (config/entrypoint) | `docker ps`, `docker logs --tail 100 <ad>` | Config düzelt + `docker compose up -d` (17-L6) |
| 2 | Disk dolu (rotasyonsuz log) | `df -h /var/lib/docker`, `du -sh /var/lib/docker/containers/*` | `daemon.json` rotasyonu uygula; taşan logu buda |
| 3 | `latest` çekilmiş / sürüm kaymış | `docker images`, compose tag kontrolü | Sabit tag'e döndür (K-10); Watchtower varsa kaldır |
| 4 | Port çakışması / UFW bypass | `ss -tlnp`, `docker port <ad>` | `127.0.0.1`-bind standardına döndür (K-10) |
### T-8 — Disk doluyor
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | Docker json-file logları | `du -sh /var/lib/docker/containers/*` | Rotasyon + budama, `docker system prune` (dikkatli) |
| 2 | journald şişmiş | `journalctl --disk-usage` | `SystemMaxUse` limiti + `journalctl --vacuum-size=` |
| 3 | Prometheus retention (merkez) | `df -h`, retention ayarı | 30–90 gün bandına çek (K-07) |
### T-9 — Monitoring'de cihaz gri/kayıp
| # | Neden | Tanı | Çözüm |
|---|---|---|---|
| 1 | Node Exporter down | `systemctl status node_exporter`, hedef scrape logu | Servisi başlat; textfile dizin izni |
| 2 | Uptime Push gelmiyor | Kuma "last seen" | Cihaz interneti + push job'ı (T-3'e dön) |
| 3 | Etiket yanlış (`BF-<no>`) | Prometheus target etiketleri | Envanterle eşitle (02) |
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Her T girdisindeki ilk tanı komutu LAB'da çalışır | Komut + örnek çıktı bu dosyada | LAB(2) |
| WG-kill → T-3 → L4 onarım tatbikatı | < hedef sürede tünel döner | P1(5) |
| Disk-doldur simülasyonu → T-8 | Alarm + temizlik çalışır | LAB(2) |
## 11. Rollback
Yanlış çözüm uygulandıysa 17-L3 (son değişikliği geri alma) işletilir; tanı komutlarının kendisi read-only'dir, rollback gerektirmez.
## 12. Kontrol Listesi
- [ ] Her girdide Yükseltme kriteri var.
- [ ] Komutların tamamı LAB 26.04.1 imajında denendi.
- [ ] Hiçbir girdide secret/şifre yazılmıyor.
- [ ] MEG'e özgü satırlar 13 ile çapraz linkli.
## 13. Açık Sorular
- [ ] Kesin `bf-gui-*` birim adları + GNOME oturum satırı — LAB çıktısı (sahibi: Faz 3).
- [ ] MEG log hacmi ölçümü → T-8 eşikleri (sahibi: 12-DOCKER yazarı).
- [ ] Turkcell CGNAT tanı notları — P1 verisi (sahibi: 08-WIREGUARD yazarı).
---
## Ek: Triyaj Akışı (hangi T girdisi?)
```mermaid
flowchart TB
SORUN["Arıza bildirimi<br/>bf-status + systemctl --failed"] --> ACILIR{"Cihaz açılıyor mu?"}
ACILIR -->|Hayır| T1["T-1: güç / BIOS / disk"]
ACILIR -->|Evet| BOOTOK{"Servisler kalkıyor mu?"}
BOOTOK -->|Hayır| T2["T-2: failed servis / disk dolu"]
BOOTOK -->|Evet| WG{"wg show handshake güncel mi?"}
WG -->|Hayır| T3["T-3: WireGuard + L4 yedek kanal"]
WG -->|Evet| SSH{"SSH oluyor mu?"}
SSH -->|Hayır| T4["T-4: sshd / anahtar / UFW"]
SSH -->|Evet| RDP{"RDP açılıyor mu?"}
RDP -->|Hayır| T5["T-5: bf-gui-on / xRDP"]
RDP -->|Evet| DERIN["T-6+: Docker / MEG / disk (T-7/T-8)"]
```

View file

@ -0,0 +1,164 @@
# 20 — Saha Teknisyeni Runbook
> Kısa özet: Sahada cihaz başına giden teknisyenin el kitabı. Tek akış: USB'yi tak → kur → bayi numarasını gir → READY'yi gör → çık. Komut ezberi istenmez; her adımda "ne göreceksin, ne yazacaksın" vardır.
- Dosya: `docs/20-FIELD-TECHNICIAN-RUNBOOK.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-09` (USB → script → bayi no → READY), `#K-12` (bayi no → `BF-<no>`), `#K-14` (`bf-status`, support-bundle)
- Durum: [ ] Taslak
---
## 1. Amaç
Teknisyenin sahada tek başına, telefonsuz bile cihazı READY hale getirmesi. Bu dosya "neden" anlatmaz, "ne yap" söyler. Neden merak eden 01'e bakar.
## 2. Kapsam
- Kapsam içi: USB ile sıfır kurulum, bayi no girişi, READY kontrolü, arızalı cihazda ilk 3 hareket, merkeze ne zaman telefon açılacağı.
- Kapsam dışı: merkez onayları (21), arıza teşhis tablosu detayı (19 — sadece yönlendirme), update dalgaları (10).
## 3. Kararlar
```text
KARAR: Teknisyen akışı 4 adımdır: USB → kur → bayi no → READY. Teknisyen hostname, IP, anahtar, config dosyası ile uğraşmaz; hepsini `blueforce-install.sh` yapar.
GEREKÇE: K-09'un hedef akışı; insan hatası en çok elle config'de olur. Teknisyenin tek manuel girdisi 8 haneli bayi numarasıdır (K-12).
ALTERNATİF: Teknisyene tam Linux eğitimi + manuel kurulum — 700 cihazda standardizasyon bozulur; elendi.
RİSK: Script USB'si eski sürüm kalır; azaltma: USB etiketinde sürüm + merkezden "şu sürümden eski USB'yi kullanma" duyurusu.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Teknisyenin işi "bilgisayarcılık" değil "bayi cihazını çalışır teslim etmek"tir. Karar, teknisyenin dikkatini tek kritik noktaya toplar: bayi numarasını doğru girmek. Geri kalan her şey script + merkez otomasyonudur. Bu yüzden bu dosya kısa cümlelerle, emir kipiyle yazılır.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Detaylı Linux kılavuzu | Bilgili teknisyen | Uzun, hata açık, herkes okumaz | Elendi |
| Merkezden uzaktan kurulum (teknisyensiz) | Saha maliyeti yok | İlk kurulumda cihazda internet/VPN yok | Elendi (ilk kurulum sahada) |
## 6. Avantajlar
- Yeni teknisyen 1 saatlik eğitimle sahaya çıkar.
- Her cihaz aynı adımla kurulur; "ustalık farkı" kapanır.
## 7. Dezavantajlar
- Script'in yapmadığını teknisyen de yapamaz; olağandışı durumda merkeze bağımlıdır (bilerek böyle).
- USB medyası fiziksel lojistik ister (sürüm takibi).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Bayi no yanlış girilir | Orta | Yüksek | Script ekranda `BF-<no>`'yu gösterir, teknisyen bayiye onaylatır |
| Eski USB ile kurulum | Orta | Orta | USB sürüm etiketi + kurucu açılışta sürümü söyler |
| READY görülmeden sahadan çıkılır | Düşük | Yüksek | Kontrol listesi imzalanmadan iş kapanmaz |
## 9. Uygulama Planı
### A. Sıfır kurulum (yeni cihaz) — 4 adım
**ADIM 1 — USB'yi tak, bilgisayarı aç.**
1. Kurulum USB'sini tak.
2. Bilgisayarı aç, USB'den başlat (açılışta genelde F12/F8/F2 — ekranda yazar).
3. Ubuntu kurulum ekranı gelene kadar bekle.
> Göreceğin: Ubuntu kurulum ekranı. Bunu görmüyorsan: USB tam takılı mı, BIOS boot sırası USB mi? Olmazsa merkeze telefon aç.
**ADIM 2 — Ubuntu'yu kur.**
1. Ekrandaki kurulumu varsayılanlarla tamamla (dil: Türkçe, disk: tamamını kullan).
2. Kurulum bitince USB'yi çıkarma, bilgisayarı yeniden başlat.
**ADIM 3 — Kurucu scripti çalıştır, bayi numarasını gir.**
1. Terminali aç, şunu yaz:
```bash
sudo ./blueforce-install.sh
```
2. Script senden **8 haneli bayi numarasını** ister. Faturadaki/sistemdeki numarayı yaz, Enter'a bas. Örnek: `12010193`.
3. Script ekranda şunu gösterecek:
```text
Device ID: BF-12010193
Hostname: bf-12010193
```
4. Numarayı bayiye sesli onaylat: "Cihaz numaranız BF-12010193, doğru mu?" Yanlışsa scriptten çık, tekrar çalıştır.
**ADIM 4 — READY'yi gör, çık.**
1. Script bitene kadar bekle (kapatma, fişi çekme).
2. Sonunda şunu çalıştır:
```bash
bf-status
```
3. Ekranda **READY** (veya tüm satırlar yeşil/OK) görmelisin.
4. Kontrol listesini doldur (§12), sahadan çık.
### B. Arızalı cihaza gittin — ilk 3 hareket
1. `bf-status` çalıştır. Kırmızı satır hangisi? Not al.
2. Bilgisayarı bir kez yeniden başlat. Düzelirse READY'yi gör, çık.
3. Düzelmezse support paketini al, merkeze gönder:
```bash
bf-support-bundle --out /tmp/bf-<bayi-no>-bundle.tar.gz
```
Paketi merkeze ilet (telefonla nasıl göndereceğin söylenir), merkez sana söylemeden başka komut çalıştırma.
### C. Merkeze telefon açma kuralları
Hemen ara: READY alamıyorsan, aynı arıza 2 cihazda üst üste çıktıysa, donanım kırık/yanık kokusu varsa, bayi numarasından emin değilsen.
Arama: cihaz başında ol, `BF-<no>`'yu ve `bf-status` çıktısını hazır tut.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Sıfır teknisyen 4 adımı desteksiz yapar | READY < hedef süre | LAB(2) |
| Yanlış bayi no girilir | Script uyarır, kuruluma devam etmez | LAB(2) |
| Elektrik kesintisi simülasyonu sonrası `bf-status` | READY döner | LAB(2) |
## 11. Rollback
Teknisyen rollback yapmaz. Kurulum yarıda kesildiyse: baştan başla (ADIM 1). İkinci denemede de olmazsa merkeze telefon aç — merkez 17-RECOVERY'den seviyeyi seçer.
## 12. Kontrol Listesi
- [ ] USB sürümü güncel (etiket + merkez duyurusu eşleşiyor).
- [ ] `BF-<no>` bayiye onaylatıldı.
- [ ] `bf-status` → READY görüldü.
- [ ] Cihaz fişe + internete bağlı bırakıldı.
- [ ] İş formu dolduruldu (bayi no, tarih, teknisyen adı).
## 13. Açık Sorular
- [ ] Kurulum USB'sinin dağıtım/sürüm takip yöntemi (sahibi: merkezi admin, 21).
- [ ] İş formu kağıt mı mobil mi (sahibi: 25-ROADMAP).
- [ ] Hedef kurulum süresi (öneri: P2'de ölçülecek).
---
## Ek: Mermaid — teknisyen akışı
```mermaid
flowchart TB
USB["USB tak → aç"] --> KUR["Ubuntu kur"]
KUR --> SCR["sudo ./blueforce-install.sh"]
SCR --> NO["Bayi no gir<br/>(8 hane)"]
NO --> ONAY["BF-no'yu bayiye onaylat"]
ONAY --> BEKLE["Script bitsin"]
BEKLE --> READY["bf-status → READY?"]
READY -->|evet| CIK["Formu doldur → çık"]
READY -->|hayır| TEL["Merkeze telefon aç"]
```

View file

@ -0,0 +1,147 @@
# 21 — Merkezi Yönetici Runbook
> Kısa özet: Merkezdeki yöneticinin el kitabı: hangi işlemi kim onaylar, update'i kim başlatır, dalga kapıları nasıl açılır, teknisyen ne zaman sahaya sürülür. Yetki ve sıra bu dosyadadır.
- Dosya: `docs/21-CENTRAL-ADMIN-RUNBOOK.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-06` (Ansible/Semaphore), `#K-11` (onay zinciri + dalgalar), `#K-13` (anahtar dağıtımı)
- Durum: [ ] Taslak
---
## 1. Amaç
Merkezde "kim, neyi, hangi sırayla yapar" sorusunu kapatmak. Update'i kim başlatır, dalgayı kim onaylar, acil durumda kim karar verir — hepsi burada yazar, kriz anında aranmaz.
## 2. Kapsam
- Kapsam içi: rol ve onay yetkileri, update başlatma akışı, dalga kapı prosedürü, anahtar/erişim yönetimi, acil durum yetkisi, günlük/haftalık rutinler.
- Kapsam dışı: tek cihaz kurulum adımları (20), komut-seviyesi teşhis (19), kurtarma seviye tablosu (17 — buradan çağrılır).
## 3. Kararlar
```text
KARAR: Update'i yalnızca merkezi yönetici başlatır; teknisyen, bayi veya otomatik zamanlayıcı update tetikleyemez. Her dalga geçişi açık onay (Semaphore kapı adımı + kayıt) gerektirir.
GEREKÇE: K-11 "onaysız update yasak" ilkesinin operasyonel karşılığıdır; tek başlatma noktası = denetlenebilirlik. Otomatik tetikleyici olmaması, zamanlanmış sürprizleri engeller.
ALTERNATİF: Takvimli otomatik dalga başlatma — onay kaydı zayıflar, arızada "kim başlattı" belirsizleşir; elendi.
RİSK: Yönetici izindeyken update kilitlenir; azaltma: en az 2 onay yetkilisi tanımlanır (asıl + vekil).
MALİYET: Ücretsiz.
LİSANS: Yok.
```
```text
KARAR: Acil güvenlik update'inde dalga sırası atlanamaz ama gözetim süreleri kısaltılabilir; kısaltma kararı ve gerekçesi kayda geçirilir.
GEREKÇE: Sıra atlamak (LAB'ı geçmeden PROD'a çıkmak) filo-çapı riskidir; süre kısaltmak ise bilinçli hızlandırmadır. Kayıt, sonradan denetimi sağlar.
ALTERNATİF: Acilde direkt PROD — geri dönüşü olmayan hata riski; elendi.
RİSK: "Acil" etiketi suistimal edilir; azaltma: acil tanımı (CVSS eşiği / aktif sömürü) 10-UPDATE'ta yazılıdır.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
700 cihazda en tehlikeli cümle "ben başlattım sandım"dır. Başlatma yetkisini tek role toplamak, hem hatayı hem suçu önler: hata olursa kayıttan bulunur, suçlama olursa kayıt konuşur. Vekil kuralı, tek kişiye bağımlılığı kaldırır.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Herkes update başlatabilir | Hızlı | Onaysız yayılım, denetimsizlik | Elendi |
| Tam otomatik pipeline | Eforsuz | Politika ihlali (K-11) | Elendi |
| Tek onay yetkilisi | Net | İzin/hastalıkta kilit | Elendi (asıl+vekil) |
## 6. Avantajlar
- Her update'in "kim başlattı, kim onayladı, ne zaman" kaydı vardır.
- Acil durumda bile sıra korunur; hız, sıranın içinde ayarlanır.
## 7. Dezavantajlar
- Onay adımı update'i yavaşlatır (bilerek; hız 25-ROADMAP'ta acil yoluyla dengelenir).
- Semaphore kapı adımı atlanırsa politika kağıtta kalır — teknik zorunluluk şarttır.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Kapı adımı bypass edilir (CLI'dan direkt run) | Orta | Yüksek | Semaphore dışı prod run'ı yasaktır; denetim logu izlenir |
| İki yetkili de ulaşılamaz | Düşük | Orta | Acil iletişim zinciri + önceden tanımlı duraklatma (devam etme, durdur) |
| Anahtar sızıntısı | Düşük | Yüksek | Per-admin anahtar iptali + rotasyon (K-13) |
## 9. Uygulama Planı
### Roller
| Rol | Kim | Yetkisi |
|---|---|---|
| Onay yetkilisi (asıl + vekil) | İsimle tanımlanır | Dalga başlatma/onay, acil kısaltma kararı, L8/L9 kararı |
| Operatör | Merkez ekibi | Onaylanmış job'u çalıştırma, monitoring izleme, teknisyen yönlendirme |
| Teknisyen | Saha ekibi | 20'deki akış; update/dalga başlatamaz |
| İzleyici (read-only) | Yönetim | Panoları görür, işlem yapamaz |
### Standart update akışı (yönetici gözüyle)
1. Update talebi gelir (güvenlik bülteni / MEG sürümü / OS yaması) → etki + geri alma planı raporlanır.
2. Onay yetkilisi LAB'ı başlatır: Semaphore'da job + kayıt.
3. LAB çıkış kriteri tuttuysa P1 → P2 → W1 → W2 → PROD, her kapıda açık onay.
4. Herhangi bir dalgada halt kuralı (18) tetiklenirse: yayılım DURUR, 17-L3 işletilir, kök neden bulunmadan kapı açılmaz.
5. PROD bitiminde kapanış kaydı (başarı/arıza sayısı, süre).
```bash
# örnek: onaylı dalga run (operatör, onay sonrası)
ansible-playbook playbooks/update.yml --limit wave_p1
# örnek: kapı kontrolü — onaysız PROD engeli (ilke; teknik karşılığı Semaphore'da)
# PROD limiti yalnızca "prod-onay" etiketli job ile koşar
```
### Anahtar ve erişim yönetimi
1. Yeni admin: anahtarı üretilir, `authorized_keys`'e Ansible ile dağıtılır (K-13); eski/ayrılan adminin anahtarı aynı yolla kaldırılır.
2. Paylaşılan tek private key YOKTUR; böyle bir dosya görülürse olay kaydı açılır.
3. Semaphore yalnızca WireGuard arkasından erişilir; gizliler yerleşik şifreli Key Store'dadır (K-06).
### Günlük / haftalık rutinler
- Günlük (operatör, 10 dk): Uptime Kuma UP/DOWN, Prometheus `up` == 0 listesi, gece reboot olanlar, yedek job durumu.
- Haftalık (yönetici, 30 dk): dalga takvimi, açık halt'lar, anahtar/envanter uyumsuzlukları, L9 tatbikat sayacı.
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| Onaysız PROD run denemesi | Engellenir + log düşer | Merkez test |
| Semaphore kapalıyken Ansible CLI run | Onaylı iş CLI'dan koşar (K-06) | LAB(2) |
| Vekil ile dalga onayı | Kayıtta vekil adı görünür | Merkez test |
## 11. Rollback
1. Hatalı dalga: 17-L3 + 10-UPDATE rollback zinciri; kapı bir sonraki dalgaya kapatılır.
2. Hatalı onay: aynı yetkili (veya vekil) durdurma kararı verir; "devam" kararı verilemez, yalnızca "dur + geri al".
## 12. Kontrol Listesi
- [ ] Asıl + vekil isimle tanımlı ve iletişim bilgileri güncel.
- [ ] Semaphore'da PROD kapı adımı teknik olarak zorunlu.
- [ ] Her dalga onayı kayıtlı (kim, ne zaman, hangi sürüm).
- [ ] Ayrılan personelin anahtarı kaldırıldı.
## 13. Açık Sorular
- [ ] Acil tanımı eşikleri (CVSS/aktif sömürü) — 10-UPDATE ile ortak onay (sahibi: yönetici).
- [ ] Kapanış raporu formatı ve saklama süresi (sahibi: 25-ROADMAP).
- [ ] Read-only yönetim panosu kapsamı (sahibi: 14-MONITORING yazarı).
---
## Ek: Update Onay Akışı (yönetici gözüyle)
```mermaid
flowchart TB
TALEP["Update talebi<br/>(güvenlik / MEG / OS)"] --> KAYIT["Değişiklik kaydı<br/>kapsam + geri alma planı"]
KAYIT --> ONAY{"Onay yetkilisi<br/>(asıl veya vekil)"}
ONAY -->|Ret| KAPANIR["Kapanış kaydı (ret)"]
ONAY -->|Onay| LAB["LAB(2) → P1(5) → P2(20)"]
LAB --> KAPI{"Sağlık kapısı temiz mi?"}
KAPI -->|Halt| DUR["Yayılım DURUR → 17-L3 rollback"]
KAPI -->|Temiz| WAVE["W1(50) → W2(100) → PROD(~523)"]
WAVE --> RAPOR["Kapanış kaydı<br/>(başarı/arıza/süre)"]
```

View file

@ -0,0 +1,124 @@
# 22 — Dokümantasyon Platformu (Documentation Platform)
> Kısa özet: Teknik dokümanların yazıldığı, sürümlendiği ve yayınlandığı platform kararı: Docusaurus önerilir. `docs/*.md` tek kaynaktır; site derlemesi CI'da yapılır; AI ajanları Markdown'u doğrudan günceller.
- Dosya: `docs/22-DOCUMENTATION-PLATFORM.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-08` (Docusaurus, MkDocs yedekte)
- Durum: [ ] Taslak
---
## 1. Amaç
27 dokümanın (00…25 + şablon) hem ham Markdown olarak Git'te hem de aranabilir site olarak yayınlanmasını sağlamak; "doküman nerede, güncel mi, kim değiştirdi" sorularını kapatmak.
## 2. Kapsam
- Kapsam içi: platform seçimi, `docs/` ↔ site ilişkisi, yazım-derleme-yayın akışı, sürümleme ve dil politikası.
- Kapsam dışı: doküman içerikleri (00…21, 23…25), CI komut detayı (25-ROADMAP'a havale).
## 3. Kararlar
```text
KARAR: Dokümantasyon platformu Docusaurus'tur; kaynak `docs-site/` iskeleti + `docs/*.md` tek-kaynak; site derlemesi CI'da yapılır.
GEREKÇE: "AI-güncelleme" kriterini yalnızca Git-yerleşik Markdown çözer: ajan `.md`'yi doğrudan yazar, değişiklik PR'dan geçer, geçmiş Git'tedir. Docusaurus yerleşik sürümleme + yerleşik i18n + MDX (Mermaid dahil) verir; derleme maliyeti alternatifleriyle eşdeğerdir.
ALTERNATİF: MkDocs + Material — eşdeğer sadelikte güçlü ikinci; Docusaurus hattı sorun çıkarırsa geçiş maliyeti düşük (kaynak yine düz Markdown) → yedekte tutulur. Wiki.js (DB+servis yükü) ve TriliumNext (tek kullanıcı) elendi.
RİSK: Node derleme hattı bozulabilir; azaltma: kilitli bağımlılıklar + CI derleme testi; derleme bozulsa bile `docs/*.md` ham haliyle okunur.
MALİYET: Ücretsiz (self-hosted/statik yayın).
LİSANS: Docusaurus MIT — https://github.com/facebook/docusaurus + https://docusaurus.io/docs/markdown-features/diagrams (doğrulanma: 2026-09-15).
```
```text
KARAR: Yayınlanan sitenin kaynağı ile Git'teki `docs/*.md` arasında elle kopyalama yapılmaz; senkronizasyon tek yönlüdür (Git → site).
GEREKÇE: Çift-kaynak, güncel-olmayan site üretir; tek kaynak + CI derlemesi "sitedeki her satırın Git karşılığı var" garantisi verir.
ALTERNATİF: Wiki'de düzenle, Git'e aktar — yön tersine döner, PR disiplini ölür; elendi.
RİSK: CI bozulursa site eskir; azaltma: CI rozeti + derleme testi her PR'da koşar.
MALİYET: Ücretsiz.
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Üç filtre (24 §4) burada da uygulandı: (1) ücretsiz — Docusaurus MIT, barındırma statik; (2) sadelik — DB'li wiki (Wiki.js) bir servis daha demektir, reddedildi; tek-kullanıcı bilgi tabanı (TriliumNext) ekip akışını taşımaz; (3) AI-uyumluluk — ajan düz Markdown'u yazar ve review'a sunar; bu, DB-içi editörde mümkün değildir. MkDocs'a karşı Docusaurus'u ayıran, sonradan eklenti aramadan gelen sürümleme + i18n'dir (700 cihazlık filonun dokümanı yıllarca yaşar, sürüm gerekir).
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| MkDocs + Material | Sade, hızlı, güçlü ikinci | Sürümleme/i18n eklentiyle | Yedek |
| Wiki.js | Güçlü editör, yetkilendirme | DB+servis yükü, Git akışı dolaylı | Elendi |
| TriliumNext | Hafif, kişisel | Ekip review akışı yok | Elendi |
| Yalnızca GitHub/GitLab render | Sıfır kurulum | Sürümleme/arama/zengin tema yok | Elendi (ham okuma zaten var) |
## 6. Avantajlar
- Derleme bozulsa bile dokümanlar kaybolmaz (`docs/*.md` her zaman okunur).
- Mermaid diyagramları (01'deki 3 akış) sitede ve PR önizlemede render olur.
- Sürümleme sayesinde "PİLOT'taki prosedür neydi" sorusu cevaplanabilir.
## 7. Dezavantajlar
- Node derleme hattı bakım ister (kilit dosyası + periyodik güncelleme).
- Editör eşiği wiki'ye göre yüksektir (PR açmak gerekir) — teknik ekip için kabul edilebilir.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Derleme hattı bozulur, site eskir | Orta | Düşük (kaynak okunur) | CI derleme testi + kilitli bağımlılık |
| Doküman-Git senkronu bozulur (elle site editi) | Düşük | Orta | Siteye yazma yetkisi yalnızca CI'da |
| İçerik eskir (prosedür değişti, doküman kalmış) | Orta | Yüksek | Her PR'da "ilgili doküman güncellendi mi" kontrolü |
## 9. Uygulama Planı
1. `docs-site/` iskeleti kurulur (Docusaurus init), `docs/*.md` siteye kaynak olarak bağlanır.
2. CI job'ı: her PR'da derleme testi (`build`); `main`'e merge'de statik yayın.
3. Yazım kuralı: yeni/degisen prosedür → önce `.md`, sonra PR; site editi yasak.
4. Sürümleme: ilk PROD dalgasında `v1` kesilir; sonraki imaj değişiklikleri yeni sürümle etiketlenir.
```bash
# örnek: yerelde önizleme (komut adları İngilizce orijinal, açıklama Türkçe)
cd docs-site
npm install
npm run build
npm run serve
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| CI derleme testi (bozuk link/Mermaid) | Hatalı PR kırmızıya düşer | CI |
| `docs/*.md` ham okunabilirlik | Git arayüzünde tablolar/diyagramlar anlaşılır | Git web |
| Sürüm kesme (`v1`) | Eski prosedüre sürüm menüsünden erişilir | Yayınlanan site |
## 11. Rollback
1. Bozuk site yayını: önceki CI çıktısına (statik) dönülür; kaynak `.md` etkilenmez.
2. Platform değişikliği (Docusaurus → MkDocs): kaynak `.md` taşındığı için içerik kaybı olmaz; yalnızca `docs-site/` yeniden yazılır.
## 12. Kontrol Listesi
- [ ] `docs-site/` derleniyor, 3 Mermaid (01) render oluyor.
- [ ] CI'da derleme testi her PR'da koşuyor.
- [ ] Siteye elle yazma kapalı (yalnızca CI yayınlıyor).
- [ ] Şablon (`_TEMPLATE.md`) ile yeni doküman açma akışı denendi.
## 13. Açık Sorular
- [ ] Statik sitenin barındırılacağı yer (merkez VDS / iç ağ) (sahibi: 25-ROADMAP).
- [ ] İlk sürüm (`v1`) kesme tarihi — PROD dalgasına bağlı (sahibi: merkezi admin, 21).
- [ ] Türkçe dışına çeviri ihtiyacı (i18n açılacak mı) (sahibi: yönetim).
---
## Ek: Mermaid — doküman akışı
```mermaid
flowchart LR
W["Yazar/ajan<br/>docs/*.md düzenler"] --> PR["PR + review"]
PR --> CI["CI: Docusaurus build testi"]
CI -->|yeşil| MERGE["main'e merge"]
MERGE --> PUB["Statik site yayını"]
PUB --> READ["Okuyucu<br/>(teknisyen/admin)"]
```

View file

@ -0,0 +1,135 @@
# 23 — Güvenlik ve Lisans Denetimi (Security & License Audit)
> Kısa özet: Mimariye giren her ücretli-aday aracın lisans hükmü + ücretsiz karşılığı tek tabloda; AnyDesk'in neden mimariden çıkarıldığı resmi URL'leriyle. Yeni araç öneren önce bu dosyaya bakar.
- Dosya: `docs/23-SECURITY-AND-LICENSE-AUDIT.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-04` (AnyDesk HAYIR + RustDesk/MeshCentral), `#K-06` (Semaphore Community), `#K-07` (Netdata elendi), `#K-10` (Watchtower)
- Durum: [ ] Taslak
---
## 1. Amaç
"Şu aracı da kursak mı?" sorusunun lisans cevabını tek yerde vermek ve 700 cihazda lisanssız ticari kullanımı baştan engellemek. Her satırda resmi kaynak URL'si vardır; kulaktan-dolma lisans bilgisi yasaktır.
## 2. Kapsam
- Kapsam içi: ücretli-aday araçların hükmü, seçilen ücretsiz karşılıklar, AnyDesk HAYIR hükmü, periyodik denetim rutini.
- Kapsam dışı: teknik kurulum (ilgili dokümanlar), firewall/SSH sertleştirme detayı (11-HARDENING).
## 3. Kararlar
```text
KARAR: AnyDesk ücretsiz sürümü Blueforce filosunda KULLANILAMAZ; AnyDesk mimariden çıkarılmıştır.
GEREKÇE: AnyDesk ücretsiz sürümü yalnızca kişisel kullanımı kapsar; 700 kurumsal saha cihazı ticari kullanımdır ve lisanssız kullanım sözleşme ihlali olur. Kurumsal kullanım en az ücretli plan gerektirir; ayrıca kapalı kaynak + self-hosted yalnızca en üst planda sunulur.
ALTERNATİF: Müşteri sahasında zaten lisanslı AnyDesk varsa opsiyonel installer modülü olarak kalabilir (merkezi mimarinin parçası değil) — bunun dışında alternatif yoktur; birincil/ikincil erişim RustDesk OSS + MeshCentral'dır (K-04).
RİSK: Sahada "alışkanlıkla" AnyDesk Free kurulur; azaltma: golden image'da AnyDesk yoktur + periyodik denetimde kurulu yazılım taraması yapılır.
MALİYET: Kullanılmadığı için lisans bedeli yoktur (kullanılsaydı: ücretli plan zorunlu).
LİSANS: AnyDesk lisans şartı — https://support.anydesk.com/docs/anydesk-licenses.md (güncelleme 2025-10-30; doğrulanma: 2026-09-15) + plan listesi https://anydesk.com/en/pricing (doğrulanma: 2026-09-15).
```
```text
KARAR: Zorunlu mimarideki tüm bileşenler FREE katmandadır; ücretli-aday her araç için ücretsiz karşılık aşağıdaki tabloda sabitlenmiştir. Hiçbir playbook, compose veya imaj ücretli özelliğe bağlanamaz.
GEREKÇE: 700 cihazda "küçük" lisans bedeli bile çarpanla büyür; ücretsiz-tabana bağlılık hem maliyeti hem denetim yükünü sıfırlar. Karşılık tablosu, gelecekteki "Pro'ya geçelim" baskısına hazır cevap verir.
ALTERNATİF: İhtiyaç oldukça ücretli plana geçme — maliyet takibi + sözleşme yükü + kilitlenme; elendi.
RİSK: Ücretsiz sürümün kapsamı değişir (upstream fiyat politikası); azaltma: yıllık lisans gözden geçirme (§9 rutin).
MALİYET: Ücretsiz (VDS kira bedeli hariç — altyapı maliyeti, lisans değil).
LİSANS: Bileşen lisansları 24-DECISION-LOG Ek A'da (doğrulama: 2026-09-15).
```
## 4. Neden Bu Karar?
Lisans denetimi "hukuk işi" değil, mimari iştir: ücretli bir bileşen mimariye girerse 700 cihazın tamamı o sözleşmeye kilitlenir. Bu dosya, her ücretli adayı daha teklif aşamasında ücretsiz karşılığıyla eşleştirir; AnyDesk maddesi bunun en sert örneğidir (kişisel-kullanım tuzağı). Güvenlik boyutu da aynı tablodadır: kapalı kaynak + dış kimlik (Tailscale/ZeroTier tipi) hem lisans hem veri-egemenliği riski taşır.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| İhtiyaç oldukça lisans satın alma | Esnek | 700 çarpanı, sözleşme takibi, kilitlenme | Elendi |
| Karma (bazı cihazlar ücretli) | Hedefli harcama | İki sınıf filo, denetim karmaşası | Elendi |
| Yıllık lisanssız "görmezden gelme" | Kısa vadeli kolay | Sözleşme ihlali + denetimde ceza | Yasak |
## 6. Avantajlar
- Denetimde (müşteri/üst yönetim) her satırın resmi URL'si hazırdır.
- Yeni araç teklifi 5 dakikada elenebilir veya kabul edilebilir (tabloya uyar mı?).
## 7. Dezavantajlar
- Upstream fiyat/lisans değişiklikleri takip ister (yıllık rutin).
- Bazı ücretsiz sürümler özelliksizdir (örn. Semaphore Community'de OIDC/2FA/Vault yok) — bu eksikler operasyonel disiplinle kapatılır (K-06).
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| Sahaya lisanssız ticari yazılım kurulur | Orta | Yüksek | İmajda yok + periyodik kurulu-yazılım taraması |
| Upstream free kapsamı daralır | Düşük | Orta | Yıllık gözden geçirme + yedek alternatifler (§9 tablo) |
| AGPL yükümlülüğü ihlali (değişiklik dağıtırsak) | Düşük | Orta | Değişikliksiz self-host politikası (RustDesk/Grafana notu) |
## 9. Uygulama Planı
### Ücretli-aday → ücretsiz-karşılık tablosu (FREE sürümler baz)
| Ücretli aday | Neden girmedi | Ücretsiz karşılık (mimaride) | Lisans / kaynak |
|---|---|---|---|
| AnyDesk (ücretli plan) | Free yalnızca kişisel kullanım; 700 cihaz ticari → ihlal | RustDesk OSS hbbs/hbbr + MeshCentral | AGPL-3.0 / Apache-2.0 — https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/ ; https://github.com/Ylianst/MeshCentral ; hüküm https://support.anydesk.com/docs/anydesk-licenses.md |
| RustDesk Pro | Gerekmez — OSS sınırsız istemci + self-host verir | RustDesk OSS 1.4.9 / sunucu 1.1.16 | AGPL-3.0 — https://rustdesk.com/pricing/ (doğrulanma: 2026-09-15) |
| Semaphore Pro/Enterprise | 700 cihaz > Pro 500 node sınırı; Community yeterli | Semaphore UI Community | MIT, Community $0 — https://semaphoreui.com/pricing + https://github.com/semaphoreui/semaphore |
| Netdata Cloud (ücretli) | Free 5 node kotası 700'de ücrete düşer | Prometheus + Node Exporter + Grafana OSS + Uptime Kuma | Apache-2.0 / AGPL-3.0 / MIT (24 Ek A 23–25) |
| Tailscale / ZeroTier (ücretli kademeler) | Freemium + merkezi kimlik | WireGuard (self-hosted hub-spoke) | OSS — https://www.wireguard.com/quickstart/ |
| Ubuntu Pro / ESM | Mimari ESM'e bel bağlamaz | Ubuntu LTS ücretsiz + onaylı update dalgaları | https://releases.ubuntu.com/ |
| Docker Business / Scout | Mimaride yok | Docker CE + sabit tag disiplini | https://docs.docker.com/ |
| Wiki.js Cloud / Confluence | DB yükü + ücret | Docusaurus (MIT) | https://github.com/facebook/docusaurus |
| AWX (operatör maliyeti) / Salt / Rudder Enterprise | K8s/agent/relay yükü | Ansible CLI + Semaphore Community | GPL-3.0 / MIT — https://github.com/ansible/ansible |
```bash
# örnek: sahada lisanssız/izinsiz yazılım taraması (merkezden)
ansible all -m shell -a "dpkg -l | grep -i -E 'anydesk|teamviewer' || echo TEMIZ"
# örnek: Watchtower kalıntısı taraması (politika ihlali, K-10)
ansible all -m shell -a "docker ps --format '{{.Names}} {{.Image}}' | grep -i watchtower || echo TEMIZ"
```
### Periyodik rutin
1. Üç ayda bir: yukarıdaki taramalar + `latest` etiketi denetimi + `unattended-upgrades` kapalılık kontrolü (K-11).
2. Yılda bir: tablo satırlarındaki resmi URL'ler yeniden çekilir, fiyat/lisans değişikliği varsa bu dosya PR ile güncellenir.
3. Yeni araç teklifi: tabloya satır eklenmeden kuruluma girmez (21'deki onay yetkilisi denetler).
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| İmajda AnyDesk/TeamViewer paketi yok | `dpkg -l` temiz | LAB(2) imaj denetimi |
| İmajda Watchtower yok, `latest` yok | `docker images` sabit tag | LAB(2) |
| `unattended-upgrades` kapalı | Timer'lar maskeli, değerler `0` | LAB(2) |
## 11. Rollback
Lisans değişikliği (upstream free kapsamı daralırsa): yedek alternatife (tablodaki "Yedek" satırları, örn. MkDocs) geçilir; değişiklik 24-DECISION-LOG PR'ı ile yapılır, bu dosya aynı PR'da güncellenir.
## 12. Kontrol Listesi
- [ ] AnyDesk HAYIR hükmü resmi URL'li (§3 birinci blok).
- [ ] Her ücretli-adayın ücretsiz karşılığı tabloda + URL'li.
- [ ] Üç aylık tarama job'ları Semaphore'da tanımlı.
- [ ] Yıllık URL tazeleme takvime işlendi.
## 13. Açık Sorular
- [ ] Üç aylık tarama sonuçlarının raporlanacağı merci (sahibi: merkezi admin, 21).
- [ ] AGPL değişiklik-dağıtım politikasının hukukça gözden geçirilmesi gerekli mi (sahibi: yönetim).
- [ ] Müşteri-lisanslı AnyDesk modülünün şartları (sahibi: 07-REMOTE-ACCESS yazarı).
---
## Ek: Lisans Karar Akışı (yeni araç teklifi)
```mermaid
flowchart TB
TEKLIF["Yeni araç teklifi"] --> UCRET{"Ücretli katman / lisans gerektirir mi?"}
UCRET -->|Hayır (OSS, kotasız)| KABUL["Mimariye alınabilir<br/>(karşılık tablosuna işlenir)"]
UCRET -->|Evet| KARSILIK{"Ücretsiz karşılığı tabloda var mı?"}
KARSILIK -->|Var| RED["Teklif elenir<br/>karşılık kullanılır"]
KARSILIK -->|Yok| PR["24-DECISION-LOG PR'ı açılır<br/>Ek A'ya URL + sürüm + tarih"]
```

358
docs/24-DECISION-LOG.md Normal file
View file

@ -0,0 +1,358 @@
# 24 — Karar Günlüğü (Decision Log)
> Kısa özet: Blueforce 700 cihaz Linux filosunun tüm nihai mimari kararları tek tabloda; her karar KARAR/GEREKÇE/ALTERNATİF/RİSK/MALİYET/LİSANS bloğu + resmi kaynak URL ile. Diğer 25 dokümanın başvurduğu kilit dosyadır.
>
> - Dosya: `docs/24-DECISION-LOG.md`
> - İlgili kararlar: bu dosyanın kendisi kilit kaynaktır; `01-ARCHITECTURE.md` bu kararları diyagramlaştırır.
> - Durum: [x] Onaylı (Faz 2 kilidi; değişiklik bu dosyadan PR ile yapılır)
> - Kural: tüm kararlarda FREE sürümler baz alınır; Pro/Enterprise zorunlu mimariye girmez.
> - Doğrulama günü: 2026-09-15 (tüm URL'ler bu tarihte HTTP 200 ile çekildi; ayrıntı `research/` dosyalarında).
---
## 1. Amaç
27 izlenebilirlik sorusunun (bkz. §13 ve Ek B) her birinin hangi karara dayandığını tek yerden göstermek; kararsız veya varsayıma dayalı seçim bırakmamak.
## 2. Kapsam
- Kapsam içi: OS/GUI/boot, 4 erişim kanalı, WireGuard, fleet, monitoring, docs, golden image, Docker, cihaz kimliği, update dalgaları — aşağıdaki K-01…K-14 kararları.
- Kapsam dışı: script kodları, VDS kurulum komutları, gerçek cihaz test sonuçları (Faz 3+ işi; ilgili dokümanlara havale edilir).
## 3. Kararlar
### K-01 — Baz işletim sistemi ve sürüm
```text
KARAR: Saha standardı Ubuntu Server 26.04.1+ LTS'tir (GUI'siz minimal kurulum; GNOME sonradan eklenir).
GEREKÇE: 26.04.1 LTS resmi indirme sayfasında yayında (kod adı Resolute Raccoon); Server ISO'su varsayılan olarak GUI kurmaz, minimal zemin + ihtiyaca göre GUI standart yoldur. Noktasürüm (.1+) baz alınır çünkü ilk .0 dalgasındaki kurulumcu hataları genelde .1'de toplanır (LAB imaj testiyle kesinleşir).
ALTERNATİF: Ubuntu 24.04 LTS — 26.04 doğrulanamasaydı yedekti; doğrulandığı için yedekte bekler. Ubuntu Desktop 26.04 (6 GB RAM şartı) saha bütçesini zorladığı için elendi.
RİSK: 26.04.x noktasürümlerinde donanım sürücü farkı; azaltma: golden image LAB(2)'de her saha donanım profilinde test edilir.
MALİYET: Ücretsiz.
LİSANS: Ubuntu LTS ücretsiz (açık kaynak bileşenler; ESM kapsamına bel bağlanmaz) — https://releases.ubuntu.com/ (26.04.1, doğrulanma: 2026-09-15) + https://ubuntu.com/download/desktop (sistem gereksinimi, doğrulanma: 2026-09-15).
```
### K-02 — Masaüstü ortamı (GNOME)
```text
KARAR: Saha masaüstü ortamı GNOME'dur (Ubuntu Desktop standardı); XFCE elendi.
GEREKÇE: Kullanıcı kararı + Ubuntu Desktop standardı: tanıdık modern masaüstü, teknisyen akışıyla birebir uyum.
ALTERNATİF: XFCE — hafif ve düşük kaynak tüketimine rağmen kullanıcı kararıyla elendi; yedekte tutulmaz.
RİSK: xRDP+GNOME kombinasyonu ek ayar isteyebilir (uyarı: GNOME oturumu RDP'de ek yapılandırma gerektirebilir); azaltma: 13-MEG-LINUX-ACCEPTANCE testi GNOME üzerinde koşar, `bf-gui-*` LAB'da 26.04.1 imajında doğrulanmadan dondurulmaz.
MALİYET: Ücretsiz.
LİSANS: GNOME (GPL/LGPL bileşenler), ücretsiz — https://www.gnome.org/ (doğrulanma: 2026-09-15).
```
### K-03 — Boot davranışı ve GUI aç/kapa
```text
KARAR: Cihazlar terminale (multi-user) boot eder; grafik katman `bf-gui-on` / `bf-gui-off` ile systemd üzerinden açılıp kapatılır.
GEREKÇE: xRDP mimarisi oturum yöneticisi (sesman) + systemd servis birimleri (`xrdp`, `xrdp-sesman`) üzerine kuruludur; GUI, display-manager + xRDP servisleri üzerinden yönetilebilir bir katman olarak modellenir. Varsayılan kapalı GUI = düşük RAM, düşük saldırı yüzeyi, öngörülebilir boot.
ALTERNATİF: Her zaman grafik boot — kaynak israfı ve 700 cihazda gereksiz hata yüzeyi nedeniyle elendi.
RİSK: Kesin birim adları ve GNOME oturum başlatma satırı 26.04.1'e göre değişebilir; azaltma: LAB'da 26.04.1 imajında doğrulanmadan `bf-gui-*` dondurulmaz.
MALİYET: Ücretsiz.
LİSANS: xRDP Apache-2.0, ücretsiz — https://github.com/neutrinolabs/xrdp (v0.10.6.1, 2026-07-07; doğrulanma: 2026-09-15).
```
### K-04 — Uzaktan erişim kanalları (4 kanal)
```text
KARAR: Dört erişim kanalı: (1) SSH-over-WireGuard (yönetim/otomasyon), (2) xRDP + GNOME (grafik bakım), (3) RustDesk OSS self-hosted hbbs/hbbr (birincil grafik uzak erişim, WireGuard-bağımsız), (4) MeshCentral self-hosted (ikincil yönetim: terminal/dosya/envanter, WireGuard-bağımsız). AnyDesk mimariden ÇIKARILDI.
GEREKÇE: RustDesk OSS sınırsız istemci, kendi ID+röle altyapısı, E2E şifreli oturum, dosya transferi ve katılımsız erişimi ücretsiz verir; istemcide VDS genel adresi kullanıldığında WireGuard çökse bile kanal ayakta kalır. MeshCentral Apache-2.0 ile ikinci bağımsız düzlemi sağlar. AnyDesk ücretsiz sürümü yalnızca kişisel kullanımı kapsar; 700 kurumsal cihaz ticari kullanımdır ve lisanssız kullanım ihlal olur (en az Advanced planı gerekirdi).
ALTERNATİF: AnyDesk (lisans maliyeti + kapalı kaynak + self-hosted yalnızca en üst planda → elendi; yalnızca müşteri sahasında zaten lisanslıysa opsiyonel installer modülü). Tailscale/ZeroTier (freemium, merkezi kimlik → elendi).
RİSK: İki VDS-bağımlı kanalın tek ortak noktası VDS + genel internet; azaltma: hbbs/hbbr `--net=host` + health monitörü (Uptime Kuma) + yedek VDS planı 17-RECOVERY'de.
MALİYET: Ücretsiz (kendi VDS'i üzerinde; VDS kira bedeli hariç — altyapı maliyeti, lisans değil).
LİSANS: RustDesk istemci+sunucu AGPL-3.0 (1.4.9 / 1.1.16) — https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/ + https://rustdesk.com/docs/en/self-host/client-deployment/ (doğrulanma: 2026-09-15); MeshCentral Apache-2.0 (1.2.5) — https://github.com/Ylianst/MeshCentral (doğrulanma: 2026-09-15); AnyDesk hükmü — https://support.anydesk.com/docs/anydesk-licenses.md (doğrulanma: 2026-09-15) + https://anydesk.com/en/pricing.
```
### K-05 — WireGuard modeli
```text
KARAR: Hub-spoke WireGuard: merkez sunucu hub, her saha cihazı spoke (peer adı = `bf-<8hane>`); istemcide `PersistentKeepalive = 25` + `wg-quick@wg0` systemd enable; RDP/SSH dış dünyaya kapalı, yalnızca WireGuard arkasında.
GEREKÇE: Resmi QuickStart NAT arkasındaki eş için 25 sn keepalive'i "geniş güvenlik-duvarı yelpazesiyle çalışan makul aralık" olarak verir; `wg-quick@.service` Ubuntu paketinden gelir, enable = açılışta otomatik VPN. Elektrik kesintisi sonrası cihaz açılınca VPN kendiliğinden gelir.
ALTERNATİF: Keepalive kapalı / agresif 10 sn — kapalı NAT eşlemesini düşürür, agresif değer saha verisi olmadan yazılmaz; PİLOT-1 kopma sayacına göre ayarlanır.
RİSK: Turkcell CGNAT davranışı resmi kaynaktan doğrulanamaz (operatör bilgisi); azaltma: PİLOT-1'de 7/24 kopma sayacı, aralık saha verisiyle ayarlanır.
MALİYET: Ücretsiz.
LİSANS: WireGuard OSS (Ubuntu paketi `wireguard-tools 1.0.20250521-1ubuntu1`) — https://www.wireguard.com/quickstart/ + https://packages.ubuntu.com/resolute/wireguard-tools (doğrulanma: 2026-09-15).
```
### K-06 — Filo yönetimi
```text
KARAR: Birincil filo otomasyonu Ansible CLI (SSH, agent'sız); operatör arayüzü Semaphore UI Community (self-hosted, MIT). Hiçbir playbook Pro/Enterprise özelliğine bağlanmaz.
GEREKÇE: En düşük hareketli parça (SSH + YAML + tek Go binary); 700 cihazda ek agent/master/K8s maliyeti yok. Community ücretsizliği resmi fiyat sayfasıyla kanıtlı ("$0, free forever"); Pro en fazla 500 managed node desteklediği için 700 cihazda ücretli yol zaten kapalı.
ALTERNATİF: AWX (K8s yükü + release'ler refactoring nedeniyle duraklatıldı → elendi); Salt (minion agent + master PKI → elendi); Rudder Community (relay/Enterprise modülleri + öğrenme eğrisi → elendi); MeshCentral (erişim aracı, filo otomasyonu değil → bu rolde elendi).
RİSK: Semaphore tek nokta arızası → Ansible CLI bağımsız çalışır (UI çökse filo durmaz). Community'de OIDC/2FA/Vault yok → Semaphore yalnızca WireGuard arkasında, erişim VPN + SSH anahtarı ile; gizliler yerleşik şifreli Key Store'da.
MALİYET: Ücretsiz (kendi VDS'i üzerinde).
LİSANS: Ansible GPL-3.0 — https://github.com/ansible/ansible; Semaphore Community MIT — https://github.com/semaphoreui/semaphore + https://semaphoreui.com/pricing (doğrulanma: 2026-09-15).
```
### K-07 — Monitoring
```text
KARAR: Birincil Prometheus + Node Exporter + Grafana OSS (17 metriğin tamamı); tamamlayıcı Uptime Kuma (saha-teknisyeni dostu UP/DOWN panosu + Push "last seen" + bildirimler). Netdata elendi.
GEREKÇE: 17 metriğin tamamı yalnızca Prometheus yığınında ücretsiz ve kotasız toplanır (WireGuard handshake, Docker, MEG sağlığı textfile collector ile). Netdata Cloud Free 5 node kotası 700 cihazda ücrete düşer. Uptime Kuma metrik vermez ama en basit çevrimdışı alarmını verir (20 sn aralık, 90+ bildirim servisi, tek konteyner).
ALTERNATİF: Yalnızca Uptime Kuma (metrik körlüğü → elendi); Netdata self-hosted Parent (merkezi tasarım yükü + kota riski → elendi).
RİSK: 700 node'da saklama/kardinalite; azaltma: scrape 60 sn, retention 30–90 gün, etiket şeması `BF-<no>` standardında, federasyon/fazlı rollout.
MALİYET: Ücretsiz.
LİSANS: Prometheus/Node Exporter Apache-2.0 — https://github.com/prometheus/prometheus + https://prometheus.io/docs/guides/node-exporter/; Grafana OSS AGPL-3.0 (değişikliksiz self-host) — https://grafana.com/oss/; Uptime Kuma MIT — https://github.com/louislam/uptime-kuma (doğrulanma: 2026-09-15).
```
### K-08 — Doküman platformu
```text
KARAR: Docusaurus (`docs-site/` iskeleti; `docs/*.md` tek kaynak, site derlemesi CI'da).
GEREKÇE: "AI-güncelleme" kriterini yalnızca Git-yerleşik Markdown çözer (ajan `.md`'yi doğrudan yazar, review PR'dan geçer). Wiki.js'nin DB+servis yükü sadelik kuralını bozar; TriliumNext tek-kullanıcı bilgi tabanıdır. MkDocs'a karşı Docusaurus: yerleşik sürümleme + yerleşik i18n + MDX; derleme maliyeti eşdeğerdir.
ALTERNATİF: MkDocs + Material (eşdeğer sadelikte güçlü ikinci; Docusaurus derleme hattı sorun çıkarırsa geçiş maliyeti düşük çünkü kaynak yine düz Markdown — yedekte tutulur). Wiki.js (DB yükü → elendi). TriliumNext (ekip akışı yok → elendi).
RİSK: Node derleme hattı bozulabilir; azaltma: kilitli bağımlılıklar + CI derleme testi; derleme bozulsa bile `docs/*.md` ham haliyle okunur.
MALİYET: Ücretsiz.
LİSANS: Docusaurus MIT — https://github.com/facebook/docusaurus + https://docusaurus.io/docs/markdown-features/diagrams (doğrulanma: 2026-09-15).
```
### K-09 — Golden image yöntemi
```text
KARAR: Golden image = Ubuntu Server 26.04.1+ minimal + `unattended-upgrades` kapalı + `blueforce-install.sh` tek kurucu (bayi no → READY); imaj, preseed/autoinstall dosyasıyla üretilir, cihaz-spesifik kimlik (`bf-<no>`) imajda DEĞİL ilk açılışta verilir.
GEREKÇE: Donanım heterojenliği bilinmediği için bit-kopya klon (Clonezilla) tek imajda kırılgandır; autoinstall + idempotent kurulum scripti her donanım profilinde aynı zemini kurar, kimlik ilk boot'ta enjekte edilir. Hedef akış: USB → Ubuntu → tek script → bayi no → READY.
ALTERNATİF: Clonezilla bit-kopya (hızlı ama donanım-fragil → yedek yöntem olarak tutulur); Packer/custom ISO (ek derleme hattı yükü → elendi); cloud-init (autoinstall'a göre saha-USB akışına daha az uygun → elendi).
RİSK: İlk imaj heterojen donanımda sürücü eksiltebilir; azaltma: önce `bf-hardware-inventory.sh` taraması (18-ROLLOUT), LAB'da her profilde test.
MALİYET: Ücretsiz.
LİSANS: Ubuntu autoinstall/subiquity (ücretsiz, Ubuntu lisans seti içinde) — https://releases.ubuntu.com/26.04/ (doğrulanma: 2026-09-15). NOT: Faz 1'de resmi autoinstall sözdizimi ayrıca doğrulanmadı; kesin direktifler 04-GOLDEN-IMAGE'da LAB çıktısıyla yazılır.
```
### K-10 — Docker restart politikası ve imaj disiplini
```text
KARAR: Tüm saha konteynerlerinde restart politikası `unless-stopped`; `latest` etiketi yasak (sabit tag zorunlu); Watchtower yok; log rotasyonu (`max-size`/`max-file`) daemon.json'da zorunlu; yayımlanan portlar `127.0.0.1`'e bağlanır (UFW bypass'a karşı).
GEREKÇE: `unless-stopped`, `always`'in aksine teknisyenin bakım için durdurduğu konteyneri reboot sonrası sürpriz kalkıştan korur; elektrik kesintisi kurtarması aynen çalışır (kesinti "manuel stop" sayılmaz). Hareketli `latest` etiketi 700 cihazda determinizmi bozar ("onaysız update yasak" politikası). Watchtower hem politikayı ihlal eder (otomatik updater) hem upstream'de arşivlenmiştir. Docker varsayılan `json-file` logu rotasyon yapmaz → dolan disk = kilitlenen cihaz. Docker yayımlanan portlarda UFW'yi baypas eder (resmi belgeli) → localhost-bind + WireGuard üzerinden erişim.
ALTERNATİF: `always` (öngörülemez bakım davranışı → elendi); `iptables:false` (resmi doküman "çoğu kullanıcı için uygun değil" diye uyarır → varsayılan çözüm değil); digest pinleme (`@sha256`) PİLOT-2'de değerlendirilecek ek sıkılık adımı.
RİSK: `max-size/max-file` değerleri MEG log hacmine göre ayarlanmazsa ya disk dolar ya log kaybolur; azaltma: PİLOT'ta hacim ölçülür, 12-DOCKER'da sabitlenir.
MALİYET: Ücretsiz (Docker CE).
LİSANS: Docker CE ücretsiz (Business/Scout mimaride yok) — https://docs.docker.com/engine/containers/start-containers-automatically/ + https://docs.docker.com/engine/logging/configure/ + https://docs.docker.com/engine/network/packet-filtering-firewalls/ (doğrulanma: 2026-09-15); Watchtower arşiv durumu — https://github.com/containrrr/watchtower (doğrulanma: 2026-09-15).
```
### K-11 — Otomatik güncelleme yasağı
```text
KARAR: Golden image'da `unattended-upgrades` kapatılır (`/etc/apt/apt.conf.d/20auto-upgrades` değerleri `0` + `apt-daily*.timer` maskeleme); tüm güncellemeler LAB→PİLOT→WAVE→PROD onay zincirinden geçer (dalgalar: LAB(2)/P1(5)/P2(20)/W1(50)/W2(100)/PROD).
GEREKÇE: `unattended-upgrades` Ubuntu Server'da varsayılan kurulu ve etkindir, günde bir kez çalışır; kapatılmazsa 700 cihaz ilk açılışta güncellemeye kalkar ("onaysız update yasak" ilkesi delinir). Kaçan timer makine açılışında hemen tetiklenir (`Persistent=true` davranışı) — saha PC'leri sık kapanan makinelerdir.
ALTERNATİF: Otomatik security update'e izin verme — 700 cihazda eşzamanlı indirme + onaysız değişim riski nedeniyle elendi; security update'ler öncelik işaretli onaylı dalga ile çıkar.
RİSK: Kapatma adımı imajda atlanırsa filo kendiliğinden güncellenir; azaltma: `blueforce-install.sh` final-check + monitoring'de `Unattended-Upgrade` durumu metriği.
MALİYET: Ücretsiz.
LİSANS: Yok (işletim sistemi yapılandırması) — https://ubuntu.com/server/docs/how-to/software/automatic-updates/ + https://manpages.ubuntu.com/manpages/resolute/en/man8/unattended-upgrade.8.html (doğrulanma: 2026-09-15).
```
### K-12 — Cihaz kimliği standardı
```text
KARAR: 8 haneli bayi no → Device ID `BF-<no>` (büyük), hostname `bf-<no>` (küçük); WireGuard peer adı, RustDesk etiketi, Ansible inventory adı, monitoring etiketi hepsi aynı ID'yi kullanır. Örnek: `BF-12010193` / `bf-12010193`.
GEREKÇE: Tek kimlik = 9 sistemde (DNS/hostname, WireGuard, RustDesk, MeshCentral, Ansible, Prometheus, log, envanter, runbook) join anahtarı; büyük/küçük ayrımı insan-makine karışıklığını önler (insan `BF-`, makine `bf-`).
ALTERNATİF: Rastgele UUID / MAC-tabanlı ad — saha teknisyeni için okunamaz, bayi eşleşmesi manuel olur → elendi.
RİSK: Bayi no değişirse kimlik çakışması; azaltma: 02-NAMING'de yeniden-no prosedürü + envanter benzersizlik kontrolü.
MALİYET: Ücretsiz.
LİSANS: Yok (isimlendirme standardı).
```
### K-13 — SSH kimlik doğrulama mimarisi
```text
KARAR: `blueforce` bakım kullanıcısı + anahtar zorunlu (password SSH kapalı, root SSH kapalı); 700 cihaza tek private key YAYILMAZ — admin başına anahtar + cihazlarda `authorized_keys` merkezi dağıtımı (Ansible), uzun vadede SSH CA hedefi.
GEREKÇE: Tek private key'in sızıntı blast-radius'u 700 cihazdır; per-admin anahtar + merkezi dağıtım sızıntıyı tek anahtarın iptaline indirger. Servisler ayrı system user ile çalışır, sudo kontrollüdür.
ALTERNATİF: Tek paylaşılan private key (basit ama 700 cihazlık blast-radius → elendi); password auth (kaba-kuvvet yüzeyi → elendi).
RİSK: Anahtar dağıtım gecikmesi yeni cihazda erişimsizlik; azaltma: golden image'da bootstrap anahtarı + ilk Ansible run'ında rotasyon.
MALİYET: Ücretsiz.
LİSANS: OpenSSH (BSD-lisanslı), ücretsiz.
```
### K-14 — Log ve sağlık disiplini
```text
KARAR: Birincil metrik/monitoring K-07; log tarafında journald + Docker `json-file` rotasyonlu + textfile `.prom` (WireGuard handshake, Docker, MEG) + `bf-status` / `bf-diagnostics` / `bf-support-bundle` (secret sızdırmaz) sözleşmeleri.
GEREKÇE: 700 dokunulmaz cihazda logsuz metrik kör, metriksiz log sağırdır; textfile collector özel metriklerin (WireGuard/MEG) standart Prometheus yoludur. Support-bundle secret dışlama kuralıyla güvenli uzaktan tanı sağlar.
ALTERNATİF: Harici log platformu (Loki/ELK) ilk fazda — ek servis yükü, sadelik kuralını bozar → Faz-sonrası hedef olarak 15-LOGGING'e not edilir.
RİSK: Log hacmi retention'ı şişirir; azaltma: PİLOT'ta hacim ölçümü + limitler 15-LOGGING'de.
MALİYET: Ücretsiz.
LİSANS: systemd-journald / Node Exporter textfile (Apache-2.0) — https://github.com/prometheus/node_exporter (doğrulanma: 2026-09-15).
```
---
## 4. Neden Bu Karar?
Tüm kararlarda aynı üç filtre uygulandı: (1) %100 ücretsiz/self-hosted — resmi URL + sürüm + tarih olmadan lisans iddiası yazılmadı; (2) sadelik — Kubernetes, microservice, gereksiz agent/DB/cloud önerisi reddedildi (AWX'in K8s zorunluluğu, Salt master PKI, Wiki.js DB yükü, harici log platformu); (3) onaysız update yasağı — unattended-upgrades, `latest`, Watchtower aynı ilkeden elendi. 700 ölçeğinde her "küçük varsayılan" (günlük otomatik update, rotasyonsuz log, UFW bypass) filo-çapı arızaya dönüşür; kararlar bu çarpanı küçültür.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Ubuntu 24.04 LTS | Olgun donanım desteği | 26.04 doğrulandı, daha kısa destek penceresi | Yedek |
| XFCE | Hafif, düşük kaynak | Kullanıcı kararıyla elendi (saha standardı GNOME) | Elendi |
| AnyDesk | Tanınmış, kolay | Ticari lisans zorunlu (700 cihaz), kapalı kaynak | Elendi |
| Tailscale/ZeroTier | Kolay mesh | Freemium, merkezi kimlik | Elendi |
| AWX | Güçlü UI | K8s zorunlu, release'ler duraklatıldı | Elendi |
| Salt / Rudder | Ölçeklenir | Agent+master/relay yükü, öğrenme eğrisi | Elendi |
| Netdata Cloud | Zengin agent | Free 5 node kotası, 700 cihaz ücretli | Elendi |
| Yalnızca Uptime Kuma | Çok kolay | Metrik körlüğü | Elendi |
| Wiki.js | Güçlü editör | DB+servis yükü, Git akışı dolaylı | Elendi |
| MkDocs + Material | Eşdeğer sade | Sürümleme/i18n eklentiyle | Yedek (güçlü ikinci) |
| TriliumNext | Hafif | Tek kullanıcı, ekip akışı yok | Elendi |
| Clonezilla bit-kopya | Hızlı klon | Donanım-fragil | Yedek yöntem |
| Docker `always` | Her koşulda ayakta | Bakım-stop'u reboot'ta deler | Elendi |
| Watchtower | Otomatik imaj | Politika ihlali + arşivlenmiş upstream | Elendi |
| Tek paylaşılan SSH key | Basit | 700 cihazlık blast-radius | Elendi |
## 6. Avantajlar
- 14 kararın tamamı ücretsiz katmanda kanıtlı; zorunlu mimaride lisans bedeli yok.
- Her kararın resmi kaynak URL'si + sürümü + doğrulama tarihi var; varsayıma dayalı karar yok (belirsizler LAB/PİLOT'a havale edildi).
- 4 erişim kanalından ikisi WireGuard-bağımsız; tek tünel arızası filoyu kör etmez.
## 7. Dezavantajlar
- K-09 (golden image) Faz 1'de tam resmi-doğrulamalı değil; autoinstall sözdizimi LAB çıktısına bağımlı.
- Semaphore Community'de OIDC/2FA/Vault yokluğu operasyonel disiplinle (VPN-arkası + Key Store) kapatılıyor; bu disiplin bozulursa güvenlik açığı doğar.
- Prometheus 700 node işletme bilgisi ister; retention/kardinalite LAB'da ölçülmeden donanım siparişi verilmemeli.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| `unattended-upgrades` imajda açık unutulur | Orta | Yüksek (filo kendiliğinden güncellenir) | install.sh final-check + monitoring metriği (K-11) |
| Docker UFW bypass ile MEG portu dışa açılır | Orta | Yüksek | localhost-bind standardı + 11-HARDENING denetimi (K-10) |
| Semaphore çöker, filo yönetimsiz kalır | Düşük | Orta | Ansible CLI bağımsız çalışır (K-06) |
| 26.04.x sürücü farkı heterojen donanımda | Orta | Orta | LAB'da profil başına imaj testi (K-01/K-09) |
| Tek VDS iki bağımsız kanalı da barındırırsa ortak arıza | Düşük | Yüksek | hbbs/hbbr + MeshCentral ayrı VDS veya yedek planı (K-04) |
| 700 node Prometheus kardinalite patlaması | Orta | Orta | 60 sn scrape, 30–90 gün retention, `BF-<no>` etiket şeması (K-07) |
## 9. Uygulama Planı
1. Golden image'a K-01/K-02/K-03/K-10/K-11 uygulanır (04-GOLDEN-IMAGE).
2. WireGuard hub + ilk peer'lar K-05'e göre kurulur (08-WIREGUARD).
3. hbbs/hbbr + MeshCentral VDS'leri K-04'e göre ayağa kaldırılır (07-REMOTE-ACCESS).
4. Ansible + Semaphore K-06'ya göre kurulur; ilk playbook LAB(2)'de koşar (09-FLEET).
5. Prometheus + Uptime Kuma K-07'ye göre kurulur; 17 metrik LAB'da doğrulanır (14-MONITORING).
6. Update zinciri K-11 dalgalarıyla işletilir (10-UPDATE).
```bash
# örnek: cihaz kimliği standardı (K-12)
hostnamectl set-hostname bf-12010193
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| `20auto-upgrades` değerleri `0`, timer'lar maskeli | Otomatik apt çalışmaz | LAB(2) imaj denetimi |
| `bf-gui-on/off` sonrası RDP oturumu | GNOME oturumu açılır/kapanır | LAB(2) |
| WireGuard down iken RustDesk oturumu | Bağlantı kurulur (bağımsız kanal) | P1(5) |
| `docker inspect` restart politikası | `unless-stopped` tüm saha konteynerlerinde | LAB(2) |
| Semaphore kapalı iken Ansible CLI run | Playbook başarıyla koşar | LAB(2) |
| Scrape + 17 metrik + Uptime Push | Grafana + Kuma panoları dolu | P1(5) |
## 11. Rollback
1. Yanlış karar tespitinde bu dosya PR ile düzeltilir; bağımlı dokümanlar (01, 03, 07, 08, 09, 12, 14) aynı PR'da güncellenir.
2. İmaj-kritik karar (K-01/K-11) geri alınırsa golden image yeniden üretilir, sahaya sürülmüş dalga 10-UPDATE rollback zinciriyle geri alınır.
3. Son çare: karar öncesi imaj sürümüne dönüş (17-RECOVERY LEVEL 9).
## 12. Kontrol Listesi
- [ ] 14 kararın her birinde KARAR/GEREKÇE/ALTERNATİF/RİSK/MALİYET/LİSANS + kaynak URL var.
- [ ] Ücretli hiçbir araç zorunlu mimaride değil; AnyDesk hükmü resmi URL'li.
- [ ] `unattended-upgrades`, `latest`, Watchtower yasakları üç dosyada da tutarlı (03/10/12).
- [ ] Ek B'deki 27 sorunun her biri ≥1 karara bağlı (boş hücre yok).
## 13. Açık Sorular
- [ ] GNOME oturum başlatma satırı + `bf-gui-*` kesin birim listesi — LAB 26.04.1 imajında (sahibi: Faz 3, 03/04 yazarları).
- [ ] MEG log hacmine göre `max-size/max-file` kesin değerleri — PİLOT ölçümü (sahibi: 12-DOCKER yazarı).
- [ ] Turkcell NAT kopma sayacı + keepalive ayarı — P1 7/24 sayaç (sahibi: 08-WIREGUARD yazarı).
- [ ] Digest pinleme (`@sha256`) kararı — PİLOT-2 değerlendirmesi (sahibi: 12-DOCKER yazarı).
- [ ] Prometheus retention/kardinalite hesabı (700 × 60 sn) — LAB ölçümü (sahibi: 14-MONITORING yazarı).
- [ ] Semaphore Global Runner sayısı + eşzamanlılık — 700 node yük testi (sahibi: 09-FLEET yazarı).
---
## Ek A: Kaynak Tablosu (URL + sürüm + tarih)
| # | Kaynak | Sürüm/tarih |
|---|---|---|
| 1 | https://releases.ubuntu.com/ | 26.04.1 LTS Resolute Raccoon, 2026-09-15 |
| 2 | https://releases.ubuntu.com/26.04/ | Server GUI kurmaz notu, 2026-09-15 |
| 3 | https://ubuntu.com/download/desktop | 2 GHz / 6 GB / 25 GB, 2026-09-15 |
| 4 | https://ubuntu.com/server/docs/how-to/software/automatic-updates/ | güncel Server docs, 2026-09-15 |
| 5 | https://manpages.ubuntu.com/manpages/resolute/en/man8/unattended-upgrade.8.html | 2.12ubuntu9, 2026-09-15 |
| 6 | https://www.gnome.org/ | Desktop standardı beyanı, 2026-09-15 |
| 7 | https://github.com/neutrinolabs/xrdp | v0.10.6.1 (2026-07-07), 2026-09-15 |
| 8 | https://www.wireguard.com/quickstart/ | keepalive 25 sn, 2026-09-15 |
| 9 | https://packages.ubuntu.com/resolute/wireguard-tools | 1.0.20250521-1ubuntu1, 2026-09-15 |
| 10 | https://docs.docker.com/engine/network/packet-filtering-firewalls/ | UFW bypass, 2026-09-15 |
| 11 | https://docs.docker.com/engine/logging/configure/ | log rotasyon, 2026-09-15 |
| 12 | https://docs.docker.com/engine/containers/start-containers-automatically/ | unless-stopped, 2026-09-15 |
| 13 | https://github.com/containrrr/watchtower | arşivli, 2026-09-15 |
| 14 | https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/ | mimari hbbs/hbbr, 2026-09-15 |
| 15 | https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/docker/ | compose + portlar, 2026-09-15 |
| 16 | https://rustdesk.com/docs/en/self-host/client-deployment/ | OSS toplu dağıtım, 2026-09-15 |
| 17 | https://rustdesk.com/pricing/ | Individual ~11,88 / Basic ~23,88 USD/ay, 2026-09-15 |
| 18 | https://support.anydesk.com/docs/anydesk-licenses.md | ticari lisans şartı (güncelleme 2025-10-30), 2026-09-15 |
| 19 | https://anydesk.com/en/pricing | Solo/Standard/Advanced/Ultimate, 2026-09-15 |
| 20 | https://github.com/Ylianst/MeshCentral | 1.2.5 (2026-08-12), Apache-2.0, 2026-09-15 |
| 21 | https://github.com/ansible/ansible | GPL-3.0, 2026-09-15 |
| 22 | https://github.com/semaphoreui/semaphore + https://semaphoreui.com/pricing | MIT, Community $0, 2026-09-15 |
| 23 | https://github.com/prometheus/prometheus + https://prometheus.io/docs/guides/node-exporter/ | Apache-2.0, 2026-09-15 |
| 24 | https://grafana.com/oss/ | AGPL-3.0 OSS, 2026-09-15 |
| 25 | https://github.com/louislam/uptime-kuma | MIT, 2026-09-15 |
| 26 | https://github.com/facebook/docusaurus + https://docusaurus.io/docs/markdown-features/diagrams | MIT, 2026-09-15 |
| 27 | https://github.com/prometheus/node_exporter | textfile collector, 2026-09-15 |
---
## Ek B: 27 Soru → Karar İzlenebilirliği
> NOT: `SUMMARY.md` Faz 4'te üretilecek; aşağıdaki S-01…S-27 listesi şartname + plandaki 27 kritik sorunun Faz 2 karşılığıdır. SUMMARY yazıldığında her cevap buradaki karara linklenecek.
| # | Soru | Karar | Doküman |
|---|---|---|---|
| S-01 | Hangi Ubuntu sürümü? | K-01 (Server 26.04.1+ LTS) | 03-UBUNTU-BASELINE |
| S-02 | Server mı Desktop mı? | K-01 (Server, GUI'siz kurulum) | 03 |
| S-03 | GNOME mu XFCE mi? | K-02 (GNOME; XFCE elendi) | 03, 07 |
| S-04 | Boot terminale mi grafiğe mi? | K-03 (terminal + bf-gui-on/off) | 03, 16 |
| S-05 | SSH nasıl (kullanıcı, auth, root)? | K-13 (key zorunlu, root kapalı) | 06 |
| S-06 | 700 cihazda tek key riski nasıl çözülür? | K-13 (per-admin key + CA hedefi) | 06 |
| S-07 | RDP hangi sunucu/masaüstü ile? | K-03 (xRDP + GNOME) | 07 |
| S-08 | RustDesk OSS neyi kapsar, Pro gerekir mi? | K-04 (OSS yeterli, Pro yok) | 07 |
| S-09 | WireGuard çökerse uzak erişim sürer mi? | K-04 (RustDesk/MeshCentral bağımsız) | 07, 08 |
| S-10 | 4. erişim kanalı hangisi? | K-04 (MeshCentral) | 07 |
| S-11 | AnyDesk ücretsiz kullanılabilir mi? | K-04 (HAYIR — mimariden çıkarıldı) | 07, 23 |
| S-12 | WireGuard modeli + keepalive + otomatik reconnect? | K-05 (hub-spoke, 25 sn, wg-quick enable) | 08 |
| S-13 | RDP/SSH dış dünyaya açık mı? | K-05 (hayır — WireGuard arkası) | 08, 11 |
| S-14 | Filo yönetimi hangi araç? | K-06 (Ansible + Semaphore Community) | 09 |
| S-15 | Semaphore Pro gerekir mi? | K-06 (hayır — kanıtlı) | 09, 23 |
| S-16 | Monitoring hangi yığın, 17 metrik nasıl? | K-07 (Prometheus + Kuma) | 14 |
| S-17 | Çevrimdışı/last-seen nasıl izlenir? | K-07 (`up` + Push monitör) | 14 |
| S-18 | Onaysız update politikası nedir? | K-11 (yasak + dalgalı onay zinciri) | 10 |
| S-19 | `unattended-upgrades` ne olacak? | K-11 (imajda kapalı) | 03, 10 |
| S-20 | Update dalgaları neler? | K-11 (LAB(2)/P1(5)/P2(20)/W1(50)/W2(100)/PROD) | 10, 18 |
| S-21 | Docker restart politikası ne? | K-10 (`unless-stopped`) | 12 |
| S-22 | `latest` / Watchtower serbest mi? | K-10 (ikisi de yasak) | 12 |
| S-23 | Docker + UFW çakışması nasıl çözülür? | K-10 (localhost-bind) | 11, 12 |
| S-24 | Log disiplini nedir? | K-10 + K-14 (rotasyon + textfile + bundle) | 12, 15 |
| S-25 | Golden image yöntemi ne? | K-09 (autoinstall + install.sh) | 04, 05 |
| S-26 | Cihaz kimliği standardı ne? | K-12 (`BF-<no>` / `bf-<no>`) | 02 |
| S-27 | Doküman platformu hangisi? | K-08 (Docusaurus) | 22 |
---
## Ek: Karar Haritası (hangi soru hangi karara?)
```mermaid
flowchart LR
SORU["27 soru (Ek B)<br/>S-01…S-27"] --> ZEMIN["Zemin: K-01/K-02/K-03<br/>K-09/K-10/K-11/K-12"]
SORU --> AG["Ağ + erişim: K-04/K-05/K-13"]
SORU --> OPS["Operasyon: K-06/K-07/K-14"]
SORU --> DOC["Docs: K-08"]
ZEMIN --> D1["03/04/05/10/12/02"]
AG --> D2["07/08/06/11"]
OPS --> D3["09/14/15"]
DOC --> D4["22"]
```

View file

@ -0,0 +1,122 @@
# 25 — Uygulama Yol Haritası (Implementation Roadmap)
> Kısa özet: Blueforce 700 cihaz projesinin FAZ'lı yol haritası: FAZ 0 hazırlık → FAZ 1 merkez → FAZ 2 imaj → FAZ 3 LAB/P1 → FAZ 4 dalgalar → FAZ 5 PROD + işletme. Katılımsız provisioning (unattended) ayrı FAZ'dır; temel akış çalışmadan otomasyona geçilmez.
- Dosya: `docs/25-IMPLEMENTATION-ROADMAP.md`
- İlgili kararlar: `24-DECISION-LOG.md#K-09` (imaj + unattended sırası), `#K-11` (dalgalar), tüm K-01…K-14 (fazlara dağılım)
- Durum: [ ] Taslak
---
## 1. Amaç
Projeyi "ne, hangi sırada, hangi kapıdan geçerek" sorusuyla yönetmek. Her FAZ'ın girişi, çıkışı ve sahibi bellidir; bir FAZ kapanmadan sonrakine iş taşınmaz.
## 2. Kapsam
- Kapsam içi: FAZ tanımı, sıra ve bağımlılıklar, her FAZ'ın çıkış kriteri, unattended provisioning FAZ'ının yeri, doküman-faz eşleşmesi.
- Kapsam dışı: dalga cihaz sayıları detayı (18), update onay akışı (10), komut-seviyesi kurulum (03/04/05).
## 3. Kararlar
```text
KARAR: Yol haritası 7 FAZ'dır: F0 Hazırlık+Envanter → F1 Merkez VDS → F2 Golden image (katılımlı) → F3 LAB+P1 → F4 Dalgalar (P2/W1/W2) → F5 PROD+İşletme → F6 Katılımsız provisioning (unattended, ayrı FAZ).
GEREKÇE: Sıra bağımlılıkları zorlar: envanter olmadan imaj (K-09), imaj olmadan LAB, LAB olmadan dalga (K-11) olmaz. Unattended provisioning ayrı FAZ'dır çünkü katılımlı akış (USB→script→bayi no) sahada kanıtlanmadan PXE/preseed otomasyonu ek yük ve ek arıza yüzeyi demektir.
ALTERNATİF: Unattended'i en başa koyma — temel akıştaki hata otomasyonla çarpılır; elendi. Tek-faz "hepsini yap" planı — kapısız ilerleme, filo-çapı risk; elendi.
RİSK: FAZ atlama baskısı (takvim); azaltma: her FAZ çıkışı 21'deki onay yetkilisinin imzasına bağlıdır.
MALİYET: Ücretsiz (işgücü planlaması; VDS kira hariç).
LİSANS: Yok.
```
## 4. Neden Bu Karar?
Klasik hata sırası tersine çevirmektir: önce otomasyon, sonra temel. Bu harita bilerek "sıkıcı" sırayı seçer — önce elle çalışan, sonra kendiliğinden çalışan. F6'nın ayrı FAZ olması, unattended'in iptal edilebilir (proje yine de biter) ama atlanamaz (sırası gelmeden yapılmaz) olduğunu söyler. Her FAZ bir karar grubunu hayata geçirir; harita ile 24-DECISION-LOG arasındaki bağ tabloyla sabittir.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| Unattended ilk FAZ | Erken otomasyon | Kanıtlanmamış akışın otomasyonu | Elendi (F6'ya taşındı) |
| Az FAZ (3 büyük) | Kısa plan | Kapılar seyrek, risk büyük | Elendi |
| Çok FAZ (12+) | Detaylı | Yönetim yükü, faz yorgunluğu | Elendi |
## 6. Avantajlar
- Her FAZ bağımsız kapanır; proje yarıda kalsa bile kazanım (örn. F1 merkezi) kalır.
- F6 opsiyoneldir: katılımlı akışla PROD bitebilir, unattended sonradan eklenir.
## 7. Dezavantajlar
- FAZ disiplini yavaş görünür; paydaşa "neden F6 en sonda" açıklaması gerekir (gerekçe §4'tür).
- FAZ'lar arası bekleme (gözetim süreleri) takvimi uzatır.
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| FAZ çıkışı atlanır, sonrakine geçilir | Orta | Yüksek | Onay yetkilisi imzası zorunlu (21) |
| Merkez VDS donanımı yetersiz çıkar (F1) | Orta | Orta | LAB yük testi; servisleri ikinci VDS'e bölme planı (01) |
| Donanım profili imajı kırar (F2→F3) | Orta | Orta | F0 envanteri + F3 profil matrisi |
## 9. Uygulama Planı
| FAZ | Ad | Kararlar | Çıkış kriteri | Dokümanlar |
|---|---|---|---|---|
| F0 | Hazırlık + donanım envanteri | K-12 (kimlik), K-09 (tarama-önce) | Profil listesi + envanter şeması onaylı | 02, 18 (FAZ 0), 00 |
| F1 | Merkez VDS kurulumu | K-04, K-05, K-06, K-07, K-08 | WG hub + hbbs/hbbr + MeshCentral + Semaphore + Prometheus/Kuma ayakta; L9 tatbikatı yapıldı | 06, 07, 08, 09, 14, 17-L9 |
| F2 | Golden image (katılımlı) | K-01, K-02, K-03, K-09, K-10, K-11 | `blueforce-install.sh` USB→READY akışı LAB donanımında çalışıyor; `unattended-upgrades` kapalı; tag/`unless-stopped` denetli | 03, 04, 05, 12 |
| F3 | LAB(2) + P1(5) | K-11 (dalga), K-14 (bundle), K-05 (kopma sayacı) | 3 akış yeşil; teknisyen desteksiz kurulum yaptı; kopma sayacı toplandı | 18, 19, 20, 10 |
| F4 | Dalgalar P2/W1/W2 | K-11, K-06, K-07 | Her dalga çıkış kriteri + halt kaydı; destek yükü hedefte | 18, 21, 14 |
| F5 | PROD (~523) + işletmeye alma | Tümü | Filo READY; rutinler (günlük/haftalık) devrede; `v1` doküman kesildi | 21, 22, 23 |
| F6 | Katılımsız provisioning (unattended) | K-09 (hedef) | Teknisyen girdisiz (veya minimum-girdili) kurulum P2 ölçeğinde kanıtlı; katılımlı akış yedekte duruyor | 04 (F6 eki) |
F6 notu: F6, F5'ten sonra başlar; F5'in kapanmasına engel değildir. F6 kapsamı (PXE/preseed derinliği, ağ gereksinimleri) F3 verisine göre F4 içinde netleştirilir. F6 başarısız olursa proje F5 haliyle tamam sayılır.
```bash
# örnek: FAZ kapısı kontrolü (merkez)
# F3 çıkışı için LAB doğrulama seti
ansible-playbook playbooks/verify-lab.yml --limit lab
bf-support-bundle --out /tmp/f3-gate-bundle.tar.gz
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| F1 L9 tatbikatı (boş VDS'e kur) | Tüm merkez servisleri ayağa kalkar | İzole VDS |
| F2 imaj denetim seti (K-10/K-11 kilitleri) | `latest` yok, timer'lar maskeli, politika `unless-stopped` | LAB(2) |
| F3 3-akış + rollback | Erişim/boot/update + geri alma yeşil | LAB(2)/P1(5) |
| F6 unattended prova | Minimum-girdi ile READY | P2 ölçeği |
## 11. Rollback
1. FAZ içi hata: ilgili dalga/iş 17-RECOVERY veya 10-UPDATE zinciriyle geri alınır; FAZ tekrarlanır.
2. FAZ kararı yanlışsa (örn. imaj yöntemi): 24-DECISION-LOG PR'ı + bağımlı FAZ'ların tekrarı.
3. F6 geri alınırsa katılımlı akışa dönülür (yedek her zaman sıcak tutulur).
## 12. Kontrol Listesi
- [ ] Her FAZ'ın çıkış kriteri + sahibi yazılı ve onaylı.
- [ ] F6'nın F5 sonrası ayrı FAZ olduğu paydaşça kabul edildi.
- [ ] Doküman-faz eşleşmesi (tablodaki son sütun) güncel.
- [ ] Onay yetkilisi (asıl+vekil) tanımlı (21).
## 13. Açık Sorular
- [ ] FAZ tarihleri ve teknisyen kapasite planı (sahibi: yönetim + 18).
- [ ] F1 VDS donanım siparişi için LAB yük ölçümü (sahibi: 14-MONITORING yazarı).
- [ ] F6 kapsamı (PXE şart mı, USB-preseed yeter mi) — F3 verisi sonrası (sahibi: 04 yazarı).
---
## Ek: Mermaid — FAZ akışı
```mermaid
flowchart LR
F0["F0 Hazırlık<br/>+ envanter"] --> F1["F1 Merkez VDS"]
F1 --> F2["F2 Golden image<br/>(katılımlı)"]
F2 --> F3["F3 LAB 2 + P1 5"]
F3 --> F4["F4 P2/W1/W2"]
F4 --> F5["F5 PROD + işletme"]
F5 --> F6["F6 Unattended<br/>(ayrı FAZ)"]
```

113
docs/_TEMPLATE.md Normal file
View file

@ -0,0 +1,113 @@
# <DOKÜMAN BAŞLIĞI>
> Kısa özet: bu doküman neyi kapsar, kimin içindir, hangi kararı verir. (2–3 cümle)
- Dosya: `docs/NN-KONU.md`
- İlgili kararlar: `24-DECISION-LOG.md#<başlık>`
- Durum: [ ] Taslak / [ ] İncelemede / [ ] Onaylı
---
## 1. Amaç
Bu dokümanın neden var olduğu, hangi sorunu çözdüğü.
## 2. Kapsam
Kapsam içi ve kapsam dışı maddeler:
- Kapsam içi: ...
- Kapsam dışı: ...
## 3. Kararlar
Her teknik karar için aşağıdaki karar bloğunu kullan:
```text
KARAR: <alınan karar, tek cümle>
GEREKÇE: <neden bu karar — teknik dayanak, 1–3 cümle>
ALTERNATİF: <değerlendirilen en güçlü alternatif + neden elendi>
RİSK: <kararın getirdiği en büyük risk + azaltma notu>
MALİYET: <Ücretsiz / Ücretli (işaretli) + not>
LİSANS: <lisans adı + kaynak URL + sürüm + doğrulama tarihi>
```
Örnek:
```text
KARAR: Filo yönetiminde Ansible + Semaphore UI Community kullanılır.
GEREKÇE: Agent gerektirmez, SSH tabanlıdır, 700 cihaz ölçeğinde yeterlidir.
ALTERNATİF: SaltStack — daha karmaşık kurulum nedeniyle elendi.
RİSK: Playbook hatası filoya yayılabilir; önce LAB(2) grubunda çalıştırılır.
MALİYET: Ücretsiz (self-hosted).
LİSANS: Semaphore Community (kaynak doğrulanacak) — URL + sürüm + tarih eklenecek.
```
## 4. Neden Bu Karar?
Kararların arkasındaki teknik ve operasyonel gerekçeler. Sadelik kuralı burada denetlenir: Kubernetes, microservice, gereksiz agent/DB/cloud öneriliyorsa neden reddedildiği yazılır.
## 5. Alternatifler
| Alternatif | Artı | Eksi | Sonuç |
|---|---|---|---|
| ... | ... | ... | Elendi / Yedek |
## 6. Avantajlar
- ...
## 7. Dezavantajlar
- ...
## 8. Riskler
| Risk | Olasılık | Etki | Azaltma |
|---|---|---|---|
| ... | Düşük/Orta/Yüksek | ... | ... |
## 9. Uygulama Planı
Numaralı adımlar; komutlar İngilizce orijinal adıyla, açıklamalar Türkçe:
1. ...
2. ...
```bash
# örnek komut bloğu
hostnamectl set-hostname bf-12010193
```
## 10. Test Planı
| Test | Beklenen sonuç | Ortam |
|---|---|---|
| ... | ... | LAB(2) |
## 11. Rollback
Başarısızlıkta önceki duruma dönüş adımları:
1. ...
2. ...
## 12. Kontrol Listesi
- [ ] ...
- [ ] ...
## 13. Açık Sorular
- [ ] ... (sahibi + tarih ile)
---
## Ek: Mermaid Örneği
```mermaid
flowchart LR
Saha["bf-12010193<br/>(saha PC'si)"] -->|WireGuard| Merkez["Merkez sunucu"]
Merkez --> Ansible["Ansible/Semaphore"]
Merkez --> Monitor["Monitoring"]
```

0
monitoring/.gitkeep Normal file
View file

0
research/.gitkeep Normal file
View file

View file

@ -0,0 +1,113 @@
# Faz 1A Araştırma — OS / GUI / RDP + WireGuard + Docker
> Durum: KAYNAK DOĞRULAMA NOTU (karar taslağı değil). Her bulgu `iddia + resmi URL + sürüm/tarih + Blueforce etkisi` formatındadır.
> Doğrulama yöntemi: resmi sayfalar 2026-09-15 tarihinde doğrudan çekilerek (HTTP 200) okundu. Web arama servisi (Nous gateway) kapalıydı; bu dosyadaki hiçbir bulgu arama özetine dayanmaz, hepsi doğrudan sayfa içeriğidir.
> Kural: tüm bileşenlerde FREE sürüm baz alınır (Ubuntu LTS, WireGuard, Docker CE, XFCE, xRDP). Ücretli varyantlar (Ubuntu Pro, Docker Business vb.) zorunlu mimariye konulmaz; free limitleri ilgili maddede kısaca not edilir.
---
## A1. Ubuntu 26.04 LTS var mı? Saha için uygun mu?
- **BULGU A1.1 — Ubuntu 26.04.1 LTS mevcut ve resmi indirme sayfasında yayında.**
- İddia: `releases.ubuntu.com` ana sayfası "Ubuntu 26.04.1 LTS (Resolute Raccoon)" başlığını, `26.04/` ve `26.04.1/` dizinlerini listeler.
- Resmi URL: https://releases.ubuntu.com/ (HTTP 200, çekilme: 2026-09-15)
- Sürüm/tarih: 26.04.1 LTS, kod adı Resolute Raccoon
- Blueforce etkisi: Şartnamedeki "Ubuntu LTS (26.04 doğrulanacak)" maddesi DOĞRULANDI — 26.04 gerçek, güncel LTS serisidir. Ancak `.1` sürümünün yayında olması, golden image için **26.04.1+ noktasürümü** baz almayı önerir (ilk .0 dalgasındaki kurulumcu hataları genelde .1'de toplanır — bu kısım genel mühendislik kanaati, LAB'da imaj testiyle kesinleşir).
- **BULGU A1.2 — 26.04 Server ISO'su varsayılan olarak GUI kurmaz.**
- İddia: `26.04/` dizin sayfası Server imajını "It will not install a graphical user interface" cümlesiyle tanımlar; Desktop ve live-server ISO'ları ayrıdır.
- Resmi URL: https://releases.ubuntu.com/26.04/ (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: "Server + sonradan XFCE" saha mimarisi temiz bir zemine oturur — minimal kurulum + ihtiyaca göre GUI, desteklenen standart yoldur.
- **BULGU A1.3 — Ubuntu Desktop 26.04 sistem gereksinimi saha PC'leri için ağırdır.**
- İddia: Resmi indirme sayfası Desktop için "2 GHz dual-core, 6 GB RAM, 25 GB disk" ister.
- Resmi URL: https://ubuntu.com/download/desktop (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: 700 saha PC'sinde tam GNOME/Ubuntu Desktop standardı RAM/disk bütçesini zorlar. Bu, XFCE tercihinin en somut dayanağıdır (bkz. A2).
- **BULGU A1.4 — `unattended-upgrades` Ubuntu Server'da VARSAYILAN OLARAK KURULU ve ETKİNDİR; günde bir kez çalışır.**
- İddia: Resmi Server dokümantasyonu: "This is done via the `unattended-upgrades` package, which is installed by default" + "Right after installation, automatic installation of security updates will be enabled" + "By default, `unattended-upgrades` runs once per day". Kapatma yolu: `/etc/apt/apt.conf.d/20auto-upgrades` içinde `Update-Package-Lists` / `Unattended-Upgrade` değerlerini `0` yapmak; tetikleyici systemd timer'ları `apt-daily.timer` / `apt-daily-upgrade.timer`.
- Resmi URL: https://ubuntu.com/server/docs/how-to/software/automatic-updates/ (HTTP 200, render; kaynak: https://raw.githubusercontent.com/canonical/ubuntu-server-documentation/main/docs/how-to/software/automatic-updates.md, HTTP 200, çekilme: 2026-09-15)
- Sürüm/tarih: güncel Server dokümantasyonu (resolute dahil); man sayfası resolute'ta `unattended-upgrades 2.12ubuntu9` paketini doğrular — https://manpages.ubuntu.com/manpages/resolute/en/man8/unattended-upgrade.8.html (HTTP 200, 2026-09-15); noble paketi https://packages.ubuntu.com/noble/unattended-upgrades (HTTP 200)
- Blueforce etkisi: KRİTİK — "onaysız update yasak" politikası için golden image'da `20auto-upgrades`'ın `0`'lanması ve timer'ların maskelenmesi ŞART; aksi halde 700 cihaz ilk açılışta güncellemeye kalkar (doküman ayrıca makine kapalıyken kaçan timer'ın açılışta hemen tetiklendiğini — `Persistent=true` davranışı — yazar; saha PC'leri sık kapanan makineler olduğu için bu not runbook'a girer). Free notu: ESM kapsamı Pro'ya girer — mimaride ESM'e bel bağlanmaz, standart `security` cebi yeterlidir (ücretsiz).
---
## A2. Masaüstü: XFCE vs GNOME + xRDP (700 ölçek)
- **BULGU A2.1 — Xfce resmi olarak "hafif, hızlı, düşük sistem kaynağı" hedefler.**
- İddia: Proje ana sayfası: "Xfce is a lightweight desktop environment… It aims to be fast and low on system resources."
- Resmi URL: https://www.xfce.org/about (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: GNOME (6 GB RAM şartı, A1.3) karşısında XFCE'nin saha standardı olması yönünde karar verilir. RDP üzerinden 700 cihaza bakımda düşük RAM/CPU ayak izi = daha az donma, daha ucuz saha donanımı.
- **BULGU A2.2 — xRDP aktif, güncel, ücretsiz (Apache-2.0) RDP sunucusudur; Temmuz 2026 sürümü var.**
- İddia: GitHub `neutrinolabs/xrdp`: açıklama "xrdp: an open source RDP server", son push 2026-09-09, son sürüm v0.10.6.1 (2026-07-07), ~6728 yıldız, varsayılan dal `devel`.
- Resmi URL'ler: https://github.com/neutrinolabs/xrdp + https://api.github.com/repos/neutrinolabs/xrdp (+ `/releases/latest`) (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: xRDP "ölü proje" riski YOK — 4. erişim yöntemi adayı olarak mimaride kalır. Lisans ücretsiz, 700 ölçekte lisans maliyeti doğmaz.
- **BULGU A2.3 — xRDP mimarisi oturum yöneticisi (sesman) + servis birimleri üzerine kuruludur; GUI aç/kapa buradan türetilir.**
- İddia: Upstream README kaynak ağacı `sesman` (session manager), `xrdp-sesman.service.in` ve `xrdp.service.in` systemd birimlerini içerir (devel dalı `instfiles/` listesi ve README'den doğrulandı).
- Resmi URL: https://github.com/neutrinolabs/xrdp (README + `instfiles/`, `sesman/` dizinleri; GitHub API HTTP 200, 2026-09-15)
- Blueforce etkisi: `bf-gui-on/off` tasarımının dayanağı: GUI, display-manager servisi + xRDP servisleri (`xrdp`, `xrdp-sesman`) üzerinden systemd ile açılıp kapatılabilir bir katman olarak modellenir (kesin birim adları ve XFCE oturum başlatma satırı LAB'da 26.04.1 imajında doğrulanacak — bu dosyada komut uydurulmaz).
- **DOĞRULANAMAYAN / LAB'A BIRAKILAN:** xRDP GitHub wiki'si JS ile yükleniyor, statik çekmede oturum-masaüstü uyumluluk tablosu okunamadı (https://github.com/neutrinolabs/xrdp/wiki, 2026-09-15). GNOME-üzerinde-xRDP'nin bilinen ek ayar ihtiyacı bu kaynaktan teyit EDİLEMEDİ → "XFCE birincil, GNOME denenmeyecek" kararı A1.3+A2.1'e dayanır; GNOME+xRDP kombinasyonu LAB gündemine "test edilmeyecek alternatif" olarak değil, "XFCE yetersiz kalırsa" yedeği olarak yazılır.
---
## A3. WireGuard otomatik reconnect (Turkcell NAT arkası saha)
- **BULGU A3.1 — NAT arkasındaki eşin erişilebilir kalmasının resmi mekanizması PersistentKeepalive'dır; önerilen değer 25 sn.**
- İddia: Resmi QuickStart "NAT and Firewall Traversal Persistence" bölümü: NAT/güvenlik duvarı arkasındaki eşin bağlantı eşlemesini canlı tutmak için periyodik keepalive göndermesi gerekir; "A sensible interval that works with a wide variety of firewalls is 25 seconds"; `0` = kapalı (varsayılan); ayar `PersistentKeepalive =` alanı veya `persistent-keepalive` komut satırı ile yapılır; çoğu kullanıcının ihtiyacı yoktur, protokolü biraz daha geveze yapar.
- Resmi URL: https://www.wireguard.com/quickstart/ (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: Saha PC'leri (mobil NAT arkası) için istemci konfigürasyonunda `PersistentKeepalive = 25` STANDART olur. Sunucu tarafında keepalive gerekmez (simetrik değil — istemci canlı tutar).
- **BULGU A3.2 — `wg-quick@.service` systemd birimi Ubuntu paketinin içinden gelir; enable = açılışta otomatik VPN.**
- İddia: `wireguard-tools` (noble/amd64) dosya listesi `/lib/systemd/system/wg-quick@.service` ve `wg-quick.target` içerir → `systemctl enable wg-quick@wg0` kalıcı açılır; resolute (26.04) paket sürümü `1.0.20250521-1ubuntu1`.
- Resmi URL'ler: https://packages.ubuntu.com/noble/amd64/wireguard-tools/filelist ve https://packages.ubuntu.com/resolute/wireguard-tools (HTTP 200, 2026-09-15)
- Blueforce etkisi: "Otomatik reconnect" iki katmandan kurulur: (1) WireGuard keepalive (A3.1) + (2) systemd `wg-quick@wg0` enable + restart. Elektrik kesintisi sonrası cihaz açılınca VPN kendiliğinden gelir — 16-POWER-LOSS dokümanının ağı ayağı hazır.
- **DOĞRULANAMAYAN / SAHADA ÖLÇÜLECEK:** "Turkcell CGNAT" özelliği resmi dokümandan doğrulanamaz (operatör bilgisi). Tasarım, operatörden bağımsız NAT-traversal'a (A3.1) dayanır; PİLOT-1'de her cihazda `PersistentKeepalive=25` ile 7/24 kopma sayacı tutulur, keepalive aralığı saha verisine göre ayarlanır. Tahminle 10 sn gibi agresif değer yazılmaz.
---
## A4. Docker (CE, ücretsiz): UFW bypass + log + restart + latest + Watchtower
- **BULGU A4.1 — Docker, yayımlanan portlarda UFW'yi BAYPAS eder; bu resmi olarak belgelenmiştir.**
- İddia: Resmi doküman "Docker and ufw": Docker ve UFW uyumsuz çalışır; konteyner portu yayımlanınca trafik `nat` tablosunda yönlendirilir, UFW'nin kullandığı INPUT/OUTPUT zincirlerine uğramadan geçer — "effectively ignoring your firewall configuration".
- Resmi URL: https://docs.docker.com/engine/network/packet-filtering-firewalls/ (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: KRİTİK — MEG ve yardımcı servisler `ports:` ile yayımlanırsa UFW kuralları delinir. Güvenli çözüm seçenekleri (dokümanın aynı sayfasından): (a) port yayımlamayı 127.0.0.1'e bağlamak, (b) `iptables:false` (doküman "çoğu kullanıcı için uygun değil, konteyner ağını bozabilir" diye uyarır — bu yüzden varsayılan çözüm DEĞİL), (c) Docker'ın `DOCKER-USER`/nftables belgeli zincirleri. Saha standardı: (a) + WireGuard üzerinden erişim; detay `12-DOCKER-OPERATIONS` ve `11-SECURITY-HARDENING`'de.
- **BULGU A4.2 — Varsayılan `json-file` log sürücüsü ROTASYON YAPMAZ; disk dolmasına yol açar. Çözüm `max-size`/`max-file` daemon ayarıdır.**
- İddia: Resmi doküman: "By default, no log-rotation is performed… which can lead to disk space exhaustion"; örnek daemon ayarı `{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }`; `max-file` gibi sayısal değerler string yazılır; ayar değişikliği sonrası Docker restart gerekir ve sadece yeni konteynerlere uygulanır.
- Resmi URL: https://docs.docker.com/engine/logging/configure/ (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: Golden image'daki `/etc/docker/daemon.json`'da log rotasyonu ZORUNLU standart olur (saha PC'leri aylarca dokunulmaz; dolan disk = kilitlenen cihaz). Değerler (10m/3) başlangıç önerisi; MEG log hacmi PİLOT'ta ölçülüp ayarlanır.
- **BULGU A4.3 — Saha standardı restart politikası `unless-stopped`'tur.**
- İddia: Resmi doküman: `unless-stopped` "`always`'e benzer, ancak konteyner durdurulmuşsa (manuel ya da başka şekilde) Docker daemon yeniden başlasa bile yeniden başlatılmaz". Politika ancak konteyner en az bir kez başarıyla başladıktan sonra devreye girer.
- Resmi URL: https://docs.docker.com/engine/containers/start-containers-automatically/ (HTTP 200, çekilme: 2026-09-15)
- Blueforce etkisi: `always` yerine `unless-stopped` seçilir — saha teknisyeni bakım için durdurduğu konteynerin reboot sonrası sürpriz şekilde kalkmaması gerekir (öngörülebilirlik > her koşulda ayakta tutma). Elektrik kesintisi kurtarması `unless-stopped` ile aynen çalışır (kesinti "manuel stop" sayılmaz).
- **BULGU A4.4 — `latest` etiketi yasaklanır (determinizm gerekçesi).**
- İddia: Docker Hub etiket-semantiği sayfası taşınmış, resmi cümle bu turda yakalanamadı (https://docs.docker.com/docker-hub/repos/manage/hub-images/ HTTP 200 ama `latest` geçmiyor, 2026-09-15). Bu yüzden yasak, resmi alıntıya değil Blueforce "onaysız update yasak" politikasına dayandırılır: hareketli etiket, hangi imajın koştuğunu belirsizleştirir; 700 cihazda aynı imajı garanti etmenin yolu sabit sürüm etiketi (+ mümkünse digest) ve merkezi rollout'tur.
- Blueforce etkisi: Compose dosyalarında `image: …:latest` YASAK; sabit tag zorunlu. Digest pinleme (`@sha256:…`) PİLOT-2'de değerlendirilecek ek sıkılık adımı olarak açık soruya yazılır (komut/sözdizimi uydurulmadı, doküman yazımında Compose spec'ten ayrıca doğrulanacak).
- **BULGU A4.5 — Watchtower kullanılmaz; iki bağımsız gerekçe.**
- İddia 1 (politika): Watchtower "otomatik imaj güncelleyici"dir — Blueforce "onaysız update yasak" kuralını doğrudan ihlal eder (LAB→PİLOT→WAVE rollout zincirini bypass eder).
- İddia 2 (upstream): `containrrr/watchtower` deposu ARŞİVLENMİŞTİR (`archived: true`, son push 2025-12-17, ~24.6k yıldız, 219 açık issue).
- Resmi URL: https://github.com/containrrr/watchtower + https://api.github.com/repos/containrrr/watchtower (HTTP 200, 2026-09-15)
- Blueforce etkisi: Watchtower mimariye GİRMEZ; güncellemeler Ansible/Semaphore zincirinden, onaylı ve dalgalı yapılır. Alternatif "unattended imaj çekme" fikri de aynı gerekçeyle reddedilir.
- Free notu: Docker CE ücretsizdir; Docker Business/Scout gibi ücretli özellikler mimaride yoktur ve gerekmez.
---
## Karar etkisi özeti (Faz 2'ye girdi)
| # | Karar yönü | Dayanak bulgu |
|---|-----------|---------------|
| 1 | Baz OS: Ubuntu Server 26.04.1+ LTS (GUI'siz kurulum, XFCE sonradan) | A1.1, A1.2 |
| 2 | Masaüstü: XFCE birincil; tam GNOME saha standardı değil | A1.3, A2.1 |
| 3 | Uzaktan bakım katmanı: xRDP (aktif upstream, ücretsiz) + systemd ile GUI aç/kapa | A2.2, A2.3 |
| 4 | `unattended-upgrades` imajda kapatılır (timer dahil), update zinciri LAB→…→PROD | A1.4 |
| 5 | WireGuard istemci: `PersistentKeepalive=25` + `wg-quick@wg0` enable | A3.1, A3.2 |
| 6 | Docker: UFW-bypass'a karşı localhost-bind standardı; log rotasyonu zorunlu; `unless-stopped`; `latest` yasak; Watchtower yok | A4.1–A4.5 |
Açık sorular (tahmin yazılmaz, LAB/PİLOT'ta ölçülür): XFCE oturum başlatma satırı ve `bf-gui-on/off` kesin birim listesi (26.04.1 imajında); MEG log hacmine göre `max-size/max-file` ayarı; Turkcell NAT kopma sayacı ve keepalive ayarı; digest pinleme kararı.

126
research/B-remote-access.md Normal file
View file

@ -0,0 +1,126 @@
# B — Uzaktan Erişim Araştırması (Faz 1B)
Tarih: 2026-09-15. Kapsam: 700 cihazlık filo için bağımsız uzaktan erişim kanalı.
Sözlük: hbbs = RustDesk ID/randevu (rendezvous) + sinyalizasyon sunucusu;
hbbr = röle (relay) sunucusu; VDS = sanal özel sunucu.
> Not: Web arama altyapısı (Nous gateway) kapalı olduğundan bulgular
> curl ile çekilen resmi dokümantasyon sayfaları + GitHub API üzerinden
> doğrulandı. Cloudflare korumalı `anydesk.com` pazarlama sayfalarına curl
> ile erişilemedi; AnyDesk fiyatlandırması gerçek tarayıcı ile, lisans
> şartları ise Cloudflare korumasız resmi bilgi bankası
> (`support.anydesk.com`) üzerinden doğrulandı.
## 1. RustDesk OSS self-hosted (hbbs + hbbr)
- Mimari: istemciler önce hbbs'e kaydolur (ID, heartbeat, NAT tipi testi);
doğrudan P2P kurulamazsa trafik hbbr üzerinden rölelenir. İkisi de tek
`rustdesk/rustdesk-server` imajından `hbbs` / `hbbr` komutuyla çalışır.
Kaynak: https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/
(erişim 2026-09-15; sürüm bilgisi aşağıda).
- VDS kurulumu (Docker Compose, önerilen `network_mode: "host"`):
`rustdesk/rustdesk-server:latest` imajı, `./data:/root` kalıcı hacmi,
`unless-stopped` yeniden başlatma. Kaynak:
https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/docker/
(erişim 2026-09-15).
- Güvenlik duvarı portları: hbbs 21115/TCP (NAT testi), 21116/TCP+UDP
(ID kaydı/heartbeat + TCP hole punching), 21118/TCP (web istemcisi,
opsiyonel); hbbr 21117/TCP (röle), 21119/TCP (web istemcisi, opsiyonel).
21114/TCP yalnızca Pro web konsolunundur. 21118/21119 kullanılmıyorsa
kapalı tutulmalıdır (IP sahteciliği uyarısı dokümanda). Kaynak: aynı
Docker sayfası (erişim 2026-09-15).
- Pro gerektirmeyen özellikler (OSS'ta mevcut): sınırsız istemci, kendi
ID + röle altyapın, uçtan uca şifreli P2P/röleli oturum, dosya transferi,
katılımsız erişim (kalıcı parola), betikli toplu dağıtım (PowerShell /
batch / MSI / macOS bash / Linux bash). Toplu dağıtımda istemciye
self-hosted sunucu adresi + yapılandırma dizesi (config string) gömülür.
Kaynak: https://rustdesk.com/docs/en/self-host/client-deployment/
(erişim 2026-09-15).
- Yalnızca Pro'da olanlar (OSS'ta YOK): web konsolu, API, OIDC/SSO, LDAP,
2FA, erişim kontrolü, rol tabanlı yönetim, denetim logları, strateji/
adres defteri, özel istemci üretici. Kaynak:
https://rustdesk.com/docs/en/self-host/rustdesk-server-oss/ +
https://rustdesk.com/pricing/ (erişim 2026-09-15; Individual ~11,88
USD/ay, Basic ~23,88 USD/ay, yıllık faturalı).
- Sürümler (GitHub API, 2026-09-15): istemci `rustdesk/rustdesk` 1.4.9
(2026-07-06); sunucu `rustdesk/rustdesk-server` 1.1.16 (2026-07-20).
Lisans: AGPL-3.0 (her iki repo). Yıldız: istemci ~123,6b, sunucu ~10,4b.
### WireGuard çökerse bağımsız kanal çalışır mı? — EVET
RustDesk istemcisi, yapılandırılan ID sunucusuna (VDS genel IP/DNS,
21115-21117) doğrudan internet üzerinden ulaşır; trafik WireGuard
arayüzünden geçme zorunluluğu yoktur (istemcide tünel içi bir adres değil,
VDS'nin gerçek adresi tanımlanır). hbbs/hbbr, istemcilerin gerçek gelen
IP'sini görmelidir (`--net=host` önerisinin gerekçesi de budur). Dolayısıyla
WireGuard servisi veya ana tünel çökse bile RustDesk kanalı ayakta kalır;
tek ortak bağımlılık VDS'nin kendisi ve genel internet erişimidir. Bu,
tasarım hedefiyle de tutarlıdır: "kendi randevu/röle sunucunu kur, verinin
kontrolü sende" (https://github.com/rustdesk/rustdesk README,
erişim 2026-09-15). Öneri: Blueforce mimarisinde RustDesk kanalını
WireGuard'a bağımlı yapmayacak şekilde, istemcide VDS genel adresi kullan;
`ALWAYS_USE_RELAY=Y` yalnız NAT sorunlu sahalarda değerlendir (gecikme/
bant genişliği maliyetiyle).
## 2. AnyDesk ticari lisans — 700 kurumsal cihazda ücretsiz kullanım yasal mı?
**HAYIR.** Ücretsiz sürüm yalnızca kişisel kullanımı kapsar; ticari
kullanımda giden bağlantıyı başlatan istemcilerin lisanslı olması şarttır.
Resmi bilgi bankası: "Only outgoing clients that initiate connections to
other AnyDesk clients for commercial use need to have an AnyDesk license."
Kaynak: https://support.anydesk.com/docs/anydesk-licenses.md
(güncellenme 2025-10-30, erişim 2026-09-15). 700 cihazlık kurumsal filo
açıkça ticari kullanımdır; ücretsiz sürüm lisans ihlali olur.
- Güncel fiyatlar (https://anydesk.com/en/pricing, tarayıcıyla erişim
2026-09-15): Solo (100 yönetilen cihaz) → Standard ~34,32 USD/ay
(500 yönetilen cihaz, 20 kullanıcı) → Advanced ~72,72 USD/ay
(1000 yönetilen cihaz, 100 kullanıcı) → Ultimate (2000 cihazdan başlar,
ölçeklenebilir, teklifli). 700 cihaz Standard'ı aşar (500) → en az
Advanced gerekir; hepsi yıllık faturalı, KDV hariç.
- **Mimari karar: AnyDesk birincil/ücretsiz kanal olarak mimariden
ÇIKARILDI.** Gerekçe: lisans maliyeti + kapalı kaynak + self-hosted
seçeneğin yalnızca en üst (Ultimate/On-Premises) planda olması.
- Opsiyonel not (mimari dışı): müşteri sahasında zaten lisanslı AnyDesk
varsa, teknisyen erişimi için "opsiyonel installer modülü" olarak
paketlenebilir; ancak Blueforce imajında varsayılan kurulu gelmez,
envanter/lisans takibi müşteriye aittir.
## 3. Dördüncü bağımsız ücretsiz erişim adayı: MeshCentral (önerilen)
Tailscale/ZeroTier gibi freemium, merkezi kimlik isteyen çözümler elendi;
gerçek OSS + self-hosted olan MeshCentral seçildi.
- Nedir: NodeJS tabanlı, web üzerinden bilgisayar yönetimi; aracı (agent)
kurulu cihazlar sunucuda görünür; web tabanlı uzak masaüstü + terminal +
dosya yönetimi dahili. Kaynak: https://meshcentral.com (erişim
2026-09-15) + https://github.com/Ylianst/MeshCentral readme.md
(erişim 2026-09-15).
- Lisans: Apache-2.0 (package.json `license` alanı + LICENSE dosyası,
GitHub API ile doğrulandı 2026-09-15). Ticari kullanım dahil ücretsiz,
self-hosted'da kullanıcı/cihaz kotası yok.
- Sürüm: 1.2.5 (yayınlanma 2026-08-12, GitHub API 2026-09-15). Aktif bakımda
(son push 2026-09-14). Yıldız ~7,2b.
- Platformlar: sunucu ve aracı Windows/Linux/macOS/FreeBSD (resmi site).
Kurulum: `meshcentral` npm paketi üzerinden (`npm install -g meshcentral`
standardı), dokümantasyon: https://ylianst.github.io/MeshCentral/
(README'de bağlantılı, erişim 2026-09-15).
- Blueforce rolü: RustDesk birincil grafik kanal; MeshCentral ikincil
yönetim düzlemi (envanter + terminal + dosya + web konsolu) olarak aynı
veya ayrı VDS'de koşar. O da kendi portları üzerinden internete çıkar;
WireGuard'dan bağımsız ikinci bir "ölüm-dışı" kanal sağlar. Not: ilk
kurulumda TLS (Let's Encrypt / ters vekil) ve 2FA açılmalıdır (resmi
dokümanda anlatılır).
## 4. Karar özeti
| Kanal | Rol | Lisans | WireGuard bağımsız mı? |
|---|---|---|---|
| RustDesk OSS (hbbs/hbbr, VDS) | Birincil grafik uzak erişim | AGPL-3.0, ücretsiz | EVET |
| MeshCentral (VDS) | İkincil yönetim (terminal/dosya/envanter) | Apache-2.0, ücretsiz | EVET |
| WireGuard | Ana güvenli ağ | OSS | — (kendisi) |
| AnyDesk | Mimariden çıkarıldı; yalnızca müşteri lisanslıysa opsiyonel installer modülü | Ticari lisans gerekli | — |
Doğrulanamayan / sonraki faza kalan: RustDesk `id_ed25519.pub` anahtar
dağıtım otomasyonu detay adımları (Faz 2 kurulum betiklerinde ele alınacak);
MeshCentral gerçek VDS kurulum testi yapılmadı (Faz 2).

View file

@ -0,0 +1,229 @@
# Faz 1C Araştırma — Fleet Yönetimi + Monitoring + Docs Platformu
- Tarih: 2026-09-15 (doğrulama günü güncel resmi kaynaklar)
- Kapsam: 700 saha cihazı, %100 ücretsiz/self-hosted, sadelik öncelikli
- Kural: Her bulgunun resmi URL'si vardır. Sürüm/plan bilgisi değişebilir; karar öncesi URL'den teyit edilir.
---
## 1. Fleet Yönetimi Karşılaştırması
### 1.1. Adaylar ve lisans (resmi kaynak)
| Araç | Lisans (OSS çekirdek) | Kaynak |
|---|---|---|
| Ansible (CLI / core) | GPL-3.0 | https://github.com/ansible/ansible |
| Semaphore UI Community | MIT, "$0, free forever, open source" | https://github.com/semaphoreui/semaphore — https://semaphoreui.com/pricing |
| AWX | Apache-2.0 | https://github.com/ansible/awx (README rozeti → https://github.com/ansible/awx/blob/devel/LICENSE.md) |
| Salt (Salt Project) | Apache-2.0 | https://github.com/saltstack/salt — https://docs.saltproject.io/ |
| Rudder (Core) | GPL-3.0, Core açık kaynak; Enterprise abonelik node başına/yıl ücretli | https://github.com/Normation/rudder — https://www.rudder.io/en/pricing/ |
| MeshCentral | Apache-2.0 | https://github.com/Ylianst/MeshCentral — https://meshcentral.com/ |
### 1.2. Semaphore UI Community — ücretsiz/OSS özellikler ve Pro bağımlılığı yoktur kanıtı
Resmi plan karşılaştırmasına göre (https://semaphoreui.com/pricing):
**Community ($0) içinde VAR (ücretsiz, MIT, self-hosted):**
Ansible/Terraform/OpenTofu/Shell/Python/PowerShell çalıştırma; статиk/dosya/dinamik envanter yönetimi;
yeniden kullanılabilir Task Template; Cron zamanlama; Variable Groups; merkezi Key Store (şifreli, runtime enjeksiyon);
Global Runner ile dağıtık çalıştırma; proje-seviyesi erişim kontrolü + RBAC; Task/Activity/Server log geçmişi;
REST API; Webhook tetikleyiciler; Git depoları (GitHub/GitLab/Bitbucket); bildirimler (e-posta, Slack, Teams vb.);
AI iş akışları için MCP sunucusu; docs + topluluk desteği.
**Yalnızca Pro/Enterprise'da VAR (Community'de YOK, ama 09-FLEET kapsamı için gerekli DEĞİL):**
izole Project Runner'lar; task özetleri; HashiCorp Vault/AWS/Azure/Devolutions gizli yönetimi;
2FA (TOTP); LDAP/AD; OIDC SSO; IdP grup eşleme; özel roller; dosya-tabanlı log dışa aktarma;
HA kurulum; air-gapped lisans; SLA destek.
**Pro bağımlılığı yok — üç kanıt:**
1. Community "free forever and open source ... start automating without a paid subscription" — https://semaphoreui.com/pricing
2. Community kodu MIT lisanslı public repo — https://github.com/semaphoreui/semaphore
3. Kritik eşik: **Pro en fazla 500 managed node** destekler ("Up to 500 managed nodes ... For larger environments,
choose Enterprise"). 700 cihaz zaten Pro kapsamını aşıyor; ücretli yola girilse bile Pro yetmez, Enterprise gerekir.
Community'de lisansla dayatılan node kotası yoktur (self-hosted, kota lisans anahtarına bağlıdır; Community anahtarsız çalışır).
Sonuç: filo yönetimi Community + Ansible CLI ile kurulur; hiçbir iş akışı Pro/Enterprise özelliğine bağlanmaz
(Vault yerine Key Store, SSO yerine WireGuard arkası + SSH anahtarı, izole runner yerine Global Runner).
**Community free limitleri (bilinerek kabul edilenler, Pro'ya taşınmadan çözümüyle):**
- OIDC/SSO, LDAP/AD, 2FA yok → çözüm: Semaphore yalnızca WireGuard arkasında, erişim VPN + SSH anahtarı ile.
- HashiCorp Vault/AWS/Azure gizli yönetimi yok → çözüm: yerleşik şifreli Key Store.
- İzole Project Runner yok → çözüm: Global Runner + proje-seviyesi erişim kontrolü.
- Dosya-tabanlı log dışa aktarma ve task özeti yok → çözüm: Task/Activity geçmişi UI + API'den çekilir, merkezi loga taşınır.
- HA yok → çözüm: Ansible CLI bağımsız çalışır; Semaphore çökse filo durmaz (günlük yedek + hızlı yeniden kurulum).
### 1.3. Karşılaştırma — 700 cihaz sadeliği
| Kriter | Ansible CLI | Semaphore Community | AWX | Salt | Rudder Community | MeshCentral |
|---|---|---|---|---|---|---|
| 700 cihaza ek yük | Yok (agent'sız, SSH) | Tek Go binary + DB, hafif | **Ağır: Kubernetes + AWX Operator zorunlu** | Minion agent + master PKI | Server + relay + agent (ağır) | Server + agent (uzaktan erişim ağırlıklı) |
| Öğrenme/işletme sadeliği | YAML playbook, en basit | Playbook'u UI'dan çalıştırma, basit | K8s bilgisi ister, karmaşık | State/pillar/grain modeli, orta-zor | Politika/direktif modeli, orta-zor | Filo otomasyonu değil, erişim aracı |
| Ücretsiz kapsam riski | Yok (GPL-3.0) | Yok (yukarıdaki kanıt) | **Sürüm riski: son release 2 Tem 2024, "releases paused during refactoring"** — https://github.com/ansible/awx | SaltStack Config (Broadcom) ücretli; OSS taraf güvenli ama master ölçekleme ister | Enterprise modülleri (relay, patch kampanyası, CVE yönetimi) ücretli — https://www.rudder.io/en/pricing/ | Yok (Apache-2.0), ama konfigürasyon yönetimi değil |
| 700 cihaz kanıtı | Binlerce node pratiği yaygın | Global Runner + dinamik envanter | Ölçeklenir ama K8s maliyetiyle | Ölçeklenir (master yatırımı) | Ölçeklenir (relay yatırımı) | 700 cihaza filo-komut modeli zayıf |
- AWX kurulumu: https://docs.ansible.com/projects/awx/en/latest/ (Operator tabanlı) ve refactoring duyuruları:
https://www.ansible.com/blog/upcoming-changes-to-the-awx-project/
- Salt docs: https://docs.saltproject.io/ — minion/master mimarisi 700 cihazda ek PKI ve master kapasite planı ister.
- MeshCentral kapsamı "remote monitoring and management" (erişim + envanter), Ansible-filo karşılığı değildir:
https://github.com/Ylianst/MeshCentral
### 1.4. KARAR
- **KARAR:** Birincil filo otomasyonu **Ansible CLI (SSH, agent'sız)**; operatör arayüzü **Semaphore UI Community
(self-hosted, MIT)**. Hiçbir playbook/iş akışı Pro/Enterprise özelliği kullanmaz.
- **GEREKÇE:** En düşük hareketli parça (SSH + YAML + tek Go binary); 700 cihazda ek agent/master/K8s/DB maliyeti yok;
Community ücretsizliği resmi fiyat sayfasıyla kanıtlı; 500-node Pro kotası 700 cihazda ücretli yolu zaten kapatıyor.
- **ALTERNATİF:** AWX (K8s yükü + release'ler duraklatıldı → elendi); Salt (agent + master PKI yükü → elendi);
Rudder Community (politika modeli güçlü ama relay/Enterprise modülleri ve öğrenme eğrisi → elendi);
MeshCentral (4. erişim kanalı adayı olarak değerlendirilir, filo otomasyonu olarak değil).
- **RİSK:** Semaphore tek nokta arızası → Ansible CLI her zaman bağımsız çalışır (UI çökse filo durmaz).
Community'de OIDC/2FA yok → Semaphore yalnızca WireGuard arkasında yayınlanır, admin erişimi VPN + SSH anahtarı ile.
- **MALİYET:** $0 (kendi VDS'i üzerinde).
- **LİSANS:** Ansible GPL-3.0, Semaphore MIT — ticari kullanımda lisans bedeli yok.
---
## 2. Monitoring Karşılaştırması
### 2.1. Adaylar ve lisans
| Çözüm | Lisans | Kaynak |
|---|---|---|
| Prometheus + Node Exporter | Apache-2.0 / Apache-2.0 | https://github.com/prometheus/prometheus — https://github.com/prometheus/node_exporter — https://prometheus.io/docs/guides/node-exporter/ |
| Grafana OSS | AGPL-3.0 (self-hosted ücretsiz) | https://github.com/grafana/grafana — https://grafana.com/oss/ |
| Netdata (Agent OSS + Cloud) | Agent GPL-3.0; **Cloud Free yalnızca 5 node'a kadar, sonrası node başına ~$4.50/ay'dan başlar** | https://github.com/netdata/netdata — https://www.netdata.cloud/pricing/ |
| Uptime Kuma | MIT | https://github.com/louislam/uptime-kuma |
### 2.2. Karşılaştırma — 700 cihaz
| Kriter | Prometheus + Node Exporter + Grafana OSS | Netdata | Uptime Kuma |
|---|---|---|---|
| Merkezi metrik (700 node) | Sınırsız, ücretsiz (kendi Prometheus'u) | Merkezi görünüm Cloud'da; **ücretsiz kota 5 node** → 700 cihaz ücretli | Metrik yok; sadece uptime/nabız |
| Cihaz başı yük | node_exporter tek binary (~hafif, :9100) | Agent zengin ama 700'de Parent/Cloud planı gerekir | Yok (ajan gerektirmez; push/ping) |
| Kurulum sadeliği | Orta (prometheus.yml + systemd) | Kolay (agent), ama 700'de merkezi tasarım gerekir | Çok kolay (tek Docker konteyneri) |
| Alarm | Alertmanager / Grafana alerting (ücretsiz) | Cloud bildirimleri kotaya bağlı | 90+ bildirim servisi, ücretsiz, 20 sn aralık — https://github.com/louislam/uptime-kuma |
| Last-seen/çevrimdışı takibi | `up` metriği + `time() - timestamp` | Agent kalp atışı (kotalı merkez) | Push monitörü + ping grafik + sertifika bilgisi |
### 2.3. 17 minimum metrik — nerede, nasıl toplanır
Önerilen mimaride (Prometheus birincil + Uptime Kuma tamamlayıcı) her metriğin kaynağı:
| # | Metrik | Prometheus + Node Exporter | Uptime Kuma | Netdata Community |
|---|---|---|---|---|
| 1 | online/offline | `up{job="node"}` (scrape başarısı) | HTTP/TCP/Ping monitörü UP/DOWN | agent kalp atışı |
| 2 | last seen (son görülme) | `time() - timestamp(up)` veya Pushgateway/nodeli `node_time_seconds` farkı | Push monitör zaman damgası | — (kotalı) |
| 3 | CPU % | `node_cpu_seconds_total` → rate | — | agent |
| 4 | RAM % | `node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes` | — | agent |
| 5 | Disk % (her mount) | `node_filesystem_avail_bytes / node_filesystem_size_bytes` | — | agent |
| 6 | Disk inode % | `node_filesystem_files_free / node_filesystem_files` | — | agent |
| 7 | Disk IO (read/write) | `node_disk_read_bytes_total`, `node_disk_written_bytes_total` | — | agent |
| 8 | Ağ up/down (B/sn) | `node_network_receive_bytes_total`, `node_network_transmit_bytes_total` | ping gecikme grafiği (kısmi) | agent |
| 9 | Load average (1/5/15) | `node_load1/5/15` | — | agent |
| 10 | Uptime / boot zamanı | `node_boot_time_seconds`, `node_time_seconds - node_boot_time_seconds` | — | agent |
| 11 | Swap kullanımı | `node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes` | — | agent |
| 12 | systemd failed üniteler | `node_systemd_unit_state{state="failed"}` (systemd collector) | — | agent |
| 13 | Sıcaklık (CPU/disk) | `node_hwmon_temp_celsius` / `node_thermal_zone_temp` (textfile ile de beslenebilir) | — | agent/eBPF |
| 14 | WireGuard handshake yaşı | textfile collector (`wg show all latest-handshakes` → `.prom`) | Ping monitörü (dolaylı: VPN çökerse DOWN) | — |
| 15 | Docker konteyner durumu (MEG dahil) | cAdvisor veya textfile (`docker ps` özeti → `.prom`) | Docker konteyner monitörü (var/yok) | agent |
| 16 | MEG süreç sağlığı | textfile (`pgrep`/health endpoint → `.prom`) + blackbox HTTP probu | HTTP(s) Keyword monitörü (MEG arayüzü kelime kontrolü) | — |
| 17 | Ping gecikmesi / paket kaybı | blackbox_exporter `probe_duration_seconds`, `probe_success` | Ping grafiği (yerleşik) | — |
- Node Exporter collector'ları ve `:9100/metrics` davranışı: https://prometheus.io/docs/guides/node-exporter/
- textfile collector (özel metrikler: WireGuard, Docker, MEG için standart yol): Node Exporter `--collector.textfile.directory`
(https://github.com/prometheus/node_exporter).
- Uptime Kuma yetenekleri (Docker konteyner, Push, HTTP Keyword, ping grafiği, 20 sn aralık, 90+ bildirim):
https://github.com/louislam/uptime-kuma
- Netdata ücretsiz kotası nedeniyle 3–17'nin merkezi takibi 700 cihazda ücrete takılır:
https://www.netdata.cloud/pricing/
**Free sürüm limit notları (monitoring):**
- Prometheus + Node Exporter: limitsiz ve kotasız (Apache-2.0); limit, donanım kapasitesidir (retention/kardinalite LAB'da ölçülür).
- Grafana OSS (AGPL-3.0, self-hosted ücretsiz): dashboard, alerting, LDAP/OAuth dahil; Enterprise'a özgü
(SAML, audit log, datasource izinleri, scaling desteği) özellikler kapsam dışı bırakıldı — 14-MONITORING yalnızca OSS
özelliği kullanır (https://grafana.com/oss/).
- Netdata: Agent OSS (GPL-3.0) tek başına kotasızdır, ancak 700 cihazın **merkezi** görünümü Cloud üzerinden
kotaya takılır (Free: 5 node; sonrası node başına ücret). Self-hosted Parent ile merkezileştirme mümkün olsa da
ek tasarım/işletme yükü getirir → elenme gerekçesi budur.
- Uptime Kuma (MIT): tüm özellikler ücretsiz, yerleşik limit yok; tek sınır, metrik toplamamasıdır (uptime nabzı verir).
### 2.4. KARAR
- **KARAR:** Birincil **Prometheus + Node Exporter + Grafana OSS** (tüm 17 metrik); tamamlayıcı **Uptime Kuma**
(saha-teknisyeni dostu UP/DOWN panosu + Push "last seen" + bildirimler). Netdata elendi.
- **GEREKÇE:** 17 metriğin tamamı yalnızca Prometheus yığınında ücretsiz ve kotasız toplanır (14/15/16 textfile ile);
Netdata Cloud Free 5 node kotası 700 cihazda ücrete düşer; Uptime Kuma metrik vermez ama en basit
çevrimdışı alarmını ve durum sayfasını verir — ikisi birbirini tamamlar, karmaşıklık artmaz (Uptime Kuma tek konteyner).
- **ALTERNATİF:** Yalnızca Uptime Kuma (metrik körlüğü → elendi); Netdata self-hosted Parent (merkezi tasarım + kota riski → elendi).
- **RİSK:** 700 node'lu Prometheus'ta saklama/kardinalite → kayıt aralığı 60 sn, retention 30–90 gün, etiket şeması
`BF-<no>` standardında sabitlenir; federasyon/fazlı rollout ile büyütülür.
- **MALİYET:** $0 (kendi VDS'i üzerinde).
- **LİSANS:** Prometheus/Node Exporter Apache-2.0; Grafana OSS AGPL-3.0 (değişiklik yapılmadan self-host kullanılır);
Uptime Kuma MIT.
---
## 3. Docs Platformu Karşılaştırması
### 3.1. Adaylar ve lisans
| Platform | Lisans | Kaynak |
|---|---|---|
| Docusaurus | MIT | https://github.com/facebook/docusaurus — https://docusaurus.io/ |
| MkDocs (+ Material) | BSD-2-Clause (MkDocs); Material for MkDocs MIT/Insiders ayrı | https://github.com/mkdocs/mkdocs — https://www.mkdocs.org/ — https://squidfunk.github.io/mkdocs-material/ |
| Wiki.js | AGPL-3.0 | https://github.com/requarks/wiki — https://js.wiki/ — https://docs.requarks.io/ |
| TriliumNext | AGPL-3.0, kişisel bilgi tabanı | https://github.com/TriliumNext/Trilium |
### 3.2. Kriter matrisi (şartname: ücretsiz/OSS, self-hosted, Git, Markdown, AI-güncelleme, search, sidebar, kod, Mermaid, koyu tema, intranet)
| Kriter | Docusaurus | MkDocs (+Material) | Wiki.js | TriliumNext |
|---|---|---|---|---|
| Ücretsiz/OSS | Evet (MIT) | Evet (BSD) | Evet (AGPL-3.0) | Evet (AGPL-3.0) |
| Self-hosted intranet | Evet (statik dosya, Nginx) | Evet (statik dosya, Nginx) | Evet (Node.js + PostgreSQL/SQLite) | Kısmi (tek kullanıcılı sunucu modu; ekip intraneti için uygun değil) |
| Git (sürümleme/diff/PR) | **Yerleşik: docs zaten Git'te** | **Yerleşik: docs zaten Git'te** | Harici: Git storage hedefi senkronu (ek yapılandırma) — https://docs.requarks.io/storage/git | Yerleşik değil (kendi sync formatı) |
| Markdown | Evet (MDX dahil) | Evet | Evet (+WYSIWYG/HTML editör) — https://js.wiki/ | Evet (zengin not, wiki değil) |
| AI ile güncelleme | **En kolay: düz `.md` dosyalar, ajan doğrudan düzenler** | **En kolay: düz `.md` dosyalar** | API/DB üzerinden (dolaylı) | API üzerinden (dolaylı) |
| Arama | Yerleşik (lokal search eklentisi, offline çalışır) | Yerleşik (Material search, offline) | Yerleşik (DB tabanlı) | Yerleşik (kişisel) |
| Sidebar/sürüm/i18n | Yerleşik (sidebar, versioning, i18n) | Eklenti/tema ile | Yerleşik navigasyon | Ağaç not yapısı |
| Kod blokları | Prism, sekmeli kod, başlıklı blok | Highlight + ek eklentiler | Evet | Evet |
| Mermaid | Resmi destek — https://docusaurus.io/docs/markdown-features/diagrams | Material ile destek — https://squidfunk.github.io/mkdocs-material/reference/diagrams/ | Modül ile (ek yapılandırma) | Sınırlı/eklenti |
| Koyu tema | Yerleşik (kullanıcı değiştirebilir) | Yerleşik (Material toggle) | Yerleşik (light/dark) — https://js.wiki/ | Tema var |
| Operasyonel yük | Derleme hattı (Node), DB yok | Derleme hattı (Python), DB yok | **Çalışan servis + DB (yedekleme/izleme ister)** | Düşük ama ekip akışına uygun değil |
- Wiki.js özellik/editör/karanlık mod/DB seçenekleri: https://js.wiki/
- Docusaurus diyagram/search/versioning/i18n: https://docusaurus.io/docs/markdown-features/diagrams
- MkDocs statik üretim: https://www.mkdocs.org/
**Free sürüm limit notları (docs):** Dört adayın da önerilen sürümü tam ücretsizdir — gizli kota yok:
Docusaurus MIT (tüm özellikler açık), MkDocs BSD + Material Community (ücretli "Insider" eklentileri kapsam dışı,
gerekli değil), Wiki.js AGPL-3.0 (tüm modüller dahil, Enterprise sürümü yok), TriliumNext AGPL-3.0.
Elendikleri için değil, free-limitleri olmadığı için not düşüldü; seçim ölçütü Git-yerleşiklik + AI-güncelleme + sıfır servis yüküdür.
### 3.3. KARAR
- **KARAR:** **Docusaurus** (repo'da `docs-site/` iskeleti; `docs/*.md` tek kaynak, site derlemesi CI'da).
- **GEREKÇE:** Şartnamedeki "AI-güncelleme" kriterini yalnızca Git-yerleşik Markdown çözer (ajan `.md`'yi doğrudan yazar,
review PR'dan geçer); Wiki.js'nin DB+servis yükü "basitlik" kuralını bozar ve Git akışını dolaylı hale getirir;
TriliumNext tek-kullanıcı bilgi tabanıdır, 26 dosyalık ekip dokümantasyonu için yayın akışı yoktur;
MkDocs'a karşı Docusaurus'u seçme nedeni: yerleşik sürümleme (LAB→PROD evrelerinde doküman sürümü),
yerleşik i18n (TR öncelikli, EN yolu açık), MDX ile runbook içi parametreli bileşenler ve React ekosisteminde
hazır intranet temaları — derleme maliyeti MkDocs ile eşdeğerdir.
- **ALTERNATİF:** MkDocs + Material (eşdeğer sadelikte güçlü ikinci; Docusaurus derleme hattı sorun çıkarırsa geçiş
maliyeti düşük çünkü kaynak yine düz Markdown). Wiki.js (DB yükü → elendi). TriliumNext (ekip akışı yok → elendi).
- **RİSK:** Node derleme hattı → `docs-site/` kilitli bağımlılıklar + CI'da derleme testi; derleme bozulsa bile
`docs/*.md` ham haliyle okunur (tek kaynak kaybı yok).
- **MALİYET:** $0.
- **LİSANS:** Docusaurus MIT; üretilen içerik bize ait.
---
## 4. Özet — üç tek-öneri
1. **Fleet:** Ansible CLI + Semaphore UI Community (Pro bağımlılığı yok — kanıt §1.2).
2. **Monitoring:** Prometheus + Node Exporter + Grafana OSS (17 metrik) + Uptime Kuma (UP/DOWN + bildirim).
3. **Docs:** Docusaurus (`docs/*.md` tek kaynak).
## 5. Açık sorular (karar günlüğüne taşınacak)
- Semaphore Community'de lisansla dayatılan node kotası yoktur varsayımı `pricing` + repo davranışıyla doğrulandı;
700 node'lu gerçek yük testi LAB evresinde yapılır (Global Runner sayısı, eşzamanlılık).
- Prometheus retention/kardinalite hesabı (700 × 60 sn scrape) LAB'da ölçülür, 14-MONITORING'e yazılır.
- Uptime Kuma Push monitörleri için cihaz başına heartbeat betiği sözleşmesi 14-MONITORING'e yazılır.

0
rustdesk/.gitkeep Normal file
View file

View file

0
scripts/install/.gitkeep Normal file
View file

View file

View file

0
tests/.gitkeep Normal file
View file