#!/usr/bin/env bash # # Homelab monitoring, Part 6: Internet traffic with pfSense # https://www.zadran.net/guides/homelab-monitoring-6-internet-traffic-pfsense # Generated from the guide, last updated 2026-10-13. # # NO WARRANTY. This script is provided as is. You are responsible for # understanding what it does before running it, and for the consequences. # Take a backup first. See https://www.zadran.net/disclaimer # # Destructive steps are left commented out on purpose -- uncomment them # only once you have understood what they do. # # Where the guide writes a file with <<'EOF' and your values are in it, # this script uses < Assignments WAN_IF='igc0' # pfSense: Interfaces -> Assignments LAN_IF='igc1' # Total size, not the amount to add DISK_SIZE='100G' # About 15 % below the disk size RETENTION_SIZE='85GB' # The speed you pay for CONTRACT_DOWN='250' # The speed you pay for CONTRACT_UP='50' pct exec ${CTID} -- df -h / pct exec ${CTID} -- du -sh /var/lib/docker/volumes/monitoring_prometheus-data pct exec ${CTID} -- bash -c "curl -s localhost:9090/api/v1/query --data-urlencode 'query=prometheus_tsdb_head_series' | grep -o '\"value\":\[[^]]*\]'" pct resize ${CTID} rootfs ${DISK_SIZE} pct exec ${CTID} -- df -h / pct exec ${CTID} -- bash -c "cd /opt/monitoring && mkdir -p backup && cp compose.yaml backup/compose.yaml.\$(date +%Y%m%d-%H%M%S) && (grep -q retention.size compose.yaml || sed -i 's|^\(\s*\)- --storage.tsdb.retention.time=\(.*\)$|&\n\1- --storage.tsdb.retention.size=${RETENTION_SIZE}|' compose.yaml) && grep -n retention compose.yaml && docker compose up -d prometheus" pct exec ${CTID} -- bash -c "curl -s localhost:9090/api/v1/status/flags | grep -o '\"storage.tsdb.retention.[a-z]*\":\"[^\"]*\"'" pct exec ${CTID} -- bash -c "cd /opt/monitoring && sed -i 's|retention.time=.*|retention.time=730d|' compose.yaml && docker compose up -d prometheus" pct exec ${CTID} -- bash -c "curl -s --max-time 5 http://${PFSENSE_IP}:9100/metrics | grep -E '^node_network_(receive|transmit)_bytes_total\{device=\"(${WAN_IF}|${LAN_IF})\"'" pct enter ${CTID} P=/opt/monitoring/prometheus/prometheus.yml cp $P /opt/monitoring/backup/prometheus.yml.$(date +%Y%m%d-%H%M%S) cat >> $P < /opt/monitoring/grafana/provisioning/dashboards/files/Network/internet-pfsense.json grep -c '"title"' /opt/monitoring/grafana/provisioning/dashboards/files/Network/internet-pfsense.json cd /root curl -fsSLO https://www.zadran.net/downloads/grafana/tools/vnstat2prom.py T0=$(pct exec ${CTID} -- bash -c "curl -fsS -G localhost:9090/api/v1/query --data-urlencode 'query=min_over_time(timestamp(up{job=\"pfsense\"})[90d:5m])'" | grep -o '"value":\[[^]]*\]' | sed -E 's/.*,"([^"]+)"\]/\1/' | cut -d. -f1) echo "Live pfSense data starts at: $(date -d @$T0)" python3 vnstat2prom.py vnstat.json wan-history.om --iface ${WAN_IF} --until $T0 pct push ${CTID} wan-history.om /tmp/wan-history.om --perms 644 pct exec ${CTID} -- bash -c "docker cp /tmp/wan-history.om prometheus:/tmp/ && rm /tmp/wan-history.om" pct exec ${CTID} -- docker exec prometheus sh -c 'promtool tsdb create-blocks-from openmetrics -q /tmp/wan-history.om /prometheus/backfill && mv /prometheus/backfill/* /prometheus/ && rmdir /prometheus/backfill' pct exec ${CTID} -- docker restart prometheus rm wan-history.om