{
"tool_response": {
"stdout": "\"\"\"Firewall-Modul: nftables-Verwaltung (NUR nftables, NICHT iptables\/ufw).\"\"\"\n\nimport argparse\nimport sys\nfrom pathlib import Path\n\nfrom shared.sysop.nftables_client import NftablesClient\n\n\ndef register(subparsers: argparse._SubParsersAction) -> None:\n \"\"\"Registriert firewall Subcommand.\"\"\"\n fw_parser = subparsers.add_parser(\"firewall\", help=\"nftables-Firewall\")\n fw_sub = fw_parser.add_subparsers(dest=\"action\", help=\"Aktionen\")\n\n # status\n status_p = fw_sub.add_parser(\"status\", help=\"Firewall-Status\")\n status_p.set_defaults(func=cmd_status)\n\n # list\n list_p = fw_sub.add_parser(\"list\", help=\"Aktive Regeln anzeigen\")\n list_p.add_argument(\"--table\", \"-t\", help=\"Nur bestimmte Tabelle\")\n list_p.set_defaults(func=cmd_list)\n\n # reload\n reload_p = fw_sub.add_parser(\"reload\", help=\"Regeln neu laden\")\n reload_p.add_argument(\"--confirm\", action=\"store_true\",\n help=\"Bestaetigung (erforderlich)\")\n reload_p.set_defaults(func=cmd_reload)\n\n # sets\n sets_p = fw_sub.add_parser(\"sets\", help=\"Sets anzeigen\")\n sets_p.set_defaults(func=cmd_sets)\n\n # set - Subparser fuer Set-Verwaltung\n set_p = fw_sub.add_parser(\"set\", help=\"Set-Verwaltung\")\n set_sub = set_p.add_subparsers(dest=\"set_action\", help=\"Set-Aktionen\")\n\n # set create\n set_create = set_sub.add_parser(\"create\", help=\"Neues Set erstellen\")\n set_create.add_argument(\"name\", help=\"Name des Sets\")\n set_create.add_argument(\"--type\", \"-t\", default=\"ipv4_addr\",\n choices=[\"ipv4_addr\", \"ipv6_addr\"],\n help=\"Set-Typ (default: ipv4_addr)\")\n set_create.add_argument(\"--table\", default=\"inet filter\", help=\"Tabelle\")\n set_create.add_argument(\"--flags\", \"-f\", default=\"interval\",\n help=\"Set-Flags (default: interval fuer CIDR)\")\n set_create.set_defaults(func=cmd_set_create)\n\n # rule - Subparser fuer Regel-Verwaltung\n rule_p = fw_sub.add_parser(\"rule\", help=\"Regel-Verwaltung\")\n rule_sub = rule_p.add_subparsers(dest=\"rule_action\", help=\"Regel-Aktionen\")\n\n # rule add\n rule_add = rule_sub.add_parser(\"add\", help=\"Regel hinzufuegen\")\n rule_add.add_argument(\"chain\", help=\"Chain-Name\")\n rule_add.add_argument(\"rule\", help=\"Regel-Definition\")\n rule_add.add_argument(\"--table\", \"-t\", default=\"inet filter\", help=\"Tabelle\")\n rule_add.set_defaults(func=cmd_rule_add)\n\n # geoblock - Subparser\n geo_p = fw_sub.add_parser(\"geoblock\", help=\"GeoIP-Blocking verwalten\")\n geo_sub = geo_p.add_subparsers(dest=\"geo_action\", help=\"GeoBlock-Aktionen\")\n\n # geoblock list\n geo_list = geo_sub.add_parser(\"list\", help=\"GeoBlock-Sets anzeigen\")\n geo_list.set_defaults(func=cmd_geoblock_list)\n\n # geoblock add\n geo_add = geo_sub.add_parser(\"add\", help=\"IP zu Set hinzufuegen\")\n geo_add.add_argument(\"set_name\", help=\"Name des Sets\")\n geo_add.add_argument(\"element\", help=\"IP oder CIDR\")\n geo_add.add_argument(\"--table\", \"-t\", default=\"inet filter\", help=\"Tabelle\")\n geo_add.set_defaults(func=cmd_geoblock_add)\n\n # geoblock remove\n geo_rm = geo_sub.add_parser(\"remove\", help=\"IP aus Set entfernen\")\n geo_rm.add_argument(\"set_name\", help=\"Name des Sets\")\n geo_rm.add_argument(\"element\", help=\"IP oder CIDR\")\n geo_rm.add_argument(\"--table\", \"-t\", default=\"inet filter\", help=\"Tabelle\")\n geo_rm.set_defaults(func=cmd_geoblock_remove)\n\n # geoblock flush\n geo_flush = geo_sub.add_parser(\"flush\", help=\"Set leeren\")\n geo_flush.add_argument(\"set_name\", help=\"Name des Sets\")\n geo_flush.add_argument(\"--table\", \"-t\", default=\"inet filter\", help=\"Tabelle\")\n geo_flush.add_argument(\"--confirm\", action=\"store_true\", help=\"Bestaetigung\")\n geo_flush.set_defaults(func=cmd_geoblock_flush)\n\n # geoblock load\n geo_load = geo_sub.add_parser(\"load\", help=\"IPs aus Datei laden\")\n geo_load.add_argument(\"set_name\", help=\"Name des Sets\")\n geo_load.add_argument(\"file\", help=\"Datei mit IPs (eine pro Zeile)\")\n geo_load.add_argument(\"--table\", \"-t\", default=\"inet filter\", help=\"Tabelle\")\n geo_load.set_defaults(func=cmd_geoblock_load)\n\n\ndef cmd_status(args: argparse.Namespace) -> None:\n \"\"\"Zeigt Firewall-Status.\"\"\"\n status = NftablesClient.status()\n\n if not status.get(\"active\"):\n print(\"nftables: nicht aktiv oder nicht installiert\")\n if status.get(\"error\"):\n print(f\" Fehler: {status['error']}\")\n return\n\n print(\"nftables Firewall-Status:\\n\")\n print(f\" Status: aktiv\")\n print(f\" Tabellen: {status['table_count']}\")\n print(f\" Regeln: ~{status['rule_count']}\")\n\n if status.get(\"tables\"):\n print(\"\\n Tabellen:\")\n for table in status[\"tables\"]:\n print(f\" - {table}\")\n\n\ndef cmd_list(args: argparse.Namespace) -> None:\n \"\"\"Zeigt aktive Firewall-Regeln.\"\"\"\n table = getattr(args, \"table\", None)\n\n try:\n rules = NftablesClient.list_rules(table=table)\n print(\"nftables Ruleset:\\n\")\n print(rules)\n except RuntimeError as e:\n print(f\"Fehler: {e}\")\n sys.exit(1)\n\n\ndef cmd_reload(args: argparse.Namespace) -> None:\n \"\"\"Laedt Firewall-Regeln neu.\"\"\"\n if not getattr(args, \"confirm\", False):\n print(\"Fehler: --confirm erforderlich fuer Reload\")\n print(\" Verwendung: kiglove sysop firewall reload --confirm\")\n sys.exit(1)\n\n success, message = NftablesClient.reload()\n\n if not success:\n print(f\"Fehler beim Reload: {message}\")\n sys.exit(1)\n\n print(message)\n\n\ndef cmd_sets(args: argparse.Namespace) -> None:\n \"\"\"Zeigt alle nftables Sets.\"\"\"\n sets = NftablesClient.list_sets()\n\n if not sets:\n print(\"Keine Sets definiert.\")\n return\n\n print(f\"nftables Sets ({len(sets)}):\\n\")\n for s in sets:\n elem_count = len(s.get(\"elements\", []))\n print(f\" {s['name']}\")\n print(f\" Type: {s.get('type', 'unknown')}\")\n print(f\" Elements: {elem_count}\")\n print()\n\n\ndef cmd_set_create(args: argparse.Namespace) -> None:\n \"\"\"Erstellt ein neues nftables Set.\"\"\"\n success, message = NftablesClient.create_set(\n args.name,\n set_type=args.type,\n table=args.table,\n flags=args.flags\n )\n\n if not success:\n print(f\"Fehler: {message}\")\n sys.exit(1)\n\n print(message)\n\n\ndef cmd_rule_add(args: argparse.Namespace) -> None:\n \"\"\"Fuegt eine Regel hinzu.\"\"\"\n success, message = NftablesClient.add_rule(\n args.chain,\n args.rule,\n table=args.table\n )\n\n if not success:\n print(f\"Fehler: {message}\")\n sys.exit(1)\n\n print(message)\n\n\ndef cmd_geoblock_list(args: argparse.Namespace) -> None:\n \"\"\"Zeigt GeoBlock-Sets.\"\"\"\n sets = NftablesClient.list_sets()\n geo_sets = [s for s in sets if \"geo\" in s[\"name\"].lower() or \"block\" in s[\"name\"].lower()]\n\n if not geo_sets:\n print(\"Keine GeoBlock-Sets gefunden.\")\n print(\" Tipp: Sets mit 'geo' oder 'block' im Namen werden angezeigt.\")\n return\n\n print(f\"GeoBlock-Sets ({len(geo_sets)}):\\n\")\n for s in geo_sets:\n elem_count = len(s.get(\"elements\", []))\n print(f\" {s['name']}: {elem_count} Elemente\")\n\n\ndef cmd_geoblock_add(args: argparse.Namespace) -> None:\n \"\"\"Fuegt IP zu GeoBlock-Set hinzu.\"\"\"\n success, message = NftablesClient.add_to_set(\n args.set_name, args.element, table=args.table\n )\n\n if not success:\n print(f\"Fehler: {message}\")\n sys.exit(1)\n\n print(message)\n\n\ndef cmd_geoblock_remove(args: argparse.Namespace) -> None:\n \"\"\"Entfernt IP aus GeoBlock-Set.\"\"\"\n success, message = NftablesClient.remove_from_set(\n args.set_name, args.element, table=args.table\n )\n\n if not success:\n print(f\"Fehler: {message}\")\n sys.exit(1)\n\n print(message)\n\n\ndef cmd_geoblock_flush(args: argparse.Namespace) -> None:\n \"\"\"Leert GeoBlock-Set.\"\"\"\n if not getattr(args, \"confirm\", False):\n print(\"Fehler: --confirm erforderlich\")\n sys.exit(1)\n\n success, message = NftablesClient.flush_set(args.set_name, table=args.table)\n\n if not success:\n print(f\"Fehler: {message}\")\n sys.exit(1)\n\n print(message)\n\n\ndef cmd_geoblock_load(args: argparse.Namespace) -> None:\n \"\"\"Laedt IPs aus Datei in GeoBlock-Set.\"\"\"\n file_path = Path(args.file)\n\n if not file_path.exists():\n print(f\"Fehler: Datei nicht gefunden: {args.file}\")\n sys.exit(1)\n\n lines = file_path.read_text().strip().split(\"\\n\")\n ips = [line.strip() for line in lines if line.strip() and not line.startswith(\"#\")]\n\n if not ips:\n print(\"Keine IPs in Datei gefunden.\")\n return\n\n print(f\"Lade {len(ips)} IPs in {args.set_name}...\")\n\n success_count = 0\n error_count = 0\n\n for ip in ips:\n success, _ = NftablesClient.add_to_set(args.set_name, ip, table=args.table)\n if success:\n success_count += 1\n else:\n error_count += 1\n\n print(f\"Ergebnis: {success_count} hinzugefuegt, {error_count} Fehler\")",
"stderr": "",
"interrupted": false,
"isImage": false,
"noOutputExpected": false
}
}