Configure UFW firewall rules in common Ansible role

Add UFW configuration to the common role for Debian hosts:
- Default deny incoming, allow outgoing
- Allow all traffic on tailscale0 interface (mesh comms)
- Allow SSH port 22 as safety net
- Per-host allowed ports via ufw_allowed_ports variable
- Enable UFW after rules are applied

helsinki-a gets ports 80/443 for reverse proxy traffic.
Other Debian hosts only need Tailscale + SSH.

Closes PESO-79
This commit is contained in:
Rasmus Wejlgaard 2026-03-29 09:07:42 +00:00
parent da80c58ca4
commit 339c08c5c2
5 changed files with 79 additions and 0 deletions

View file

@ -9,3 +9,7 @@ docker_services:
- authelia - authelia
- forgejo - forgejo
- bitwarden - bitwarden
ufw_allowed_ports:
- { port: 80, proto: tcp, comment: "HTTP" }
- { port: 443, proto: tcp, comment: "HTTPS" }

View file

@ -3,3 +3,5 @@ host_role: mail
host_description: "Mail server (poste.io)" host_description: "Mail server (poste.io)"
host_location: "Hetzner Cloud" host_location: "Hetzner Cloud"
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3
# NOTE: Alpine host — UFW tasks are Debian-only.
# Firewall rules for mail ports (25,465,587,993,143,80,443) managed separately.

View file

@ -0,0 +1,7 @@
---
# UFW firewall defaults
# Override ufw_allowed_ports in host_vars for public-facing services.
ufw_enabled: true
ufw_allowed_ports: []
# - { port: 80, proto: tcp, comment: "HTTP" }
# - { port: 443, proto: tcp, comment: "HTTPS" }

View file

@ -3,3 +3,7 @@
ansible.builtin.service: ansible.builtin.service:
name: sshd name: sshd
state: restarted state: restarted
- name: Reload ufw
community.general.ufw:
state: reloaded

View file

@ -100,3 +100,65 @@
state: started state: started
enabled: true enabled: true
when: ansible_facts["os_family"] == "Debian" when: ansible_facts["os_family"] == "Debian"
# --- UFW firewall (Debian only) ---
- name: Set UFW default deny incoming
community.general.ufw:
direction: incoming
default: deny
when:
- ansible_facts["os_family"] == "Debian"
- ufw_enabled | bool
notify: Reload ufw
- name: Set UFW default allow outgoing
community.general.ufw:
direction: outgoing
default: allow
when:
- ansible_facts["os_family"] == "Debian"
- ufw_enabled | bool
notify: Reload ufw
- name: Allow all traffic on Tailscale interface
community.general.ufw:
rule: allow
interface_or_direction: in
interface: tailscale0
comment: "Tailscale mesh - allow all"
when:
- ansible_facts["os_family"] == "Debian"
- ufw_enabled | bool
notify: Reload ufw
- name: Allow SSH (safety net)
community.general.ufw:
rule: allow
port: '22'
proto: tcp
comment: "SSH"
when:
- ansible_facts["os_family"] == "Debian"
- ufw_enabled | bool
notify: Reload ufw
- name: Allow host-specific ports
community.general.ufw:
rule: allow
port: "{{ item.port | string }}"
proto: "{{ item.proto | default('tcp') }}"
comment: "{{ item.comment | default(omit) }}"
loop: "{{ ufw_allowed_ports }}"
when:
- ansible_facts["os_family"] == "Debian"
- ufw_enabled | bool
- ufw_allowed_ports | length > 0
notify: Reload ufw
- name: Enable UFW
community.general.ufw:
state: enabled
when:
- ansible_facts["os_family"] == "Debian"
- ufw_enabled | bool