Now Calling the correct package

This commit is contained in:
2025-08-15 15:19:46 -05:00
parent beca1e7abf
commit cb3f04f2b1
4 changed files with 75 additions and 34 deletions

Binary file not shown.

View File

@@ -9,3 +9,6 @@ HOME_ASSISTANT_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI1MGRhNGI
# Google Home Speaker Entity ID in Home Assistant
GOOGLE_HOME_SPEAKER_ID = "media_player.nestmini2138"
# Ollama Host
OLLAMA_HOST = "http://192.168.2.114:11434"

25
monitor_agent.log Normal file
View File

@@ -0,0 +1,25 @@
2025-08-15 14:44:41,331 - INFO - --- Running Monitoring Cycle ---
2025-08-15 14:44:41,332 - INFO - System Logs: {'log': "Failed login attempt for user 'root' from 10.0.0.1"}
2025-08-15 14:44:43,383 - WARNING - Could not parse ping output with jc. Returning raw output.
2025-08-15 14:44:43,384 - INFO - Network Metrics: {'ping_output': '\nPinging 8.8.8.8 with 32 bytes of data:\nReply from 8.8.8.8: bytes=32 time=18ms TTL=111\nReply from 8.8.8.8: bytes=32 time=23ms TTL=111\nReply from 8.8.8.8: bytes=32 time=18ms TTL=111\n\nPing statistics for 8.8.8.8:\n Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),\nApproximate round trip times in milli-seconds:\n Minimum = 18ms, Maximum = 23ms, Average = 19ms\n'}
2025-08-15 14:44:43,384 - INFO - Combined Data: {
"system_logs": {
"log": "Failed login attempt for user 'root' from 10.0.0.1"
},
"network_metrics": {
"ping_output": "\nPinging 8.8.8.8 with 32 bytes of data:\nReply from 8.8.8.8: bytes=32 time=18ms TTL=111\nReply from 8.8.8.8: bytes=32 time=23ms TTL=111\nReply from 8.8.8.8: bytes=32 time=18ms TTL=111\n\nPing statistics for 8.8.8.8:\n Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),\nApproximate round trip times in milli-seconds:\n Minimum = 18ms, Maximum = 23ms, Average = 19ms\n"
}
}
2025-08-15 14:44:56,562 - INFO - HTTP Request: POST http://192.168.2.114:11434/api/generate "HTTP/1.1 200 OK"
2025-08-15 14:44:56,562 - INFO - LLM Response: After analyzing the system data in JSON format, I've identified a potential issue.
The log entry indicates a failed login attempt for the 'root' user from IP address 10.0.0.1. While failed login attempts are not uncommon, this one stands out because it is not accompanied by any subsequent successful login attempts or other related log entries. This suggests that the failed login may have been an isolated incident and could be a sign of malicious activity.
I would categorize this anomaly as medium severity due to the potential security implications. The possible cause could be unauthorized access attempts, which might warrant further investigation into the system's authentication mechanisms and access controls.
Report:
"A failed login attempt for the 'root' user from IP address 10.0.0.1 indicates a potential security risk with a medium severity level. Further analysis is required to determine the root cause, but it may be indicative of unauthorized access attempts."
2025-08-15 14:44:56,563 - INFO - Anomaly detected, sending alerts...
2025-08-15 14:44:56,885 - INFO - Discord alert sent.
2025-08-15 14:44:56,891 - INFO - Google Home alert sent.
2025-08-15 14:44:56,891 - INFO - --- Cycle Complete, sleeping for 5 minutes ---

View File

