apply($host, sprintf( 'nft add element inet clupilot_filter %s { %s timeout %ds }', $this->setFor($ip), $ip, $seconds, )); } public function release(Host $host, string $ip): bool { return $this->apply($host, sprintf( 'nft delete element inet clupilot_filter %s { %s }', $this->setFor($ip), $ip, )); } /** Die Adressfamilie entscheidet über die Menge — v4 und v6 leben getrennt. */ private function setFor(string $ip): string { return str_contains($ip, ':') ? 'clupilot_blocked6' : 'clupilot_blocked'; } private function apply(Host $host, string $command): bool { try { $this->shell->connectWithKey( $host->wg_ip, 'root', (string) app(SecretVault::class)->get('ssh.private_key'), $host->ssh_host_key, // gepinnt bei EstablishSshTrust ); return $this->shell->run($command)->ok(); } catch (Throwable) { return false; } } }