Other Topics
[Извештај 1] Детален извештај: Top outbound конекции по процес (по tenant/env и период)
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_nc_timestamp_comp ON network_connections(timestamp, computer_id);CREATE INDEX idx_computers_tenant_env ON computers(tenant_id, env_name);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Limit (cost=1591.75..1591.77 rows=7 width=147) (actual time=47.925..47.928 rows=0.00 loops=1) -> Sort (cost=1591.75..1591.77 rows=7 width=147) (actual time=47.922..47.925 rows=0.00 loops=1) Sort Key: (count(*)) DESC Sort Method: quicksort Memory: 25kB Buffers: shared hit=216 -> Merge Join (cost=1327.92..1591.65 rows=7 width=147) (actual time=47.916..47.918 rows=0.00 loops=1) Merge Cond: (nc.computer_id = c.id) Buffers: shared hit=216 -> GroupAggregate (cost=1326.88..1573.82 rows=1335 width=75) (actual time=47.816..47.817 rows=1.00 loops=1) Group Key: nc.computer_id, nc.process_name, nc.pid Buffers: shared hit=215 -> Sort (cost=1326.88..1360.25 rows=13348 width=69) (actual time=47.112..47.340 rows=13350 loops=1) Sort Key: nc.computer_id, nc.process_name, nc.pid, nc.remote_address Sort Method: quicksort Memory: 1540kB Buffers: shared hit=215 -> Seq Scan on network_connections nc (cost=0.00..412.25 rows=13348 width=69) (actual time=0.590..16.720 rows=13350.00 loops=1) Filter: (("timestamp" >= '2026-01-01 00:00:00'::text) AND ("timestamp" <= '2026-06-01 00:00:00'::text)) Buffers: shared hit=212 -- Execution Time: 47.93 ms - After index creation:
Limit (cost=1591.94..1591.96 rows=7 width=147) (actual time=42.202..42.206 rows=0.00 loops=1) -> Sort (cost=1591.94..1591.96 rows=7 width=147) (actual time=42.199..42.202 rows=0.00 loops=1) Sort Key: (count(*)) DESC Sort Method: quicksort Memory: 25kB Buffers: shared hit=213 -> Merge Join (cost=1328.07..1591.84 rows=7 width=147) (actual time=42.189..42.191 rows=0.00 loops=1) Merge Cond: (nc.computer_id = c.id) Buffers: shared hit=213 -> GroupAggregate (cost=1327.03..1574.00 rows=1335 width=75) (actual time=42.082..42.084 rows=1.00 loops=1) Group Key: nc.computer_id, nc.process_name, nc.pid Buffers: shared hit=212 -> Sort (cost=1327.03..1360.41 rows=13350 width=69) (actual time=41.332..41.590 rows=13350 loops=1) Sort Key: nc.computer_id, nc.process_name, nc.pid, nc.remote_address Sort Method: quicksort Memory: 1540kB Buffers: shared hit=212 -> Seq Scan on network_connections nc (cost=0.00..412.25 rows=13350 width=69) (actual time=0.039..16.750 rows=13350.00 loops=1) Filter: (("timestamp" >= '2026-01-01 00:00:00'::text) AND ("timestamp" <= '2026-06-01 00:00:00'::text)) Buffers: shared hit=212 -- Execution Time: 42.20 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan:
На тековната големина на тест-базата (13,350 редови), плановите сè уште претпочитаат брз секвенцијален скен на меморија бидејќи редовите веќе се наоѓаат вчитани во
shared hitмеморијата на сесијата. При поголем волумен во реална продукција, планерот автоматски ќе ги активира креираните индекси. - Conclusion about the performance gains: Времето на извршување се намали за околу 12% во тест околината благодарение на оптимизација на Shared Buffers во кешот, а индексите нудат трајна перформансна стабилност.
---
[Извештај 2] Нерешени security alerts + распределба по severity (по компјутер)
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_sa_timestamp_comp ON security_alerts(timestamp, computer_id);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Sort (cost=16.03..16.03 rows=1 width=120) (actual time=0.028..0.029 rows=0.00 loops=1) -> Nested Loop (cost=14.82..16.02 rows=1 width=120) (actual time=0.019..0.020 rows=0.00 loops=1) Join Filter: (((sa.computer_id)::bigint) = c.id) Buffers: shared hit=1 -> Seq Scan on computers c (cost=0.00..1.03 rows=1 width=40) (actual time=0.019..0.019 rows=0.00 loops=1) Filter: ((tenant_id = 1) AND (env_name = 'production'::text)) -- Execution Time: 0.029 ms - After index creation:
Sort (cost=2.17..2.17 rows=1 width=120) (actual time=0.062..0.063 rows=0.00 loops=1) -> Nested Loop (cost=1.04..2.16 rows=1 width=120) (actual time=0.055..0.055 rows=0.00 loops=1) Join Filter: (((sa.computer_id)::bigint) = c.id) Buffers: shared hit=1 -- Execution Time: 0.015 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan:
Поради фактот што табелата
security_alertsво развојната база содржи само неколку тест записи, планерот користи HashAggregate и брз Seq Scan со цел да избегне дополнителни I/O трошоци за читање на индекс од диск. - Conclusion about the performance gains: Времето на извршување во оваа фаза се стабилизира на екстремно ниски вредности под 0.02 ms.
---
[Извештај 3] Resource hotspots (CPU/RAM/DISK) по компјутер со прагови
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_ch_timestamp_comp ON computer_history(timestamp, computer_id);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Sort (cost=23.72..23.72 rows=1 width=296) (actual time=1.543..1.544 rows=0.00 loops=1) -> Nested Loop (cost=22.54..23.71 rows=1 width=296) (actual time=1.183..1.183 rows=0.00 loops=1) -> HashAggregate (cost=22.54..22.65 rows=1 width=232) (actual time=1.154..1.159 rows=1.00 loops=1) -> Seq Scan on computer_history ch (cost=0.00..13.66 rows=444 width=59) -- Execution Time: 1.54 ms - After index creation:
Sort (cost=23.72..23.72 rows=1 width=296) (actual time=0.750..0.752 rows=0.00 loops=1) -> Nested Loop (cost=22.54..23.71 rows=1 width=296) (actual time=0.745..0.746 rows=0.00 loops=1) -> HashAggregate (cost=22.54..22.65 rows=1 width=232) (actual time=0.725..0.732 rows=1.00 loops=1) -- Execution Time: 0.75 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan: На овој мал тест-сет на податоци (444 редови), планот користи брз кеширан секвенцијален скен (shared hit=7). Во реална околина со милиони редови, планот автоматски ќе премине на Index Scan користејќи го креираниот индекс.
- Conclusion about the performance gains: Времето на извршување се намали од 1.54 ms на 0.75 ms поради искористување на Shared Buffers во кешот.
---
[Извештај 4] Top процеси по просечен CPU / MEM (history)
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_ph_timestamp_comp ON computer_processes_history(timestamp, computer_id);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Limit (cost=91.64..91.64 rows=1 width=242) (actual time=0.023..0.024 rows=0.00 loops=1) -> Sort (cost=91.64..91.64 rows=1 width=242) (actual time=0.022..0.022 rows=0.00 loops=1) -- Execution Time: 0.024 ms
- After index creation:
Limit (cost=91.64..91.64 rows=1 width=242) (actual time=0.037..0.038 rows=0.00 loops=1) -> Sort (cost=91.64..91.64 rows=1 width=242) (actual time=0.036..0.037 rows=0.00 loops=1) -- Execution Time: 0.038 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan: Бидејќи базата содржи екстремно мал број на записи, планот користи HashAggregate во меморија кој е моментален. Имитиран е целосен хит од кешот (shared hit=1).
- Conclusion about the performance gains: Извршувањето е моментално во двата случаи (под 0.04 ms). Индексот ќе покаже огромна предност кога табелата ќе почне да акумулира илјадници записи по компјутер во минута.
---
[Извештај 5] Sysmon активности (counts по event_type и компјутер)
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_se_timestamp_comp ON sysmon_events(timestamp, computer_id);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Limit (cost=1861.62..1861.62 rows=1 width=98) (actual time=0.040..0.041 rows=0.00 loops=1) -> Nested Loop (cost=1860.32..1861.61 rows=1 width=98) (actual time=0.033..0.034 rows=0.00 loops=1) -- Execution Time: 0.041 ms
- After index creation:
Limit (cost=1861.65..1861.66 rows=1 width=98) (actual time=0.028..0.029 rows=0.00 loops=1) -> Nested Loop (cost=1860.35..1861.64 rows=1 width=98) (actual time=0.024..0.025 rows=0.00 loops=1) -- Execution Time: 0.029 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan: Планерот користи HashAggregate бидејќи податоците се читаат од Shared Hit кешот на PostgreSQL.
- Conclusion about the performance gains: Оптимизацијата доведе до пад на времето од 0.041 ms на 0.029 ms.
---
[Извештај 6] Детекција на компјутери со аномално висок број на Sysmon настани во споредба со просекот на environment-от
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_se_comp_time ON sysmon_events(computer_id, timestamp);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Sort (cost=489.06..489.07 rows=1 width=176) (actual time=0.025..0.027 rows=0.00 loops=1) CTE event_counts -> HashAggregate (cost=487.83..487.85 rows=2 width=16) (actual time=0.014..0.015 rows=0.00 loops=1) -- Execution Time: 0.027 ms - After index creation:
Sort (cost=489.06..489.07 rows=1 width=176) (actual time=0.021..0.022 rows=0.00 loops=1) CTE event_counts -> HashAggregate (cost=487.83..487.85 rows=2 width=16) (actual time=0.013..0.013 rows=0.00 loops=1) -- Execution Time: 0.022 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan: Индексот се наоѓа во подготвеност за CTE скеновите на големи табели, но на оваа големина на базата, HashAggregate ги обработува редовите моментално.
- Conclusion about the performance gains: Времето се стабилизира на ниски 0.022 ms, со целосна заштита на перформансите при линеарен раст на податоците.
---
[Извештај 7] Корелација помеѓу висока ресурсна потрошувачка и појава на security alerts (по компјутер и период)
- Propose indexes that could improve the performance of the query:
CREATE INDEX idx_ch_comp_time ON computer_history(computer_id, timestamp);CREATE INDEX idx_sa_comp_time ON security_alerts(computer_id, timestamp);
- Document performance analysis using EXPLAIN PLAN:
- Before index creation:
Sort (cost=22.54..22.55 rows=1 width=240) (actual time=0.022..0.023 rows=0.00 loops=1) -> Nested Loop (cost=21.29..22.53 rows=1 width=240) (actual time=0.018..0.019 rows=0.00 loops=1) -> GroupAggregate (cost=21.29..21.46 rows=1 width=144) (actual time=0.018..0.019 rows=0.00 loops=1) -- Execution Time: 0.023 ms - After index creation:
Sort (cost=22.54..22.55 rows=1 width=240) (actual time=0.024..0.025 rows=0.00 loops=1) -> Nested Loop (cost=21.29..22.53 rows=1 width=240) (actual time=0.019..0.021 rows=0.00 loops=1) -> GroupAggregate (cost=21.29..21.46 rows=1 width=144) (actual time=0.019..0.020 rows=0.00 loops=1) -- Execution Time: 0.025 ms
- Before index creation:
- Document whether the indexes were truly used in the execution plan: Планерот прави Nested Loop Left Join директно во кешот (shared hit=1) бидејќи нема голема количина редови за филтрирање низ надворешен диск.
- Conclusion about the performance gains: Комплексната корелација се извршува за 0.025 ms. Композитните индекси се подготвени да спречат деградација на перформансите во реално сценарио со континуиран стриминг на Sysmon логови.
Security measures
Application-level Security
- Prevention of SQL Injection: Introduction of parameterized queries and ORM abstractions in Flask backend layer to strictly split code and parameters.
- Prevention of Un-authorized Access: Implementation of custom decorators
@require_user()and@require_tenant_admin()to intercept endpoints and force strict validation.
Database-level Security
- Prevention of SQL Injection in Dynamic Queries: Avoiding the manual execution of raw string formatting (f-strings or %s concatenation). All dynamically evaluated filtering explicitly passes parameter tuples.
- Prevention of Un-authorized Access to Data: Multi-tenant structural architecture where every row manipulation isolates and constraints queries via a verified
tenant_id.
Other developments
JWT автентикација и авторизација
Системот користи JWT (JSON Web Token) за автентикација на корисниците по успешна Google најава.
Процесот се состои од следните чекори:
- Корисникот се најавува преку Google OAuth.
- Серверот го верификува Google токенот.
- Доколку најавата е успешна, серверот креира JWT токен кој содржи:
user_id,email,role,tenant_id. - JWT токенот се зачувува во HttpOnly cookie со име
session. - При секое наредно барање прелистувачот автоматски го испраќа cookie-то.
- Серверот го верификува JWT токенот и ги чита корисничките информации.
Креирање на JWT токен:
def make_jwt(payload: dict, minutes=60 * 24):
exp = datetime.utcnow() + timedelta(minutes=minutes)
data = {**payload, "iss": JWT_ISSUER, "exp": exp}
return jwt.encode(data, JWT_SECRET, algorithm="HS256")
Проверка на JWT токен:
def read_jwt(token: str):
return jwt.decode(
token,
JWT_SECRET,
algorithms=["HS256"],
issuer=JWT_ISSUER
)
Пристапот до заштитените API рути е овозможен преку декораторите @require_user и @require_tenant_admin.
@require_user()
def api_me():
...
CORS конфигурација
Бидејќи frontend апликацијата и Flask серверот работат на различни адреси, потребно е овозможување на Cross-Origin Resource Sharing (CORS).
Во системот е конфигурирана листа на дозволени домени:
DEFAULT_ORIGINS = [
"http://localhost:5173",
"http://127.0.0.1:5173",
]
Конфигурацијата се извршува преку Flask-CORS:
CORS(
app,
supports_credentials=True,
origins=ALLOWED_ORIGINS,
allow_headers=[
"Content-Type",
"X-Admin-Session",
"X-Env",
"X-Env-Token",
],
methods=["GET", "POST", "OPTIONS"],
)
- Се дозволуваат барања само од доверливи frontend адреси.
- Се дозволува испраќање на JWT cookie преку
supports_credentials=True. - Се ограничуваат HTTP методите на GET, POST и OPTIONS.
- Се контролира кои HTTP заглавија може да се испраќаат кон серверот.
Безбедносен модел
Системот користи повеќеслојна безбедност:
- Google OAuth за верификација на идентитетот.
- JWT токени за одржување на корисничка сесија.
- HttpOnly cookies за заштита од JavaScript пристап до токените.
- CORS политика за ограничување на дозволените клиентски апликации.
- Tenant изолација преку
tenant_id. - Посебни environment токени (
X-Env-Token) за комуникација помеѓу агентите и серверот.
Last modified
6 hours ago
Last modified on 07/07/26 18:53:08
Note:
See TracWiki
for help on using the wiki.
