diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json index 57258190..5ae9a97f 100755 --- a/front/php/templates/language/en_us.json +++ b/front/php/templates/language/en_us.json @@ -578,18 +578,6 @@ "MQTT_QOS_description" : "Quality of service setting for MQTT message sending. 0 - Low quality to 2 - High quality. The higher the quality the longer the delay.", "MQTT_DELAY_SEC_name" : "MQTT delay per device", "MQTT_DELAY_SEC_description" : "A little hack - delay adding to the queue in case the process is restarted and previous publish processes aborted (it takes ~2s to update a sensor config on the broker). Tested with 2-3 seconds of delay. This delay is only applied when devices are created (during the first notification loop). It doesn not affect subsequent scans or notifications.", - "DynDNS_display_name" : "DynDNS", - "DynDNS_icon" : "", - "DDNS_ACTIVE_name" : "Enable DynDNS", - "DDNS_ACTIVE_description" : "Enable DynDNS service", - "DDNS_DOMAIN_name" : "DynDNS domain URL", - "DDNS_DOMAIN_description" : "DynDNS host URL (do not include http:// or https://).", - "DDNS_USER_name" : "DynDNS user", - "DDNS_USER_description" : "The username used to login to the DynDNS service (sometimes a full email address).", - "DDNS_PASSWORD_name" : "DynDNS password", - "DDNS_PASSWORD_description" : "The DynDNS service access password", - "DDNS_UPDATE_URL_name" : "DynDNS update URL", - "DDNS_UPDATE_URL_description" : "Update URL starting with http:// or https://.", "API_display_name" : "API", "API_icon" : "", "API_CUSTOM_SQL_name" : "Custom endpoint", diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json index 01ca5dbe..0d298b11 100755 --- a/front/php/templates/language/es_es.json +++ b/front/php/templates/language/es_es.json @@ -569,18 +569,6 @@ "MQTT_QOS_description" : "Configuración de calidad de servicio para el envío de mensajes MQTT. 0: baja calidad a 2: alta calidad. Cuanto mayor sea la calidad, mayor será el retraso.", "MQTT_DELAY_SEC_name" : "Retraso de MQTT por dispositivo", "MQTT_DELAY_SEC_description" : "Un pequeño truco: retrase la adición a la cola en caso de que el proceso se reinicie y los procesos de publicación anteriores se anulen (se necesitan ~2s para actualizar la configuración de un sensor en el intermediario). Probado con 2-3 segundos de retraso. Este retraso solo se aplica cuando se crean dispositivos (durante el primer bucle de notificación). No afecta los escaneos o notificaciones posteriores.", - "DynDNS_display_name" : "DynDNS", - "DynDNS_icon" : "", - "DDNS_ACTIVE_name" : "Habilitar DynDNS", - "DDNS_ACTIVE_description" : "Habilitar el servicio DynDNS", - "DDNS_DOMAIN_name" : "URL del dominio DynDNS", - "DDNS_DOMAIN_description" : "URL del host DynDNS (no incluya http:// o https://).", - "DDNS_USER_name" : "Usuario de DynDNS", - "DDNS_USER_description" : "El nombre de usuario utilizado para iniciar sesión en el servicio DynDNS (a veces, una dirección de correo electrónico completa).", - "DDNS_PASSWORD_name" : "Contraseña de DynDNS", - "DDNS_PASSWORD_description" : "La contraseña de acceso al servicio DynDNS.", - "DDNS_UPDATE_URL_name" : "URL de actualización de DynDNS", - "DDNS_UPDATE_URL_description" : "Actualice la URL que comienza con http:// o https://.", "API_display_name" : "API", "API_icon" : "", "API_CUSTOM_SQL_name" : "Endpoint personalizado", diff --git a/front/plugins/ddns_update/README.md b/front/plugins/ddns_update/README.md new file mode 100755 index 00000000..03fa70f4 --- /dev/null +++ b/front/plugins/ddns_update/README.md @@ -0,0 +1,7 @@ +## Overview + +Plugin to run regular database cleanup tasks. It is strongly recommended to have an hourly or at least daily schedule running. + +### Usage + +- Check the Settings page for details. diff --git a/front/plugins/ddns_update/config.json b/front/plugins/ddns_update/config.json new file mode 100755 index 00000000..e29d683f --- /dev/null +++ b/front/plugins/ddns_update/config.json @@ -0,0 +1,559 @@ +{ + "code_name": "ddns_update", + "unique_prefix": "DDNS", + "enabled": true, + "data_filters": [ + { + "compare_column": "Object_PrimaryID", + "compare_operator": "==", + "compare_field_id": "txtMacFilter", + "compare_js_template": "'{value}'.toString()", + "compare_use_quotes": true + } + ], + "data_source": "script", + "show_ui": true, + "localized": [ + "display_name", + "description", + "icon" + ], + "display_name": [ + { + "language_code": "en_us", + "string": "Internet check" + } + ], + "icon": [ + { + "language_code": "en_us", + "string": "" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "A plugin update the DDNS record." + } + ], + "params": [ + { + "name": "prev_ip", + "type": "sql", + "value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' " + }, + { + "name": "DDNS_UPDATE_URL", + "type": "setting", + "value": "DDNS_UPDATE_URL" + }, + { + "name": "DDNS_USER", + "type": "setting", + "value": "DDNS_USER" + }, + { + "name": "DDNS_PASSWORD", + "type": "setting", + "value": "DDNS_PASSWORD" + }, + { + "name": "DDNS_DOMAIN", + "type": "setting", + "value": "DDNS_DOMAIN" + } + ], + "settings": [ + { + "function": "RUN", + "events": ["run"], + "type": "text.select", + "default_value": "schedule", + "options": [ + "disabled", + "once", + "schedule", + "always_after_scan" + ], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "When to run" + }, + { + "language_code": "es_es", + "string": "Cuándo ejecutar" + }, + { + "language_code": "de_de", + "string": "Wann laufen" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "When the plugin should run. An hourly or daily SCHEDULE is a good option." + } + ] + }, + { + "function": "CMD", + "type": "readonly", + "default_value": "python3 /home/pi/pialert/front/plugins/ddns_update/script.py prev_ip={prev_ip} DDNS_UPDATE_URL={DDNS_UPDATE_URL} DDNS_USER={DDNS_USER} DDNS_PASSWORD={DDNS_PASSWORD} DDNS_DOMAIN={DDNS_DOMAIN} ", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Command" + }, + { + "language_code": "es_es", + "string": "Comando" + }, + { + "language_code": "de_de", + "string": "Befehl" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Command to run. This can not be changed" + }, + { + "language_code": "es_es", + "string": "Comando a ejecutar. Esto no se puede cambiar" + }, + { + "language_code": "de_de", + "string": "Befehl zum Ausführen. Dies kann nicht geändert werden" + } + ] + }, + { + "function": "RUN_SCHD", + "type": "text", + "default_value": "*/5 * * * *", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Schedule" + }, + { + "language_code": "es_es", + "string": "Schedule" + }, + { + "language_code": "de_de", + "string": "Schedule" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Only enabled if you select schedule in the DDNS_RUN setting. Make sure you enter the schedule in the correct cron-like format (e.g. validate at crontab.guru). For example entering 0 4 * * * will run the scan after 4 am in the TIMEZONE you set above. Will be run NEXT time the time passes." + }, + { + "language_code": "es_es", + "string": "Solo está habilitado si selecciona schedule en la configuración DDNS_RUN. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en crontab.guru). Por ejemplo, ingresar 0 4 * * * ejecutará el escaneo después de las 4 a.m. en el TIMEZONE que configuró arriba. Se ejecutará la PRÓXIMA vez que pase el tiempo." + }, + { + "language_code": "de_de", + "string": "Nur aktiviert, wenn Sie schedule in der DDNS_RUN-Einstellung auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter crontab.guru). Wenn Sie beispielsweise 0 4 * * * eingeben, wird der Scan nach 4 Uhr morgens in der TIMEZONE den Sie oben festgelegt haben. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht." + } + ] + }, + { + "function": "RUN_TIMEOUT", + "type": "integer", + "default_value": 30, + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Run timeout" + }, + { + "language_code": "es_es", + "string": "Tiempo límite de ejecución" + }, + { + "language_code": "de_de", + "string": "Zeitüberschreitung" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted." + }, + { + "language_code": "es_es", + "string": "Tiempo máximo en segundos para esperar a que finalice el script. Si se supera este tiempo, el script se cancela." + }, + { + "language_code": "de_de", + "string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen." + } + ] + }, + { + "function": "DOMAIN", + "type": "text", + "default_value": "your_domain.freeddns.org", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "DynDNS domain URL" + }, + { + "language_code": "es_es", + "string": "URL del dominio DynDNS" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "DynDNS host URL (do not include http:// or https://)." + }, + { + "language_code": "es_es", + "string": "URL del host DynDNS (no incluya http:// o https://)." + } + ] + }, + { + "function": "USER", + "type": "text", + "default_value": "dynu_user", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "DynDNS user" + }, + { + "language_code": "es_es", + "string": "Usuario de DynDNS" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "The username used to login to the DynDNS service (sometimes a full email address)." + }, + { + "language_code": "es_es", + "string": "El nombre de usuario utilizado para iniciar sesión en el servicio DynDNS (a veces, una dirección de correo electrónico completa)." + } + ] + }, + { + "function": "PASSWORD", + "type": "password", + "default_value": "A0000000B0000000C0000000D0000000", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "DynDNS password" + }, + { + "language_code": "es_es", + "string": "Contraseña de DynDNS" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "The DynDNS service access password" + }, + { + "language_code": "es_es", + "string": "La contraseña de acceso al servicio DynDNS." + } + ] + }, + { + "function": "UPDATE_URL", + "type": "text", + "default_value": "https://api.dynu.com/nic/update?", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "DynDNS update URL" + }, + { + "language_code": "es_es", + "string": "URL de actualización de DynDNS" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Update URL starting with http:// or https://." + }, + { + "language_code": "es_es", + "string": "Actualice la URL que comienza con http:// o https://." + } + ] + }, + { + "function": "WATCH", + "type": "text.multiselect", + "default_value": [ + "Watched_Value1" + ], + "options": [ + "Watched_Value1", + "Watched_Value2", + "Watched_Value3", + "Watched_Value4" + ], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Watched" + }, + { + "language_code": "es_es", + "string": "Visto" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Send a notification if selected values change. Use CTRL + Click to select/deselect. " + } + ] + }, + { + "function": "REPORT_ON", + "type": "text.multiselect", + "default_value":["new","watched-changed"], + "options": ["new","watched-changed","watched-not-changed", "missing-in-last-scan"], + "localized": ["name", "description"], + "name" :[{ + "language_code":"en_us", + "string" : "Report on" + }, + { + "language_code":"es_es", + "string" : "Informar sobre" + } ] , + "description":[{ + "language_code":"en_us", + "string" : "Send a notification only on these statuses. new means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. watched-changed means that selected Watched_ValueN columns changed." + }, + { + "language_code":"es_es", + "string" : "Envíe una notificación solo en estos estados. new significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). watched-changed significa que las columnas Watched_ValueN seleccionadas cambiaron." + }] + } + ], + "database_column_definitions": [ + { + "column": "Object_PrimaryID", + "css_classes": "col-sm-2", + "show": true, + "type": "device_name_mac", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "MAC" + }, + { + "language_code": "es_es", + "string": "MAC" + } + ] + }, + { + "column": "Object_SecondaryID", + "css_classes": "col-sm-2", + "show": true, + "type": "device_ip", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "IP" + }, + { + "language_code": "es_es", + "string": "IP" + } + ] + }, + { + "column": "Watched_Value1", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Extra" + } + ] + }, + { + "column": "Dummy", + "mapped_to_column_data": { + "value": "DDNS" + }, + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Scan method" + }, + { + "language_code": "es_es", + "string": "Método de escaneo" + } + ] + }, + { + "column": "DateTimeCreated", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Created" + }, + { + "language_code": "es_es", + "string": "Creado" + } + ] + }, + { + "column": "DateTimeChanged", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Changed" + }, + { + "language_code": "es_es", + "string": "Cambiado" + } + ] + }, + { + "column": "Status", + "css_classes": "col-sm-1", + "show": true, + "type": "replace", + "default_value": "", + "options": [ + { + "equals": "watched-not-changed", + "replacement": "
" + }, + { + "equals": "watched-changed", + "replacement": "
" + }, + { + "equals": "new", + "replacement": "
" + }, + { + "equals": "missing-in-last-scan", + "replacement": "
" + } + ], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Status" + }, + { + "language_code": "es_es", + "string": "Estado" + } + ] + } + ] +} \ No newline at end of file diff --git a/front/plugins/ddns_update/script.py b/front/plugins/ddns_update/script.py new file mode 100755 index 00000000..67c62168 --- /dev/null +++ b/front/plugins/ddns_update/script.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python +# test script by running: +# /home/pi/pialert/front/plugins/internet_ip/script.py TBD + +import os +import pathlib +import argparse +import sys +import hashlib +import csv +import subprocess +import re +import base64 +import sqlite3 +from io import StringIO +from datetime import datetime + +sys.path.append("/home/pi/pialert/front/plugins") +sys.path.append('/home/pi/pialert/pialert') + +from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64 +from logger import mylog, append_line_to_file +from helper import timeNowTZ, check_IP_format +from const import logPath, pialertPath, fullDbPath + + +CUR_PATH = str(pathlib.Path(__file__).parent.resolve()) +LOG_FILE = os.path.join(CUR_PATH, 'script.log') +RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log') + +def main(): + + mylog('verbose', ['[DDNS] In script']) + + parser = argparse.ArgumentParser(description='Check internet connectivity and IP') + + parser.add_argument('prev_ip', action="store", help="Previous IP address to compare against the current IP") + parser.add_argument('DDNS_UPDATE_URL', action="store", help="URL for updating Dynamic DNS (DDNS)") + parser.add_argument('DDNS_USER', action="store", help="Username for Dynamic DNS (DDNS) authentication") + parser.add_argument('DDNS_PASSWORD', action="store", help="Password for Dynamic DNS (DDNS) authentication") + parser.add_argument('DDNS_DOMAIN', action="store", help="Dynamic DNS (DDNS) domain name") + + + values = parser.parse_args() + + PREV_IP = values.prev_ip.split('=')[1] + DDNS_UPDATE_URL = values.DDNS_UPDATE_URL.split('=')[1] + DDNS_USER = values.DDNS_USER.split('=')[1] + DDNS_PASSWORD = values.DDNS_PASSWORD.split('=')[1] + DDNS_DOMAIN = values.DDNS_DOMAIN.split('=')[1] + + # perform the new IP lookup and DDNS tasks if enabled + ddns_update( DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN, PREV_IP) + + mylog('verbose', ['[DDNS] Finished ']) + + return 0 + + +#=============================================================================== +# INTERNET IP CHANGE +#=============================================================================== +def ddns_update ( DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN, PREV_IP ): + + # Update DDNS record if enabled and IP is different + # Get Dynamic DNS IP + + mylog('verbose', ['[DDNS] Retrieving Dynamic DNS IP']) + dns_IP = get_dynamic_DNS_IP(DDNS_DOMAIN) + + # Check Dynamic DNS IP + if dns_IP == "" or dns_IP == "0.0.0.0" : + mylog('none', ['[DDNS] Error retrieving Dynamic DNS IP']) + + mylog('none', ['[DDNS] ', dns_IP]) + + # Check DNS Change + if dns_IP != internet_IP : + mylog('none', ['[DDNS] Updating Dynamic DNS IP']) + message = set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN) + mylog('none', ['[DDNS] ', message]) + + # plugin_objects = Plugin_Objects(RESULT_FILE) + + # plugin_objects.add_object( + # primaryId = 'Internet', # MAC (Device Name) + # secondaryId = new_internet_IP, # IP Address + # watched1 = f'Previous IP: {PREV_IP}', + # watched2 = '', + # watched3 = '', + # watched4 = '', + # extra = f'Previous IP: {PREV_IP}', + # foreignKey = 'Internet') + + # plugin_objects.write_result_file() + + +#------------------------------------------------------------------------------- +def get_dynamic_DNS_IP (DDNS_DOMAIN): + + # Using supplied DNS server + dig_args = ['dig', '+short', DDNS_DOMAIN] + + try: + # try runnning a subprocess + dig_output = subprocess.check_output (dig_args, universal_newlines=True) + except subprocess.CalledProcessError as e: + # An error occured, handle it + mylog('none', ['[DDNS] ERROR - ', e.output]) + dig_output = '' # probably no internet + + # Check result is an IP + IP = check_IP_format (dig_output) + + # Handle invalid response + if IP == '': + IP = '0.0.0.0' + + return IP + +#------------------------------------------------------------------------------- +def set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN): + try: + # try runnning a subprocess + # Update Dynamic IP + curl_output = subprocess.check_output (['curl', + '-s', + DDNS_UPDATE_URL + + 'username=' + DDNS_USER + + '&password=' + DDNS_PASSWORD + + '&hostname=' + DDNS_DOMAIN], + universal_newlines=True) + except subprocess.CalledProcessError as e: + # An error occured, handle it + mylog('none', ['[DDNS] ERROR - ',e.output]) + curl_output = "" + + return curl_output + + +#=============================================================================== +# BEGIN +#=============================================================================== +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/front/plugins/internet_ip/config.json b/front/plugins/internet_ip/config.json index 8e8cb617..d78a44ba 100755 --- a/front/plugins/internet_ip/config.json +++ b/front/plugins/internet_ip/config.json @@ -43,31 +43,6 @@ "type": "sql", "value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' " }, - { - "name": "DDNS_ACTIVE", - "type": "setting", - "value": "DDNS_ACTIVE" - }, - { - "name": "DDNS_UPDATE_URL", - "type": "setting", - "value": "DDNS_UPDATE_URL" - }, - { - "name": "DDNS_USER", - "type": "setting", - "value": "DDNS_USER" - }, - { - "name": "DDNS_PASSWORD", - "type": "setting", - "value": "DDNS_PASSWORD" - }, - { - "name": "DDNS_DOMAIN", - "type": "setting", - "value": "DDNS_DOMAIN" - }, { "name": "DIG_GET_IP_ARG", "type": "setting", @@ -108,14 +83,14 @@ "description": [ { "language_code": "en_us", - "string": "When the cleanup should be performed. An hourly or daily SCHEDULE is a good option." + "string": "When the plugin should run. An hourly or daily SCHEDULE is a good option." } ] }, { "function": "CMD", "type": "readonly", - "default_value": "python3 /home/pi/pialert/front/plugins/internet_ip/script.py prev_ip={prev_ip} DDNS_ACTIVE={DDNS_ACTIVE} DDNS_UPDATE_URL={DDNS_UPDATE_URL} DDNS_USER={DDNS_USER} DDNS_PASSWORD={DDNS_PASSWORD} DDNS_DOMAIN={DDNS_DOMAIN} DIG_GET_IP_ARG={DIG_GET_IP_ARG}", + "default_value": "python3 /home/pi/pialert/front/plugins/internet_ip/script.py prev_ip={prev_ip} DIG_GET_IP_ARG={DIG_GET_IP_ARG}", "options": [], "localized": [ "name", @@ -255,7 +230,7 @@ "description": [ { "language_code": "en_us", - "string": "Send a notification if selected values change. Use CTRL + Click to select/deselect.
  • Watched_Value1 is Internet IP/li>
  • Watched_Value2 is Previous IP (not recommended)
  • Watched_Value3 unused
  • Watched_Value4 unused
