File size: 4,776 Bytes
5765e13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import json
import os
from datetime import datetime
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib.utils import simpleSplit

class ReportGenerator:
    def __init__(self, db):
        self.db = db
        self.report_dir = "reports"
        os.makedirs(self.report_dir, exist_ok=True)

    def _get_cursor(self):
        _, cursor = self.db._get_connection()
        return cursor

    def generate_report(self, reason="scheduled"):
        ts = datetime.now()
        base_name = f"security_report_{ts.strftime('%Y%m%d_%H%M%S')}"
        data = self._collect_data(ts)

        json_path = os.path.join(self.report_dir, base_name + ".json")
        with open(json_path, 'w') as f:
            json.dump(data, f, indent=2)

        txt_path = os.path.join(self.report_dir, base_name + ".txt")
        with open(txt_path, 'w') as f:
            f.write(self._format_text(data))

        pdf_path = os.path.join(self.report_dir, base_name + ".pdf")
        self._generate_pdf(data, pdf_path)

        cursor = self._get_cursor()
        cursor.execute('INSERT INTO reports (timestamp, report_path, type) VALUES (?, ?, ?)',
                       (ts.isoformat(), json_path, reason))
        self.db._get_connection()[0].commit()
        return json_path, txt_path, pdf_path

    def _collect_data(self, ts):
        events = self.db.get_recent_events(200)
        threats = self.db.get_threat_summary(24)
        blocked = self.db.get_blocked_ips()
        total_packets = len(events)
        unique_src = set(e[2] for e in events)
        return {
            "report_time": ts.isoformat(),
            "summary": {
                "total_events": total_packets,
                "unique_sources": len(unique_src),
                "threats_detected": len([e for e in events if e[7] is not None]),
                "blocked_ips": len(blocked)
            },
            "threat_breakdown": [{"type": t[0], "count": t[1], "avg_risk": t[2]} for t in threats],
            "blocked_ips_list": [{"ip": b[0], "time": b[1], "reason": b[2]} for b in blocked],
            "top_suspicious": self._get_top_ips(events),
            "recommendations": self._generate_recs(threats, len(blocked))
        }

    def _get_top_ips(self, events, n=5):
        freq = {}
        for e in events:
            ip = e[2]
            freq[ip] = freq.get(ip, 0) + 1
        sorted_ips = sorted(freq.items(), key=lambda x: x[1], reverse=True)[:n]
        return [{"ip": ip, "packets": cnt} for ip, cnt in sorted_ips]

    def _generate_recs(self, threats, blocked_count):
        recs = []
        if any(t[0] == "PORT_SCAN" for t in threats):
            recs.append("Enable port knocking or move SSH/RDP to non-standard ports.")
        if any(t[0] == "BRUTE_FORCE" for t in threats):
            recs.append("Enforce strong passwords and consider account lockout policies.")
        if blocked_count > 10:
            recs.append("Review blocked IP list; consider using an IP reputation feed.")
        if not recs:
            recs.append("No immediate action required. Continue monitoring.")
        return recs

    def _format_text(self, data):
        lines = []
        lines.append("="*60)
        lines.append(f"MayOne Security Report - {data['report_time']}")
        lines.append("="*60)
        lines.append("\nSUMMARY")
        for k,v in data['summary'].items():
            lines.append(f"  {k}: {v}")
        lines.append("\nTHREAT BREAKDOWN")
        for t in data['threat_breakdown']:
            lines.append(f"  {t['type']}: {t['count']} events, avg risk {t['avg_risk']:.1f}")
        lines.append("\nBLOCKED IPs")
        for b in data['blocked_ips_list'][:10]:
            lines.append(f"  {b['ip']} - {b['reason']} (since {b['time']})")
        lines.append("\nRECOMMENDATIONS")
        for r in data['recommendations']:
            lines.append(f"  - {r}")
        return "\n".join(lines)

    def _generate_pdf(self, data, path):
        c = canvas.Canvas(path, pagesize=letter)
        width, height = letter
        y = height - 50
        c.drawString(50, y, f"MayOne Security Report - {data['report_time']}")
        y -= 30
        c.drawString(50, y, "Summary")
        y -= 20
        for k,v in data['summary'].items():
            c.drawString(70, y, f"{k}: {v}")
            y -= 15
        y -= 10
        c.drawString(50, y, "Top Recommendations")
        y -= 20
        for rec in data['recommendations'][:3]:
            lines = simpleSplit(rec, "Helvetica", 12, width-100)
            for line in lines:
                c.drawString(70, y, f"- {line}")
                y -= 15
        c.save()