AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

UFW Allow Port with Ansible: Complete Firewall Management Guide (Ubuntu/Debian)

By Luca Berton · Published 2024-01-01 · Category: installation

Manage UFW firewall rules with Ansible on Ubuntu and Debian. Allow ports, deny traffic, rate-limit SSH, configure web server and database firewalls, IPv6.

UFW Allow Port with Ansible: Complete Firewall Management Guide (Ubuntu/Debian)

How to open firewall ports in Debian-like systems with Ansible? I'm going to show you a live Playbook and some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.

Ansible open firewall ports in Debian-like systems

Today we're talking about the Ansible module UFW. The full name is community.general.ufw, which means that is part of the collection supported by the Ansible community. This module requires Ansible 2.9+. It works in Debian-like systems so distributions like Debian, Ubuntu, and Mint with ufw firewall, the Uncomplicated Firewall. This module manages the firewall with UFW.

See also: Ansible on Debian 11 Bullseye: UFW Firewall Automation Complete Guide

Parameters

The parameter list is pretty wide but these are the most important options for our use case to open firewall ports. The first set of parameters controls UFW program and the second the single rules.

UFW program parameters

| Parameter | Type | Options | Description | |-----------|------|---------|-------------| | default (policy) | string | allow / deny / reject | Change default policy for incoming or outgoing traffic | | logging | string | on / off / low / medium / high / full | Toggle UFW logging (uses LOG_KERN syslog) | | state | string | enabled / disabled / reloaded / reset | Enable, disable, reload, or reset firewall | | direction | string | in / incoming / out / outgoing / routed | Direction for the default policy |

The "state" parameter options: • enabled - reloads firewall and enables firewall on boot • disabled - unloads firewall and disables firewall on boot • reloaded - reloads firewall • reset - disables and resets firewall to installation defaults

Rule-specific parameters

| Parameter | Type | Options | Description | |-----------|------|---------|-------------| | rule | string | allow / deny / limit / reject | Firewall rule action | | name (app) | string | Application name | Uses profile in /etc/ufw/applications.d | | port (to_port) | string | Port number or range | Destination port (e.g., 80 or 60000:61000) | | proto | string | any / tcp / udp / ipv6 / esp / ah / gre / igmp | Protocol | | from_ip | string | IP address or CIDR | Source address (default: any) | | to_ip | string | IP address or CIDR | Destination address (default: any) | | interface | string | Interface name | Network interface for the rule | | direction | string | in / out | Direction for interface rules | | route | boolean | true / false | Apply rule to routed/forwarded packets | | comment | string | Text | Add comment to the rule | | insert | integer | Rule number | Insert rule at position instead of appending | | insert_relative_to | string | zero / first-ipv4 / last-ipv4 / first-ipv6 / last-ipv6 | Relative position for insert | | delete | boolean | true / false | Delete matching rule | | log | boolean | true / false | Log matched packets |

Basic Playbook: Open Firewall Ports

---
- name: ufw module Playbook
  hosts: all
  become: true
  tasks:
    - name: nginx installed
      ansible.builtin.apt:
        name: "nginx"
        state: "present"
        update_cache: true

- name: ufw enabled community.general.ufw: state: "enabled" policy: "deny" logging: "on"

- name: ufw rules community.general.ufw: rule: "allow" port: "{{ item }}" proto: "tcp" loop: - "22" - "80" - "443"

See also: Ansible on Debian 12 Bookworm: UFW Firewall Automation Complete Guide

Allow Port: Common Examples

Allow a Single Port

- name: Allow SSH
  community.general.ufw:
    rule: allow
    port: '22'
    proto: tcp

Allow Port from Specific IP

- name: Allow SSH from office network
  community.general.ufw:
    rule: allow
    port: '22'
    proto: tcp
    from_ip: '10.0.0.0/8'
    comment: 'SSH from office'

Allow Port Range

- name: Allow high ports for passive FTP
  community.general.ufw:
    rule: allow
    port: '60000:61000'
    proto: tcp
    comment: 'Passive FTP range'

