Merge remote-tracking branch 'origin/leiweibau-merge-2022-07-31' into pr/55

This commit is contained in:
jokob-sk
2022-07-31 10:09:27 +10:00
39 changed files with 1284 additions and 160 deletions

View File

@@ -75,6 +75,9 @@ def main ():
return
cycle = str(sys.argv[1])
## Upgrade DB if needed
upgradeDB()
## Main Commands
if cycle == 'internet_IP':
res = check_internet_IP()
@@ -353,15 +356,12 @@ def scan_network ():
# ScanCycle data
cycle_interval = scanCycle_data['cic_EveryXmin']
arpscan_retries = scanCycle_data['cic_arpscanCycles']
# TESTING - Fast scan
# arpscan_retries = 1
# arp-scan command
print ('\nScanning...')
print (' arp-scan Method...')
print_log ('arp-scan starts...')
arpscan_devices = execute_arpscan (arpscan_retries)
arpscan_devices = execute_arpscan ()
print_log ('arp-scan ends')
# DEBUG - print number of rows updated
# print (arpscan_devices)
@@ -447,27 +447,13 @@ def query_ScanCycle_Data (pOpenCloseDB = False):
return sqlRow
#-------------------------------------------------------------------------------
def execute_arpscan (pRetries):
def execute_arpscan ():
# #101 - arp-scan subnet configuration
# Prepare command arguments
subnets = SCAN_SUBNETS.strip().split()
# arp-scan for larger Networks like /16
# otherwise the system starts multiple processes. the 15min cronjob isn't necessary.
# the scan is about 4min on a /16 network
arpscan_args = ['sudo', 'arp-scan', '--ignoredups', '--bandwidth=512k', '--retry=3', SCAN_SUBNETS]
# Default arp-scan
# 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']
# DEBUG - arp-scan command
# print (" ".join (arpscan_args))
# Retry is 6 to avoid false offline devices
arpscan_args = ['sudo', 'arp-scan', '--ignoredups', '--retry=6'] + subnets
# Execute command
arpscan_output = subprocess.check_output (arpscan_args, universal_newlines=True)
@@ -481,9 +467,6 @@ def execute_arpscan (pRetries):
devices_list = [device.groupdict()
for device in re.finditer (re_pattern, arpscan_output)]
# Bugfix #5 - Delete duplicated MAC's with different IP's
# TEST - Force duplicated device
# devices_list.append(devices_list[0])
# Delete duplicate MAC
unique_mac = []
unique_devices = []
@@ -701,14 +684,17 @@ def print_scan_stats ():
sql.execute("SELECT * FROM Devices")
History_All = sql.fetchall()
History_All_Devices = len(History_All)
sql.execute("SELECT * FROM Devices WHERE dev_Archived = 1")
History_Archived = sql.fetchall()
History_Archived_Devices = len(History_Archived)
sql.execute("SELECT * FROM CurrentScan")
sql.execute("""SELECT * FROM CurrentScan WHERE cur_ScanCycle = ? """, (cycle,))
History_Online = sql.fetchall()
History_Online_Devices = len(History_Online)
History_Offline_Devices = History_All_Devices - History_Archived_Devices - History_Online_Devices
sql.execute ("INSERT INTO Online_History (Scan_Date, Online_Devices, Down_Devices, All_Devices, Archived_Devices ) "+
sql.execute ("INSERT INTO Online_History (Scan_Date, Online_Devices, Down_Devices, All_Devices, Archived_Devices) "+
"VALUES ( ?, ?, ?, ?, ?)", (startTime, History_Online_Devices, History_Offline_Devices, History_All_Devices, History_Archived_Devices ) )
#-------------------------------------------------------------------------------
@@ -725,6 +711,16 @@ def create_new_devices ():
WHERE dev_MAC = cur_MAC) """,
(startTime, cycle) )
print_log ('New devices - Insert Connection into session table')
sql.execute ("""INSERT INTO Sessions (ses_MAC, ses_IP, ses_EventTypeConnection, ses_DateTimeConnection,
ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_StillConnected, ses_AdditionalInfo)
SELECT cur_MAC, cur_IP,'Connected',?, NULL , NULL ,1, cur_Vendor
FROM CurrentScan
WHERE cur_ScanCycle = ?
AND NOT EXISTS (SELECT 1 FROM Sessions
WHERE ses_MAC = cur_MAC) """,
(startTime, cycle) )
# arpscan - Create new devices
print_log ('New devices - 2 Create devices')
sql.execute ("""INSERT INTO Devices (dev_MAC, dev_name, dev_Vendor,
@@ -952,17 +948,10 @@ def update_devices_data_from_scan ():
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ",
recordsToUpdate )
# New Apple devices -> Cycle 15
print_log ('Update devices - 6 Cycle for Apple devices')
sql.execute ("""UPDATE Devices SET dev_ScanCycle = 1
WHERE dev_FirstConnection = ?
AND UPPER(dev_Vendor) LIKE '%APPLE%' """,
(startTime,) )
print_log ('Update devices end')
#-------------------------------------------------------------------------------
# Feature #43 - Resoltion name for unknown devices
# Feature #43 - Resolve name for unknown devices
def update_devices_names ():
# Initialize variables
recordsToUpdate = []
@@ -1185,20 +1174,21 @@ def skip_repeated_notifications ():
def email_reporting ():
global mail_text
global mail_html
# Reporting section
print ('\nReporting...')
openDB()
# Disable reporting on events for devices where reporting is disabled based on the MAC address
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_MAC IN
WHERE eve_PendingAlertEmail = 1 AND eve_EventType != 'Device Down' AND eve_MAC IN
(
SELECT dev_MAC FROM Devices WHERE dev_AlertEvents = 0
SELECT dev_MAC FROM Devices WHERE dev_AlertEvents = 0
)""")
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType = 'Device Down' AND eve_MAC IN
(
SELECT dev_MAC FROM Devices WHERE dev_AlertDeviceDown = 0
)""")
# Open text Template
# Open text Template
template_file = open(PIALERT_BACK_PATH + '/report_template.txt', 'r')
@@ -1245,16 +1235,18 @@ def email_reporting ():
WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
ORDER BY eve_DateTime""")
for eventAlert in sql :
mail_section_Internet = True
mail_text_Internet += text_line_template.format (
eventAlert['eve_EventType'], eventAlert['eve_DateTime'],
eventAlert['eve_IP'], eventAlert['eve_AdditionalInfo'])
'Event:', eventAlert['eve_EventType'], 'Time:', eventAlert['eve_DateTime'],
'IP:', eventAlert['eve_IP'], 'More Info:', eventAlert['eve_AdditionalInfo'])
mail_html_Internet += html_line_template.format (
REPORT_DEVICE_URL, eventAlert['eve_MAC'],
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)
@@ -1281,7 +1273,7 @@ def email_reporting ():
REPORT_DEVICE_URL, eventAlert['eve_MAC'], eventAlert['eve_MAC'],
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)
@@ -1356,16 +1348,16 @@ def email_reporting ():
send_email (mail_text, mail_html)
else :
print (' Skip mail...')
if REPORT_PUSHSAFER :
print (' Sending report by PUSHSAFER...')
send_pushsafer (mail_text)
else :
print (' Skip PUSHSAFER...')
if REPORT_NTFY :
print (' Sending report by NTFY...')
send_ntfy (mail_text)
else :
print (' Skip NTFY...')
if REPORT_PUSHSAFER :
print (' Sending report by PUSHSAFER...')
send_pushsafer (mail_text)
else :
print (' Skip PUSHSAFER...')
else :
print (' No changes to report...')
@@ -1385,8 +1377,16 @@ def email_reporting ():
# Commit changes
sql_connection.commit()
closeDB()
#-------------------------------------------------------------------------------
def send_ntfy (_Text):
requests.post("https://ntfy.sh/{}".format(NTFY_TOPIC),
data=_Text,
headers={
"Title": "Pi.Alert Notification",
"Actions": "view, Open Dashboard, "+ REPORT_DASHBOARD_URL,
"Priority": "urgent",
"Tags": "warning"
})
def send_pushsafer (_Text):
url = 'https://www.pushsafer.com/api'
@@ -1402,24 +1402,8 @@ def send_pushsafer (_Text):
"ut" : 'Open Pi.Alert',
"k" : PUSHSAFER_TOKEN,
}
requests.post(url, data=post_fields)
#request = Request(url, urlencode(post_fields).encode())
#json = urlopen(request).read().decode()
# print(json)
#-------------------------------------------------------------------------------
def send_ntfy (_Text):
requests.post("https://ntfy.sh/{}".format(NTFY_TOPIC),
data=_Text,
headers={
"Title": "Pi.Alert Notification",
"Click": REPORT_DASHBOARD_URL,
"Priority": "urgent",
"Tags": "warning"
})
#-------------------------------------------------------------------------------
def format_report_section (pActive, pSection, pTable, pText, pHTML):
global mail_text
@@ -1510,6 +1494,46 @@ def SafeParseGlobalBool(boolVariable):
#===============================================================================
# DB
#===============================================================================
def upgradeDB ():
openDB()
# indicates, if Online_History table is available
onlineHistoryAvailable = sql.execute("""
SELECT name FROM sqlite_master WHERE type='table'
AND name='Online_History';
""").fetchall() != []
# Check if it is incompatible (Check if table has all required columns)
isIncompatible = False
if onlineHistoryAvailable :
isIncompatible = sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Archived_Devices'
""").fetchone()[0] == 0
# Drop table if available, but incompatible
if onlineHistoryAvailable and isIncompatible:
print_log ('Table is incompatible, Dropping the Online_History table)')
sql.execute("DROP TABLE Online_History;")
onlineHistoryAvailable = False
if onlineHistoryAvailable == False :
sql.execute("""
CREATE TABLE "Online_History" (
"Index" INTEGER,
"Scan_Date" TEXT,
"Online_Devices" INTEGER,
"Down_Devices" INTEGER,
"All_Devices" INTEGER,
"Archived_Devices" INTEGER,
PRIMARY KEY("Index" AUTOINCREMENT)
);
""")
#-------------------------------------------------------------------------------
def openDB ():
global sql_connection
global sql

View File

@@ -1,11 +1,6 @@
Report Date: <REPORT_DATE>
Server: <SERVER_NAME>
<SECTION_INTERNET>
Internet
----------------------
<TABLE_INTERNET>
</SECTION_INTERNET><SECTION_NEW_DEVICES>
<SECTION_NEW_DEVICES>
New Devices
----------------------
<TABLE_NEW_DEVICES>
@@ -17,4 +12,8 @@ Devices Down
Events
----------------------
<TABLE_EVENTS>
</SECTION_EVENTS>
</SECTION_EVENTS><SECTION_INTERNET>
Internet
----------------------
<TABLE_INTERNET>
</SECTION_INTERNET>