89 lines
2.2 KiB
PHP
89 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Modals;
|
|
|
|
use App\Models\AuditEvent;
|
|
use App\Models\Server;
|
|
use App\Services\Fail2banService;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use LivewireUI\Modal\ModalComponent;
|
|
use Throwable;
|
|
|
|
/**
|
|
* Manually ban an IP in a fail2ban jail (R5: a deliberate confirm dialog, not a
|
|
* native popup). Fail2banService refuses to ban loopback or Clusev's own connection,
|
|
* so this can never lock the operator out.
|
|
*/
|
|
class Fail2banBan extends ModalComponent
|
|
{
|
|
public int $serverId;
|
|
|
|
/** @var array<int, string> */
|
|
public array $jails = [];
|
|
|
|
public string $jail = '';
|
|
|
|
public string $ip = '';
|
|
|
|
public ?string $error = null;
|
|
|
|
/**
|
|
* @param array<int, string> $jails
|
|
*/
|
|
public function mount(int $serverId, array $jails = []): void
|
|
{
|
|
$this->serverId = $serverId;
|
|
$this->jails = array_values($jails);
|
|
$this->jail = $this->jails[0] ?? 'sshd';
|
|
}
|
|
|
|
public static function modalMaxWidth(): string
|
|
{
|
|
return 'lg';
|
|
}
|
|
|
|
public function save(Fail2banService $fail2ban): void
|
|
{
|
|
$this->error = null;
|
|
|
|
$server = Server::find($this->serverId);
|
|
if (! $server) {
|
|
$this->error = 'Server nicht gefunden.';
|
|
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$res = $fail2ban->ban($server, $this->jail, trim($this->ip));
|
|
} catch (Throwable $e) {
|
|
$this->error = $e->getMessage();
|
|
|
|
return;
|
|
}
|
|
|
|
if (! $res['ok']) {
|
|
$this->error = $res['output'] !== '' ? $res['output'] : 'Sperren fehlgeschlagen.';
|
|
|
|
return;
|
|
}
|
|
|
|
AuditEvent::create([
|
|
'user_id' => Auth::id(),
|
|
'server_id' => $server->id,
|
|
'actor' => Auth::user()?->name ?? 'system',
|
|
'action' => 'fail2ban.ban',
|
|
'target' => trim($this->ip).' · '.$this->jail.' · '.$server->name,
|
|
'ip' => request()->ip(),
|
|
]);
|
|
|
|
$this->dispatch('fail2banChanged');
|
|
$this->dispatch('notify', message: 'IP '.trim($this->ip).' gesperrt.');
|
|
$this->closeModal();
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.modals.fail2ban-ban');
|
|
}
|
|
}
|