mailwolt/database/seeders/Fail2banSeeder.php

110 lines
3.7 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Fail2banSetting;
use App\Models\Fail2banIpList;
use Illuminate\Support\Facades\Log;
class Fail2banSeeder extends Seeder
{
public function run(): void
{
$this->command->info('⚙️ Fail2ban Defaults werden initialisiert …');
// -----------------------------------------------------------
// 1) Standardwerte für Fail2ban Settings
// -----------------------------------------------------------
$settings = Fail2banSetting::firstOrCreate([], [
'bantime' => 3600, // 1h
'max_bantime' => 43200, // 12h
'bantime_increment' => true,
'bantime_factor' => 1.5,
'max_retry' => 5,
'findtime' => 600, // 10m
'cidr_v4' => 32,
'cidr_v6' => 128,
'external_mode' => false,
]);
// -----------------------------------------------------------
// 2) Standard-IPs für Whitelist
// -----------------------------------------------------------
$defaultWhitelist = [
'127.0.0.1/8',
'::1',
];
foreach ($defaultWhitelist as $ip) {
Fail2banIpList::firstOrCreate([
'ip' => $ip,
'type' => Fail2banIpList::TYPE_WHITELIST,
]);
}
// -----------------------------------------------------------
// 3) Fail2ban Config-Dateien erzeugen
// -----------------------------------------------------------
$this->writeDefaultsConfig($settings);
$this->writeWhitelistConfig();
// -----------------------------------------------------------
// 4) Fail2ban reload (optional, falls Dienst läuft)
// -----------------------------------------------------------
$out = shell_exec('sudo -n fail2ban-client reload 2>&1') ?? '';
if (stripos($out, 'OK') === false && stripos($out, 'Reloaded') === false) {
Log::warning('Fail2ban reload output', ['out' => $out]);
$this->command->warn('⚠️ Fail2ban reload möglicherweise nicht erfolgreich.');
} else {
$this->command->info('✅ Fail2ban reload erfolgreich.');
}
}
// -----------------------------------------------------------
// interne Hilfsfunktionen
// -----------------------------------------------------------
private function writeDefaultsConfig(Fail2banSetting $s): void
{
$content = <<<CONF
[DEFAULT]
bantime = {$s->bantime}
findtime = {$s->findtime}
maxretry = {$s->max_retry}
bantime.increment = {$this->boolToString($s->bantime_increment)}
bantime.factor = {$s->bantime_factor}
bantime.maxtime = {$s->max_bantime}
CONF;
$this->atomicWrite('/etc/fail2ban/jail.d/00-mailwolt-defaults.local', $content);
}
private function writeWhitelistConfig(): void
{
$ips = Fail2banIpList::where('type', Fail2banIpList::TYPE_WHITELIST)
->pluck('ip')
->toArray();
$ignore = implode(' ', array_unique(array_filter($ips)));
$content = "[DEFAULT]\nignoreip = {$ignore}\n";
$this->atomicWrite('/etc/fail2ban/jail.d/mailwolt-whitelist.local', $content);
}
private function atomicWrite(string $path, string $content): void
{
$tmp = $path . '.tmp';
file_put_contents($tmp, $content);
rename($tmp, $path);
@chown($path, 'root');
@chgrp($path, 'root');
@chmod($path, 0644);
}
private function boolToString(bool $v): string
{
return $v ? 'true' : 'false';
}
}