Spaces:
Sleeping
Sleeping
Update logger_service.py
Browse files- logger_service.py +76 -57
logger_service.py
CHANGED
|
@@ -1,66 +1,85 @@
|
|
| 1 |
-
import os
|
| 2 |
import pandas as pd
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
#
|
| 6 |
-
DATASET_REPO_ID = "My-Project-Team/Digital-Bodyguard-Dataset"
|
| 7 |
-
CSV_FILENAME = "baseline_logs.csv"
|
| 8 |
-
HF_TOKEN = os.getenv("HF_TOKEN")
|
| 9 |
-
|
| 10 |
-
# 🌟 批次上傳門檻 (每累積幾筆資料才備份到雲端一次)
|
| 11 |
-
BATCH_SIZE = 30
|
| 12 |
-
unsynced_count = 0
|
| 13 |
-
|
| 14 |
-
if HF_TOKEN:
|
| 15 |
-
login(token=HF_TOKEN)
|
| 16 |
|
| 17 |
-
#
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
# try:
|
| 21 |
-
# path = hf_hub_download(
|
| 22 |
-
# repo_id=DATASET_REPO_ID,
|
| 23 |
-
# filename=CSV_FILENAME,
|
| 24 |
-
# repo_type="dataset",
|
| 25 |
-
# token=HF_TOKEN
|
| 26 |
-
# )
|
| 27 |
-
# return pd.read_csv(path)
|
| 28 |
-
# except Exception as e:
|
| 29 |
-
# print(f"⚠️ 無法下載雲端資料,可能為首次運行: {e}")
|
| 30 |
-
# return pd.DataFrame(columns=["timestamp", "ip_address", "cookie_id", "account", "role", "action", "status"])
|
| 31 |
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
token=HF_TOKEN,
|
| 41 |
-
commit_message=f"System auto-log batch update ({BATCH_SIZE} logs)"
|
| 42 |
-
)
|
| 43 |
-
return True
|
| 44 |
-
except Exception as e:
|
| 45 |
-
print(f"❌ 雲端同步失敗: {e}")
|
| 46 |
-
return False
|
| 47 |
|
| 48 |
-
|
|
|
|
| 49 |
"""
|
| 50 |
-
|
| 51 |
-
有效避免 429 Rate Limit 並大幅提升網頁操作流暢度。
|
| 52 |
"""
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
|
|
|
| 65 |
|
| 66 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import pandas as pd
|
| 2 |
+
import os
|
| 3 |
+
from datetime import datetime
|
| 4 |
+
import joblib # 確保有安裝此套件
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
+
# --- 全域變數與模型載入 ---
|
| 7 |
+
global system_weights
|
| 8 |
+
system_weights = {"ow": 0, "gw": 0, "tw": 0}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
+
# 嘗試載入您的 HDBSCAN 模型
|
| 11 |
+
HDBSCAN_MODEL = None
|
| 12 |
+
try:
|
| 13 |
+
if os.path.exists('hdbscan_model.pkl'):
|
| 14 |
+
HDBSCAN_MODEL = joblib.load('hdbscan_model.pkl')
|
| 15 |
+
print("✅ HDBSCAN 模型載入成功")
|
| 16 |
+
except Exception as e:
|
| 17 |
+
print(f"❌ 模型載入失敗: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
+
# --- 新增:將系統行為映射至 Web Log 特徵 ---
|
| 20 |
+
def map_to_web_log_features(action, status_label):
|
| 21 |
"""
|
| 22 |
+
將內部 action 轉換為訓練資料中的 Method, Path, Status 數字
|
|
|
|
| 23 |
"""
|
| 24 |
+
method = "GET"
|
| 25 |
+
path = "/usr/student"
|
| 26 |
+
status_code = 200
|
| 27 |
|
| 28 |
+
# 映射邏輯 (根據您的訓練資料截圖進行模擬)
|
| 29 |
+
if action == "login_attempt":
|
| 30 |
+
method = "POST"
|
| 31 |
+
path = "/usr/login"
|
| 32 |
+
elif "admin" in action or "manage" in action:
|
| 33 |
+
path = "/usr/admin"
|
| 34 |
+
elif action == "malicious_sql_injection":
|
| 35 |
+
method = "DELETE"
|
| 36 |
+
path = "/usr/admin/developer"
|
| 37 |
|
| 38 |
+
# 根據狀態標籤給予初始代碼
|
| 39 |
+
if "failed" in status_label:
|
| 40 |
+
status_code = 401
|
| 41 |
+
elif "異常" in status_label:
|
| 42 |
+
status_code = 403
|
| 43 |
|
| 44 |
+
return method, path, status_code
|
| 45 |
+
|
| 46 |
+
# --- 修改後的 check_anomaly ---
|
| 47 |
+
def check_anomaly(ip, account, action, log_time):
|
| 48 |
+
# 如果是登入或登出,直接放行 (200)
|
| 49 |
+
if action in ["login_attempt", "logout"]:
|
| 50 |
+
return "success (200)"
|
| 51 |
+
|
| 52 |
+
try:
|
| 53 |
+
ow = float(system_weights.get("ow", 0))
|
| 54 |
+
gw = float(system_weights.get("gw", 0))
|
| 55 |
+
tw = float(system_weights.get("tw", 0))
|
| 56 |
+
|
| 57 |
+
# 1. 地理位置權重攔截
|
| 58 |
+
from logger_service import get_geo_level # 假設此函式存在於同檔案
|
| 59 |
+
geo_level = get_geo_level(ip)
|
| 60 |
+
if gw == 100 and geo_level > 0:
|
| 61 |
+
return "⚠️異常_地理位置受限 (100%絕對鎖定: 僅限校內專網存取) (403)"
|
| 62 |
+
elif gw >= 90 and geo_level > 1:
|
| 63 |
+
return "⚠️異常_地理位置受限 (高敏感防護: 僅限校園網路與宿舍) (403)"
|
| 64 |
+
|
| 65 |
+
# 2. 頻率檢查
|
| 66 |
+
# (此處保留您原有的 recent_clicks 計算邏輯...)
|
| 67 |
+
# if (recent_clicks + 1) > max_allowed_clicks:
|
| 68 |
+
# return f"⚠️異常_單一操作頻率過高 (403)"
|
| 69 |
+
|
| 70 |
+
# 3. HDBSCAN 模型檢測
|
| 71 |
+
if HDBSCAN_MODEL:
|
| 72 |
+
# 轉換特徵
|
| 73 |
+
method, path, base_code = map_to_web_log_features(action, "success")
|
| 74 |
+
|
| 75 |
+
# ⚠️ 注意:這裡需要接入您當初訓練時的「特徵工程」轉換代碼 (例如 LabelEncoder 或 Scaler)
|
| 76 |
+
# 範例結構:
|
| 77 |
+
# features = preprocess_logic(ip, log_time, method, path, base_code)
|
| 78 |
+
# result = HDBSCAN_MODEL.fit_predict(features)
|
| 79 |
+
# if result[-1] == -1: return "⚠️異常_作息或行為不符 (403)"
|
| 80 |
+
pass
|
| 81 |
+
|
| 82 |
+
return "success (200)"
|
| 83 |
+
|
| 84 |
+
except Exception as e:
|
| 85 |
+
return f"⚠️系統錯誤: {str(e)} (500)"
|