- retention: ежедневный cron (03:17) + запуск на старте удаляет сырые
agent_stats_samples старше STATS_RETENTION_DAYS (по умолчанию 30);
lifetime-итоги на агенте и агрегаты сохраняются
- N+1 на поллинг-пути агента: evaluateAgentPolicy теперь делает по одному
батч-запросу на записи списков / резолвы hostname / имена списков вместо
запроса на каждое правило; mapPolicyRules и port-rules GET — аналогично
- пагинация: GET /agents, /lists, /rules, /install-links принимают
limit/offset и возвращают total; без параметров — прежнее поведение
- openapi.yaml: approve-bulk, PUT /policy-sets/{id}/agents, параметры
пагинации (redocly lint OK); тесты (47 passed)
968 lines
27 KiB
YAML
968 lines
27 KiB
YAML
openapi: 3.0.3
|
||
info:
|
||
title: EvoFirewall API
|
||
version: 0.2.0
|
||
description: |
|
||
Centralized firewall control plane.
|
||
|
||
**HTTP SoT:** this OpenAPI document.
|
||
**Runtime validation:** Zod schemas in `@evofw/shared` (authoritative for request bodies).
|
||
servers:
|
||
- url: http://localhost:8080
|
||
description: Local API
|
||
security: []
|
||
paths:
|
||
/health:
|
||
get:
|
||
summary: Liveness
|
||
tags: [system]
|
||
responses:
|
||
'200':
|
||
description: OK
|
||
|
||
/api/v1/dashboard:
|
||
get:
|
||
summary: Dashboard KPI
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Stats
|
||
|
||
/api/v1/install-context:
|
||
get:
|
||
summary: Public install base URL + enroll seed hint
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Install context
|
||
|
||
/api/v1/install-links:
|
||
get:
|
||
summary: List install links
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Links (items + total)
|
||
post:
|
||
summary: Create install link + invited agent
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'201':
|
||
description: Created
|
||
|
||
/api/v1/install-links/{id}:
|
||
delete:
|
||
summary: Revoke install link
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Revoked
|
||
|
||
/api/v1/agents:
|
||
get:
|
||
summary: List agents
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Agents (items + total)
|
||
|
||
/api/v1/agents/approve-bulk:
|
||
post:
|
||
summary: Approve many pending/invited agents in one request
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [agent_ids]
|
||
properties:
|
||
agent_ids:
|
||
type: array
|
||
maxItems: 1000
|
||
items: { type: string }
|
||
responses:
|
||
'200':
|
||
description: Approved agents (skips non-pending/invited)
|
||
|
||
/api/v1/agents/{id}:
|
||
get:
|
||
summary: Get agent
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Agent
|
||
patch:
|
||
summary: Update agent
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Updated
|
||
delete:
|
||
summary: Delete agent
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/agents/{id}/approve:
|
||
post:
|
||
summary: Approve pending/invited agent
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Approved
|
||
|
||
/api/v1/agents/{id}/revoke:
|
||
post:
|
||
summary: Revoke agent
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Revoked
|
||
|
||
/api/v1/agents/{id}/preview:
|
||
get:
|
||
summary: Policy preview (truncated CIDRs)
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
- name: limit_cidrs
|
||
in: query
|
||
schema: { type: integer, default: 50, maximum: 5000 }
|
||
responses:
|
||
'200':
|
||
description: Preview
|
||
|
||
/api/v1/agents/{id}/policy-sets:
|
||
get:
|
||
summary: Assigned policy sets
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Sets
|
||
put:
|
||
summary: Replace assigned policy sets (order = sort)
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Updated
|
||
|
||
/api/v1/agents/{id}/overrides:
|
||
get:
|
||
summary: List IP overrides
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Overrides
|
||
post:
|
||
summary: Create override
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Created
|
||
|
||
/api/v1/agents/{id}/overrides/{overrideId}:
|
||
delete:
|
||
summary: Delete override
|
||
tags: [agents]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
- name: overrideId
|
||
in: path
|
||
required: true
|
||
schema: { type: string }
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/lists:
|
||
get:
|
||
summary: List IP lists
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Lists (items + total)
|
||
post:
|
||
summary: Create IP list
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Created
|
||
|
||
/api/v1/lists/{id}:
|
||
get:
|
||
summary: List detail + entries
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Detail
|
||
delete:
|
||
summary: Delete list
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/lists/{id}/refresh:
|
||
post:
|
||
summary: Refresh remote/json/evobgp list
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Refreshed
|
||
|
||
/api/v1/lists/{id}/entries:
|
||
post:
|
||
summary: Add manual entries
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Updated
|
||
delete:
|
||
summary: Delete entry
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/policy-sets:
|
||
get:
|
||
summary: List policy sets
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Sets
|
||
post:
|
||
summary: Create policy set
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Created
|
||
|
||
/api/v1/policy-sets/{id}:
|
||
get:
|
||
summary: Get policy set
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Set
|
||
patch:
|
||
summary: Patch policy set
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Updated
|
||
delete:
|
||
summary: Delete policy set
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/policy-sets/{id}/rules:
|
||
get:
|
||
summary: Rules in set
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Rules
|
||
|
||
/api/v1/policy-sets/{id}/rules/reorder:
|
||
put:
|
||
summary: Reorder rules in a set
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Reordered
|
||
|
||
/api/v1/policy-sets/{id}/agents:
|
||
put:
|
||
summary: Replace which agents have this set assigned
|
||
description: >-
|
||
Listed agents gain the set (other assignments preserved), unlisted
|
||
agents lose it. Body — { agent_ids: string[] } (empty array clears).
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: '{ agent_ids, added, removed }'
|
||
'404':
|
||
description: Set or agent not found
|
||
|
||
/api/v1/rules:
|
||
get:
|
||
summary: List policy rules (optional set filter)
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Limit'
|
||
- $ref: '#/components/parameters/Offset'
|
||
responses:
|
||
'200':
|
||
description: Rules (items + total)
|
||
post:
|
||
summary: Create policy rule
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Created
|
||
|
||
/api/v1/rules/{id}:
|
||
patch:
|
||
summary: Patch rule
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Updated
|
||
delete:
|
||
summary: Delete rule
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/stats/recent:
|
||
get:
|
||
summary: Recent apply samples
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Samples
|
||
|
||
/api/v1/agents/{id}/stats:
|
||
get:
|
||
summary: Apply samples for one agent
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Samples
|
||
|
||
/api/v1/agents/{id}/stats/reset:
|
||
post:
|
||
summary: Reset packet totals, samples, and per-IP block stats
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Agent after reset
|
||
|
||
/api/v1/agents/{id}/blocked-ips:
|
||
get:
|
||
summary: Per-IP/CIDR drop counters (Linux nft/ipset; MikroTik HITS)
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Top blocked IPs by accumulated packets (+ optional top ports per IP on Linux)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [ip, packets, first_seen_at, last_seen_at]
|
||
properties:
|
||
ip: { type: string }
|
||
packets: { type: integer }
|
||
first_seen_at: { type: string, format: date-time }
|
||
last_seen_at: { type: string, format: date-time }
|
||
ports:
|
||
type: array
|
||
description: Top destination ports for this IP (Linux nft)
|
||
items:
|
||
type: object
|
||
required: [port, protocol, packets]
|
||
properties:
|
||
port: { type: integer, minimum: 1, maximum: 65535 }
|
||
protocol: { type: string, enum: [tcp, udp] }
|
||
packets: { type: integer }
|
||
|
||
/api/v1/agents/{id}/blocked-ports:
|
||
get:
|
||
summary: Aggregate destination ports hit by denied sources (Linux nft)
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Top ports by accumulated packets across all blocked IPs
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required: [port, protocol, packets, last_seen_at]
|
||
properties:
|
||
port: { type: integer, minimum: 1, maximum: 65535 }
|
||
protocol: { type: string, enum: [tcp, udp] }
|
||
packets: { type: integer }
|
||
last_seen_at: { type: string, format: date-time }
|
||
|
||
/api/v1/agents/{id}/port-rules:
|
||
get:
|
||
summary: Desired Port ACL rules (Linux)
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Port ACL rules
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/AgentPortRule'
|
||
post:
|
||
summary: Create Port ACL rule
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateAgentPortRule'
|
||
responses:
|
||
'200':
|
||
description: Created rule
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/AgentPortRule'
|
||
'400':
|
||
description: Validation / non-linux
|
||
|
||
/api/v1/agents/{id}/port-rules/import:
|
||
post:
|
||
summary: Import Port ACL from IP list or policy set sources
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [from, action, ports]
|
||
properties:
|
||
from: { type: string, enum: [list, set] }
|
||
list_id: { type: string }
|
||
set_id: { type: string }
|
||
action: { type: string, enum: [open, close] }
|
||
protocol: { type: string, enum: [tcp, udp, both], default: tcp }
|
||
ports:
|
||
type: array
|
||
minItems: 1
|
||
maxItems: 50
|
||
items:
|
||
type: object
|
||
required: [port_start]
|
||
properties:
|
||
port_start: { type: integer, minimum: 1, maximum: 65535 }
|
||
port_end: { type: integer, minimum: 1, maximum: 65535 }
|
||
enabled: { type: boolean, default: true }
|
||
comment: { type: string, maxLength: 500 }
|
||
responses:
|
||
'200':
|
||
description: Created rules
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/AgentPortRule'
|
||
|
||
/api/v1/agents/{id}/port-rules/{ruleId}:
|
||
patch:
|
||
summary: Update Port ACL rule
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
- name: ruleId
|
||
in: path
|
||
required: true
|
||
schema: { type: string }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdateAgentPortRule'
|
||
responses:
|
||
'200':
|
||
description: Updated rule
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/AgentPortRule'
|
||
delete:
|
||
summary: Delete Port ACL rule
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
- name: ruleId
|
||
in: path
|
||
required: true
|
||
schema: { type: string }
|
||
responses:
|
||
'200':
|
||
description: Deleted
|
||
|
||
/api/v1/agents/{id}/host-firewall:
|
||
get:
|
||
summary: Last observed host firewall snapshot (Linux)
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Snapshot (empty if never reported)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
collected_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
raw_digest:
|
||
type: string
|
||
nullable: true
|
||
rules:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/HostFwRule'
|
||
listeners:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/HostListener'
|
||
|
||
/api/v1/integrations/evobgp/communities:
|
||
get:
|
||
summary: Proxy EvoBGP communities
|
||
tags: [integrations]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Communities
|
||
|
||
/api/v1/settings:
|
||
get:
|
||
summary: Settings map (token masked)
|
||
tags: [settings]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Settings
|
||
put:
|
||
summary: Update whitelisted settings keys
|
||
tags: [settings]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
type: string
|
||
description: Keys — enroll_seed, evobgp_api_url, evobgp_api_token, agent_sync_interval_sec, show_quick_actions
|
||
responses:
|
||
'200':
|
||
description: Saved
|
||
'400':
|
||
description: Unknown key / validation
|
||
|
||
/api/v1/audit:
|
||
get:
|
||
summary: Local audit log
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- name: action
|
||
in: query
|
||
schema: { type: string }
|
||
- name: severity
|
||
in: query
|
||
schema: { type: string, enum: [info, warning, critical] }
|
||
- name: limit
|
||
in: query
|
||
schema: { type: integer, default: 200 }
|
||
responses:
|
||
'200':
|
||
description: Audit entries
|
||
|
||
/v1/agent/install.sh:
|
||
get:
|
||
summary: Agent install script
|
||
tags: [agent-public]
|
||
responses:
|
||
'200':
|
||
description: Shell script
|
||
|
||
/v1/agent/sync-script:
|
||
get:
|
||
summary: Linux sync agent (evofw-firewall.sh)
|
||
tags: [agent-public]
|
||
parameters:
|
||
- name: If-None-Match
|
||
in: header
|
||
schema: { type: string }
|
||
description: ETag from a previous GET (`"<sha256>"`)
|
||
responses:
|
||
'200':
|
||
description: Shell script
|
||
headers:
|
||
ETag:
|
||
schema: { type: string }
|
||
description: '"<sha256 of file bytes>"'
|
||
X-Evofw-Script-Sha256:
|
||
schema: { type: string }
|
||
description: Hex sha256 of the script body
|
||
'304':
|
||
description: Script unchanged
|
||
|
||
/v1/agent/enroll:
|
||
post:
|
||
summary: Enroll agent (X-EvoFW-Seed)
|
||
tags: [agent-public]
|
||
responses:
|
||
'201':
|
||
description: Pending agent
|
||
|
||
/v1/agent/policy:
|
||
get:
|
||
summary: Evaluated policy for agent
|
||
tags: [agent]
|
||
security: [{ agentToken: [] }]
|
||
responses:
|
||
'200':
|
||
description: Policy (includes script_sha256 for Linux self-update; not part of policy.hash)
|
||
|
||
/v1/agent/policy.rsc:
|
||
get:
|
||
summary: MikroTik RSC policy
|
||
tags: [agent]
|
||
security: [{ agentToken: [] }]
|
||
responses:
|
||
'200':
|
||
description: RSC text
|
||
|
||
/v1/agent/heartbeat:
|
||
post:
|
||
summary: Agent heartbeat
|
||
tags: [agent]
|
||
security: [{ agentToken: [] }]
|
||
responses:
|
||
'200':
|
||
description: OK
|
||
|
||
/v1/agent/apply-report:
|
||
post:
|
||
summary: Apply report + packet stats (+ optional ip_hits / port_hits / host_firewall)
|
||
tags: [agent]
|
||
security: [{ agentToken: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [status]
|
||
properties:
|
||
status: { type: string }
|
||
prefix_count: { type: integer }
|
||
packets_dropped: { type: integer }
|
||
packets_accepted: { type: integer }
|
||
kernel_method: { type: string }
|
||
error: { type: string }
|
||
source: { type: string }
|
||
ip_hits:
|
||
type: array
|
||
maxItems: 200
|
||
description: Linux per-element drop counters (packets > 0)
|
||
items:
|
||
type: object
|
||
required: [ip, packets]
|
||
properties:
|
||
ip: { type: string, maxLength: 64 }
|
||
packets: { type: integer, minimum: 0 }
|
||
port_hits:
|
||
type: array
|
||
maxItems: 500
|
||
description: Linux nft deny_port_hits (ip × proto × dport, packets > 0)
|
||
items:
|
||
type: object
|
||
required: [ip, port, protocol, packets]
|
||
properties:
|
||
ip: { type: string, maxLength: 64 }
|
||
port: { type: integer, minimum: 1, maximum: 65535 }
|
||
protocol: { type: string, enum: [tcp, udp] }
|
||
packets: { type: integer, minimum: 0 }
|
||
host_firewall:
|
||
$ref: '#/components/schemas/HostFirewallPayload'
|
||
responses:
|
||
'200':
|
||
description: OK
|
||
|
||
components:
|
||
parameters:
|
||
Id:
|
||
name: id
|
||
in: path
|
||
required: true
|
||
schema: { type: string }
|
||
Limit:
|
||
name: limit
|
||
in: query
|
||
schema: { type: integer, minimum: 1, maximum: 1000 }
|
||
description: Page size (without limit/offset the full list is returned)
|
||
Offset:
|
||
name: offset
|
||
in: query
|
||
schema: { type: integer, minimum: 0 }
|
||
description: Page offset (response includes total)
|
||
schemas:
|
||
AgentPortRule:
|
||
type: object
|
||
required:
|
||
[
|
||
id,
|
||
agent_id,
|
||
action,
|
||
protocol,
|
||
port_start,
|
||
port_end,
|
||
src_kind,
|
||
enabled,
|
||
priority,
|
||
created_at,
|
||
updated_at,
|
||
]
|
||
properties:
|
||
id: { type: string }
|
||
agent_id: { type: string }
|
||
action: { type: string, enum: [open, close] }
|
||
protocol: { type: string, enum: [tcp, udp, both] }
|
||
port_start: { type: integer, minimum: 1, maximum: 65535 }
|
||
port_end: { type: integer, minimum: 1, maximum: 65535 }
|
||
src_kind: { type: string, enum: [all, cidr, list] }
|
||
src_cidr: { type: string, nullable: true }
|
||
list_id: { type: string, nullable: true }
|
||
list_name: { type: string, nullable: true }
|
||
enabled: { type: boolean }
|
||
comment: { type: string, nullable: true }
|
||
priority: { type: integer }
|
||
created_at: { type: string, format: date-time }
|
||
updated_at: { type: string, format: date-time }
|
||
CreateAgentPortRule:
|
||
type: object
|
||
required: [action, port_start]
|
||
properties:
|
||
action: { type: string, enum: [open, close] }
|
||
protocol: { type: string, enum: [tcp, udp, both], default: tcp }
|
||
port_start: { type: integer, minimum: 1, maximum: 65535 }
|
||
port_end: { type: integer, minimum: 1, maximum: 65535 }
|
||
src_kind: { type: string, enum: [all, cidr, list], default: all }
|
||
src_cidr: { type: string }
|
||
list_id: { type: string }
|
||
enabled: { type: boolean, default: true }
|
||
comment: { type: string, maxLength: 500 }
|
||
priority: { type: integer, default: 100 }
|
||
UpdateAgentPortRule:
|
||
type: object
|
||
properties:
|
||
action: { type: string, enum: [open, close] }
|
||
protocol: { type: string, enum: [tcp, udp, both] }
|
||
port_start: { type: integer, minimum: 1, maximum: 65535 }
|
||
port_end: { type: integer, minimum: 1, maximum: 65535 }
|
||
src_kind: { type: string, enum: [all, cidr, list] }
|
||
src_cidr: { type: string, nullable: true }
|
||
list_id: { type: string, nullable: true }
|
||
enabled: { type: boolean }
|
||
comment: { type: string, maxLength: 500, nullable: true }
|
||
priority: { type: integer }
|
||
HostFwRule:
|
||
type: object
|
||
required: [ownership, backend, raw]
|
||
properties:
|
||
ownership: { type: string, enum: [evofw, foreign] }
|
||
backend:
|
||
type: string
|
||
enum: [nft, iptables, ufw, firewalld, listener]
|
||
table: { type: string }
|
||
chain: { type: string }
|
||
action: { type: string }
|
||
protocol: { type: string }
|
||
dport: { type: string }
|
||
sport: { type: string }
|
||
saddr: { type: string }
|
||
daddr: { type: string }
|
||
comment: { type: string }
|
||
raw: { type: string, maxLength: 512 }
|
||
HostListener:
|
||
type: object
|
||
required: [protocol, port, address]
|
||
properties:
|
||
protocol: { type: string }
|
||
port: { type: integer, minimum: 0, maximum: 65535 }
|
||
address: { type: string }
|
||
process: { type: string }
|
||
HostFirewallPayload:
|
||
type: object
|
||
properties:
|
||
rules:
|
||
type: array
|
||
maxItems: 500
|
||
items:
|
||
$ref: '#/components/schemas/HostFwRule'
|
||
listeners:
|
||
type: array
|
||
maxItems: 200
|
||
items:
|
||
$ref: '#/components/schemas/HostListener'
|
||
securitySchemes:
|
||
bearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
description: Portal JWT (app id fw)
|
||
agentToken:
|
||
type: http
|
||
scheme: bearer
|
||
description: Agent enroll token
|
||
|
||
tags:
|
||
- name: system
|
||
- name: ops
|
||
- name: agents
|
||
- name: lists
|
||
- name: policies
|
||
- name: settings
|
||
- name: integrations
|
||
- name: agent-public
|
||
- name: agent
|