Allow by Application Profile

- name: Allow Nginx Full profile
  community.general.ufw:
    rule: allow
    name: 'Nginx Full'
    comment: 'Web server HTTP and HTTPS'

To see available application profiles:

sudo ufw app list
# Available applications:
#   Nginx Full
#   Nginx HTTP
#   Nginx HTTPS
#   OpenSSH

Allow on Specific Interface

- name: Allow MySQL on internal interface only
  community.general.ufw:
    rule: allow
    port: '3306'
    proto: tcp
    interface: eth1
    direction: in
    comment: 'MySQL on private network'

Deny and Reject Rules

- name: Deny incoming telnet
  community.general.ufw:
    rule: deny
    port: '23'
    proto: tcp

- name: Reject with ICMP unreachable community.general.ufw: rule: reject port: '25' proto: tcp comment: 'Reject SMTP - use relay instead'

The difference: deny silently drops packets (attacker gets no response). reject sends an ICMP unreachable back (faster failure for legitimate clients).

See also: Ansible on Debian 13 Trixie: UFW Firewall Automation Complete Guide

Rate Limiting with UFW

The limit rule allows only 6 connections per 30 seconds from a single IP. Essential for SSH brute-force protection:

- name: Rate limit SSH connections
  community.general.ufw:
    rule: limit
    port: '22'
    proto: tcp
    comment: 'Rate limit SSH - 6 conn/30s'

Delete Rules

- name: Remove old FTP rule
  community.general.ufw:
    rule: allow
    port: '21'
    proto: tcp
    delete: true

Complete Web Server Firewall Playbook

---
- name: Configure web server firewall
  hosts: webservers
  become: true

vars: allowed_ssh_networks: - '10.0.0.0/8' - '172.16.0.0/12' web_ports: - { port: '80', comment: 'HTTP' } - { port: '443', comment: 'HTTPS' } monitoring_port: '9100' monitoring_server: '10.0.10.50'

tasks: - name: Install UFW ansible.builtin.apt: name: ufw state: present update_cache: true

- name: Set default deny incoming community.general.ufw: default: deny direction: incoming

- name: Set default allow outgoing community.general.ufw: default: allow direction: outgoing

- name: Allow SSH from trusted networks community.general.ufw: rule: limit port: '22' proto: tcp from_ip: "{{ item }}" comment: "SSH from {{ item }}" loop: "{{ allowed_ssh_networks }}"

- name: Allow web traffic from anywhere community.general.ufw: rule: allow port: "{{ item.port }}" proto: tcp comment: "{{ item.comment }}" loop: "{{ web_ports }}"

- name: Allow node-exporter from monitoring server community.general.ufw: rule: allow port: "{{ monitoring_port }}" proto: tcp from_ip: "{{ monitoring_server }}" comment: "Prometheus scrape from monitoring"

- name: Enable UFW logging community.general.ufw: logging: 'low'

- name: Enable UFW community.general.ufw: state: enabled

- name: Verify UFW status ansible.builtin.command: cmd: ufw status verbose register: ufw_status changed_when: false

- name: Show firewall rules ansible.builtin.debug: msg: "{{ ufw_status.stdout_lines }}"

Database Server Firewall

---
- name: Configure database firewall
  hosts: databases
  become: true

vars: app_servers: - '10.0.1.10' - '10.0.1.11' - '10.0.1.12' db_port: '5432'

tasks: - name: Default deny incoming community.general.ufw: default: deny direction: incoming

- name: Allow PostgreSQL from app servers only community.general.ufw: rule: allow port: "{{ db_port }}" proto: tcp from_ip: "{{ item }}" comment: "PostgreSQL from {{ item }}" loop: "{{ app_servers }}"

- name: Allow SSH from bastion community.general.ufw: rule: allow port: '22' proto: tcp from_ip: '10.0.0.5' comment: 'SSH from bastion host'

