feat(firewall): complete operational reliability phase
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -169,7 +169,8 @@ class FirewallService
|
||||
self::DEFAULT_AUTO_BLOCK_DURATION,
|
||||
self::MAX_AUTO_BLOCK_DURATION
|
||||
);
|
||||
if (!$this->store->claimBruteForce($tenantId, $ipAddress, $blockDuration)) {
|
||||
$responseCooldown = min($windowSeconds, max(1, intdiv($blockDuration, 2)));
|
||||
if (!$this->store->claimBruteForce($tenantId, $ipAddress, $responseCooldown)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -204,7 +205,17 @@ class FirewallService
|
||||
sprintf('Auto-blocked: %d failed auth attempts in %d seconds', $failureCount, $windowSeconds),
|
||||
null, // System-created
|
||||
$blockDuration,
|
||||
FirewallRuleManager::ORIGIN_AUTOMATIC
|
||||
FirewallRuleManager::ORIGIN_AUTOMATIC,
|
||||
[
|
||||
'failureThreshold' => $this->getBoundedIntegerConfig(
|
||||
self::CONFIG_MAX_FAILURES,
|
||||
self::DEFAULT_MAX_AUTH_FAILURES,
|
||||
self::MAX_AUTH_FAILURES
|
||||
),
|
||||
'failureWindowSeconds' => $windowSeconds,
|
||||
'lastFailureCount' => $failureCount,
|
||||
'blockDurationSeconds' => $blockDuration,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -257,6 +268,7 @@ class FirewallService
|
||||
SecurityEvent::ACCESS_DENIED => FirewallLogObject::EVENT_RULE_MATCH,
|
||||
SecurityEvent::SUSPICIOUS_ACTIVITY => FirewallLogObject::EVENT_SUSPICIOUS,
|
||||
SecurityEvent::FIREWALL_RULE_CREATED => FirewallLogObject::EVENT_RULE_CREATED,
|
||||
SecurityEvent::FIREWALL_RULE_EXTENDED => FirewallLogObject::EVENT_RULE_EXTENDED,
|
||||
SecurityEvent::FIREWALL_RULE_DISABLED => FirewallLogObject::EVENT_RULE_DISABLED,
|
||||
SecurityEvent::FIREWALL_RULE_REMOVED => FirewallLogObject::EVENT_RULE_REMOVED,
|
||||
default => FirewallLogObject::EVENT_ACCESS_CHECK,
|
||||
@@ -272,6 +284,7 @@ class FirewallService
|
||||
SecurityEvent::AUTH_SUCCESS,
|
||||
SecurityEvent::ACCESS_GRANTED => FirewallLogObject::RESULT_ALLOWED,
|
||||
SecurityEvent::FIREWALL_RULE_CREATED,
|
||||
SecurityEvent::FIREWALL_RULE_EXTENDED,
|
||||
SecurityEvent::FIREWALL_RULE_DISABLED,
|
||||
SecurityEvent::FIREWALL_RULE_REMOVED => FirewallLogObject::RESULT_RECORDED,
|
||||
default => FirewallLogObject::RESULT_BLOCKED,
|
||||
@@ -341,15 +354,31 @@ class FirewallService
|
||||
*/
|
||||
public function cleanup(): array
|
||||
{
|
||||
$expiredRules = $this->store->cleanupExpiredRules();
|
||||
$oldLogs = $this->store->cleanupOldLogs(30);
|
||||
$expiredClaims = $this->store->cleanupExpiredBruteForceClaims();
|
||||
$startedAt = new \DateTimeImmutable();
|
||||
|
||||
return [
|
||||
'expiredRules' => $expiredRules,
|
||||
'oldLogs' => $oldLogs,
|
||||
'expiredBruteForceClaims' => $expiredClaims,
|
||||
];
|
||||
try {
|
||||
$result = [
|
||||
'expiredRules' => $this->store->cleanupExpiredRules(),
|
||||
'oldLogs' => $this->store->cleanupOldLogs(30),
|
||||
'expiredBruteForceClaims' => $this->store->cleanupExpiredBruteForceClaims(),
|
||||
];
|
||||
$this->store->recordMaintenanceStatus($startedAt, new \DateTimeImmutable(), 'success', $result);
|
||||
|
||||
return $result;
|
||||
} catch (\Throwable $error) {
|
||||
try {
|
||||
$this->store->recordMaintenanceStatus(
|
||||
$startedAt,
|
||||
new \DateTimeImmutable(),
|
||||
'failed',
|
||||
[],
|
||||
$error->getMessage()
|
||||
);
|
||||
} catch (\Throwable) {
|
||||
// Preserve the cleanup failure when the status store is also unavailable.
|
||||
}
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user