weareinteractive/ansible-ufw

[BUG] Allow all traffic to any port from anywhere enabled by default

petarnikolovski opened this issue · 8 comments

Description

No matter which rules I set, I always get that all traffic to any port is enabled by default.

Versions

  • Ansible: 2.10.2
  • Python 3.9.0
  • OS: Ubuntu 20.04
  • ufw role: 2.0.0

Playbook

    - name: weareinteractive.ufw
      vars:
        ufw_enabled: true
        ufw_ipv6: "yes"
        ufw_rules:
          - logging: "full"
          - port: 22
            rule: allow
          - port: 80
            rule: allow
          - port: 443
            rule: allow
        ufw_manage_config: true

Expected results

user@host:~# ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
80                         ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
22 (v6)                    ALLOW       Anywhere (v6)             
80 (v6)                    ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             

Actual results

user@host:~# ufw status
Status: active

To                         Action      From
--                         ------      ----
Anywhere                   ALLOW       Anywhere                  
Anywhere (v6)              ALLOW       Anywhere (v6)  

Seeing this here as well... My guess is the root cause being a missing "mapping" of the "port" parameter in https://github.com/weareinteractive/ansible-ufw/blob/master/tasks/manage.yml. I'm working on a PR to hopefully fix the issue.

@gizero That's strange, I thought that port parameter does not need to be explicitly added, since it is alias for the to_port parameter in the underlying module. I've changed in my playbook port to to_port and resolved the issue. However, I'm not sure anymore if this is a bug, or how the ufw module is supposed to work now.

@petarGitNik To my understanding, aliasing can only happen at the community.general.ufw level. Your role is "forging" the parameters set for community.general.ufw based on your roles variable. When setting port but not port_to you are calling the underneath module with neither port nor port_to which means the module's default (any) is assumed.

Raising ANSIBLE_VERBOSITY clearly shows how the mapping happens when setting an allow rule for port: '80':

changed: [default] => (item={u'port': u'80', u'rule': u'allow', u'proto': u'tcp'}) => {"ansible_loop_var": "item", "changed": true, "commands": ["/usr/sbin/ufw status verbose", "/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules", "/usr/sbin/ufw --version", "/usr/sbin/ufw allow from any to any proto tcp", "/usr/sbin/ufw status verbose", "/bin/grep -h '^### tuple' /lib/ufw/user.rules /lib/ufw/user6.rules /etc/ufw/user.rules /etc/ufw/user6.rules /var/lib/ufw/user.rules /var/lib/ufw/user6.rules"], "item": {"port": "80", "proto": "tcp", "rule": "allow"}, "msg": "Status: active\nLogging: on (full)\nDefault: deny (incoming), allow (outgoing), disabled (routed)\nNew profiles: skip\n\nTo                         Action      From\n--                         ------      ----\nAnywhere/tcp               ALLOW IN    Anywhere/tcp              \nAnywhere/tcp (v6)          ALLOW IN    Anywhere/tcp (v6)"}

Well, the fix in https://github.com/gizero/ansible-ufw/tree/fix-port-parameter-mapping shows that adding port to the list of the arguments that end up being mapped into the underlying module solves the issue @petarGitNik raised. Nevertheless the same applies to other aliases community.general.ufw supports. Would be nice if @franklinkim can comment on its original intention here. I don't see it explicitly stated in the README, but looks like the idea is to expose the same exact syntax that community.general.ufw supports via the ufw_rules variable. If this is the case, then the same fix must be applied to every aliases the community module already supports. That said, even though I'm not aware of a better way to build the set of parameters for community.general.ufw, I can see how this pattern can expose the role to similar issues in the future, even in the case of non breaking changes in the modules API.

Hi, as @gizero correctly stated, this role exposes the community.general.ufw module to manage the rules. I didn't pass through the aliases since I think you should use the explicit variable names. I didn't update them myself though on my way to version 2.x, my bad. I updated the examples and added a reference to the module documentation in 2.0.1.

Ok, fair enough. That's your choice which options of the upstream module to support. Good to have documentation fixed accordingly. Already in master, but you probably referenced the wrong issue in commit 9baae35. I expected this one to be mentioned instead of #25. Anyway I think this issue can be closed as well. Thanks.

@gizero right, wrong reference. Thanks for the notice.

I can't use the 2.x branch because my ansible is old (v2.9.27), does this work in the 1.10.0 version?
These are my vars in my playbook:

    ufw_rules:
      # Set loggin
      - logging: "full"
      # Allow OpenSSH
      - rule: allow
        to_port: 22
      # Allow all access to tcp port 80
      - rule: allow
        to_port: '80'
        proto: tcp

No matter what I try there are the rules the are created in my server (see how rule 1 allows everything, so the rest rules are useless)

     To                         Action      From
     --                         ------      ----
[ 1] Anywhere                   ALLOW IN    Anywhere
[ 2] 22                         ALLOW IN    Anywhere
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] Anywhere (v6)              ALLOW IN    Anywhere (v6)
[ 5] 22 (v6)                    ALLOW IN    Anywhere (v6)
[ 6] 80/tcp (v6)                ALLOW IN    Anywhere (v6)

Can I block the rest of the traffic by default somehow?