- name: Deny all other PostgreSQL access community.general.ufw: rule: deny port: "{{ db_port }}" proto: tcp comment: 'Deny direct DB access'

- name: Enable UFW community.general.ufw: state: enabled

Kubernetes Node Firewall

---
- name: Configure K8s node firewall
  hosts: k8s_nodes
  become: true

tasks: - name: Default deny incoming community.general.ufw: default: deny direction: incoming

- name: Allow Kubernetes API server community.general.ufw: rule: allow port: '6443' proto: tcp comment: 'K8s API server'

- name: Allow kubelet API community.general.ufw: rule: allow port: '10250' proto: tcp comment: 'Kubelet API'

- name: Allow NodePort range community.general.ufw: rule: allow port: '30000:32767' proto: tcp comment: 'K8s NodePort services'

- name: Allow flannel VXLAN community.general.ufw: rule: allow port: '8472' proto: udp comment: 'Flannel VXLAN'

- name: Allow etcd (control plane only) community.general.ufw: rule: allow port: '2379:2380' proto: tcp comment: 'etcd client and peer' when: "'control_plane' in group_names"

- name: Enable UFW community.general.ufw: state: enabled

IPv6 Support

- name: Configure IPv6 firewall rules
  hosts: all
  become: true

tasks: - name: Enable IPv6 in UFW config ansible.builtin.lineinfile: path: /etc/default/ufw regexp: '^IPV6=' line: 'IPV6=yes' notify: reload ufw

- name: Allow HTTP over IPv6 community.general.ufw: rule: allow port: '80' proto: tcp from_ip: '::/0' comment: 'HTTP IPv6'

handlers: - name: reload ufw community.general.ufw: state: reloaded

Firewall Reset

- name: Reset UFW to defaults
  community.general.ufw:
    state: reset

- name: Disable UFW completely community.general.ufw: state: disabled

Verification Commands

# Check UFW status
sudo ufw status
sudo ufw status verbose
sudo ufw status numbered

# Check specific app profiles sudo ufw app list sudo ufw app info 'Nginx Full'

# Check UFW logs sudo tail -f /var/log/ufw.log

code with ❤️ in GitHub

FAQ

How do I allow a port with UFW in Ansible?

Use community.general.ufw with rule: allow and specify the port and proto parameters. For example: community.general.ufw: rule=allow port=80 proto=tcp. Add from_ip to restrict access to specific source networks.

What is the difference between deny and reject in UFW?

deny silently drops the packet - the sender gets no response and eventually times out. reject sends an ICMP unreachable message back. Use deny for external-facing rules (reveals less information to attackers) and reject for internal rules (faster failure for legitimate connections).

How do I rate-limit SSH with Ansible and UFW?

Use rule: limit instead of rule: allow. This automatically limits connections to 6 per 30 seconds from a single IP address: community.general.ufw: rule=limit port=22 proto=tcp. This is the simplest brute-force protection.

Can I use UFW with Docker?

Docker modifies iptables directly, bypassing UFW rules. Containers with published ports are accessible even if UFW blocks the port. Use DOCKER_OPTS="--iptables=false" or the ufw-docker utility to make Docker respect UFW rules.

How do I allow a port range with UFW in Ansible?

Specify the range with a colon: port: '60000:61000'. You must also specify proto: tcp or proto: udp - port ranges require an explicit protocol.

Conclusion

Now you know how to manage firewall rules on Debian-like systems with Ansible using UFW, the Uncomplicated Firewall. From basic port opening to complete web server, database, and Kubernetes firewall configurations - the community.general.ufw module handles it all with simple, declarative YAML.

Related Articles

Ansible firewalld ufw Module: Manage Firewall Rules GuideDeploy a web server with Ansible (apt, copy, service, ufw)reverse proxy with Ansible Nginxsudo and become in Ansible playbooksAnsible on Ubuntu 26.04 LTS

Category: installation

Watch the video: UFW Allow Port with Ansible: Complete Firewall Management Guide (Ubuntu/Debian) — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home