feat ✨: Add Fail2ban integration with Proxmox Firewall #43
@@ -27,6 +27,7 @@
|
||||
| Logrotate protection | ✅ | ✅ | ✅ |
|
||||
| Powertop auto-tune | ✅ | ✅ | ✅ |
|
||||
| Utilities | ✅ | ✅ | ✅ |
|
||||
| Fail2Ban Integration | ✅ | ✅ | ✅ |
|
||||
|
|
||||
|
||||
## 📂 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
|
||||
|
||||
@@ -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
|
||||
|
||||
#################################################
|
||||
|
||||
Reference in New Issue
Block a user
[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.