feat(Production): Complete production deployment infrastructure

- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -0,0 +1,420 @@
<?php
declare(strict_types=1);
namespace App\Framework\Waf\Layers;
use App\Framework\Waf\Layers\LayerInterface;
use App\Framework\Waf\LayerResult;
use App\Framework\Waf\ValueObjects\LayerConfig;
use App\Framework\Waf\ValueObjects\LayerMetrics;
use App\Framework\Waf\ValueObjects\Detection;
use App\Framework\Waf\ValueObjects\DetectionCategory;
use App\Framework\Waf\ValueObjects\DetectionSeverity;
use App\Framework\Waf\ValueObjects\DetectionStatus;
use App\Framework\Waf\MachineLearning\BehaviorPatternExtractor;
use App\Framework\Waf\MachineLearning\BehaviorAnomalyDetector;
use App\Framework\Waf\MachineLearning\RequestHistoryTracker;
use App\Framework\Http\Request;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Percentage;
use App\Framework\Core\ValueObjects\Score;
use Psr\Log\LoggerInterface;
/**
* ML-Enhanced WAF Layer for Advanced Behavioral Analysis
*
* Provides sophisticated threat detection through:
* - Behavioral pattern extraction (8 features)
* - Statistical anomaly detection
* - Heuristic-based threat classification
* - Request sequence analysis
*
* Architecture:
* RequestHistoryTracker → BehaviorPatternExtractor → BehaviorAnomalyDetector → LayerResult
*/
final class MLEnhancedWafLayer implements LayerInterface
{
private const string LAYER_NAME = 'ML-Enhanced Behavioral Analysis';
private const string VERSION = '1.0.0';
private const int PRIORITY = 100; // High priority for ML analysis
private LayerConfig $config;
private LayerMetrics $metrics;
private bool $isHealthy = true;
private int $detectionCount = 0;
private int $requestCount = 0;
/**
* @param Score $confidenceThreshold Minimum confidence for threat classification
* @param int $minHistorySize Minimum request history for analysis
* @param bool $enableStatisticalDetection Use statistical baseline comparison
*/
public function __construct(
private readonly RequestHistoryTracker $historyTracker,
private readonly BehaviorPatternExtractor $patternExtractor,
private readonly BehaviorAnomalyDetector $anomalyDetector,
private readonly LoggerInterface $logger,
private readonly Score $confidenceThreshold = new Score(0.6),
private readonly int $minHistorySize = 5,
private readonly bool $enableStatisticalDetection = true
) {
$this->config = LayerConfig::default()
->withTimeout(Duration::fromMilliseconds(100))
->withConfidenceThreshold(Percentage::from(60.0));
$this->metrics = new LayerMetrics(
totalRequests: 0,
totalDetections: 0,
totalBlocks: 0,
averageProcessingTime: Duration::fromMilliseconds(0),
falsePositiveRate: Percentage::from(0.0),
detectionRate: Percentage::from(0.0)
);
}
public function getName(): string
{
return self::LAYER_NAME;
}
public function analyze(Request $request): LayerResult
{
$startTime = microtime(true);
$this->requestCount++;
try {
// 1. Track current request for sequence building
$this->historyTracker->track($request);
// 2. Get request sequence for client IP
$clientIp = $request->server->getRemoteAddr();
$sequence = $this->historyTracker->getSequence($clientIp);
// 3. Check if we have enough history for analysis
if (!$this->historyTracker->hasSufficientHistory($clientIp, $this->minHistorySize)) {
$processingTime = Duration::fromMilliseconds((microtime(true) - $startTime) * 1000);
return LayerResult::clean(
$this->getName(),
'Insufficient request history for behavioral analysis',
$processingTime
);
}
// 4. Extract behavioral features
$features = $this->patternExtractor->extract($sequence);
// 5. Detect anomalies
$anomalyResult = $this->anomalyDetector->detect(
$features,
[] // TODO: Implement baseline storage for statistical detection
);
$processingTime = Duration::fromMilliseconds((microtime(true) - $startTime) * 1000);
// 6. Evaluate threat level
if (!$anomalyResult->isAnomalous) {
return LayerResult::clean(
$this->getName(),
$anomalyResult->primaryIndicator,
$processingTime
);
}
// 7. Check if anomaly score exceeds threshold
if ($anomalyResult->anomalyScore->isBelow($this->confidenceThreshold)) {
return LayerResult::clean(
$this->getName(),
"Low confidence anomaly: {$anomalyResult->primaryIndicator}",
$processingTime,
metadata: [
'anomaly_score' => $anomalyResult->anomalyScore->value(),
'severity' => $anomalyResult->getSeverity(),
'below_threshold' => true
]
);
}
// 8. Build detections from anomaly result
$detections = $this->buildDetections($anomalyResult, $sequence);
$this->detectionCount += count($detections);
// 9. Log threat detection
if ($this->config->logDetections) {
$this->logger->warning('ML WAF: Behavioral anomaly detected', [
'layer' => $this->getName(),
'client_ip' => $clientIp->toString(),
'anomaly_score' => $anomalyResult->anomalyScore->value(),
'severity' => $anomalyResult->getSeverity(),
'primary_indicator' => $anomalyResult->primaryIndicator,
'detected_patterns' => $anomalyResult->detectedPatterns,
'sequence_stats' => $sequence->getStatistics()
]);
}
return LayerResult::threat(
$this->getName(),
$anomalyResult->primaryIndicator,
$this->mapScoreToStatus($anomalyResult->anomalyScore),
$detections,
$processingTime,
metadata: [
'anomaly_score' => $anomalyResult->anomalyScore->value(),
'severity' => $anomalyResult->getSeverity(),
'recommended_action' => $anomalyResult->getRecommendedAction(),
'top_contributors' => $anomalyResult->getTopContributors()
]
);
} catch (\Throwable $e) {
$processingTime = Duration::fromMilliseconds((microtime(true) - $startTime) * 1000);
$this->logger->error('ML WAF Layer analysis failed', [
'layer' => $this->getName(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
$this->isHealthy = false;
return LayerResult::error(
$this->getName(),
'Behavioral analysis failed: ' . $e->getMessage(),
$processingTime
);
}
}
/**
* Build Detection objects from anomaly result
*/
private function buildDetections(
\App\Framework\Waf\MachineLearning\ValueObjects\BehaviorAnomalyResult $anomalyResult,
\App\Framework\Waf\MachineLearning\ValueObjects\RequestSequence $sequence
): array {
$detections = [];
foreach ($anomalyResult->detectedPatterns as $pattern) {
$patternType = $pattern['type'] ?? 'unknown';
$category = $this->mapPatternToCategory($patternType);
$severity = $this->mapScoreToSeverity($anomalyResult->anomalyScore);
$detections[] = new Detection(
category: $category,
severity: $severity,
pattern: $patternType,
value: json_encode($pattern),
description: $this->buildPatternDescription($pattern),
confidence: Percentage::fromDecimal($anomalyResult->anomalyScore->value()),
location: 'behavioral_analysis',
status: DetectionStatus::CONFIRMED
);
}
// Add feature-based detections for top contributors
foreach ($anomalyResult->getTopContributors(3) as $featureName => $score) {
$detections[] = new Detection(
category: DetectionCategory::BEHAVIORAL_ANOMALY,
severity: $this->mapScoreToSeverity($score),
pattern: "anomalous_{$featureName}",
value: (string) $score->value(),
description: "Anomalous {$featureName} pattern detected",
confidence: Percentage::fromDecimal($score->value()),
location: 'feature_analysis',
status: DetectionStatus::CONFIRMED
);
}
return $detections;
}
/**
* Map pattern type to detection category
*/
private function mapPatternToCategory(string $patternType): DetectionCategory
{
return match ($patternType) {
'potential_ddos' => DetectionCategory::DDOS_ATTACK,
'potential_scanning' => DetectionCategory::SECURITY_SCANNING,
'potential_bot' => DetectionCategory::BOT_ACTIVITY,
'potential_credential_stuffing' => DetectionCategory::AUTHENTICATION_ABUSE,
'statistical_outlier', 'iqr_outlier' => DetectionCategory::BEHAVIORAL_ANOMALY,
default => DetectionCategory::BEHAVIORAL_ANOMALY
};
}
/**
* Map Score to DetectionSeverity
*/
private function mapScoreToSeverity(Score $score): DetectionSeverity
{
return match (true) {
$score->isCritical() => DetectionSeverity::CRITICAL,
$score->isHigh() => DetectionSeverity::HIGH,
$score->isMedium() => DetectionSeverity::MEDIUM,
default => DetectionSeverity::LOW
};
}
/**
* Map Score to DetectionStatus
*/
private function mapScoreToStatus(Score $score): DetectionStatus
{
return match (true) {
$score->isCritical(), $score->isHigh() => DetectionStatus::CONFIRMED,
$score->isMedium() => DetectionStatus::SUSPECTED,
default => DetectionStatus::POSSIBLE
};
}
/**
* Build human-readable pattern description
*/
private function buildPatternDescription(array $pattern): string
{
$type = $pattern['type'] ?? 'unknown';
return match ($type) {
'potential_ddos' => sprintf(
'High request frequency (%.2f req/s) with low endpoint diversity (%.2f)',
$pattern['frequency'] ?? 0.0,
$pattern['diversity'] ?? 0.0
),
'potential_scanning' => sprintf(
'High parameter entropy (%.2f) combined with geographic anomaly (%.2f)',
$pattern['entropy'] ?? 0.0,
$pattern['geo_anomaly'] ?? 0.0
),
'potential_bot' => sprintf(
'Perfect timing regularity (%.2f) with high payload similarity (%.2f)',
$pattern['regularity'] ?? 0.0,
$pattern['similarity'] ?? 0.0
),
'potential_credential_stuffing' => sprintf(
'High frequency (%.2f req/s) with inconsistent User-Agent (%.2f)',
$pattern['frequency'] ?? 0.0,
$pattern['ua_consistency'] ?? 0.0
),
'statistical_outlier' => sprintf(
'Feature %s is a statistical outlier (z-score: %.2f)',
$pattern['feature'] ?? 'unknown',
$pattern['z_score'] ?? 0.0
),
default => 'Behavioral anomaly detected'
};
}
public function isEnabled(): bool
{
return $this->config->enabled;
}
public function isHealthy(): bool
{
return $this->isHealthy;
}
public function getPriority(): int
{
return self::PRIORITY;
}
public function getConfidenceLevel(): Percentage
{
// Average confidence based on detection rate
if ($this->requestCount === 0) {
return Percentage::from(100.0);
}
$detectionRate = ($this->detectionCount / $this->requestCount) * 100;
$confidence = 100.0 - min($detectionRate, 50.0); // Lower confidence if too many detections
return Percentage::from($confidence);
}
public function getTimeoutThreshold(): Duration
{
return $this->config->getEffectiveTimeout();
}
public function configure(LayerConfig $config): void
{
$this->config = $config;
}
public function getConfig(): LayerConfig
{
return $this->config;
}
public function getMetrics(): LayerMetrics
{
return $this->metrics;
}
public function reset(): void
{
$this->detectionCount = 0;
$this->requestCount = 0;
$this->isHealthy = true;
$this->metrics = new LayerMetrics(
totalRequests: 0,
totalDetections: 0,
totalBlocks: 0,
averageProcessingTime: Duration::fromMilliseconds(0),
falsePositiveRate: Percentage::from(0.0),
detectionRate: Percentage::from(0.0)
);
}
public function warmUp(): void
{
$this->logger->info('ML WAF Layer warming up', [
'layer' => $this->getName(),
'confidence_threshold' => $this->confidenceThreshold->value(),
'min_history_size' => $this->minHistorySize
]);
}
public function shutdown(): void
{
$this->logger->info('ML WAF Layer shutting down', [
'layer' => $this->getName(),
'total_requests' => $this->requestCount,
'total_detections' => $this->detectionCount
]);
}
public function getDependencies(): array
{
return [
RequestHistoryTracker::class,
BehaviorPatternExtractor::class,
BehaviorAnomalyDetector::class
];
}
public function supportsParallelProcessing(): bool
{
return true; // Can run in parallel with other layers
}
public function getVersion(): string
{
return self::VERSION;
}
public function getSupportedCategories(): array
{
return [
DetectionCategory::BEHAVIORAL_ANOMALY,
DetectionCategory::DDOS_ATTACK,
DetectionCategory::SECURITY_SCANNING,
DetectionCategory::BOT_ACTIVITY,
DetectionCategory::AUTHENTICATION_ABUSE
];
}
}