feat : Add Fail2ban integration with Proxmox Firewall #43

Merged
Jose merged 13 commits from dev into main 2026-02-24 19:22:28 +01:00
2 changed files with 65 additions and 40 deletions
Showing only changes of commit d3527c14e4 - Show all commits

View File

@@ -27,6 +27,7 @@
| Logrotate protection | ✅ | ✅ | ✅ |
| Powertop auto-tune | ✅ | ✅ | ✅ |
| Utilities | ✅ | ✅ | ✅ |
| Fail2Ban Integration | ✅ | ✅ | ✅ |
Review

[Score: 3] Added new feature without proper documentation or explanation. It's important to clearly document any new additions for the sake of maintainability and ease of understanding for other developers.

[Score: 3] Added new feature without proper documentation or explanation. It's important to clearly document any new additions for the sake of maintainability and ease of understanding for other developers.
## 📂 Directory Structure
@@ -40,6 +41,7 @@ ansible_role_proxmox_provision/
├── meta/ # Role metadata
│ └── main.yml
├── tasks/ # Main role tasks
│ ├── fail2ban.yml # Fail2Ban integration tasks
│ ├── logrotate.yml # logrotate setup
│ ├── main.yml # Core tasks
│ ├── powertop.yml # powertop setup
@@ -69,6 +71,7 @@ proxmox_enable_powertop: true
## Logrotate
proxmox_logrotate_maxsize: "100M"
proxmox_logrotate_rotate: 7
...
```
## Example usage

View File

@@ -3,35 +3,65 @@
# Deploy Fail2Ban integrated with Proxmox Firewall
# -------------------------------------------------
#################################################
# Detect cluster
#################################################
- name: fail2ban | Detect Proxmox cluster
ansible.builtin.stat:
path: /etc/pve/corosync.conf
register: cluster_status
- name: fail2ban | Set cluster fact
ansible.builtin.set_fact:
pve_clustered: "{{ cluster_status.stat.exists }}"
#################################################
# Determine Correct Firewall File
#################################################
- name: fail2ban | Get Proxmox node name
ansible.builtin.command: hostname
register: pve_node
changed_when: false
- name: fail2ban | Set firewall config path
ansible.builtin.set_fact:
pve_firewall_config: >-
{{
'/etc/pve/firewall/cluster.fw'
if pve_clustered
else '/etc/pve/firewall/' + pve_node.stdout + '.fw'
}}
#################################################
# Detect firewall configuration
#################################################
- name: fail2ban | Check if cluster firewall config exists
- name: fail2ban | Check firewall config exists
ansible.builtin.stat:
path: /etc/pve/firewall/cluster.fw
register: cluster_fw
path: "{{ pve_firewall_config }}"
register: fw_stat
- name: fail2ban | Read cluster firewall config
slurp:
src: /etc/pve/firewall/cluster.fw
register: cluster_fw_content
when: cluster_fw.stat.exists
- name: fail2ban | Read firewall config
ansible.builtin.slurp:
src: "{{ pve_firewall_config }}"
register: fw_content
when: fw_stat.stat.exists
- name: fail2ban | Determine if firewall enabled
ansible.builtin.set_fact:
pve_firewall_enabled: >-
{{
cluster_fw.stat.exists and
(cluster_fw_content.content | b64decode)
is search('enable:\s*1')
fw_stat.stat.exists and
(fw_content.content | b64decode) is search('enable:\s*1')
}}
- name: fail2ban | Abort if firewall not enabled
ansible.builtin.fail:
- name: fail2ban | Warn if firewall not enabled
ansible.builtin.debug:
msg: >
Proxmox firewall is not enabled at Datacenter level.
Enable it before deploying Fail2Ban integration.
WARNING: Proxmox firewall is disabled in configuration.
Fail2Ban will not actively block traffic.
when: not pve_firewall_enabled
#################################################
@@ -49,20 +79,7 @@
msg: >
Proxmox firewall service is not running.
Run: systemctl enable --now pve-firewall
when: "'Status: enabled' not in pve_fw_status.stdout"
#################################################
# Detect cluster
#################################################
- name: fail2ban | Detect Proxmox cluster
ansible.builtin.stat:
path: /etc/pve/corosync.conf
register: cluster_status
- name: fail2ban | Set cluster fact
ansible.builtin.set_fact:
pve_clustered: "{{ cluster_status.stat.exists }}"
when: pve_fw_status.rc != 0
#################################################
# Corosync safety validation
@@ -82,8 +99,7 @@
Refusing to continue to prevent cluster outage.
when:
- cluster_status.stat.exists
- compiled_fw.stdout is search('5404')
- compiled_fw.stdout is search('DROP')
- compiled_fw.stdout is search('5404.*DROP|5405.*DROP')
#################################################
# Install Fail2Ban
@@ -96,32 +112,36 @@
update_cache: true
#################################################
# Create Proxmox firewall IPSet (cluster-wide)
# Create Proxmox firewall IPSet
#################################################
- name: fail2ban | Ensure firewall cluster config exists
- name: fail2ban | Ensure firewall directory exists
ansible.builtin.file:
path: /etc/pve/firewall
state: directory
when: pve_clustered
- name: fail2ban | Add Fail2Ban IPSet to cluster firewall
ansible.builtin.blockinfile:
path: /etc/pve/firewall/cluster.fw
path: "{{ pve_firewall_config }}"
marker: "# {mark} ANSIBLE FAIL2BAN IPSET"
block: |
[IPSET {{ f2b_ipset_name }}]
comment: Fail2Ban dynamic blacklist
create: true
when: pve_clustered
- name: fail2ban | Ensure RULES section exists
ansible.builtin.blockinfile:
path: "{{ pve_firewall_config }}"
marker: "# {mark} ANSIBLE RULES HEADER"
block: |
[RULES]
- name: fail2ban | Add drop rule for Fail2Ban IPSet
ansible.builtin.blockinfile:
path: /etc/pve/firewall/cluster.fw
path: "{{ pve_firewall_config }}"
marker: "# {mark} ANSIBLE FAIL2BAN RULE"
block: |
[RULES]
IN DROP -source +{{ f2b_ipset_name }}
when: pve_clustered
- name: fail2ban | Extract corosync ring0 address
ansible.builtin.shell: grep ring0_addr /etc/pve/corosync.conf | awk '{print $2}'
@@ -172,7 +192,7 @@
bantime.max = {{ f2b_bantime_max }}
backend = systemd
banaction = proxmox-fw
ignoreip = 127.0.0.1/8 {{ corosync_ip.stdout | default('') }} 192.168.2.0/24
ignoreip = 127.0.0.1/8{% if pve_clustered %} {{ corosync_ip.stdout }}{% endif %} 192.168.2.0/24
#################################################
# SSH
@@ -233,6 +253,8 @@
- name: fail2ban | Reload Proxmox firewall
ansible.builtin.command: pve-firewall reload
when: fw_stat.changed or
"'ANSIBLE FAIL2BAN' in fw_content.content | default('')"
changed_when: false
#################################################