internet_ip plugin 0.2
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td height=200 valign=top style="padding: 10px">
|
<td height=200 valign=top style="padding: 10px">
|
||||||
|
|
||||||
<INTERNET_TABLE>
|
|
||||||
<NEW_DEVICES_TABLE>
|
<NEW_DEVICES_TABLE>
|
||||||
<DOWN_DEVICES_TABLE>
|
<DOWN_DEVICES_TABLE>
|
||||||
<EVENTS_TABLE>
|
<EVENTS_TABLE>
|
||||||
|
|||||||
@@ -4,5 +4,4 @@ Server: <SERVER_NAME>
|
|||||||
<SECTION_NEW_DEVICES>
|
<SECTION_NEW_DEVICES>
|
||||||
<SECTION_DEVICES_DOWN>
|
<SECTION_DEVICES_DOWN>
|
||||||
<SECTION_EVENTS>
|
<SECTION_EVENTS>
|
||||||
<SECTION_INTERNET>
|
|
||||||
<PLUGINS_TABLE>
|
<PLUGINS_TABLE>
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td height=200 valign=top style="padding: 10px">
|
<td height=200 valign=top style="padding: 10px">
|
||||||
|
|
||||||
<INTERNET_TABLE>
|
|
||||||
<NEW_DEVICES_TABLE>
|
<NEW_DEVICES_TABLE>
|
||||||
<DOWN_DEVICES_TABLE>
|
<DOWN_DEVICES_TABLE>
|
||||||
<EVENTS_TABLE>
|
<EVENTS_TABLE>
|
||||||
|
|||||||
@@ -14,23 +14,24 @@
|
|||||||
|
|
||||||
### 🔌 Plugins & 📚 Docs
|
### 🔌 Plugins & 📚 Docs
|
||||||
|
|
||||||
| Required | CurrentScan | Unique Prefix | Plugin Type | Link + Docs |
|
| Required | CurrentScan | Unique Prefix | Plugin Type | Link + Docs |
|
||||||
|-------------|-------------|-----------------------|------------------------|----------------------------------------------------------|
|
|-------------|-------------|-----------------------|------------------------|----------------------------------------------------------|
|
||||||
| | Yes | ARPSCAN | Script | 📚[arp_scan](/front/plugins/arp_scan/) |
|
| | Yes | ARPSCAN | Script | 📚[arp_scan](/front/plugins/arp_scan/) |
|
||||||
| | | CSVBCKP | Script | 📚[csv_backup](/front/plugins/csv_backup/) |
|
| | | CSVBCKP | Script | 📚[csv_backup](/front/plugins/csv_backup/) |
|
||||||
| Yes* | | DBCLNP | Script | 📚[db_cleanup](/front/plugins/db_cleanup/) |
|
| Yes* | | DBCLNP | Script | 📚[db_cleanup](/front/plugins/db_cleanup/) |
|
||||||
| | Yes | DHCPLSS | Script | 📚[dhcp_leases](/front/plugins/dhcp_leases/) |
|
| | Yes | DHCPLSS | Script | 📚[dhcp_leases](/front/plugins/dhcp_leases/) |
|
||||||
| | | DHCPSRVS | Script | 📚[dhcp_servers](/front/plugins/dhcp_servers/) |
|
| | | DHCPSRVS | Script | 📚[dhcp_servers](/front/plugins/dhcp_servers/) |
|
||||||
| Yes | | NEWDEV | Template | 📚[newdev_template](/front/plugins/newdev_template/) |
|
| | Yes | INTRNT | Script | 📚[internet_ip](/front/plugins/internet_ip/) |
|
||||||
| | | NMAP | Script | 📚[nmap_scan](/front/plugins/nmap_scan/) |
|
| Yes | | NEWDEV | Template | 📚[newdev_template](/front/plugins/newdev_template/) |
|
||||||
| | Yes | PIHOLE | External SQLite DB | 📚[pihole_scan](/front/plugins/pihole_scan/) |
|
| | | NMAP | Script | 📚[nmap_scan](/front/plugins/nmap_scan/) |
|
||||||
| | | SETPWD | Script | 📚[set_password](/front/plugins/set_password/) |
|
| | Yes | PIHOLE | External SQLite DB | 📚[pihole_scan](/front/plugins/pihole_scan/) |
|
||||||
| | | SNMPDSC | Script | 📚[snmp_discovery](/front/plugins/snmp_discovery/) |
|
| | | SETPWD | Script | 📚[set_password](/front/plugins/set_password/) |
|
||||||
| | Yes* | UNDIS | Script | 📚[undiscoverables](/front/plugins/undiscoverables/) |
|
| | | SNMPDSC | Script | 📚[snmp_discovery](/front/plugins/snmp_discovery/) |
|
||||||
| | Yes | UNFIMP | Script | 📚[unifi_import](/front/plugins/unifi_import/) |
|
| | Yes* | UNDIS | Script | 📚[undiscoverables](/front/plugins/undiscoverables/) |
|
||||||
| | | VNDRPDT | Script | 📚[vendor_update](/front/plugins/vendor_update/) |
|
| | Yes | UNFIMP | Script | 📚[unifi_import](/front/plugins/unifi_import/) |
|
||||||
| | | WEBMON | Script | 📚[website_monitor](/front/plugins/website_monitor/) |
|
| | | VNDRPDT | Script | 📚[vendor_update](/front/plugins/vendor_update/) |
|
||||||
| N/A | | N/A | SQL query | No example available, but the External SQLite based plugins work very similar |
|
| | | WEBMON | Script | 📚[website_monitor](/front/plugins/website_monitor/) |
|
||||||
|
| N/A | | N/A | SQL query | N/A, but the External SQLite DB plugins work similar |
|
||||||
|
|
||||||
> \* The Undiscoverables plugin (`UNDIS`) inserts only user-specified dummy devices.
|
> \* The Undiscoverables plugin (`UNDIS`) inserts only user-specified dummy devices.
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -352,7 +352,7 @@
|
|||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Status"
|
"string" : "Status"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Estado"
|
"string" : "Estado"
|
||||||
}]
|
}]
|
||||||
|
|||||||
@@ -2,10 +2,23 @@
|
|||||||
"code_name": "internet_ip",
|
"code_name": "internet_ip",
|
||||||
"unique_prefix": "INTRNT",
|
"unique_prefix": "INTRNT",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"mapped_to_table": "CurrentScan",
|
||||||
|
"data_filters": [
|
||||||
|
{
|
||||||
|
"compare_column": "Object_PrimaryID",
|
||||||
|
"compare_operator": "==",
|
||||||
|
"compare_field_id": "txtMacFilter",
|
||||||
|
"compare_js_template": "'{value}'.toString()",
|
||||||
|
"compare_use_quotes": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"data_source": "script",
|
"data_source": "script",
|
||||||
"show_ui": true,
|
"show_ui": true,
|
||||||
"localized": ["display_name", "description", "icon"],
|
"localized": [
|
||||||
|
"display_name",
|
||||||
|
"description",
|
||||||
|
"icon"
|
||||||
|
],
|
||||||
"display_name": [
|
"display_name": [
|
||||||
{
|
{
|
||||||
"language_code": "en_us",
|
"language_code": "en_us",
|
||||||
@@ -24,58 +37,89 @@
|
|||||||
"string": "A plugin to check your internet connectivity and IP."
|
"string": "A plugin to check your internet connectivity and IP."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"params" : [{
|
"params": [
|
||||||
"name" : "pluginskeephistory",
|
{
|
||||||
"type" : "setting",
|
"name": "prev_ip",
|
||||||
"value" : "PLUGINS_KEEP_HIST"
|
"type": "sql",
|
||||||
|
"value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' "
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "daystokeepevents",
|
"name": "DDNS_ACTIVE",
|
||||||
"type" : "setting",
|
"type": "setting",
|
||||||
"value" : "DAYS_TO_KEEP_EVENTS"
|
"value": "DDNS_ACTIVE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "hourstokeepnewdevice",
|
"name": "DDNS_UPDATE_URL",
|
||||||
"type" : "setting",
|
"type": "setting",
|
||||||
"value" : "HRS_TO_KEEP_NEWDEV"
|
"value": "DDNS_UPDATE_URL"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "pholuskeepdays",
|
"name": "DDNS_USER",
|
||||||
"type" : "setting",
|
"type": "setting",
|
||||||
"value" : "PHOLUS_DAYS_DATA"
|
"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",
|
||||||
|
"value": "DIG_GET_IP_ARG",
|
||||||
|
"base64": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"function": "RUN",
|
"function": "RUN",
|
||||||
"type": "text.select",
|
"type": "text.select",
|
||||||
"default_value":"schedule",
|
"default_value": "schedule",
|
||||||
"options": ["disabled", "once", "schedule", "always_after_scan"],
|
"options": [
|
||||||
"localized": ["name", "description"],
|
"disabled",
|
||||||
"name" :[{
|
"once",
|
||||||
"language_code":"en_us",
|
"schedule",
|
||||||
"string" : "When to run"
|
"always_after_scan"
|
||||||
},
|
],
|
||||||
{
|
"localized": [
|
||||||
"language_code":"es_es",
|
"name",
|
||||||
"string" : "Cuándo ejecutar"
|
"description"
|
||||||
},
|
],
|
||||||
{
|
"name": [
|
||||||
"language_code":"de_de",
|
{
|
||||||
"string" : "Wann laufen"
|
"language_code": "en_us",
|
||||||
}],
|
"string": "When to run"
|
||||||
"description": [{
|
},
|
||||||
"language_code":"en_us",
|
{
|
||||||
"string" : "When the cleanup should be performed. An hourly or daily <code>SCHEDULE</code> is a good option."
|
"language_code": "es_es",
|
||||||
}]
|
"string": "Cuándo ejecutar"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"language_code": "de_de",
|
||||||
|
"string": "Wann laufen"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "When the cleanup should be performed. An hourly or daily <code>SCHEDULE</code> is a good option."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"function": "CMD",
|
"function": "CMD",
|
||||||
"type": "readonly",
|
"type": "readonly",
|
||||||
"default_value": "python3 /home/pi/pialert/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}",
|
"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}",
|
||||||
"options": [],
|
"options": [],
|
||||||
"localized": ["name", "description"],
|
"localized": [
|
||||||
|
"name",
|
||||||
|
"description"
|
||||||
|
],
|
||||||
"name": [
|
"name": [
|
||||||
{
|
{
|
||||||
"language_code": "en_us",
|
"language_code": "en_us",
|
||||||
@@ -108,40 +152,50 @@
|
|||||||
{
|
{
|
||||||
"function": "RUN_SCHD",
|
"function": "RUN_SCHD",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"default_value":"*/30 * * * *",
|
"default_value": "*/5 * * * *",
|
||||||
"options": [],
|
"options": [],
|
||||||
"localized": ["name", "description"],
|
"localized": [
|
||||||
"name" : [{
|
"name",
|
||||||
"language_code":"en_us",
|
"description"
|
||||||
"string" : "Schedule"
|
],
|
||||||
},
|
"name": [
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code": "en_us",
|
||||||
"string" : "Schedule"
|
"string": "Schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"de_de",
|
"language_code": "es_es",
|
||||||
"string" : "Schedule"
|
"string": "Schedule"
|
||||||
}],
|
},
|
||||||
"description": [{
|
{
|
||||||
"language_code":"en_us",
|
"language_code": "de_de",
|
||||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#DBCLNP_RUN\"><code>DBCLNP_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
"string": "Schedule"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"language_code":"es_es",
|
"description": [
|
||||||
"string" : "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#DBCLNP_RUN\"><code>DBCLNP_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 a.m. en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ código> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo."
|
{
|
||||||
},
|
"language_code": "en_us",
|
||||||
{
|
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#INTRNT_RUN\"><code>INTRNT_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||||
"language_code":"de_de",
|
},
|
||||||
"string" : "Nur aktiviert, wenn Sie <code>schedule</code> in der <a href=\"#DBCLNP_RUN\"><code>DBCLNP_RUN</code>-Einstellung</a> auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Wenn Sie beispielsweise <code>0 4 * * *</code> eingeben, wird der Scan nach 4 Uhr morgens in der <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ ausgeführt. Code> den Sie oben festgelegt haben</a>. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht."
|
{
|
||||||
}]
|
"language_code": "es_es",
|
||||||
},
|
"string": "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#INTRNT_RUN\"><code>INTRNT_RUN</code></a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 a.m. en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ código> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "de_de",
|
||||||
|
"string": "Nur aktiviert, wenn Sie <code>schedule</code> in der <a href=\"#INTRNT_RUN\"><code>INTRNT_RUN</code>-Einstellung</a> auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Wenn Sie beispielsweise <code>0 4 * * *</code> eingeben, wird der Scan nach 4 Uhr morgens in der <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ ausgeführt. Code> den Sie oben festgelegt haben</a>. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"function": "RUN_TIMEOUT",
|
"function": "RUN_TIMEOUT",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default_value": 30,
|
"default_value": 30,
|
||||||
"options": [],
|
"options": [],
|
||||||
"localized": ["name", "description"],
|
"localized": [
|
||||||
|
"name",
|
||||||
|
"description"
|
||||||
|
],
|
||||||
"name": [
|
"name": [
|
||||||
{
|
{
|
||||||
"language_code": "en_us",
|
"language_code": "en_us",
|
||||||
@@ -170,11 +224,212 @@
|
|||||||
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
|
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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 <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is response status code (e.g.: 200, 404)</li><li><code>Watched_Value2</code> is Latency (not recommended)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "es_es",
|
||||||
|
"string": "Envíe una notificación si los valores seleccionados cambian. Use <code>CTRL + Click</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es un código de estado de respuesta (por ejemplo: 200, 404) </li><li><code>Valor_observado2</code> es Latencia (no recomendado)</li><li><code>Valor_observado3</code> no utilizado </li><li><code>Valor_observado4 </ code> sin usar </li></ul>"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"database_column_definitions": [
|
||||||
"database_column_definitions":
|
{
|
||||||
[
|
"column": "Object_PrimaryID",
|
||||||
|
"mapped_to_column": "cur_MAC",
|
||||||
|
"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": "Watched_Value1",
|
||||||
|
"mapped_to_column": "cur_IP",
|
||||||
|
"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_Value2",
|
||||||
|
"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": "cur_ScanMethod",
|
||||||
|
"mapped_to_column_data": {
|
||||||
|
"value": "INTRNT"
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
"mapped_to_column": "cur_DateTime",
|
||||||
|
"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": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"equals": "watched-changed",
|
||||||
|
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"equals": "new",
|
||||||
|
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"equals": "missing-in-last-scan",
|
||||||
|
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"localized": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"language_code": "en_us",
|
||||||
|
"string": "Status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code": "es_es",
|
||||||
|
"string": "Estado"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ sys.path.append('/home/pi/pialert/pialert')
|
|||||||
|
|
||||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||||
from logger import mylog, append_line_to_file
|
from logger import mylog, append_line_to_file
|
||||||
from helper import timeNowTZ, get_internet_IP
|
from helper import timeNowTZ, check_IP_format
|
||||||
from const import logPath, pialertPath, fullDbPath
|
from const import logPath, pialertPath, fullDbPath
|
||||||
|
|
||||||
|
|
||||||
@@ -32,31 +32,71 @@ def main():
|
|||||||
mylog('verbose', ['[INTRNT] In script'])
|
mylog('verbose', ['[INTRNT] In script'])
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Check internet connectivity and IP')
|
parser = argparse.ArgumentParser(description='Check internet connectivity and IP')
|
||||||
parser.add_argument('pluginskeephistory', action="store", help="TBC")
|
|
||||||
parser.add_argument('hourstokeepnewdevice', action="store", help="TBC")
|
|
||||||
parser.add_argument('daystokeepevents', action="store", help="TBC")
|
|
||||||
parser.add_argument('pholuskeepdays', action="store", help="TBC")
|
|
||||||
|
|
||||||
values = parser.parse_args()
|
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")
|
||||||
|
|
||||||
DDNS_ACTIVE = values.TBC.split('=')[1]
|
args = parser.parse_args()
|
||||||
DDNS_UPDATE_URL = values.TBC.split('=')[1]
|
|
||||||
DDNS_USER = values.TBC.split('=')[1]
|
|
||||||
DDNS_PASSWORD = values.TBC.split('=')[1]
|
|
||||||
DDNS_DOMAIN = values.TBC.split('=')[1]
|
|
||||||
|
|
||||||
# Connect to the PiAlert SQLite database
|
PREV_IP = values.prev_ip.split('=')[1]
|
||||||
conn = sqlite3.connect(fullDbPath)
|
DDNS_ACTIVE = values.DDNS_ACTIVE.split('=')[1]
|
||||||
cursor = conn.cursor()
|
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]
|
||||||
|
|
||||||
# do stuff
|
mylog('verbose', ['[INTRNT] DIG_GET_IP_ARG: ', DIG_GET_IP_ARG])
|
||||||
check_internet_IP(conn, cursor, DDNS_ACTIVE, DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN)
|
|
||||||
|
|
||||||
cursor.execute ("""SELECT from Online_History""") # TODO delete
|
# Decode the base64-encoded value to get the actual value in ASCII format.
|
||||||
|
DIG_GET_IP_ARG = base64.b64decode(DIG_GET_IP_ARG).decode('ascii')
|
||||||
|
|
||||||
conn.commit()
|
mylog('verbose', ['[INTRNT] DIG_GET_IP_ARG resolved: ', DIG_GET_IP_ARG])
|
||||||
# Close the database connection
|
|
||||||
conn.close()
|
# 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)
|
||||||
|
|
||||||
|
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}',
|
||||||
|
watched3 = '',
|
||||||
|
watched4 = '',
|
||||||
|
extra = f'Previous IP: {prev_ip}',
|
||||||
|
foreignKey = 'Internet')
|
||||||
|
|
||||||
|
plugin_objects.write_result_file()
|
||||||
|
|
||||||
mylog('verbose', ['[INTRNT] Finished '])
|
mylog('verbose', ['[INTRNT] Finished '])
|
||||||
|
|
||||||
@@ -67,37 +107,26 @@ def main():
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# INTERNET IP CHANGE
|
# INTERNET IP CHANGE
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
def check_internet_IP (conn, cursor, DDNS_ACTIVE, DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN ):
|
def check_internet_IP ( DDNS_ACTIVE, DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN, PREV_IP, DIG_GET_IP_ARG ):
|
||||||
|
|
||||||
# Header
|
|
||||||
updateState("Scan: Internet IP")
|
|
||||||
mylog('verbose', ['[INTRNT] Check Internet IP started'])
|
|
||||||
|
|
||||||
# Get Internet IP
|
# Get Internet IP
|
||||||
mylog('verbose', ['[INTRNT] - Retrieving Internet IP'])
|
mylog('verbose', ['[INTRNT] - Retrieving Internet IP'])
|
||||||
internet_IP = get_internet_IP()
|
internet_IP = get_internet_IP(DIG_GET_IP_ARG)
|
||||||
# TESTING - Force IP
|
|
||||||
# internet_IP = "1.2.3.4"
|
|
||||||
|
|
||||||
# Check result = IP
|
# Check result = IP
|
||||||
if internet_IP == "" :
|
if internet_IP == "" :
|
||||||
mylog('none', ['[INTRNT] Error retrieving Internet IP'])
|
mylog('none', ['[INTRNT] Error retrieving Internet IP'])
|
||||||
mylog('none', ['[INTRNT] Exiting...'])
|
|
||||||
return False
|
|
||||||
mylog('verbose', ['[INTRNT] IP: ', internet_IP])
|
|
||||||
|
|
||||||
# Get previous stored IP
|
# Get previous stored IP
|
||||||
mylog('verbose', ['[INTRNT] Retrieving previous IP:'])
|
previous_IP = '0.0.0.0'
|
||||||
previous_IP = get_previous_internet_IP (conn, cursor)
|
|
||||||
|
if PREV_IP is not None and len(result) > 0 :
|
||||||
|
previous_IP = PREV_IP
|
||||||
|
|
||||||
mylog('verbose', ['[INTRNT] ', previous_IP])
|
mylog('verbose', ['[INTRNT] ', previous_IP])
|
||||||
|
|
||||||
# Check IP Change
|
# logging
|
||||||
if internet_IP != previous_IP :
|
append_line_to_file (logPath + '/IP_changes.log', '['+str(timeNowTZ()) +']\t'+ pNewIP +'\n')
|
||||||
mylog('minimal', ['[INTRNT] New internet IP: ', internet_IP])
|
|
||||||
save_new_internet_IP (conn, cursor, internet_IP)
|
|
||||||
|
|
||||||
else :
|
|
||||||
mylog('verbose', ['[INTRNT] No changes to perform'])
|
|
||||||
|
|
||||||
# Get Dynamic DNS IP
|
# Get Dynamic DNS IP
|
||||||
if DDNS_ACTIVE :
|
if DDNS_ACTIVE :
|
||||||
@@ -119,49 +148,7 @@ def check_internet_IP (conn, cursor, DDNS_ACTIVE, DDNS_UPDATE_URL, DDNS_USER, DD
|
|||||||
else :
|
else :
|
||||||
mylog('verbose', ['[DDNS] Skipping Dynamic DNS update'])
|
mylog('verbose', ['[DDNS] Skipping Dynamic DNS update'])
|
||||||
|
|
||||||
|
return internet_IP
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def save_new_internet_IP (conn, cursor, pNewIP):
|
|
||||||
# Log new IP into logfile
|
|
||||||
append_line_to_file (logPath + '/IP_changes.log',
|
|
||||||
'['+str(timeNowTZ()) +']\t'+ pNewIP +'\n')
|
|
||||||
|
|
||||||
prevIp = get_previous_internet_IP(conn, cursor)
|
|
||||||
# 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,) )
|
|
||||||
|
|
||||||
# commit changes
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def get_previous_internet_IP (conn, cursor):
|
|
||||||
|
|
||||||
previous_IP = '0.0.0.0'
|
|
||||||
|
|
||||||
# get previous internet IP stored in DB
|
|
||||||
cursor.execute ("SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' ")
|
|
||||||
result = db.sql.fetchone()
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
if result is not None and len(result) > 0 :
|
|
||||||
previous_IP = result[0]
|
|
||||||
|
|
||||||
# return previous IP
|
|
||||||
return previous_IP
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@@ -194,12 +181,13 @@ def set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN):
|
|||||||
try:
|
try:
|
||||||
# try runnning a subprocess
|
# try runnning a subprocess
|
||||||
# Update Dynamic IP
|
# Update Dynamic IP
|
||||||
curl_output = subprocess.check_output (['curl', '-s',
|
curl_output = subprocess.check_output (['curl',
|
||||||
DDNS_UPDATE_URL +
|
'-s',
|
||||||
'username=' + DDNS_USER +
|
DDNS_UPDATE_URL +
|
||||||
'&password=' + DDNS_PASSWORD +
|
'username=' + DDNS_USER +
|
||||||
'&hostname=' + DDNS_DOMAIN],
|
'&password=' + DDNS_PASSWORD +
|
||||||
universal_newlines=True)
|
'&hostname=' + DDNS_DOMAIN],
|
||||||
|
universal_newlines=True)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
# An error occured, handle it
|
# An error occured, handle it
|
||||||
mylog('none', ['[DDNS] ERROR - ',e.output])
|
mylog('none', ['[DDNS] ERROR - ',e.output])
|
||||||
@@ -207,6 +195,27 @@ def set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN):
|
|||||||
|
|
||||||
return 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:
|
||||||
|
cmd_output = subprocess.check_output (dig_args, universal_newlines=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
mylog('none', [e.output])
|
||||||
|
cmd_output = '' # no internet
|
||||||
|
|
||||||
|
# Check result is an IP
|
||||||
|
IP = check_IP_format (cmd_output)
|
||||||
|
|
||||||
|
# Handle invalid response
|
||||||
|
if IP == '':
|
||||||
|
IP = '0.0.0.0'
|
||||||
|
|
||||||
|
return IP
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# BEGIN
|
# BEGIN
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
|||||||
@@ -54,15 +54,14 @@ def main():
|
|||||||
timeoutSec = values.timeoutSec[0].split('=')[1]
|
timeoutSec = values.timeoutSec[0].split('=')[1]
|
||||||
|
|
||||||
# Printing the extracted base64-encoded subnet information.
|
# Printing the extracted base64-encoded subnet information.
|
||||||
print(userSubnetsParamBase64)
|
mylog('verbose', [f'[PHOLUS] { userSubnetsParamBase64 }'])
|
||||||
print(timeoutSec)
|
mylog('verbose', [f'[PHOLUS] { timeoutSec }'])
|
||||||
|
|
||||||
# Decode the base64-encoded subnet information to get the actual subnet information in ASCII format.
|
# Decode the base64-encoded subnet information to get the actual subnet information in ASCII format.
|
||||||
userSubnetsParam = base64.b64decode(userSubnetsParamBase64).decode('ascii')
|
userSubnetsParam = base64.b64decode(userSubnetsParamBase64).decode('ascii')
|
||||||
|
|
||||||
# Print the decoded subnet information.
|
# Print the decoded subnet information.
|
||||||
print('userSubnetsParam:')
|
mylog('verbose', [f'[PHOLUS] userSubnetsParam { userSubnetsParam } '])
|
||||||
print(userSubnetsParam)
|
|
||||||
|
|
||||||
# Check if the decoded subnet information contains multiple subnets separated by commas.
|
# Check if the decoded subnet information contains multiple subnets separated by commas.
|
||||||
# If it does, split the string into a list of individual subnets.
|
# If it does, split the string into a list of individual subnets.
|
||||||
@@ -101,7 +100,7 @@ def execute_pholus_scan(userSubnets, timeoutSec):
|
|||||||
|
|
||||||
timeoutPerSubnet = float(timeoutSec) / len(userSubnets)
|
timeoutPerSubnet = float(timeoutSec) / len(userSubnets)
|
||||||
|
|
||||||
print(timeoutPerSubnet)
|
mylog('verbose', [f'[PHOLUS] { timeoutPerSubnet } '])
|
||||||
|
|
||||||
# scan each interface
|
# scan each interface
|
||||||
|
|
||||||
@@ -110,7 +109,7 @@ def execute_pholus_scan(userSubnets, timeoutSec):
|
|||||||
temp = interface.split("--interface=")
|
temp = interface.split("--interface=")
|
||||||
|
|
||||||
if len(temp) != 2:
|
if len(temp) != 2:
|
||||||
mylog('none', ["[PholusScan] Skip scan (need interface in format '192.168.1.0/24 --inteface=eth0'), got: ", interface])
|
mylog('none', ["[PHOLUS] Skip scan (need interface in format '192.168.1.0/24 --inteface=eth0'), got: ", interface])
|
||||||
return
|
return
|
||||||
|
|
||||||
mask = temp[0].strip()
|
mask = temp[0].strip()
|
||||||
@@ -118,7 +117,7 @@ def execute_pholus_scan(userSubnets, timeoutSec):
|
|||||||
|
|
||||||
pholus_output_list = execute_pholus_on_interface (interface, timeoutPerSubnet, mask)
|
pholus_output_list = execute_pholus_on_interface (interface, timeoutPerSubnet, mask)
|
||||||
|
|
||||||
print(pholus_output_list)
|
mylog('verbose', [f'[PHOLUS] { pholus_output_list } '])
|
||||||
|
|
||||||
|
|
||||||
result_list += pholus_output_list
|
result_list += pholus_output_list
|
||||||
@@ -134,8 +133,8 @@ def execute_pholus_on_interface(interface, timeoutSec, mask):
|
|||||||
|
|
||||||
# logging & updating app state
|
# logging & updating app state
|
||||||
|
|
||||||
mylog('verbose', ['[PholusScan] Scan: Pholus for ', str(timeoutSec), 's ('+ str(round(int(timeoutSec) / 60, 1)) +'min)'])
|
mylog('verbose', ['[PHOLUS] Scan: Pholus for ', str(timeoutSec), 's ('+ str(round(int(timeoutSec) / 60, 1)) +'min)'])
|
||||||
mylog('verbose', ["[PholusScan] Pholus scan on [interface] ", interface, " [mask] " , mask])
|
mylog('verbose', ["[PHOLUS] Pholus scan on [interface] ", interface, " [mask] " , mask])
|
||||||
|
|
||||||
# the scan always lasts 2x as long, so the desired user time from settings needs to be halved
|
# the scan always lasts 2x as long, so the desired user time from settings needs to be halved
|
||||||
adjustedTimeout = str(round(int(timeoutSec) / 2, 0))
|
adjustedTimeout = str(round(int(timeoutSec) / 2, 0))
|
||||||
@@ -151,15 +150,15 @@ def execute_pholus_on_interface(interface, timeoutSec, mask):
|
|||||||
output = subprocess.check_output (pholus_args, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeoutSec + 30))
|
output = subprocess.check_output (pholus_args, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeoutSec + 30))
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
# An error occured, handle it
|
# An error occured, handle it
|
||||||
mylog('none', ['[PholusScan]', e.output])
|
mylog('none', ['[PHOLUS]', e.output])
|
||||||
mylog('none', ["[PholusScan] Error - Pholus Scan - check logs"])
|
mylog('none', ["[PHOLUS] Error - Pholus Scan - check logs"])
|
||||||
except subprocess.TimeoutExpired as timeErr:
|
except subprocess.TimeoutExpired as timeErr:
|
||||||
mylog('none', ['[PholusScan] Pholus TIMEOUT - the process forcefully terminated as timeout reached'])
|
mylog('none', ['[PHOLUS] Pholus TIMEOUT - the process forcefully terminated as timeout reached'])
|
||||||
|
|
||||||
if output == "": # check if the subprocess failed
|
if output == "": # check if the subprocess failed
|
||||||
mylog('none', ['[PholusScan] Scan: Pholus FAIL - check logs'])
|
mylog('none', ['[PHOLUS] Scan: Pholus FAIL - check logs'])
|
||||||
else:
|
else:
|
||||||
mylog('verbose', ['[PholusScan] Scan: Pholus SUCCESS'])
|
mylog('verbose', ['[PHOLUS] Scan: Pholus SUCCESS'])
|
||||||
|
|
||||||
# check the last run output
|
# check the last run output
|
||||||
f = open(logPath + '/pialert_pholus_lastrun.log', 'r+')
|
f = open(logPath + '/pialert_pholus_lastrun.log', 'r+')
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ The original pilaert.py code is now moved to this new folder and split into diff
|
|||||||
|```__init__.py```| an empty init file|
|
|```__init__.py```| an empty init file|
|
||||||
|```README.md```| this readme file|
|
|```README.md```| this readme file|
|
||||||
|**publishers**| a folder containing all modules used to publish the results|
|
|**publishers**| a folder containing all modules used to publish the results|
|
||||||
|**scanners**| a folder containing all modules used to scan for devices |
|
|
||||||
|```api.py```| updating the API endpoints with the relevant data. (Should move to publishers)|
|
|```api.py```| updating the API endpoints with the relevant data. (Should move to publishers)|
|
||||||
|```const.py```| A place to define the constants for Pi.Alert like log path or config path.|
|
|```const.py```| A place to define the constants for Pi.Alert like log path or config path.|
|
||||||
|```conf.py```| conf.py holds the configuration variables and makes them available for all modules. It is also the <b>workaround</b> for global variables that need to be resolved at some point|
|
|```conf.py```| conf.py holds the configuration variables and makes them available for all modules. It is also the <b>workaround</b> for global variables that need to be resolved at some point|
|
||||||
@@ -35,12 +34,5 @@ publishers generally have a check_config method as well as a send method.
|
|||||||
|```pushsafer.py```| integrate with pushsafer |
|
|```pushsafer.py```| integrate with pushsafer |
|
||||||
|```webhook.py```| integrate via webhook |
|
|```webhook.py```| integrate via webhook |
|
||||||
|
|
||||||
## scanners
|
|
||||||
different methods to scan the network for devices or to find more details about the discovered devices
|
|
||||||
|
|
||||||
| Module | Description |
|
|
||||||
|--------|-----------|
|
|
||||||
|```__init__.py```| an empty init file (oops missing in the repo)|
|
|
||||||
|```internet.py```| discover the internet interface and check the external IP also manage Dynamic DNS |
|
|
||||||
|```nmapscan.py```| use Nmap to discover more about devices |
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ from database import DB, get_all_devices
|
|||||||
from reporting import check_and_run_event, send_notifications
|
from reporting import check_and_run_event, send_notifications
|
||||||
from plugin import run_plugin_scripts
|
from plugin import run_plugin_scripts
|
||||||
|
|
||||||
# different scanners
|
|
||||||
from scanners.internet import check_internet_IP
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -54,8 +50,6 @@ main structure of Pi Alert
|
|||||||
run frontend events
|
run frontend events
|
||||||
update API
|
update API
|
||||||
run plugins (scheduled)
|
run plugins (scheduled)
|
||||||
check internet IP
|
|
||||||
check vendor
|
|
||||||
processing scan results
|
processing scan results
|
||||||
run plugins (after Scan)
|
run plugins (after Scan)
|
||||||
reporting
|
reporting
|
||||||
@@ -124,7 +118,6 @@ def main ():
|
|||||||
|
|
||||||
# last time any scan or maintenance/upkeep was run
|
# last time any scan or maintenance/upkeep was run
|
||||||
conf.last_scan_run = loop_start_time
|
conf.last_scan_run = loop_start_time
|
||||||
last_internet_IP_scan = conf.last_internet_IP_scan
|
|
||||||
|
|
||||||
# Header
|
# Header
|
||||||
updateState("Process: Start")
|
updateState("Process: Start")
|
||||||
@@ -139,12 +132,6 @@ def main ():
|
|||||||
# determine run/scan type based on passed time
|
# determine run/scan type based on passed time
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
|
|
||||||
# check for changes in Internet IP
|
|
||||||
if last_internet_IP_scan + datetime.timedelta(minutes=3) < loop_start_time:
|
|
||||||
conf.cycle = 'internet_IP'
|
|
||||||
last_internet_IP_scan = loop_start_time
|
|
||||||
check_internet_IP(db)
|
|
||||||
|
|
||||||
# Run splugin scripts which are set to run every timne after a scans finished
|
# Run splugin scripts which are set to run every timne after a scans finished
|
||||||
pluginsState = run_plugin_scripts(db,'always_after_scan', pluginsState)
|
pluginsState = run_plugin_scripts(db,'always_after_scan', pluginsState)
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ plugins_once_run = False
|
|||||||
newVersionAvailable = False
|
newVersionAvailable = False
|
||||||
time_started = ''
|
time_started = ''
|
||||||
startTime = ''
|
startTime = ''
|
||||||
last_internet_IP_scan = ''
|
|
||||||
last_scan_run = ''
|
last_scan_run = ''
|
||||||
last_version_check = ''
|
last_version_check = ''
|
||||||
arpscan_devices = []
|
arpscan_devices = []
|
||||||
@@ -44,7 +43,7 @@ UI_LANG = 'English'
|
|||||||
UI_PRESENCE = ['online', 'offline', 'archived']
|
UI_PRESENCE = ['online', 'offline', 'archived']
|
||||||
PIALERT_WEB_PROTECTION = False
|
PIALERT_WEB_PROTECTION = False
|
||||||
PIALERT_WEB_PASSWORD = '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'
|
PIALERT_WEB_PASSWORD = '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'
|
||||||
INCLUDED_SECTIONS = ['internet', 'new_devices', 'down_devices', 'events']
|
INCLUDED_SECTIONS = ['new_devices', 'down_devices', 'events']
|
||||||
DAYS_TO_KEEP_EVENTS = 90
|
DAYS_TO_KEEP_EVENTS = 90
|
||||||
REPORT_DASHBOARD_URL = 'http://pi.alert/'
|
REPORT_DASHBOARD_URL = 'http://pi.alert/'
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import subprocess
|
|||||||
|
|
||||||
import conf
|
import conf
|
||||||
import re
|
import re
|
||||||
from helper import timeNowTZ, get_setting, get_setting_value,resolve_device_name_dig, resolve_device_name_pholus, check_IP_format, get_internet_IP
|
from helper import timeNowTZ, get_setting, get_setting_value,resolve_device_name_dig, resolve_device_name_pholus, check_IP_format
|
||||||
from logger import mylog, print_log
|
from logger import mylog, print_log
|
||||||
from const import vendorsPath6, vendorsPath9
|
from const import vendorsPath6, vendorsPath9
|
||||||
|
|
||||||
@@ -13,13 +13,6 @@ from const import vendorsPath6, vendorsPath9
|
|||||||
def save_scanned_devices (db):
|
def save_scanned_devices (db):
|
||||||
sql = db.sql #TO-DO
|
sql = db.sql #TO-DO
|
||||||
|
|
||||||
# Check Internet connectivity
|
|
||||||
internet_IP = get_internet_IP()
|
|
||||||
# TESTING - Force IP
|
|
||||||
# internet_IP = ""
|
|
||||||
if internet_IP != "" :
|
|
||||||
sql.execute (f"""INSERT INTO CurrentScan (cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod)
|
|
||||||
VALUES ( 'Internet', '{internet_IP}', Null, 'queryDNS') """)
|
|
||||||
|
|
||||||
# #76 Add Local MAC of default local interface
|
# #76 Add Local MAC of default local interface
|
||||||
# BUGFIX #106 - Device that pialert is running
|
# BUGFIX #106 - Device that pialert is running
|
||||||
|
|||||||
@@ -291,26 +291,6 @@ def check_IP_format (pIP):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def get_internet_IP ():
|
|
||||||
# BUGFIX #46 - curl http://ipv4.icanhazip.com repeatedly is very slow
|
|
||||||
# Using 'dig'
|
|
||||||
dig_args = ['dig', '+short'] + conf.DIG_GET_IP_ARG.strip().split()
|
|
||||||
try:
|
|
||||||
cmd_output = subprocess.check_output (dig_args, universal_newlines=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
mylog('none', [e.output])
|
|
||||||
cmd_output = '' # no internet
|
|
||||||
|
|
||||||
# Check result is an IP
|
|
||||||
IP = check_IP_format (cmd_output)
|
|
||||||
|
|
||||||
# Handle invalid response
|
|
||||||
if IP == '':
|
|
||||||
IP = '0.0.0.0'
|
|
||||||
|
|
||||||
return IP
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def resolve_device_name_dig (pMAC, pIP):
|
def resolve_device_name_dig (pMAC, pIP):
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ def importConfigs (db):
|
|||||||
conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', 'integer', '', 'General')
|
conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', 'integer', '', 'General')
|
||||||
conf.PIALERT_WEB_PROTECTION = ccd('PIALERT_WEB_PROTECTION', False , c_d, 'Enable logon', 'boolean', '', 'General')
|
conf.PIALERT_WEB_PROTECTION = ccd('PIALERT_WEB_PROTECTION', False , c_d, 'Enable logon', 'boolean', '', 'General')
|
||||||
conf.PIALERT_WEB_PASSWORD = ccd('PIALERT_WEB_PASSWORD', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92' , c_d, 'Logon password', 'readonly', '', 'General')
|
conf.PIALERT_WEB_PASSWORD = ccd('PIALERT_WEB_PASSWORD', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92' , c_d, 'Logon password', 'readonly', '', 'General')
|
||||||
conf.INCLUDED_SECTIONS = ccd('INCLUDED_SECTIONS', ['internet', 'new_devices', 'down_devices', 'events'] , c_d, 'Notify on', 'text.multiselect', "['internet', 'new_devices', 'down_devices', 'events', 'plugins']", 'General')
|
conf.INCLUDED_SECTIONS = ccd('INCLUDED_SECTIONS', ['new_devices', 'down_devices', 'events'] , c_d, 'Notify on', 'text.multiselect', "['new_devices', 'down_devices', 'events', 'plugins']", 'General')
|
||||||
conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://pi.alert/' , c_d, 'PiAlert URL', 'text', '', 'General')
|
conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://pi.alert/' , c_d, 'PiAlert URL', 'text', '', 'General')
|
||||||
conf.DIG_GET_IP_ARG = ccd('DIG_GET_IP_ARG', '-4 myip.opendns.com @resolver1.opendns.com' , c_d, 'DIG arguments', 'text', '', 'General')
|
conf.DIG_GET_IP_ARG = ccd('DIG_GET_IP_ARG', '-4 myip.opendns.com @resolver1.opendns.com' , c_d, 'DIG arguments', 'text', '', 'General')
|
||||||
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', 'text.select', "['English', 'German', 'Spanish']", 'General')
|
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', 'text.select', "['English', 'German', 'Spanish']", 'General')
|
||||||
@@ -176,7 +176,6 @@ def importConfigs (db):
|
|||||||
now_minus_24h = conf.time_started - datetime.timedelta(hours = 24)
|
now_minus_24h = conf.time_started - datetime.timedelta(hours = 24)
|
||||||
|
|
||||||
# set these times to the past to force the first run
|
# set these times to the past to force the first run
|
||||||
conf.last_internet_IP_scan = now_minus_24h
|
|
||||||
conf.last_scan_run = now_minus_24h
|
conf.last_scan_run = now_minus_24h
|
||||||
conf.last_version_check = now_minus_24h
|
conf.last_version_check = now_minus_24h
|
||||||
|
|
||||||
|
|||||||
@@ -183,20 +183,20 @@ def send_notifications (db):
|
|||||||
|
|
||||||
mylog('verbose', ['[Notification] included sections: ', conf.INCLUDED_SECTIONS ])
|
mylog('verbose', ['[Notification] included sections: ', conf.INCLUDED_SECTIONS ])
|
||||||
|
|
||||||
if 'internet' in conf.INCLUDED_SECTIONS :
|
# if 'internet' in conf.INCLUDED_SECTIONS :
|
||||||
# Compose Internet Section
|
# # Compose Internet Section
|
||||||
sqlQuery = """SELECT eve_MAC as MAC, eve_IP as IP, eve_DateTime as Datetime, eve_EventType as "Event Type", eve_AdditionalInfo as "More info" FROM Events
|
# sqlQuery = """SELECT eve_MAC as MAC, eve_IP as IP, eve_DateTime as Datetime, eve_EventType as "Event Type", eve_AdditionalInfo as "More info" FROM Events
|
||||||
WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
|
# WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
|
||||||
ORDER BY eve_DateTime"""
|
# ORDER BY eve_DateTime"""
|
||||||
|
|
||||||
notiStruc = construct_notifications(db, sqlQuery, "Internet IP change")
|
# notiStruc = construct_notifications(db, sqlQuery, "Internet IP change")
|
||||||
|
|
||||||
# collect "internet" (IP changes) for the webhook json
|
# # collect "internet" (IP changes) for the webhook json
|
||||||
json_internet = notiStruc.json["data"]
|
# json_internet = notiStruc.json["data"]
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<SECTION_INTERNET>', notiStruc.text + '\n')
|
# mail_text = mail_text.replace ('<SECTION_INTERNET>', notiStruc.text + '\n')
|
||||||
mail_html = mail_html.replace ('<INTERNET_TABLE>', notiStruc.html)
|
# mail_html = mail_html.replace ('<INTERNET_TABLE>', notiStruc.html)
|
||||||
mylog('verbose', ['[Notification] Internet sections done.'])
|
# mylog('verbose', ['[Notification] Internet sections done.'])
|
||||||
|
|
||||||
if 'new_devices' in conf.INCLUDED_SECTIONS :
|
if 'new_devices' in conf.INCLUDED_SECTIONS :
|
||||||
# Compose New Devices Section
|
# Compose New Devices Section
|
||||||
|
|||||||
@@ -1,156 +0,0 @@
|
|||||||
""" internet related functions to support Pi.Alert """
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import re
|
|
||||||
|
|
||||||
# pialert modules
|
|
||||||
|
|
||||||
import conf
|
|
||||||
from helper import timeNowTZ, updateState, check_IP_format, get_internet_IP
|
|
||||||
from logger import append_line_to_file, mylog
|
|
||||||
from const import logPath
|
|
||||||
|
|
||||||
|
|
||||||
#===============================================================================
|
|
||||||
# INTERNET IP CHANGE
|
|
||||||
#===============================================================================
|
|
||||||
def check_internet_IP ( db ):
|
|
||||||
|
|
||||||
# Header
|
|
||||||
updateState("Scan: Internet IP")
|
|
||||||
mylog('verbose', ['[Internet IP] Check Internet IP started'])
|
|
||||||
|
|
||||||
# Get Internet IP
|
|
||||||
mylog('verbose', ['[Internet IP] - Retrieving Internet IP'])
|
|
||||||
internet_IP = get_internet_IP()
|
|
||||||
# TESTING - Force IP
|
|
||||||
# internet_IP = "1.2.3.4"
|
|
||||||
|
|
||||||
# Check result = IP
|
|
||||||
if internet_IP == "" :
|
|
||||||
mylog('none', ['[Internet IP] Error retrieving Internet IP'])
|
|
||||||
mylog('none', ['[Internet IP] Exiting...'])
|
|
||||||
return False
|
|
||||||
mylog('verbose', ['[Internet IP] IP: ', internet_IP])
|
|
||||||
|
|
||||||
# Get previous stored IP
|
|
||||||
mylog('verbose', ['[Internet IP] Retrieving previous IP:'])
|
|
||||||
previous_IP = get_previous_internet_IP (db)
|
|
||||||
mylog('verbose', ['[Internet IP] ', previous_IP])
|
|
||||||
|
|
||||||
# Check IP Change
|
|
||||||
if internet_IP != previous_IP :
|
|
||||||
mylog('minimal', ['[Internet IP] New internet IP: ', internet_IP])
|
|
||||||
save_new_internet_IP (db, internet_IP)
|
|
||||||
|
|
||||||
else :
|
|
||||||
mylog('verbose', ['[Internet IP] No changes to perform'])
|
|
||||||
|
|
||||||
# Get Dynamic DNS IP
|
|
||||||
if conf.DDNS_ACTIVE :
|
|
||||||
mylog('verbose', ['[DDNS] Retrieving Dynamic DNS IP'])
|
|
||||||
dns_IP = get_dynamic_DNS_IP()
|
|
||||||
|
|
||||||
# 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 ()
|
|
||||||
mylog('none', ['[DDNS] ', message])
|
|
||||||
else :
|
|
||||||
mylog('verbose', ['[DDNS] No changes to perform'])
|
|
||||||
else :
|
|
||||||
mylog('verbose', ['[DDNS] Skipping Dynamic DNS update'])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def get_previous_internet_IP (db):
|
|
||||||
|
|
||||||
previous_IP = '0.0.0.0'
|
|
||||||
|
|
||||||
# get previous internet IP stored in DB
|
|
||||||
db.sql.execute ("SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' ")
|
|
||||||
result = db.sql.fetchone()
|
|
||||||
|
|
||||||
db.commitDB()
|
|
||||||
|
|
||||||
if result is not None and len(result) > 0 :
|
|
||||||
previous_IP = result[0]
|
|
||||||
|
|
||||||
# return previous IP
|
|
||||||
return previous_IP
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def save_new_internet_IP (db, pNewIP):
|
|
||||||
# Log new IP into logfile
|
|
||||||
append_line_to_file (logPath + '/IP_changes.log',
|
|
||||||
'['+str(timeNowTZ()) +']\t'+ pNewIP +'\n')
|
|
||||||
|
|
||||||
prevIp = get_previous_internet_IP(db)
|
|
||||||
# Save event
|
|
||||||
db.sql.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
|
|
||||||
db.sql.execute ("""UPDATE Devices SET dev_LastIP = ?
|
|
||||||
WHERE dev_MAC = 'Internet' """,
|
|
||||||
(pNewIP,) )
|
|
||||||
|
|
||||||
# commit changes
|
|
||||||
db.commitDB()
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def get_dynamic_DNS_IP ():
|
|
||||||
# Using OpenDNS server
|
|
||||||
# dig_args = ['dig', '+short', DDNS_DOMAIN, '@resolver1.opendns.com']
|
|
||||||
|
|
||||||
# Using default DNS server
|
|
||||||
dig_args = ['dig', '+short', conf.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 ():
|
|
||||||
try:
|
|
||||||
# try runnning a subprocess
|
|
||||||
# Update Dynamic IP
|
|
||||||
curl_output = subprocess.check_output (['curl', '-s',
|
|
||||||
conf.DDNS_UPDATE_URL +
|
|
||||||
'username=' + conf.DDNS_USER +
|
|
||||||
'&password=' + conf.DDNS_PASSWORD +
|
|
||||||
'&hostname=' + conf.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
|
|
||||||
Reference in New Issue
Block a user