Shodan and jobs
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
# Fallback base URL since 'request.host_url' is not available in background threads
|
||||
SERVER_BASE_URL = os.getenv("SERVER_BASE_URL", "https://smartwave.matthiasg.dev")
|
||||
|
||||
|
||||
def job_server_cve_audit(shodan_auditor, db):
|
||||
"""Job 1: Audits Flask server public IP for CVEs and saves to MongoDB."""
|
||||
print("[Cron] Starting Server CVE Audit...")
|
||||
|
||||
audit_results = shodan_auditor.audit_server_vulnerabilities()
|
||||
|
||||
db.cve_audit_results.insert_one({
|
||||
"audit_results": audit_results,
|
||||
"timestamp": datetime.now(timezone.utc)
|
||||
})
|
||||
|
||||
print(f"[Cron] Server CVE Audit finished. Status: {audit_results.get('status')}")
|
||||
|
||||
|
||||
def job_client_ip_audit(shodan_auditor, db):
|
||||
"""
|
||||
Job 2: Fetches distinct client IPs logged in the last 24h and audits them.
|
||||
Deduplicates IPs and applies rate limits to protect Shodan API credits.
|
||||
"""
|
||||
print("[Cron] Starting Client IP Security Audit...")
|
||||
|
||||
pipeline = [
|
||||
{"$group": {
|
||||
"_id": "$client_ip",
|
||||
"microwave_ids": {"$addToSet": "$microwave_id"},
|
||||
"last_seen": {"$max": "$received_at"}
|
||||
}}
|
||||
]
|
||||
|
||||
recent_clients = list(db.device_ip_collection.aggregate(pipeline))
|
||||
|
||||
for entry in recent_clients:
|
||||
client_ip = entry["_id"]
|
||||
|
||||
# Skip local/private IPs
|
||||
if not client_ip or client_ip in ["127.0.0.1", "localhost"] or client_ip.startswith(("10.", "192.168.", "172.16.")):
|
||||
continue
|
||||
|
||||
profile = shodan_auditor.profile_client_ip(client_ip)
|
||||
|
||||
# Upsert client profile in a separate collection
|
||||
db.client_audit_results.update_one(
|
||||
{"client_ip": client_ip},
|
||||
{
|
||||
"$set": {
|
||||
"client_ip": client_ip,
|
||||
"microwave_ids": entry["microwave_ids"],
|
||||
"last_seen": entry["last_seen"],
|
||||
"profile": profile,
|
||||
"audited_at": datetime.now(timezone.utc)
|
||||
}
|
||||
},
|
||||
upsert=True
|
||||
)
|
||||
|
||||
# Pause 1 second to respect Shodan API rate limits (1 req/sec)
|
||||
time.sleep(1)
|
||||
|
||||
print(f"[Cron] Client IP Security Audit completed for {len(recent_clients)} IPs.")
|
||||
|
||||
|
||||
def job_request_telemetry(send_command_func):
|
||||
"""Job 3: Triggers MQTT command to request telemetry from all microwaves."""
|
||||
print("[Cron] Sending MQTT Telemetry Request to cmd/all...")
|
||||
|
||||
telemetry_url = f"{SERVER_BASE_URL.rstrip('/')}/telemetry"
|
||||
cmd_payload = {
|
||||
"action": "request_telemetry",
|
||||
"endpoint": telemetry_url
|
||||
}
|
||||
|
||||
try:
|
||||
send_command_func(topic="cmd/all", payload=cmd_payload)
|
||||
print("[Cron] Telemetry request successfully published.")
|
||||
except Exception as e:
|
||||
print(f"[Cron Error] Failed to publish MQTT command: {str(e)}")
|
||||
Reference in New Issue
Block a user