# Core/Services/Gatekeepers — IP/bakım/veritabanı kapıları, WAF, GeoIP (13 dosya) > **Doğrulanan kod tabanı:** `c23b431f` · **Tarih:** 2026-10-05 · **Yayın:** 0.9.7 = bu commit + sonrası; belge yalnız doğrulama anındaki kodu anlatır > **Kaynak klasör:** `Core/Services/Gatekeepers/` — **13 `*.php`** = 5 kök + `Concerns/` 2 + > `Handlers/` 5 + `Providers/` 1. > **Envanter:** 13 dosyanın **13'u** anlatıldı. > **Doğrulama platformu:** Windows + PHP 8.3; `IpGuardService::isAgentEndpoint()` 11 bypass > denemesiyle, `RawHtmlGate` ve `SystemGuardHandler` yardımcıları gerçekten çalıştırıldı. ## 1. Ne işe yarar, kim kullanır **İsteğin sunucuya girmeden önce "geçmeli mi?" sorusunu yanıtlayan** katman. Beş kapı var ve hepsi `Kernel` aşamalarından ya da `ShieldSentinel`'dan çağrılır: | Kapı | Servis | Aşama | |---|---|---| | Erken boot güvenliği | `BootSentinel` | `PreBoot` | | IP / WAF / hız sınırı | `IpGuardService` | `ShieldSentinel` | | Bakım modu / VIP | `SystemGuardService` | `ShieldSentinel` | | Veritabanı bütünlüğü | `DatabaseGuardService` | `DatabaseGuardStage` | | Güvenlik ayarları | `ShieldSettingsService` | her yerden | **Değişmez kural:** `shield_ip_guard_mode` **bu çalışmada değiştirilmedi**. Varsayılan `log_only`; `enforce` **yalnız tam `'enforce'` metni** ile açılır (`IpGuardHandler.php:40-43`). ## 2. Klasör/dosya envanteri (13/13) | Dosya | Görev | Önemli public yöntemler | |---|---|---| | `BootSentinel.php` (154) | **Sıfır bağımlılıklı** erken-boot bekçisi: `set_exception_handler`, `set_error_handler`, `register_shutdown_function` kurar ve 3 katmanlı kurtarma yürütür. | `static register(?Throwable $e=null): void`, `dispatch(Throwable $e): void`, `static render(Throwable $e): void` | | `IpGuardService.php` (566) | **Ana IP kapısı.** Kara/beyaz liste, bot, GeoIP, WAF taraması, ajan ucu muafiyeti, kademeli ceza. | `boot()`, `check()`, `isLimitReached(string $identifier,string $action): bool`, `remainingTime(string,string): int`, `recordHit(string,string,array $metadata=[]): bool`, `countryCode(string $ip): string`, `flag(string $countryCode): string`, `isBlockedBot(string $userAgent): bool`, `isAgentEndpoint(?string $uri=null): bool`, `detectAttack(?string $body=null): ?string`, `progressiveBlockMinutes(string $ip): int`, `blockIpAddress(string $ip,string $reason,int $durationMinutes=1440,?int $projectId=0): void` · `const BODY_SCAN_MAX_BYTES=65536`, `const KADEMELI_CEZA_DAKIKA=[15,60,1440,1440]` | | `SystemGuardService.php` (42) | Bakım modu orkestratörü (42 satır). | `boot()`, `check(): void` | | `DatabaseGuardService.php` (77) | Veritabanı yolu/ayar doğrulama orkestratörü. | `boot()`, `resolvePath(string $category,?string $projectKey=null): string`, `resolveConfig(string $category,?string $projectKey=null): DatabaseConfig`, `check(): void` | | `ShieldSettingsService.php` (51) | Güvenlik anahtarı okuma/yazma + önbellek temizleme. | `getSetting(string $key,$default=null)`, `getGroup(string $groupKey): array`, `set(string $key,$value,string $groupKey='general',string $valueType='boolean',?string $projectKey=null): bool` | | `Handlers/IpGuardHandler.php` (464) | **Karar motoru.** Beyaz liste → bot → ajan muafiyeti → WAF → kara liste sırası; log_only/enforce. | `check(): array` · korumalı: `wouldBlock()`, `decision()`, `logWouldBlock()`, `logWarning()`, `logError()` | | `Handlers/SystemGuardHandler.php` (248) | Bakım modu + VIP (geliştirici token, yerel IP, global VIP listesi). | `isAccessDenied(): bool`, `getMaintenanceMessage(): string` · korumalı: `isStaticAssetPath(string)`, `isCliRequest()`, `safeConfig()`, `resolveFailClosed()`, `logGuardWarning()` · `private const FAILCLOSED_OFF_VALUES` | | `Handlers/DatabaseGuardHandler.php` (245) | Yol bütünlüğü, tablo varlığı, proje durumu, **lisans kapısı**, yazma yetkisi. | `resolve(string $category,?string $projectKey=null): string` · korumalı: `validateIntegrity()`, `verifyTables()`, `checkProjectStatus()`, `isUnrestricted()`, `checkWritePermissions()` | | `Handlers/RateLimitHandler.php` (215) | Hız sınırı (nitelikli sayaç). | `__construct()`, `isBlocked(string $identifier,string $action): bool`, `canonicalAction(string $action): string`, `hasLimit(string $action): bool`, `recordAttempt(string $identifier,string $action,array $metadata=[]): bool`, `getRemainingTime(string $identifier,string $action): int`, `getLimits(): array` · korumalı: `logWarning()` | | `Handlers/GeoIPHandler.php` (389) | IP → ülke kodu (harici `ipwho.is`), bayrak/ülke adı. | `getCountryCode(string $ip): string`, `static ulkeKoduAyikla(?string $govde): string`, `getFlag(string $countryCode): string`, `getCountryName(string $countryCode): string` · `public const BILINMEYEN_ULKE='XX'` · `private const GEOIP_UC_NOKTA/GEOIP_SUNUCU/GEOIP_TIMEOUT_SN/GEOIP_MAX_GOVDE_BAYT` | | `Providers/DatabaseGuardProvider.php` (197) | Veritabanı sağlayıcısı: kimlik bilgisi, bağlantı testi, tablo listesi, **heartbeat yazma testi**. | `loadCredentials(string $category,string $path): array`, `testConnection(string $category): \PDO`, `fetchTableList(\PDO): array`, `fetchProjectData(string $projectKey): ?array`, `performHeartbeatTest(\PDO): void` · `private const PROJECT_DATA_COLUMNS` | | `Concerns/LogsGuardErrors.php` (56) | Koruma katmanı hata günlükleme. | `logGuardError(…)` | | `Concerns/LogsLicenceWarnings.php` (44) | Lisans anormallik günlükleme (B-04 tekrar koruması). | `licenceWarn(string $message): void`, `licenceWarnOnce(string $message): void` | ## 3. Akış — `BootSentinel` (154 satır, **hiç miras yok**) ``` BootSentinel::register() BootSentinel.php:26 ├─ $e verilmişse → dispatch($e) ve return :31-34 ├─ set_exception_handler([$instance,'dispatch']) :37 ├─ set_error_handler(...) → ErrorException'a çevirir :39-43 └─ register_shutdown_function(...) → E_ERROR/E_PARSE/E_CORE_ERROR/E_COMPILE_ERROR :45-50 BootSentinel::dispatch($e) :56-106 0. LogHandler::failsafeLog() — panik seviyesinde kayıt :60-73 · level = ShieldMetadata::ERROR_MAP[...] ?? 'development' :63 · reason = level==='user' ? 'warning' : 'panic' :65 1. ExceptionHandler::handle($e) + exit :79-87 2. SurvivalProvider::render(...) + exit :90-102 3. self::render($e) ← sıfır bağımlılıklı son savunma :105 BootSentinel::render($e) :111-153 ├─ define('RBN_PANIC_ACTIVE', true) :114-116 ├─ Watchdog::$inPanic = true :118-120 ├─ while (ob_get_level() > 0) ob_end_clean() :123-125 ├─ header 500 + Content-Type (headers_sent değilse) :128-131 ├─ Resources/Views/Errors/panic.view.php include + exit(1) :140-145 └─ die("