" + "string": "Send a notification if selected values change. Use CTRL + Click to select/deselect.
  • Watched_Value1 is Previous IP (not recommended)
  • Watched_Value2 unused
  • Watched_Value3 unused
  • Watched_Value4 unused
" } ] }, @@ -307,7 +282,7 @@ ] }, { - "column": "Watched_Value1", + "column": "Object_SecondaryID", "mapped_to_column": "cur_IP", "css_classes": "col-sm-2", "show": true, @@ -329,7 +304,7 @@ ] }, { - "column": "Watched_Value2", + "column": "Watched_Value1", "css_classes": "col-sm-2", "show": true, "type": "label", diff --git a/front/plugins/internet_ip/script.py b/front/plugins/internet_ip/script.py index fc88da93..844a54ab 100755 --- a/front/plugins/internet_ip/script.py +++ b/front/plugins/internet_ip/script.py @@ -35,63 +35,30 @@ def main(): parser = argparse.ArgumentParser(description='Check internet connectivity and IP') parser.add_argument('prev_ip', action="store", help="Previous IP address to compare against the current IP") - parser.add_argument('DDNS_ACTIVE', action="store", help="Indicates if Dynamic DNS (DDNS) is active (True/False)") - parser.add_argument('DDNS_UPDATE_URL', action="store", help="URL for updating Dynamic DNS (DDNS)") - parser.add_argument('DDNS_USER', action="store", help="Username for Dynamic DNS (DDNS) authentication") - parser.add_argument('DDNS_PASSWORD', action="store", help="Password for Dynamic DNS (DDNS) authentication") - parser.add_argument('DDNS_DOMAIN', action="store", help="Dynamic DNS (DDNS) domain name") parser.add_argument('DIG_GET_IP_ARG', action="store", help="Arguments for the 'dig' command to retrieve the IP address") values = parser.parse_args() - PREV_IP = values.prev_ip.split('=')[1] - DDNS_ACTIVE = values.DDNS_ACTIVE.split('=')[1] - DDNS_UPDATE_URL = values.DDNS_UPDATE_URL.split('=')[1] - DDNS_USER = values.DDNS_USER.split('=')[1] - DDNS_PASSWORD = values.DDNS_PASSWORD.split('=')[1] - DDNS_DOMAIN = values.DDNS_DOMAIN.split('=')[1] - DIG_GET_IP_ARG = values.DIG_GET_IP_ARG.split('=')[1] + PREV_IP = values.prev_ip.split('=')[1] + DIG_GET_IP_ARG = values.DIG_GET_IP_ARG.split('=b')[1] # byte64 encoded - mylog('verbose', ['[INTRNT] DIG_GET_IP_ARG: ', DIG_GET_IP_ARG]) + mylog('verbose', ['[INTRNT] DIG_GET_IP_ARG: ', DIG_GET_IP_ARG]) # Decode the base64-encoded value to get the actual value in ASCII format. - DIG_GET_IP_ARG = base64.b64decode(DIG_GET_IP_ARG.split('b')[1]).decode('ascii') + DIG_GET_IP_ARG = base64.b64decode(DIG_GET_IP_ARG).decode('ascii') mylog('verbose', [f'[INTRNT] DIG_GET_IP_ARG resolved: {DIG_GET_IP_ARG} ']) - # if internet_IP != "" : - # sql.execute (f"""INSERT INTO CurrentScan (cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) - # VALUES ( 'Internet', '{internet_IP}', Null, 'queryDNS') """) - - # # Save event - # cursor.execute ("""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime, - # eve_EventType, eve_AdditionalInfo, - # eve_PendingAlertEmail) - # VALUES ('Internet', ?, ?, 'Internet IP Changed', - # 'Previous Internet IP: '|| ?, 1) """, - # (pNewIP, timeNowTZ(), prevIp) ) - - - # # Save new IP - # cursor.execute ("""UPDATE Devices SET dev_LastIP = ? - # WHERE dev_MAC = 'Internet' """, - # (pNewIP,) ) - - - # Object_PrimaryID - cur_MAC - # Watched_Value1 - cur_IP - # Watched_Value2 - Extra / prev IP - - - new_internet_IP = check_internet_IP( DDNS_ACTIVE, DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN, PREV_IP, DIG_GET_IP_ARG) + # perform the new IP lookup + new_internet_IP = check_internet_IP( PREV_IP, DIG_GET_IP_ARG) plugin_objects = Plugin_Objects(RESULT_FILE) plugin_objects.add_object( primaryId = 'Internet', # MAC (Device Name) - secondaryId = '', - watched1 = new_internet_IP, # IP Address - watched2 = f'Previous IP: {PREV_IP}', + secondaryId = new_internet_IP, # IP Address + watched1 = f'Previous IP: {PREV_IP}', + watched2 = '', watched3 = '', watched4 = '', extra = f'Previous IP: {PREV_IP}', @@ -102,104 +69,36 @@ def main(): mylog('verbose', ['[INTRNT] Finished ']) return 0 - - + #=============================================================================== # INTERNET IP CHANGE #=============================================================================== -def check_internet_IP ( DDNS_ACTIVE, DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN, PREV_IP, DIG_GET_IP_ARG ): +def check_internet_IP ( PREV_IP, DIG_GET_IP_ARG ): # Get Internet IP mylog('verbose', ['[INTRNT] - Retrieving Internet IP']) internet_IP = get_internet_IP(DIG_GET_IP_ARG) - # Check result = IP - if internet_IP == "" : - mylog('none', ['[INTRNT] Error retrieving Internet IP']) + mylog('verbose', [f'[INTRNT] Current internet_IP : {internet_IP}']) - # Get previous stored IP + # Check previously stored IP previous_IP = '0.0.0.0' if PREV_IP is not None and len(PREV_IP) > 0 : previous_IP = PREV_IP - mylog('verbose', ['[INTRNT] ', previous_IP]) + mylog('verbose', [f'[INTRNT] previous_IP : {previous_IP}']) # logging - append_line_to_file (logPath + '/IP_changes.log', '['+str(timeNowTZ()) +']\t'+ internet_IP +'\n') - - # Get Dynamic DNS IP - if DDNS_ACTIVE : - mylog('verbose', ['[DDNS] Retrieving Dynamic DNS IP']) - dns_IP = get_dynamic_DNS_IP(DDNS_DOMAIN) - - # Check Dynamic DNS IP - if dns_IP == "" or dns_IP == "0.0.0.0" : - mylog('none', ['[DDNS] Error retrieving Dynamic DNS IP']) - mylog('none', ['[DDNS] ', dns_IP]) - - # Check DNS Change - if dns_IP != internet_IP : - mylog('none', ['[DDNS] Updating Dynamic DNS IP']) - message = set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN) - mylog('none', ['[DDNS] ', message]) - else : - mylog('verbose', ['[DDNS] No changes to perform']) - else : - mylog('verbose', ['[DDNS] Skipping Dynamic DNS update']) + append_line_to_file (logPath + '/IP_changes.log', '['+str(timeNowTZ()) +']\t'+ internet_IP +'\n') return internet_IP -#------------------------------------------------------------------------------- -def get_dynamic_DNS_IP (DDNS_DOMAIN): - # Using OpenDNS server - # dig_args = ['dig', '+short', DDNS_DOMAIN, '@resolver1.opendns.com'] - - # Using default DNS server - dig_args = ['dig', '+short', DDNS_DOMAIN] - - try: - # try runnning a subprocess - dig_output = subprocess.check_output (dig_args, universal_newlines=True) - except subprocess.CalledProcessError as e: - # An error occured, handle it - mylog('none', ['[DDNS] ERROR - ', e.output]) - dig_output = '' # probably no internet - - # Check result is an IP - IP = check_IP_format (dig_output) - - # Handle invalid response - if IP == '': - IP = '0.0.0.0' - - return IP - -#------------------------------------------------------------------------------- -def set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN): - try: - # try runnning a subprocess - # Update Dynamic IP - curl_output = subprocess.check_output (['curl', - '-s', - DDNS_UPDATE_URL + - 'username=' + DDNS_USER + - '&password=' + DDNS_PASSWORD + - '&hostname=' + DDNS_DOMAIN], - universal_newlines=True) - except subprocess.CalledProcessError as e: - # An error occured, handle it - mylog('none', ['[DDNS] ERROR - ',e.output]) - curl_output = "" - - return curl_output - - #------------------------------------------------------------------------------- def get_internet_IP (DIG_GET_IP_ARG): - # BUGFIX #46 - curl http://ipv4.icanhazip.com repeatedly is very slow + # Using 'dig' dig_args = ['dig', '+short'] + DIG_GET_IP_ARG.strip().split() try: diff --git a/front/plugins/vendor_update/config.json b/front/plugins/vendor_update/config.json index 2f56cada..024dec7f 100755 --- a/front/plugins/vendor_update/config.json +++ b/front/plugins/vendor_update/config.json @@ -61,7 +61,7 @@ "description": [ { "language_code": "en_us", - "string": "When the cleanup should be performed. An overnight weekly SCHEDULE is recommended." + "string": "When the plugin should run. An overnight weekly SCHEDULE is recommended." } ] }, diff --git a/pialert/conf.py b/pialert/conf.py index 77b30c25..9d5ddd30 100755 --- a/pialert/conf.py +++ b/pialert/conf.py @@ -101,10 +101,3 @@ MQTT_DELAY_SEC = 2 # API API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0' - -# DynDNS -DDNS_ACTIVE = False -DDNS_DOMAIN = 'your_domain.freeddns.org' -DDNS_USER = 'dynu_user' -DDNS_PASSWORD = 'A0000000B0000000C0000000D0000000' -DDNS_UPDATE_URL = 'https://api.dynu.com/nic/update?' \ No newline at end of file diff --git a/pialert/initialise.py b/pialert/initialise.py index a90f1b10..d253f6cd 100755 --- a/pialert/initialise.py +++ b/pialert/initialise.py @@ -153,14 +153,6 @@ def importConfigs (db): conf.MQTT_PASSWORD = ccd('MQTT_PASSWORD', '' , c_d, 'MQTT password', 'password', '', 'MQTT') conf.MQTT_QOS = ccd('MQTT_QOS', 0 , c_d, 'MQTT Quality of Service', 'integer.select', "['0', '1', '2']", 'MQTT') conf.MQTT_DELAY_SEC = ccd('MQTT_DELAY_SEC', 2 , c_d, 'MQTT delay', 'integer.select', "['2', '3', '4', '5']", 'MQTT') - - # DynDNS - conf.DDNS_ACTIVE = ccd('DDNS_ACTIVE', False , c_d, 'Enable DynDNS', 'boolean', '', 'DynDNS') - conf.DDNS_DOMAIN = ccd('DDNS_DOMAIN', 'your_domain.freeddns.org' , c_d, 'DynDNS domain URL', 'text', '', 'DynDNS') - conf.DDNS_USER = ccd('DDNS_USER', 'dynu_user' , c_d, 'DynDNS user', 'text', '', 'DynDNS') - conf.DDNS_PASSWORD = ccd('DDNS_PASSWORD', 'A0000000B0000000C0000000D0000000' , c_d, 'DynDNS password', 'password', '', 'DynDNS') - conf.DDNS_UPDATE_URL = ccd('DDNS_UPDATE_URL', 'https://api.dynu.com/nic/update?' , c_d, 'DynDNS update URL', 'text', '', 'DynDNS') - # Init timezone in case it changed conf.tz = timezone(conf.TIMEZONE)