@@ -1,13 +1,23 @@
import json
import platform
import subprocess
import time
from syslog_rfc5424_parser import parse
import logging
from syslog_rfc5424_parser import SyslogMessage
import jc
import ollama
from discord_webhook import DiscordWebhook, DiscordEmbed
import requests
import config
# --- Logging Configuration ---
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("monitor_agent.log"),
logging.StreamHandler()
])
# --- Data Ingestion & Parsing Functions ---
def get_system_logs():
@@ -21,17 +31,17 @@ def get_system_logs():
dict: A dictionary representing the parsed log entry.
"""
mock_log_entry = '<165>1 2025-08-15T12:00:00Z my-host app-name - - [meta sequenceId="1"] { "log": "Failed login attempt for user \'root\' from 10.0.0.1" }'
parsed_log = parse(mock_log_entry)
# The message part is a string, so we need to parse it as JSON
# In a real scenario, you might need to handle non-json messages
if parsed_log.message:
try:
log_content = json.loads(parsed_log.message)
# We can merge the log content with the parsed log for a more complete picture
# For now, we'll just return the content of the log message
return log_content
except json.JSONDecodeError:
return {"log": parsed_log.message}
try:
parsed_log = SyslogMessage.parse(mock_log_entry)
if parsed_log.msg:
try:
log_content = json.loads(parsed_log.msg)
return log_content
except json.JSONDecodeError:
logging.warning(f"Could not parse log message as JSON: {parsed_log.msg}")
return {"log": parsed_log.msg}
except Exception as e:
logging.error(f"Error parsing syslog message: {e}")
return {}
def get_network_metrics():
@@ -44,17 +54,17 @@ def get_network_metrics():
Returns:
dict: A dictionary containing the parsed network metrics.
"""
# We ping a reliable address, like Google's DNS, 3 times.
# The '-c 3' argument is for Linux/macOS. For Windows, it would be '-n 3'.
# Since the target is an Ubuntu server, we'll use '-c'.
ping_param = '-n' if platform.system() == "Windows" else '-c'
try:
ping_output = subprocess.run(['ping', '-c', '3', '8.8.8.8'], capture_output=True, text=True, check=True).stdout
ping_output = subprocess.run(['ping', ping_param, '3', '8.8.8.8'], capture_output=True, text=True, check=True).stdout
parsed_metrics = jc.parse('ping', ping_output)
# We're interested in the summary statistics
if parsed_metrics:
if parsed_metrics and isinstance(parsed_metrics, list):
return parsed_metrics[0]
else:
logging.warning("Could not parse ping output with jc. Returning raw output.")
return {"ping_output": ping_output}
except (subprocess.CalledProcessError, FileNotFoundError) as e:
# Handle cases where ping fails or is not installed
logging.error(f"Error running ping command: {e}")
return {"error": str(e)}
return {}
@@ -79,12 +89,14 @@ Output Request: If you find an anomaly, provide a report as a single, coherent,
Reasoning Hint: Think step by step to come to your conclusion. This is very important."""
try:
response = ollama.generate(
client = ollama.Client(host=config.OLLAMA_HOST)
response = client.generate(
model="llama3.1:8b",
prompt=prompt
)
return response['response'].strip()
except Exception as e:
logging.error(f"Error communicating with Ollama: {e}")
return f"Error communicating with Ollama: {e}"
# --- Alerting Functions ---
@@ -97,7 +109,7 @@ def send_discord_alert(message):
message (str): The message to send.
"""
if config.DISCORD_WEBHOOK_URL == "YOUR_DISCORD_WEBHOOK_URL_HERE":
print("Skipping Discord alert: Webhook URL not configured.")
logging.info("Skipping Discord alert: Webhook URL not configured.")
return
webhook = DiscordWebhook(url=config.DISCORD_WEBHOOK_URL)
@@ -105,9 +117,9 @@ def send_discord_alert(message):
webhook.add_embed(embed)
try:
response = webhook.execute()
print("Discord alert sent.")
logging.info("Discord alert sent.")
except Exception as e:
print(f"Error sending Discord alert: {e}")
logging.error(f"Error sending Discord alert: {e}")
def send_google_home_alert(message):
"""
@@ -116,9 +128,8 @@ def send_google_home_alert(message):
Args:
message (str): The message to be spoken.
"""
# Long or complex messages should be simplified for better Text-to-Speech delivery.
if config.HOME_ASSISTANT_URL == "http://YOUR_HOME_ASSISTANT_IP:8123":
print("Skipping Google Home alert: Home Assistant URL not configured.")
logging.info("Skipping Google Home alert: Home Assistant URL not configured.")
return
url = f"{config.HOME_ASSISTANT_URL}/api/services/tts/speak"
@@ -134,10 +145,10 @@ def send_google_home_alert(message):
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status() # Raise an exception for bad status codes
print("Google Home alert sent.")
response.raise_for_status()
logging.info("Google Home alert sent.")
except requests.exceptions.RequestException as e:
print(f"Error sending Google Home alert: {e}")
logging.error(f"Error sending Google Home alert: {e}")
# --- Main Script Logic ---
@@ -146,26 +157,28 @@ def main():
The main execution loop for the monitoring agent.
"""
while True:
print("--- Running Monitoring Cycle ---")
logging.info("--- Running Monitoring Cycle ---")
system_logs = get_system_logs()
logging.info(f"System Logs: {system_logs}")
network_metrics = get_network_metrics()
logging.info(f"Network Metrics: {network_metrics}")
combined_data = {
"system_logs": system_logs,
"network_metrics": network_metrics
}
logging.info(f"Combined Data: {json.dumps(combined_data, indent=2)}")
llm_response = analyze_data_with_llm(combined_data)
print(f"LLM Response: {llm_response}")
logging.info(f"LLM Response: {llm_response}")
if llm_response != "OK":
print("Anomaly detected, sending alerts...")
logging.info("Anomaly detected, sending alerts...")
send_discord_alert(llm_response)
send_google_home_alert(llm_response)
print("--- Cycle Complete, sleeping for 5 minutes ---")
logging.info("--- Cycle Complete, sleeping for 5 minutes ---")
time.sleep(300) # 300 seconds = 5 minutes
if __name__ == "__main__":
main()
main()