Check for missing Fail2Ban jails (proxmox, proxmenux) and create them. Returns (success, message, applied_jails).
()
| 1029 | |
| 1030 | |
| 1031 | def apply_missing_jails(): |
| 1032 | """ |
| 1033 | Check for missing Fail2Ban jails (proxmox, proxmenux) and create them. |
| 1034 | Returns (success, message, applied_jails). |
| 1035 | """ |
| 1036 | applied = [] |
| 1037 | errors = [] |
| 1038 | |
| 1039 | # Check which jails are currently active |
| 1040 | rc, out, _ = _run_cmd(["fail2ban-client", "status"]) |
| 1041 | if rc != 0: |
| 1042 | return False, "Cannot communicate with fail2ban-client", [] |
| 1043 | |
| 1044 | current_jails = [] |
| 1045 | for line in out.splitlines(): |
| 1046 | if "Jail list:" in line: |
| 1047 | jails_str = line.split(":", 1)[1].strip() |
| 1048 | current_jails = [j.strip().lower() for j in jails_str.split(",") if j.strip()] |
| 1049 | |
| 1050 | # --- Proxmox jail (port 8006) --- |
| 1051 | # Fail2Ban's systemd backend can't reliably read pvedaemon worker entries |
| 1052 | # in real-time. We use a systemd service that tails the journal to a file |
| 1053 | # and fail2ban monitors that file with backend=auto. |
| 1054 | if "proxmox" not in current_jails: |
| 1055 | try: |
| 1056 | # Create the auth logger service if not present |
| 1057 | logger_service = "/etc/systemd/system/proxmox-auth-logger.service" |
| 1058 | if not os.path.isfile(logger_service): |
| 1059 | service_content = """[Unit] |
| 1060 | Description=Proxmox Auth Logger for Fail2Ban |
| 1061 | After=pvedaemon.service |
| 1062 | PartOf=fail2ban.service |
| 1063 | |
| 1064 | [Service] |
| 1065 | Type=simple |
| 1066 | ExecStart=/bin/bash -c 'journalctl -f _SYSTEMD_UNIT=pvedaemon.service -o short-iso --no-pager >> /var/log/proxmox-auth.log' |
| 1067 | Restart=always |
| 1068 | RestartSec=5 |
| 1069 | |
| 1070 | [Install] |
| 1071 | WantedBy=multi-user.target |
| 1072 | """ |
| 1073 | with open(logger_service, "w") as f: |
| 1074 | f.write(service_content) |
| 1075 | |
| 1076 | # Create log file |
| 1077 | log_file = "/var/log/proxmox-auth.log" |
| 1078 | if not os.path.isfile(log_file): |
| 1079 | with open(log_file, "w") as f: |
| 1080 | pass |
| 1081 | os.chmod(log_file, 0o640) |
| 1082 | |
| 1083 | _run_cmd(["systemctl", "daemon-reload"]) |
| 1084 | _run_cmd(["systemctl", "enable", "--now", "proxmox-auth-logger.service"]) |
| 1085 | |
| 1086 | # Create filter (only if user hasn't placed their own version) |
| 1087 | filter_path = "/etc/fail2ban/filter.d/proxmox.conf" |
| 1088 | if not os.path.isfile(filter_path): |
nothing calls this directly
no test coverage detected