From 4072bbf4061f53e9d2f720b4e16479719820c2b3 Mon Sep 17 00:00:00 2001 From: pucherot Date: Wed, 21 Apr 2021 19:23:35 +0200 Subject: [PATCH] Pi.Alert 3.00 --- back/pialert.py | 78 ++++++-- config/pialert.conf | 13 ++ config/version.conf | 4 +- db/pialert.db | Bin 180224 -> 180224 bytes front/css/pialert.css | 57 +++++- front/deviceDetails.php | 278 ++++++++++++++++++++++----- front/devices.php | 144 ++++++++------ front/events.php | 18 +- front/index.php | 144 ++++++++------ front/js/pialert_common.js | 92 ++++++++- front/php/server/devices.php | 59 ++++-- front/php/templates/header.php | 11 +- front/php/templates/notification.php | 34 +++- front/presence.php | 96 ++++----- install/pialert_update.sh | 14 ++ 15 files changed, 756 insertions(+), 286 deletions(-) diff --git a/back/pialert.py b/back/pialert.py index 8a9fe755..48fdabb9 100644 --- a/back/pialert.py +++ b/back/pialert.py @@ -216,7 +216,8 @@ def get_previous_internet_IP (): #------------------------------------------------------------------------------- def save_new_internet_IP (pNewIP): # Log new IP into logfile - append_line_to_file (LOG_PATH + '/IP_changes.log', str(startTime) +'\t'+ pNewIP +'\n') + append_line_to_file (LOG_PATH + '/IP_changes.log', + str(startTime) +'\t'+ pNewIP +'\n') # Save event sql.execute ("""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime, @@ -295,7 +296,8 @@ def update_devices_MAC_vendors (pArg = ''): # print (recordsToUpdate) # update devices - sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ", recordsToUpdate ) + sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ", + recordsToUpdate ) # DEBUG - print number of rows updated # print (sql.rowcount) @@ -443,8 +445,13 @@ def query_ScanCycle_Data (pOpenCloseDB = False): #------------------------------------------------------------------------------- def execute_arpscan (pRetries): - # Prepara command arguments - arpscan_args = ['sudo', 'arp-scan', '--localnet', '--ignoredups', '--retry=' + str(pRetries)] + + # #101 - arp-scan subnet configuration + # Prepare command arguments + subnets = SCAN_SUBNETS.strip().split() + arpscan_args = ['sudo', 'arp-scan', '--ignoredups', '--retry=' + str(pRetries)] + subnets + # arpscan_args = ['sudo', 'arp-scan', SCAN_SUBNETS, '--ignoredups', '--retry=' + str(pRetries)] + # print (arpscan_args) # TESTING - Fast Scan # arpscan_args = ['sudo', 'arp-scan', '--localnet', '--ignoredups', '--retry=1'] @@ -570,6 +577,25 @@ def save_scanned_devices (p_arpscan_devices, p_cycle_interval): (int(startTime.strftime('%s')) - 60 * p_cycle_interval), cycle) ) + # Check Internet connectivity + internet_IP = get_internet_IP() + # TESTING - Force IP + # internet_IP = "" + if internet_IP != "" : + sql.execute ("""INSERT INTO CurrentScan (cur_ScanCycle, cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) + VALUES (?, 'Internet', ?, Null, 'queryDNS') """, (cycle, internet_IP) ) + + # #76 Add Local MAC of default local interface + local_mac_cmd = ["ifconfig `ip route list default | awk {'print $5'}` | grep ether | awk '{print $2}'"] + local_mac = subprocess.Popen (local_mac_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() + + local_ip_cmd = ["ip route list default | awk {'print $7'}"] + local_ip = subprocess.Popen (local_ip_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0].strip() + + sql.execute ("INSERT INTO CurrentScan (cur_ScanCycle, cur_MAC, cur_IP, cur_Vendor, cur_ScanMethod) "+ + "VALUES ( ?, ?, ?, Null, 'local_MAC') ", (cycle, local_mac, local_ip) ) + + #------------------------------------------------------------------------------- def print_scan_stats (): # Devices Detected @@ -672,9 +698,9 @@ def create_new_devices (): sql.execute ("""INSERT INTO Devices (dev_MAC, dev_name, dev_Vendor, dev_LastIP, dev_FirstConnection, dev_LastConnection, dev_ScanCycle, dev_AlertEvents, dev_AlertDeviceDown, - dev_PresentLastScan, dev_NewDevice) + dev_PresentLastScan) SELECT cur_MAC, '(unknown)', cur_Vendor, cur_IP, ?, ?, - 1, 1, 0, 1, 1 + 1, 1, 0, 1 FROM CurrentScan WHERE cur_ScanCycle = ? AND NOT EXISTS (SELECT 1 FROM Devices @@ -701,9 +727,9 @@ def create_new_devices (): sql.execute ("""INSERT INTO Devices (dev_MAC, dev_name, dev_Vendor, dev_LastIP, dev_FirstConnection, dev_LastConnection, dev_ScanCycle, dev_AlertEvents, dev_AlertDeviceDown, - dev_PresentLastScan, dev_NewDevice) + dev_PresentLastScan) SELECT PH_MAC, PH_Name, PH_Vendor, IFNULL (PH_IP,'-'), - ?, ?, 1, 1, 0, 1, 1 + ?, ?, 1, 1, 0, 1 FROM PiHole_Network WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE dev_MAC = PH_MAC) """, @@ -731,7 +757,7 @@ def create_new_devices (): sql.execute ("""INSERT INTO Devices (dev_MAC, dev_name, dev_LastIP, dev_Vendor, dev_FirstConnection, dev_LastConnection, dev_ScanCycle, dev_AlertEvents, dev_AlertDeviceDown, - dev_PresentLastScan, dev_NewDevice) + dev_PresentLastScan) SELECT DISTINCT DHCP_MAC, (SELECT DHCP_Name FROM DHCP_Leases AS D2 WHERE D2.DHCP_MAC = D1.DHCP_MAC @@ -739,7 +765,7 @@ def create_new_devices (): (SELECT DHCP_IP FROM DHCP_Leases AS D2 WHERE D2.DHCP_MAC = D1.DHCP_MAC ORDER BY DHCP_DateTime DESC LIMIT 1), - '(unknown)', ?, ?, 1, 1, 0, 1, 1 + '(unknown)', ?, ?, 1, 1, 0, 1 FROM DHCP_Leases AS D1 WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE dev_MAC = DHCP_MAC) """, @@ -913,7 +939,8 @@ def update_devices_names (): # Devices without name print (' Trying to resolve devices without name...', end='') - for device in sql.execute ("SELECT * FROM Devices WHERE dev_Name IN ('(unknown)','') ") : + # BUGFIX #97 - Updating name of Devices w/o IP + for device in sql.execute ("SELECT * FROM Devices WHERE dev_Name IN ('(unknown)','') AND dev_LastIP <> '-'") : # Resolve device name newName = resolve_device_name (device['dev_MAC'], device['dev_LastIP']) @@ -949,11 +976,14 @@ def resolve_device_name (pMAC, pIP): if len(pMACstr) != 17 or len(mac) != 12 : return -2 + # DEBUG + # print (pMAC, pIP) + # Resolve name with DIG dig_args = ['dig', '+short', '-x', pIP] newName = subprocess.check_output (dig_args, universal_newlines=True) - # Check if Eliminate local domain + # Check returns newName = newName.strip() if len(newName) == 0 : return -2 @@ -981,7 +1011,8 @@ def void_ghost_disconnections (): print_log ('Void - 1 Connect ghost events') sql.execute ("""UPDATE Events SET eve_PairEventRowid = Null, eve_EventType ='VOIDED - ' || eve_EventType - WHERE eve_EventType = 'Connected' + WHERE eve_MAC != 'Internet' + AND eve_EventType = 'Connected' AND eve_DateTime = ? AND eve_MAC IN ( SELECT Events.eve_MAC @@ -1000,7 +1031,8 @@ def void_ghost_disconnections (): # Void connect paired events print_log ('Void - 2 Paired events') sql.execute ("""UPDATE Events SET eve_PairEventRowid = Null - WHERE eve_PairEventRowid IN ( + WHERE eve_MAC != 'Internet' + AND eve_PairEventRowid IN ( SELECT Events.RowID FROM CurrentScan, Devices, ScanCycles, Events WHERE cur_ScanCycle = ? @@ -1018,7 +1050,8 @@ def void_ghost_disconnections (): print_log ('Void - 3 Disconnect ghost events') sql.execute ("""UPDATE Events SET eve_PairEventRowid = Null, eve_EventType = 'VOIDED - '|| eve_EventType - WHERE ROWID IN ( + WHERE eve_MAC != 'Internet' + AND ROWID IN ( SELECT Events.RowID FROM CurrentScan, Devices, ScanCycles, Events WHERE cur_ScanCycle = ? @@ -1180,7 +1213,8 @@ def email_reporting (): eventAlert['eve_EventType'], eventAlert['eve_DateTime'], eventAlert['eve_IP'], eventAlert['eve_AdditionalInfo']) - format_report_section (mail_section_Internet, 'SECTION_INTERNET', 'TABLE_INTERNET', mail_text_Internet, mail_html_Internet) + format_report_section (mail_section_Internet, 'SECTION_INTERNET', + 'TABLE_INTERNET', mail_text_Internet, mail_html_Internet) # Compose New Devices Section mail_section_new_devices = False @@ -1207,7 +1241,8 @@ def email_reporting (): eventAlert['eve_DateTime'], eventAlert['eve_IP'], eventAlert['dev_Name'], eventAlert['eve_AdditionalInfo']) - format_report_section (mail_section_new_devices, 'SECTION_NEW_DEVICES', 'TABLE_NEW_DEVICES', mail_text_new_devices, mail_html_new_devices) + format_report_section (mail_section_new_devices, 'SECTION_NEW_DEVICES', + 'TABLE_NEW_DEVICES', mail_text_new_devices, mail_html_new_devices) # Compose Devices Down Section mail_section_devices_down = False @@ -1233,7 +1268,8 @@ def email_reporting (): eventAlert['eve_DateTime'], eventAlert['eve_IP'], eventAlert['dev_Name']) - format_report_section (mail_section_devices_down, 'SECTION_DEVICES_DOWN', 'TABLE_DEVICES_DOWN', mail_text_devices_down, mail_html_devices_down) + format_report_section (mail_section_devices_down, 'SECTION_DEVICES_DOWN', + 'TABLE_DEVICES_DOWN', mail_text_devices_down, mail_html_devices_down) # Compose Events Section mail_section_events = False @@ -1263,7 +1299,8 @@ def email_reporting (): eventAlert['eve_EventType'], eventAlert['dev_Name'], eventAlert['eve_AdditionalInfo']) - format_report_section (mail_section_events, 'SECTION_EVENTS', 'TABLE_EVENTS', mail_text_events, mail_html_events) + format_report_section (mail_section_events, 'SECTION_EVENTS', + 'TABLE_EVENTS', mail_text_events, mail_html_events) # DEBUG - Write output emails for testing if True : @@ -1319,7 +1356,8 @@ def remove_section (pText, pSection): if pText.find ('<'+ pSection +'>') >=0 \ and pText.find ('') >=0 : # return text without the section - return pText[:pText.find ('<'+ pSection+'>')] + pText[pText.find ('') + len (pSection) +3:] + return pText[:pText.find ('<'+ pSection+'>')] + \ + pText[pText.find ('') + len (pSection) +3:] else : # return all text return pText diff --git a/config/pialert.conf b/config/pialert.conf index 68b7e5f3..65c0bf03 100644 --- a/config/pialert.conf +++ b/config/pialert.conf @@ -35,3 +35,16 @@ PIHOLE_ACTIVE = False PIHOLE_DB = '/etc/pihole/pihole-FTL.db' DHCP_ACTIVE = False DHCP_LEASES = '/etc/pihole/dhcp.leases' + +# arp-scan options & samples +# +# Scan local network (default) +# SCAN_SUBNETS = '--localnet' +# +# Scan two subnets +# SCAN_SUBNETS = '192.168.11.0/24 192.168.144.0/24' +# +# Scan using interface eth0 +# SCAN_SUBNETS = '--localnet --interface=eth0' + +SCAN_SUBNETS = '--localnet' diff --git a/config/version.conf b/config/version.conf index 7fc3c716..5a9f9db1 100644 --- a/config/version.conf +++ b/config/version.conf @@ -1,3 +1,3 @@ -VERSION = '2.70' +VERSION = '3.00' VERSION_YEAR = '2021' -VERSION_DATE = '2021-02-01' +VERSION_DATE = '2021-04-21' diff --git a/db/pialert.db b/db/pialert.db index 2d2038dab14e03388409861c3ffb507ac2d79700..ff4e27315457b56f048e1ce792b7f6e37591bc93 100644 GIT binary patch delta 55 zcmZo@;BIK(o*>PbGf~EwF=t}}S3V0T5NyuNpKxLNKY2!u?Q8~&Kjgv8cD4k@?Q985 Gzv2PzrxFtY delta 54 zcmZo@;BIK(o*>PbJyFJ)F?(YISN`-|c_#MFh55Y~mjCl-6hIK||MD5P|I24$3IG5e C8WgMm diff --git a/front/css/pialert.css b/front/css/pialert.css index 43378ec9..8cdb7702 100644 --- a/front/css/pialert.css +++ b/front/css/pialert.css @@ -37,6 +37,10 @@ color: #808080; } +.text-gray-20 { + color: rgba(192,192,192,20%); +} + .text-aqua-20 { color: rgba(0,192,239,20%); } @@ -151,6 +155,13 @@ margin-bottom: 1.3em; } +.pa-small-box-footer { + color: white !important; + font-size: 18px; +} + + +/* -------------------------------------------------------------------------- */ .pa-small-box-aqua { border-top: 3px solid #00c0ef; box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1); @@ -169,8 +180,6 @@ color: #00c0ef; } - - /* -------------------------------------------------------------------------- */ .pa-small-box-green { border-top: 3px solid #00a65a; @@ -228,7 +237,26 @@ color: #dd4b39; } - + /* -------------------------------------------------------------------------- */ +.pa-small-box-gray { + border-top: 3px solid #a0a0a0; + box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1); +} + +.pa-small-box-gray .inner { + color: #a0a0a0; + background-color:#FFFFFF; +} + +.pa-small-box-gray .inner h3 { + margin-left: 0.5em; +} + +.pa-small-box-gray .icon { + color: #a0a0a0; +} + + /* ----------------------------------------------------------------------------- Customized Box Borders ----------------------------------------------------------------------------- */ @@ -304,6 +332,29 @@ color: #B0B0B0; } +/* ----------------------------------------------------------------------------- + Customized buttons +----------------------------------------------------------------------------- */ +.pa-btn { + padding: 10px; + min-width: 90px; +} + +.pa-btn-delete { + border-color:#ffb060; + background-color:#ffd080; +} + +.pa-btn-delete:hover { + border-color:#ffb060; + background-color:#ffb060; +} + +.pa-btn-records, .pa-btn-records:hover, .pa-btn-records:focus, .pa-btn-records:active { + border-color:#ddd; + background-color:#f4f4f4; + cursor: default; +} /* ----------------------------------------------------------------------------- diff --git a/front/deviceDetails.php b/front/deviceDetails.php index 98cfad2b..4fc4f7b0 100644 --- a/front/deviceDetails.php +++ b/front/deviceDetails.php @@ -42,15 +42,10 @@
- @@ -58,15 +53,10 @@
- @@ -74,15 +64,10 @@
- @@ -90,15 +75,10 @@
- @@ -111,13 +91,28 @@ + +
+ +
+ +
+
+ + +
+ +
+ +     + + + + + +
+
+
- - - +
+ + + +
@@ -488,13 +511,15 @@