--- # Security playbook: iptables + fail2ban for all VMs # # Run: ansible-playbook -i inventory.ini playbooks/security.yml # # This playbook uses direct iptables rules instead of ufw to ensure # bridge network traffic is properly blocked (ufw's before.rules allows # ICMP before custom deny rules can take effect). - name: Configure Security for All VMs hosts: all become: true tasks: # Load netfilter kernel modules (required on fresh VMs) - name: Load netfilter kernel modules community.general.modprobe: name: "{{ item }}" state: present loop: - ip_tables - ip6_tables - iptable_filter - ip6table_filter # Install security packages - name: Install iptables and fail2ban community.general.pacman: name: - iptables - fail2ban state: present # Stop and disable ufw if present (migrating to iptables) - name: Check if ufw is installed command: pacman -Q ufw register: ufw_check ignore_errors: true changed_when: false - name: Stop ufw if running systemd: name: ufw state: stopped when: ufw_check.rc == 0 ignore_errors: true - name: Disable ufw systemd: name: ufw enabled: false when: ufw_check.rc == 0 ignore_errors: true # Deploy iptables rules - name: Deploy iptables rules template: src: ../templates/iptables.rules.j2 dest: /etc/iptables/iptables.rules mode: '0644' notify: reload iptables # Enable and start iptables service - name: Enable and start iptables systemd: name: iptables state: started enabled: true # Configure fail2ban - name: Create fail2ban local config copy: dest: /etc/fail2ban/jail.local content: | [DEFAULT] bantime = 1h findtime = 10m maxretry = 5 [sshd] enabled = true port = ssh filter = sshd backend = systemd mode: '0644' notify: restart fail2ban # Enable fail2ban service - name: Enable and start fail2ban systemd: name: fail2ban state: started enabled: true handlers: - name: reload iptables systemd: name: iptables state: restarted - name: restart fail2ban systemd: name: fail2ban state: restarted