From f2cebcdf385ac27b69bb09131b17e363095167ba Mon Sep 17 00:00:00 2001 From: "Rasmus \"Pez\" Wejlgaard" Date: Mon, 30 Mar 2026 22:56:59 +0100 Subject: [PATCH] Bind node_exporter to Tailscale IP on public-facing hosts (#31) node_exporter was listening on 0.0.0.0:9100 on helsinki-a and london-a, exposing metrics to the public internet. Changes: - Add node_exporter_bind_tailscale flag (default false) to opt in - Set flag on helsinki-a and london-a host_vars - Debian: configure ARGS in /etc/default/prometheus-node-exporter - FreeBSD: use native node_exporter_listen_address rc.conf variable - Add handlers to restart on config change Prometheus already scrapes via Tailscale IPs, no scrape config changes needed. Fixes PESO-98 --- ansible/inventory/host_vars/helsinki-a.yml | 2 ++ ansible/inventory/host_vars/london-a.yml | 1 + ansible/roles/node_exporter/defaults/main.yml | 4 ++++ ansible/roles/node_exporter/handlers/main.yml | 10 +++++++++ ansible/roles/node_exporter/tasks/main.yml | 21 +++++++++++++++++++ 5 files changed, 38 insertions(+) create mode 100644 ansible/roles/node_exporter/defaults/main.yml create mode 100644 ansible/roles/node_exporter/handlers/main.yml diff --git a/ansible/inventory/host_vars/helsinki-a.yml b/ansible/inventory/host_vars/helsinki-a.yml index 6c9de61..5fb181a 100644 --- a/ansible/inventory/host_vars/helsinki-a.yml +++ b/ansible/inventory/host_vars/helsinki-a.yml @@ -10,6 +10,8 @@ docker_services: - forgejo - bitwarden +node_exporter_bind_tailscale: true + common_ufw_allowed_ports: - {port: 80, proto: tcp, comment: "HTTP"} - {port: 443, proto: tcp, comment: "HTTPS"} diff --git a/ansible/inventory/host_vars/london-a.yml b/ansible/inventory/host_vars/london-a.yml index 4ce9f61..e608cd2 100644 --- a/ansible/inventory/host_vars/london-a.yml +++ b/ansible/inventory/host_vars/london-a.yml @@ -1,4 +1,5 @@ --- +node_exporter_bind_tailscale: true host_role: monitoring host_description: "Monitoring stack (Prometheus, Grafana)" host_location: "London" diff --git a/ansible/roles/node_exporter/defaults/main.yml b/ansible/roles/node_exporter/defaults/main.yml new file mode 100644 index 0000000..a6d19c0 --- /dev/null +++ b/ansible/roles/node_exporter/defaults/main.yml @@ -0,0 +1,4 @@ +--- +# When true, bind node_exporter to the Tailscale IP (ansible_host) only. +# Use on public-facing hosts to avoid exposing metrics on 0.0.0.0. +node_exporter_bind_tailscale: false diff --git a/ansible/roles/node_exporter/handlers/main.yml b/ansible/roles/node_exporter/handlers/main.yml new file mode 100644 index 0000000..1c993e9 --- /dev/null +++ b/ansible/roles/node_exporter/handlers/main.yml @@ -0,0 +1,10 @@ +--- +- name: Restart node-exporter (Debian) + ansible.builtin.service: + name: prometheus-node-exporter + state: restarted + +- name: Restart node_exporter (FreeBSD) + ansible.builtin.service: + name: node_exporter + state: restarted diff --git a/ansible/roles/node_exporter/tasks/main.yml b/ansible/roles/node_exporter/tasks/main.yml index 8209461..708138d 100644 --- a/ansible/roles/node_exporter/tasks/main.yml +++ b/ansible/roles/node_exporter/tasks/main.yml @@ -1,6 +1,7 @@ --- # Install node_exporter for Prometheus monitoring. # Uses system packages on Linux, pkg on FreeBSD. +# Optionally binds to Tailscale IP on public-facing hosts. - name: Install prometheus-node-exporter (Debian) ansible.builtin.apt: @@ -14,6 +15,16 @@ state: present when: ansible_facts["os_family"] == "Alpine" +- name: Configure listen address (Debian) + ansible.builtin.lineinfile: + path: /etc/default/prometheus-node-exporter + regexp: '^ARGS=' + line: 'ARGS="--web.listen-address={{ ansible_host }}:9100"' + when: + - ansible_facts["os_family"] == "Debian" + - node_exporter_bind_tailscale | bool + notify: Restart node-exporter (Debian) + - name: Enable and start node-exporter (Debian) ansible.builtin.service: name: prometheus-node-exporter @@ -41,6 +52,16 @@ line: 'node_exporter_enable="YES"' when: ansible_facts["os_family"] == "FreeBSD" +- name: Configure listen address (FreeBSD) + ansible.builtin.lineinfile: + path: /etc/rc.conf + regexp: '^node_exporter_listen_address=' + line: 'node_exporter_listen_address="{{ ansible_host }}:9100"' + when: + - ansible_facts["os_family"] == "FreeBSD" + - node_exporter_bind_tailscale | bool + notify: Restart node_exporter (FreeBSD) + - name: Start node_exporter (FreeBSD) ansible.builtin.service: name: node_exporter