How can I clear any ufw entries that are not in a list with ansible

Viewed 1454

https://docs.ansible.com/ansible/latest/modules/ufw_module.html

I have configured Ansible 2 to allow a bunch of ip addresses with ufw with entries like this:

  - name: allow from this one computer
    ufw:
      rule: allow
      port: 22
      src: 192.168.5.5

However, I would also like to remove any old entries, or entries that got there by mistake.

For example, if an old version had 192.168.8.8, I would like to remove it. Or if somebody added it manually.

Is there any reasonable way to do that? I guess if the server is only ever configured by ansible, and when I remove an ip address from the list, I add an entry to remove it, I won't have that problem.

2 Answers

I faced a similar issue when trying to standardise my servers' UFW with Ansible v2.9 after having different rules on each one.

The approach was to reset the UFW, which deletes all existing rules, and create the rules I wanted, taking a lot of care about not locking me outside the server.

The code:


- name: Setup admin production UFW
  hosts: my_hosts
  gather_facts: no
  tasks:
    - block:
      - name: Reset UFW
        ufw: 
          state: reset

      - name: Allow outgoing
        ufw: 
          default: allow
          direction: outgoing

      - name: Disallow ingoing
        ufw: 
          default: deny
          direction: incoming

      - name: Establish regular admin rules
        ufw:
          rule: allow
          direction: in
          port: '5432'
          proto: tcp
          from_ip: '{{ item }}'
        loop:
          - 123.456.789/32
          - 987.654.321/32

      always:
        - name: Grant ssh access
          ufw:
            rule: allow
            direction: in
            port: '22'
            proto: tcp
            from_ip: 321.456.987/32
        
         - name: Enable Firewall
           ufw: 
            state: enabled

Explained step by step

Notice the block: always: parameters. You will set almost all actions inside block: and leave always: as a security valve so in case of any failure you're sure you'll still have SSH access to your server.

This may also be accomplished with ignore_errors: yes at the block level, but I perceive from the documentation that is not the 'safest' option.

Allow outgoing and Disallow ingoing defines general behavior.

Then, you add as many rules as you will, and close with the always allowing SSH, and enabling your Firewall, having a safe playbook.

Recommendation

I strongly suggest that you do not test your UFW playbooks in servers which you will miss if something gets wrong.

Test your UFW playbooks in a single testing server to which you have one or two SSH connections already set up, so if you rule denies all SSH connections, you're still inside and can ufw allow 22

Q: "An old version had 192.168.8.8, I would like to remove it."

A: See the parameter delete. For example

  - name: delete rule
    ufw:
      delete: true
      rule: allow
      port: 22
      src: 192.168.8.8
Related