补测:行为检测支持历史区间;特征扫描自动时间切片;历史画像保留
This commit is contained in:
1 parent
d78eabc458
commit
897828f506
5 files changed
+229
-18
No files matched your search
+15
-2
@@ -134,11 +134,20 @@ def asn_info(ip, root):
|
||||
return {"asn": "", "org": "未知", "shared": "unknown"}
|
||||
|
||||
|
||||
RANGE_OVERRIDE = None
|
||||
|
||||
|
||||
def pivot(client, series, row_groups, column_groups=None, query="*",
|
||||
limit=300, timeout=180000):
|
||||
if RANGE_OVERRIDE:
|
||||
timerange = {"type": "absolute",
|
||||
"from": RANGE_OVERRIDE["from"],
|
||||
"to": RANGE_OVERRIDE["to"]}
|
||||
else:
|
||||
timerange = {"type": "relative", "range": WINDOW}
|
||||
body = {"queries": [{
|
||||
"id": "q1",
|
||||
"timerange": {"type": "relative", "range": WINDOW},
|
||||
"timerange": timerange,
|
||||
"query": {"type": "elasticsearch", "query_string": query},
|
||||
"filter": {"type": "or", "filters": [{"type": "stream",
|
||||
"id": "6ac83059a6878e26256fcacc"}]},
|
||||
@@ -401,9 +410,13 @@ class BehaviorAnalyzer:
|
||||
except GraylogError:
|
||||
pass
|
||||
try:
|
||||
extra = {}
|
||||
if RANGE_OVERRIDE:
|
||||
extra = {"from_ts": RANGE_OVERRIDE["from"],
|
||||
"to_ts": RANGE_OVERRIDE["to"]}
|
||||
hist = self.client.histogram(query=q, range_seconds=self.window,
|
||||
interval="5m",
|
||||
filter_str=self.filter_str)
|
||||
filter_str=self.filter_str, **extra)
|
||||
from .client import normalize_histogram
|
||||
detail["buckets5m"] = [b["count"]
|
||||
for b in normalize_histogram(hist)]
|
||||
|
||||
+38
-5
@@ -345,7 +345,8 @@ class Store:
|
||||
country_code TEXT, country_name TEXT, region TEXT, city TEXT
|
||||
)"""
|
||||
)
|
||||
for column in ("asn_brand TEXT", "asn_type TEXT", "asn_icon TEXT"):
|
||||
for column in ("asn_brand TEXT", "asn_type TEXT", "asn_icon TEXT",
|
||||
"historical INTEGER DEFAULT 0"):
|
||||
try:
|
||||
self.conn.execute(
|
||||
"ALTER TABLE behavior_profiles ADD COLUMN %s" % column)
|
||||
@@ -497,10 +498,40 @@ class Store:
|
||||
return item
|
||||
|
||||
# ---------------------------------------------------------- behaviour
|
||||
def upsert_historical_profiles(self, items):
|
||||
"""Insert backfilled behaviour profiles; live rows win on conflict."""
|
||||
stamp = now_iso()
|
||||
with self.lock, self.conn:
|
||||
for item in items:
|
||||
self.conn.execute(
|
||||
"""INSERT OR IGNORE INTO behavior_profiles
|
||||
(ip, score, verdict, signals, reason_text, share_note,
|
||||
behavior_type, asn, asn_org, shared_type, asn_brand,
|
||||
asn_type, asn_icon, total, pct4, uri_card, uri_templates,
|
||||
ua_card, host_card, coverage, peak_share, top_uri, top_ua,
|
||||
last_ts, updated_at, country_code, country_name, region,
|
||||
city, historical)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1)""",
|
||||
(item["ip"], item.get("score"), item.get("verdict"),
|
||||
json.dumps(item.get("signals") or [], ensure_ascii=False),
|
||||
item.get("reason_text"), item.get("share_note"),
|
||||
item.get("behavior_type"), item.get("asn"),
|
||||
item.get("asn_org"), item.get("shared_type"),
|
||||
item.get("asn_brand"), item.get("asn_type"),
|
||||
item.get("asn_icon"), int(item.get("total") or 0),
|
||||
item.get("pct4"), item.get("uri_card"),
|
||||
item.get("uri_templates"), item.get("ua_card"),
|
||||
item.get("host_card"), item.get("coverage"),
|
||||
item.get("peak_share"), item.get("top_uri"),
|
||||
item.get("top_ua"), item.get("last_ts") or stamp, stamp,
|
||||
item.get("country_code"), item.get("country_name"),
|
||||
item.get("region"), item.get("city")))
|
||||
|
||||
def replace_behavior_profiles(self, items):
|
||||
stamp = now_iso()
|
||||
with self.lock, self.conn:
|
||||
self.conn.execute("DELETE FROM behavior_profiles")
|
||||
self.conn.execute(
|
||||
"DELETE FROM behavior_profiles WHERE COALESCE(historical,0)=0")
|
||||
for item in items:
|
||||
self.conn.execute(
|
||||
"""INSERT OR REPLACE INTO behavior_profiles
|
||||
@@ -509,8 +540,8 @@ class Store:
|
||||
asn_type, asn_icon, total, pct4, uri_card, uri_templates,
|
||||
ua_card, host_card, coverage, peak_share, top_uri, top_ua,
|
||||
last_ts, updated_at, country_code, country_name, region,
|
||||
city)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
|
||||
city, historical)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0)""",
|
||||
(item["ip"], item.get("score"), item.get("verdict"),
|
||||
json.dumps(item.get("signals") or [], ensure_ascii=False),
|
||||
item.get("reason_text"), item.get("share_note"),
|
||||
@@ -649,11 +680,13 @@ class Store:
|
||||
if beh["verdict"] != "建议封禁" or ip in wanted:
|
||||
continue
|
||||
prev = existing.get(ip)
|
||||
historical = bool(beh["historical"]) if "historical" in beh.keys() else False
|
||||
fallback = (beh["last_ts"] if historical and beh["last_ts"] else now)
|
||||
wanted[ip] = {
|
||||
"sources": "behavior",
|
||||
"feature_score": None,
|
||||
"behavior_score": beh["score"],
|
||||
"first_banned_at": prev["first_banned_at"] if prev else now,
|
||||
"first_banned_at": prev["first_banned_at"] if prev else fallback,
|
||||
"last_activity_at": iso(beh["last_ts"]),
|
||||
"fused_reason": "行为表现:" + (beh["reason_text"] or ""),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user