From 825f42d9513db287f7ed5eef055ef4daf096e69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro?= Date: Mon, 5 Jan 2026 18:07:42 -0300 Subject: [PATCH] feat: Add OpenVPN discovery and data collection scripts with caching for Zabbix. --- .../files/openvpn-collector.sh | 53 +++++++++++++++++ .../files/openvpn-discovery.sh | 57 +++++-------------- 2 files changed, 66 insertions(+), 44 deletions(-) create mode 100644 templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-collector.sh diff --git a/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-collector.sh b/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-collector.sh new file mode 100644 index 0000000..33bedf9 --- /dev/null +++ b/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-collector.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# OpenVPN Discovery - COLETOR (Arthur's Gold Standard v6-CACHE) +# Este script roda via CRON e grava o resultado em cache +# Compatível com: pfSense 2.x / FreeBSD +# +# Instalação: +# 1. Copie para /opt/zabbix/openvpn-collector.sh +# 2. chmod +x /opt/zabbix/openvpn-collector.sh +# 3. Adicione ao cron: */1 * * * * /opt/zabbix/openvpn-collector.sh + +SOCKET_DIR="/var/etc/openvpn" +CACHE_FILE="/tmp/openvpn_discovery.json" +CACHE_FILE_TMP="/tmp/openvpn_discovery.json.tmp" + +# Inicia JSON +printf '{"data":[' > "$CACHE_FILE_TMP" + +first=1 + +# Loop através de cada socket +for sockdir in "$SOCKET_DIR"/server*/; do + [ -d "$sockdir" ] || continue + + sockfile="${sockdir}sock" + [ -S "$sockfile" ] || continue + + server_name=$(basename "$sockdir") + + # Consulta o socket e processa linha por linha + (echo "status 2"; sleep 0.3; echo "quit") | /usr/bin/nc -U "$sockfile" 2>/dev/null | \ + grep "^CLIENT_LIST," | grep -v "Common Name" | \ + while IFS=',' read -r type cn realaddr virtaddr rest; do + [ -z "$cn" ] && continue + + real_ip=$(echo "$realaddr" | cut -d: -f1) + virt_ip=$(echo "$virtaddr" | cut -d: -f1) + + if [ $first -eq 0 ]; then + printf ',' + fi + + printf '{"{#VPN.USER}":"%s","{#VPN.SERVER}":"%s","{#VPN.REAL_IP}":"%s","{#VPN.VIRTUAL_IP}":"%s"}' "$cn" "$server_name" "$real_ip" "$virt_ip" + first=0 + done >> "$CACHE_FILE_TMP" + + first=0 +done + +printf ']}\n' >> "$CACHE_FILE_TMP" + +# Move atomicamente para evitar leitura parcial +mv "$CACHE_FILE_TMP" "$CACHE_FILE" +chmod 644 "$CACHE_FILE" diff --git a/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-discovery.sh b/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-discovery.sh index b588d16..4cede49 100644 --- a/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-discovery.sh +++ b/templates_gold/pfsense_hybrid_snmp_agent/files/openvpn-discovery.sh @@ -1,47 +1,16 @@ #!/bin/sh -# OpenVPN Discovery Script via Management Interface (Arthur's Gold Standard v5-FINAL) -# Compatível com: pfSense 2.x / FreeBSD -# -# Outputs: {#VPN.USER}, {#VPN.SERVER}, {#VPN.REAL_IP}, {#VPN.VIRTUAL_IP} +# OpenVPN Discovery - LEITOR (Arthur's Gold Standard v6-CACHE) +# Este script é chamado pelo Zabbix e apenas lê o cache +# Execução INSTANTÂNEA - sem timeout +# +# Dependência: openvpn-collector.sh rodando via cron -SOCKET_DIR="/var/etc/openvpn" +CACHE_FILE="/tmp/openvpn_discovery.json" -# Inicia JSON -printf '{"data":[' - -first=1 - -# Loop através de cada socket -for sockdir in "$SOCKET_DIR"/server*/; do - [ -d "$sockdir" ] || continue - - sockfile="${sockdir}sock" - [ -S "$sockfile" ] || continue - - server_name=$(basename "$sockdir") - - # Consulta o socket e processa linha por linha - (echo "status 2"; sleep 0.3; echo "quit") | /usr/bin/nc -U "$sockfile" 2>/dev/null | \ - grep "^CLIENT_LIST," | grep -v "Common Name" | \ - while IFS=',' read -r type cn realaddr virtaddr rest; do - # Ignora se CN está vazio ou é o header - [ -z "$cn" ] && continue - - # Extrai apenas IP (remove porta) - real_ip=$(echo "$realaddr" | cut -d: -f1) - virt_ip=$(echo "$virtaddr" | cut -d: -f1) - - # Imprime separador se não for primeiro - if [ $first -eq 0 ]; then - printf ',' - fi - - printf '{"{#VPN.USER}":"%s","{#VPN.SERVER}":"%s","{#VPN.REAL_IP}":"%s","{#VPN.VIRTUAL_IP}":"%s"}' "$cn" "$server_name" "$real_ip" "$virt_ip" - first=0 - done - - # Atualiza flag first se houve saída - first=0 -done - -printf ']}\n' \ No newline at end of file +# Se o cache existe e tem menos de 5 minutos, usa ele +if [ -f "$CACHE_FILE" ]; then + cat "$CACHE_FILE" +else + # Cache não existe, retorna vazio + echo '{"data":[]}' +fi \ No newline at end of file