--- # ------------------------------------------------------------------------------ # FILE: roles/llm-inference-multimodel/tasks/firewall.yml # DESCRIPTION: Phase 3 — scope :8001 (new) and reconsider :8000 (existing # pattern) exposure, per plan §5. # # Current baseline pattern (0.0.0.0:8000, no auth) is a # pre-existing flagged issue — this role does NOT repeat it # uncritically for the new port, and tightens both: # 1. Bind address: handled in systemd.yml templates via # {{ llm_bind_address }} (default 10.1.71.130, NOT 0.0.0.0). # 2. Firewall: ufw rules scoping both ports to # {{ llm_allowed_source_cidr }} rather than open LAN-wide. # # Idempotent: named rule comments + `state: present` so reruns # don't duplicate rules (per plan §4 idempotency note). # ------------------------------------------------------------------------------ - name: Check whether ufw is installed/active ansible.builtin.command: cmd: ufw status register: llm_ufw_status changed_when: false failed_when: false become: true - name: WARNING — ufw not active, firewall scoping cannot be applied ansible.builtin.debug: msg: >- ufw does not appear to be active on this host (`ufw status` returned: {{ llm_ufw_status.stdout | default('n/a') }}). Firewall scoping for ports {{ llm_aux_port }}/{{ llm_toolcall_port }} was skipped. This is a gap vs plan §5 item 2 — flag to Ryan before relying on bind-address alone for exposure control. when: "'Status: active' not in (llm_ufw_status.stdout | default(''))" - name: Allow aux port ({{ llm_aux_port }}) from the Hermes source subnet community.general.ufw: rule: allow port: "{{ llm_aux_port | string }}" proto: tcp src: "{{ llm_allowed_source_cidr }}" comment: "llm-inference-multimodel: aux (Phi-4) — scoped to Hermes subnet" become: true when: "'Status: active' in (llm_ufw_status.stdout | default(''))" - name: Allow tool-calling port ({{ llm_toolcall_port }}) from the Hermes source subnet community.general.ufw: rule: allow port: "{{ llm_toolcall_port | string }}" proto: tcp src: "{{ llm_allowed_source_cidr }}" comment: "llm-inference-multimodel: toolcall (Mistral-Small) — scoped to Hermes subnet" become: true when: "'Status: active' in (llm_ufw_status.stdout | default(''))" - name: Report firewall scoping applied ansible.builtin.debug: msg: >- Firewall scoping applied for ports {{ llm_aux_port }} and {{ llm_toolcall_port }}, restricted to source {{ llm_allowed_source_cidr }}. Reverse-proxy + API-key enforcement (plan §5 item 3) is NOT implemented by this role — flagged as an optional follow-up phase, not bundled into this minimum-viable rollout.