Iptables rule --set

Hello everyone,

I’ve just started with ansible (and like it!), now I’m trying to figure out how to create this iptables rule:

iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set

This is the task I’ve created:

- name: Add iptables rule
  ansible.builtin.iptables:
    chain: INPUT
    protocol: tcp
    match: tcp,state
    ctstate: new 
    destination_port: '{{ sshport  }}'

The result is:
iptables -I INPUT -p tcp --dport 22 -m state --state NEW

So -m recent --set is still missing. I’ve added recent in the match parameter:

- name: Add iptables rule
  ansible.builtin.iptables:
    chain: INPUT
    protocol: tcp
    match: tcp,state,recent
    ctstate: new 
    destination_port: '{{ sshport  }}'

But which parameter is needed for --set?

I think it’s more flexible to use the template mechanics see template_module
This would allow to always generate on target the desired iptables, and more importantly, the order of rules

Thanks for your reply! I’m going to figure out the template_module :smiley:

I’ve spent some hours figuring out how to make it work, and job done!

This is what i’ve created.

Tasks:

- name: Install the iptables-persistent package
  ansible.builtin.apt:
    name: iptables-persistent
    update_cache: yes
    state: present

- name: Create temporary iptables dir
  ansible.builtin.file:
    path: /etc/iptables-tmp
    state: directory

- name: Upload iptables template
  ansible.builtin.template:
    src: templates/ssh_iptables.j2
    dest: /etc/iptables-tmp/ssh_iptables

- name: Implement connection rate throttling IPv4
  community.general.iptables_state:
    ip_version: ipv4
    state: restored
    path: /etc/iptables-tmp/ssh_iptables
    noflush: true
  async: "{{ ansible_timeout }}"
  poll: 0

- name: Implement connection rate throttling IPv6
  community.general.iptables_state:
    ip_version: ipv6
    state: restored
    path: /etc/iptables-tmp/ssh_iptables
    noflush: true
  async: "{{ ansible_timeout }}"
  poll: 0

- name: Make firewall rules persistent
  ansible.builtin.shell: |
    sudo iptables-save > /etc/iptables/rules.v4
    sudo ip6tables-save > /etc/iptables/rules.v6

- name: Remove temporary iptables dir
  ansible.builtin.file:
    path: /etc/iptables-tmp
    state: absent

template.j2

*filter

-I INPUT -p tcp --dport {{ sshport }} -m state --state NEW -m recent --set
-I INPUT -p tcp --dport {{ sshport }} -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP

COMMIT

I’ve tried to use the community.general.iptables_state, but it didn’t make the iptables rules persistent, that’s why i choose to use the ansible.builtin.shell.

- name: save current state of the firewall in system file
  community.general.iptables_state:
    ip_version: ipv6
    table: filter
    state: saved
    path: /etc/iptables/rules.v6