diff --git a/ansible/inventory/host_vars/helsinki-a.yml b/ansible/inventory/host_vars/helsinki-a.yml index 3dd4849..418aee7 100644 --- a/ansible/inventory/host_vars/helsinki-a.yml +++ b/ansible/inventory/host_vars/helsinki-a.yml @@ -9,3 +9,7 @@ docker_services: - authelia - forgejo - bitwarden + +ufw_allowed_ports: + - { port: 80, proto: tcp, comment: "HTTP" } + - { port: 443, proto: tcp, comment: "HTTPS" } diff --git a/ansible/inventory/host_vars/nuremberg-a.yml b/ansible/inventory/host_vars/nuremberg-a.yml index 07f69bd..2061d0d 100644 --- a/ansible/inventory/host_vars/nuremberg-a.yml +++ b/ansible/inventory/host_vars/nuremberg-a.yml @@ -3,3 +3,5 @@ host_role: mail host_description: "Mail server (poste.io)" host_location: "Hetzner Cloud" 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. diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml new file mode 100644 index 0000000..8249b70 --- /dev/null +++ b/ansible/roles/common/defaults/main.yml @@ -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" } diff --git a/ansible/roles/common/handlers/main.yml b/ansible/roles/common/handlers/main.yml index 6998953..350609b 100644 --- a/ansible/roles/common/handlers/main.yml +++ b/ansible/roles/common/handlers/main.yml @@ -3,3 +3,7 @@ ansible.builtin.service: name: sshd state: restarted + +- name: Reload ufw + community.general.ufw: + state: reloaded diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml index 06f2d0a..9cde5e2 100644 --- a/ansible/roles/common/tasks/main.yml +++ b/ansible/roles/common/tasks/main.yml @@ -100,3 +100,65 @@ state: started enabled: true 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 diff --git a/ansible/services/prometheus/prometheus.yml b/ansible/services/prometheus/prometheus.yml index d73d329..88ed3b6 100644 --- a/ansible/services/prometheus/prometheus.yml +++ b/ansible/services/prometheus/prometheus.yml @@ -8,13 +8,6 @@ global: scrape_interval: 15s evaluation_interval: 15s -alerting: - alertmanagers: - - static_configs: - - targets: [] - -rule_files: [] - scrape_configs: - job_name: "prometheus" static_configs: