internet_ip plugin 0.2

This commit is contained in:
Jokob-sk
2023-09-20 21:53:22 +10:00
parent add9800f42
commit c08b70a38d
18 changed files with 495 additions and 439 deletions

View File

@@ -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|
|```README.md```| this readme file|
|**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)|
|```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|
@@ -35,12 +34,5 @@ publishers generally have a check_config method as well as a send method.
|```pushsafer.py```| integrate with pushsafer |
|```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 |

View File

@@ -32,10 +32,6 @@ from database import DB, get_all_devices
from reporting import check_and_run_event, send_notifications
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
update API
run plugins (scheduled)
check internet IP
check vendor
processing scan results
run plugins (after Scan)
reporting
@@ -123,8 +117,7 @@ def main ():
if conf.last_scan_run + datetime.timedelta(minutes=1) < conf.loop_start_time :
# last time any scan or maintenance/upkeep was run
conf.last_scan_run = loop_start_time
last_internet_IP_scan = conf.last_internet_IP_scan
conf.last_scan_run = loop_start_time
# Header
updateState("Process: Start")
@@ -138,12 +131,6 @@ def main ():
# 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
pluginsState = run_plugin_scripts(db,'always_after_scan', pluginsState)

View File

@@ -20,7 +20,6 @@ plugins_once_run = False
newVersionAvailable = False
time_started = ''
startTime = ''
last_internet_IP_scan = ''
last_scan_run = ''
last_version_check = ''
arpscan_devices = []
@@ -44,7 +43,7 @@ UI_LANG = 'English'
UI_PRESENCE = ['online', 'offline', 'archived']
PIALERT_WEB_PROTECTION = False
PIALERT_WEB_PASSWORD = '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'
INCLUDED_SECTIONS = ['internet', 'new_devices', 'down_devices', 'events']
INCLUDED_SECTIONS = ['new_devices', 'down_devices', 'events']
DAYS_TO_KEEP_EVENTS = 90
REPORT_DASHBOARD_URL = 'http://pi.alert/'

View File

@@ -3,7 +3,7 @@ import subprocess
import conf
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 const import vendorsPath6, vendorsPath9
@@ -13,13 +13,6 @@ from const import vendorsPath6, vendorsPath9
def save_scanned_devices (db):
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
# BUGFIX #106 - Device that pialert is running

View File

@@ -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):

View File

@@ -96,7 +96,7 @@ def importConfigs (db):
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_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.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')
@@ -175,8 +175,7 @@ def importConfigs (db):
conf.startTime = conf.time_started
now_minus_24h = conf.time_started - datetime.timedelta(hours = 24)
# set these times to the past to force the first run
conf.last_internet_IP_scan = now_minus_24h
# set these times to the past to force the first run
conf.last_scan_run = now_minus_24h
conf.last_version_check = now_minus_24h

View File

@@ -183,20 +183,20 @@ def send_notifications (db):
mylog('verbose', ['[Notification] included sections: ', conf.INCLUDED_SECTIONS ])
if 'internet' in conf.INCLUDED_SECTIONS :
# 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
WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
ORDER BY eve_DateTime"""
# if 'internet' in conf.INCLUDED_SECTIONS :
# # 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
# WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
# 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
json_internet = notiStruc.json["data"]
# # collect "internet" (IP changes) for the webhook json
# json_internet = notiStruc.json["data"]
mail_text = mail_text.replace ('<SECTION_INTERNET>', notiStruc.text + '\n')
mail_html = mail_html.replace ('<INTERNET_TABLE>', notiStruc.html)
mylog('verbose', ['[Notification] Internet sections done.'])
# mail_text = mail_text.replace ('<SECTION_INTERNET>', notiStruc.text + '\n')
# mail_html = mail_html.replace ('<INTERNET_TABLE>', notiStruc.html)
# mylog('verbose', ['[Notification] Internet sections done.'])
if 'new_devices' in conf.INCLUDED_SECTIONS :
# Compose New Devices Section

View File

@@ -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