feat(api, web): implement port ACL and host firewall snapshot features
- Added support for managing desired L4 port ACL rules for Linux agents, allowing for open/close actions on specified ports. - Introduced a new endpoint for CRUD operations on port rules, enhancing the API's capabilities for agent management. - Implemented functionality to collect and report host firewall snapshots, capturing observed rules and listeners for better monitoring. - Updated the agent detail view to include tabs for managing port ACLs and viewing host firewall data, improving user experience. - Enhanced documentation to reflect the new features and API changes, ensuring clarity for users and developers. These changes significantly improve the management and visibility of firewall rules and port access control for agents.
This commit is contained in:
+257
-1
@@ -457,6 +457,161 @@ paths:
|
||||
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
|
||||
@@ -557,7 +712,7 @@ paths:
|
||||
|
||||
/v1/agent/apply-report:
|
||||
post:
|
||||
summary: Apply report + packet stats (+ optional ip_hits / port_hits)
|
||||
summary: Apply report + packet stats (+ optional ip_hits / port_hits / host_firewall)
|
||||
tags: [agent]
|
||||
security: [{ agentToken: [] }]
|
||||
requestBody:
|
||||
@@ -597,6 +752,8 @@ paths:
|
||||
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
|
||||
@@ -608,6 +765,105 @@ components:
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user