commit 3fcbd91d2571e618a0cd956a14bf3afde402f1a8 Author: Tizian Maxime Weigt Date: Sat Feb 21 13:03:04 2026 +0000 README.md hinzugefügt diff --git a/README.md b/README.md new file mode 100644 index 0000000..1d8c78f --- /dev/null +++ b/README.md @@ -0,0 +1,4238 @@ +# TMW Shield On-Prem API Documentation + +## Api Authentication + +All API endpoints require authentication using a Bearer token + +**Header:** +``` +Authorization: Bearer YOUR_API_KEY +``` + +Invalid or missing tokens will result in a `401 Unauthorized` response + +--- + +## Swagger + +[Swagger Editor](https://editor.swagger.io/) + +## Base URL + +``` +http://{instance_ip}:8081/api/v2 +``` + +```yaml +openapi: 3.0.0 +info: + title: TMW Shield REST API v2 + +servers: + - url: http://{instance_ip}:8081/api/v2 + variables: + instance_ip: + default: 127.0.0.1 + description: IP address of the TMW Shield instance. + +components: + securitySchemes: + QueryKeyAuth: + type: apiKey + in: header + name: Authorization + description: Bearer token authentication + + schemas: + GenericError: + type: object + properties: + success: + type: boolean + example: false + error: + type: string + example: "Invalid request parameters" + GenericSuccess: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "Operation completed successfully" + BlacklistEntry: + type: object + properties: + src: + type: string + description: Source IP address or subnet + example: "192.168.1.100" + dst: + type: string + description: Destination IP address or subnet + example: "10.0.0.5" + direction: + type: string + enum: ["src", "dst", "both"] + description: Traffic direction to filter + example: "both" + type: + type: string + enum: ["IP", "Subnet"] + description: Entry type + example: "IP" + timestamp: + type: integer + format: int64 + description: Unix timestamp when entry was added + example: 1705900000 + BlacklistResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "Blacklist entry created" + data: + type: array + items: + $ref: '#/components/schemas/BlacklistEntry' + WhitelistEntry: + type: object + properties: + src: + type: string + description: Source IP address or subnet + example: "192.168.1.100" + dst: + type: string + description: Destination IP address or subnet + example: "10.0.0.5" + direction: + type: string + enum: ["src", "dst", "both"] + description: Traffic direction to filter + example: "both" + type: + type: string + enum: ["IP", "Subnet"] + description: Entry type + example: "IP" + timestamp: + type: integer + format: int64 + description: Unix timestamp when entry was added + example: 1705900000 + WhitelistResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "Whitelist entry created" + data: + type: array + items: + $ref: '#/components/schemas/WhitelistEntry' + ProtocolEntry: + type: object + properties: + dst: + type: string + description: Destination IP address + example: "10.0.0.5" + protocol: + type: integer + minimum: 0 + maximum: 255 + description: Protocol number (e.g., 6 for TCP, 17 for UDP) + example: 17 + timestamp: + type: integer + format: int64 + description: Unix timestamp when entry was added + example: 1705900000 + ProtocolResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "Protocol allow entry created" + data: + type: array + items: + $ref: '#/components/schemas/ProtocolEntry' + ServicePortEntry: + type: object + properties: + interface: + type: string + description: Network interface name + example: "eth0" + ports: + type: array + items: + type: integer + minimum: 1 + maximum: 65535 + description: List of service ports + example: [22, 80, 443, 8080] + ServicePortResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "Service port added" + data: + type: array + items: + $ref: '#/components/schemas/ServicePortEntry' + VLANEntry: + type: object + properties: + interface: + type: string + description: Network interface name + example: "eth0" + vlans: + type: array + items: + type: integer + minimum: 0 + maximum: 4095 + description: List of VLAN IDs + example: [100, 200, 300] + VLANResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: "VLAN bypass added" + data: + type: array + items: + $ref: '#/components/schemas/VLANEntry' + StatsLiveResponse: + type: object + properties: + counters: + type: object + current: + type: object + validated: + type: object + StatsPerIPResponse: + type: object + properties: + list: + type: array + items: + type: object + StatsAggregatedResponse: + type: object + properties: + allowed: + type: array + items: + type: integer + dropped: + type: array + items: + type: integer + validated: + type: array + items: + type: integer + activeProtections: + type: array + sentProtections: + type: array + activeAttacks: + type: array + AttacksResponse: + type: object + properties: + success: + type: boolean + attacks: + type: array + items: + type: object + AttacksHistoryResponse: + type: object + properties: + success: + type: boolean + attacks: + type: array + items: + type: object + LogsResponse: + type: object + properties: + success: + type: boolean + activeProtections: + type: array + sentProtections: + type: array + StatusResponse: + type: object + properties: + status: + type: string + example: "ok" + WebhookEntry: + type: object + properties: + target: + type: string + example: "192.168.1.100" + url: + type: string + example: "https://example.com/webhook" + WebhookResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + webhooks: + type: object + EmailEntry: + type: object + properties: + target: + type: string + example: "192.168.1.100" + email: + type: string + example: "admin@example.com" + EmailResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + emails: + type: array + items: + $ref: '#/components/schemas/EmailEntry' + SMTPConfig: + type: object + properties: + server: + type: string + example: "smtp.example.com" + port: + type: integer + example: 587 + user: + type: string + example: "smtp_user" + pass: + type: string + example: "smtp_password" + from: + type: string + example: "shield@example.com" + SMTPResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + CheckIPRequest: + type: object + properties: + ip: + type: string + example: "198.51.100.7" + CheckIPResponse: + type: object + properties: + ip: + type: string + blocked: + type: boolean + source: + type: string + ClusterStatusResponse: + type: object + properties: + in_cluster: + type: boolean + node_id: + type: string + status: + type: string + active_nodes: + type: integer + messages_sent: + type: integer + messages_received: + type: integer + ClusterNodesResponse: + type: object + properties: + in_cluster: + type: boolean + total_nodes: + type: integer + nodes: + type: array + items: + type: object + ClusterJoinRequest: + type: object + properties: + seed: + type: string + example: "192.168.1.10:5555" + ClusterSyncRequest: + type: object + properties: + node: + type: string + AbuseIPDBEntry: + type: object + properties: + src: + type: string + example: "198.51.100.7" + AbuseIPDBResponse: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + AbuseIPDBListResponse: + type: object + properties: + success: + type: boolean + blocked_ips: + type: array + items: + type: object + enabled_destinations: + type: array + items: + type: object + AbuseIPDBConfigRequest: + type: object + properties: + dst: + type: string + example: "10.0.0.1" + enable: + type: boolean + example: true + + security: + - QueryKeyAuth: [] + +paths: + /blacklists: + get: + summary: List Blacklist Entries + description: Retrieves all blacklist entries across all interfaces + security: + - QueryKeyAuth: [] + responses: + "200": + description: Blacklist entries retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/BlacklistResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Create Blacklist Entry + description: Creates a new blacklist entry for blocking traffic + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - src + - dst + properties: + src: + type: string + description: Source IP address or subnet + example: "192.168.1.100" + dst: + type: string + description: Destination IP address or subnet + example: "10.0.0.5" + direction: + type: string + enum: ["src", "dst", "both"] + default: "both" + description: Traffic direction to filter + example: "both" + responses: + "201": + description: Blacklist entry created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove Blacklist Entry + description: Removes a blacklist entry + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - src + - dst + properties: + src: + type: string + description: Source IP address or subnet + example: "192.168.1.100" + dst: + type: string + description: Destination IP address or subnet + example: "10.0.0.5" + responses: + "204": + description: Blacklist entry removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Entry does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /whitelists: + get: + summary: List Whitelist Entries + description: Retrieves all whitelist entries across all interfaces + security: + - QueryKeyAuth: [] + responses: + "200": + description: Whitelist entries retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/WhitelistResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Create Whitelist Entry + description: Creates a new whitelist entry for allowing traffic + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - src + - dst + properties: + src: + type: string + description: Source IP address or subnet + example: "192.168.1.100" + dst: + type: string + description: Destination IP address or subnet + example: "10.0.0.5" + direction: + type: string + enum: ["src", "dst", "both"] + default: "both" + description: Traffic direction to filter + example: "both" + responses: + "201": + description: Whitelist entry created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove Whitelist Entry + description: Removes a whitelist entry + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - src + - dst + properties: + src: + type: string + description: Source IP address or subnet + example: "192.168.1.100" + dst: + type: string + description: Destination IP address or subnet + example: "10.0.0.5" + responses: + "204": + description: Whitelist entry removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Entry does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /protocols: + get: + summary: List Protocol Allow Entries + description: Retrieves all protocol allow entries across all interfaces + security: + - QueryKeyAuth: [] + responses: + "200": + description: Protocol allow entries retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ProtocolResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Create Protocol Allow Entry + description: Creates a new protocol allow entry for specific destination + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - dst + - protocol + properties: + dst: + type: string + description: Destination IP address + example: "10.0.0.5" + protocol: + type: integer + minimum: 0 + maximum: 255 + description: Protocol number (e.g., 6 for TCP, 17 for UDP) + example: 17 + responses: + "201": + description: Protocol allow entry created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove Protocol Allow Entry + description: Removes a protocol allow entry + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - dst + - protocol + properties: + dst: + type: string + description: Destination IP address + example: "10.0.0.5" + protocol: + type: integer + minimum: 0 + maximum: 255 + description: Protocol number (e.g., 6 for TCP, 17 for UDP) + example: 17 + responses: + "204": + description: Protocol allow entry removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Entry does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /service-ports: + get: + summary: List Service Ports + description: Retrieves all service ports across all interfaces + security: + - QueryKeyAuth: [] + responses: + "200": + description: Service ports retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ServicePortResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Add Service Port + description: Adds a new service port for monitoring + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - port + properties: + port: + type: integer + minimum: 1 + maximum: 65535 + description: Port number to add + example: 8080 + responses: + "201": + description: Service port added successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove Service Port + description: Removes a service port + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - port + properties: + port: + type: integer + minimum: 1 + maximum: 65535 + description: Port number to remove + example: 8080 + responses: + "204": + description: Service port removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Port does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /vlans: + get: + summary: List VLAN Bypass Entries + description: Retrieves all VLAN bypass entries across all interfaces + security: + - QueryKeyAuth: [] + responses: + "200": + description: VLAN bypass entries retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/VLANResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Add VLAN Bypass Entry + description: Adds a new VLAN bypass for traffic + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - vlan + properties: + vlan: + type: integer + minimum: 0 + maximum: 4095 + description: VLAN ID to bypass + example: 100 + responses: + "201": + description: VLAN bypass added successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove VLAN Bypass Entry + description: Removes a VLAN bypass entry + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - vlan + properties: + vlan: + type: integer + minimum: 0 + maximum: 4095 + description: VLAN ID to remove + example: 100 + responses: + "204": + description: VLAN bypass removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - VLAN does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /stats/live: + get: + summary: Get Live Traffic Statistics + description: Retrieves current live traffic statistics and counters + security: + - QueryKeyAuth: [] + responses: + "200": + description: Live statistics retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/StatsLiveResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /stats/per-ip: + get: + summary: Get Per-IP Statistics + description: Retrieves traffic statistics for specific IP addresses + security: + - QueryKeyAuth: [] + parameters: + - name: ip + in: query + description: Filter for a specific IP address + required: false + schema: + type: string + example: "203.0.113.5" + responses: + "200": + description: Per-IP statistics retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/StatsPerIPResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /stats/aggregated: + get: + summary: Get Aggregated Historical Statistics + description: Retrieves aggregated historical traffic statistics + security: + - QueryKeyAuth: [] + parameters: + - name: range + in: query + description: Time range for aggregated data + required: false + schema: + type: string + enum: ["1m", "1h", "1d", "week", "quarter"] + example: "1h" + responses: + "200": + description: Aggregated statistics retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/StatsAggregatedResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /attacks: + get: + summary: List Current Active Attacks + description: Retrieves currently active attack information + security: + - QueryKeyAuth: [] + responses: + "200": + description: Active attacks retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AttacksResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /attacks/history: + get: + summary: Get Attack History + description: Retrieves historical attack data for specific IP + security: + - QueryKeyAuth: [] + parameters: + - name: ip + in: query + description: Filter for a specific IP address + required: false + schema: + type: string + example: "203.0.113.5" + responses: + "200": + description: Attack history retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AttacksHistoryResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /logs: + get: + summary: Get System Logs + description: Retrieves system and security logs + security: + - QueryKeyAuth: [] + responses: + "200": + description: System logs retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/LogsResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /status: + get: + summary: Get System Status + description: Retrieves current TMW Shield system status and configuration + security: + - QueryKeyAuth: [] + responses: + "200": + description: System status retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/StatusResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /abuseipdb: + get: + summary: List AbuseIPDB Blocked IPs + description: Retrieves all AbuseIPDB blocklist entries + security: + - QueryKeyAuth: [] + responses: + "200": + description: AbuseIPDB list retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AbuseIPDBListResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Add IP to AbuseIPDB Blocklist + description: Adds an IP to the AbuseIPDB blocklist + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - src + properties: + src: + type: string + description: Source IP address to block + example: "198.51.100.7" + responses: + "201": + description: IP added to blocklist successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AbuseIPDBResponse' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove IP from AbuseIPDB Blocklist + description: Removes an IP from the AbuseIPDB blocklist + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - src + properties: + src: + type: string + description: Source IP address to unblock + example: "198.51.100.7" + responses: + "204": + description: IP removed from blocklist successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AbuseIPDBResponse' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - IP does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /abuseipdb/config: + get: + summary: List AbuseIPDB Enabled Destinations + description: Retrieves all destinations with AbuseIPDB check enabled + security: + - QueryKeyAuth: [] + responses: + "200": + description: AbuseIPDB config retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AbuseIPDBListResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Enable AbuseIPDB Check for Destination + description: Enables AbuseIPDB check for a destination IP + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - dst + - enable + properties: + dst: + type: string + description: Destination IP address + example: "10.0.0.1" + enable: + type: boolean + description: Enable or disable check + example: true + responses: + "201": + description: AbuseIPDB check configured successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AbuseIPDBResponse' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Disable AbuseIPDB Check for Destination + description: Disables AbuseIPDB check for a destination IP + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - dst + properties: + dst: + type: string + description: Destination IP address + example: "10.0.0.1" + responses: + "204": + description: AbuseIPDB check disabled successfully + content: + application/json: + schema: + $ref: '#/components/schemas/AbuseIPDBResponse' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Destination not configured + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /webhooks: + get: + summary: List Webhooks + description: Retrieves all configured webhooks + security: + - QueryKeyAuth: [] + responses: + "200": + description: Webhooks retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Add Webhook + description: Adds a new webhook for attack notifications + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - target + - url + properties: + target: + type: string + description: Target IP, CIDR, or * for all + example: "192.168.1.100" + url: + type: string + description: Webhook URL + example: "https://example.com/webhook" + responses: + "201": + description: Webhook added successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove Webhook + description: Removes a webhook + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - target + - url + properties: + target: + type: string + description: Target IP or CIDR + example: "192.168.1.100" + url: + type: string + description: Webhook URL to remove + example: "https://example.com/webhook" + responses: + "204": + description: Webhook removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Webhook does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /emails: + get: + summary: List Email Notifications + description: Retrieves all configured email notifications + security: + - QueryKeyAuth: [] + responses: + "200": + description: Email notifications retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmailResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Add Email Notification + description: Adds a new email notification for attacks + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - target + - email + properties: + target: + type: string + description: Target IP or CIDR + example: "192.168.1.100" + email: + type: string + description: Email address + example: "admin@example.com" + responses: + "201": + description: Email notification added successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + delete: + summary: Remove Email Notification + description: Removes an email notification + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - target + - email + properties: + target: + type: string + description: Target IP or CIDR + example: "192.168.1.100" + email: + type: string + description: Email address to remove + example: "admin@example.com" + responses: + "204": + description: Email notification removed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "404": + description: Not found - Email notification does not exist + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /smtp: + get: + summary: Get SMTP Configuration + description: Retrieves the SMTP server configuration + security: + - QueryKeyAuth: [] + responses: + "200": + description: SMTP configuration retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/SMTPConfig' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + post: + summary: Configure SMTP + description: Configures the SMTP server settings + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - server + - port + - user + - pass + - from + properties: + server: + type: string + description: SMTP server hostname + example: "smtp.example.com" + port: + type: integer + description: SMTP port + example: 587 + user: + type: string + description: SMTP username + example: "smtp_user" + pass: + type: string + description: SMTP password + example: "smtp_password" + from: + type: string + description: From email address + example: "shield@example.com" + responses: + "201": + description: SMTP configured successfully + content: + application/json: + schema: + $ref: '#/components/schemas/SMTPResponse' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /check-ip: + post: + summary: Check IP Threat + description: Checks an IP address for threats + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - ip + properties: + ip: + type: string + description: IP address to check + example: "198.51.100.7" + responses: + "200": + description: IP check completed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/CheckIPResponse' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /cluster/status: + get: + summary: Get Cluster Status + description: Retrieves current cluster membership status and statistics + security: + - QueryKeyAuth: [] + responses: + "200": + description: Cluster status retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterStatusResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /cluster/nodes: + get: + summary: List Cluster Nodes + description: Retrieves all nodes in the cluster + security: + - QueryKeyAuth: [] + responses: + "200": + description: Cluster nodes retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterNodesResponse' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /cluster/join: + post: + summary: Join Cluster + description: Joins the node to an existing cluster via a seed node + security: + - QueryKeyAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterJoinRequest' + example: + seed: "192.168.1.10:5555" + responses: + "200": + description: Successfully joined cluster + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "409": + description: Conflict - Already in a cluster + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /cluster/leave: + post: + summary: Leave Cluster + description: Gracefully leaves the current cluster + security: + - QueryKeyAuth: [] + responses: + "200": + description: Successfully left cluster + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Not in a cluster + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + + /cluster/sync: + post: + summary: Trigger Cluster Sync + description: Requests full state synchronization from all nodes or a specific node + security: + - QueryKeyAuth: [] + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/ClusterSyncRequest' + example: + node: "b2c3d4e5-f6a7-8901-bcde-f23456789012" + responses: + "200": + description: Sync requested successfully + content: + application/json: + schema: + $ref: '#/components/schemas/GenericSuccess' + "400": + description: Bad request - Invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "401": + description: Unauthorized - Invalid or missing API key + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' + "500": + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/GenericError' +``` + +--- + +## Quick Examples + +### Check Status + +```bash +curl -H "Authorization: Bearer YOUR_KEY" http://localhost:8081/api/v2/status +``` + +### Blacklist IP + +```bash +curl -X POST -H "Authorization: Bearer YOUR_KEY" \ + -H "Content-Type: application/json" \ + -d '{"src":"1.2.3.4","dst":"5.6.7.8","direction":"both"}' \ + "http://localhost:8081/api/v2/blacklists" +``` + +### Statistics & Monitoring + +```bash +# Get live statistics +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/stats/live" + +# Get per-IP statistics +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/stats/per-ip?ip=203.0.113.5" + +# Get aggregated statistics +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/stats/aggregated?range=1h" + +# Get current attacks +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/attacks" + +# Get attack history +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/attacks/history?ip=203.0.113.5" + +# Get system logs +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/logs" + +# Get system status +curl -X GET -H "Authorization: Bearer YOUR_KEY" \ + "http://localhost:8081/api/v2/status" +``` + +--- + +# API Endpoints + +--- + +## 1. Instance Status + +### GET /api/v2/status + +Retrieves the current TMW Shield instance status. + +**Request:** + +```bash +curl -H "Authorization: Bearer YOUR_KEY" http://127.0.0.1:8081/api/v2/status +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "status": "ok" +} +``` + +**Possible Status Values:** + +- `ok` - Instance running normally +- `degraded` - Reduced functionality +- `error` - Error present + +--- + +## 2. Statistics + +### GET /api/stats/live + +Retrieves global real-time statistics including cumulative counters, current PPS rates, and validation statistics. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/stats/live +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "counters": { + "syn_received": 123456, + "syn_dropped": 1234, + "syn_allowed": 122222, + "syn_cookies_sent": 500, + "ack_packets_dropped": 50, + "ack_validated": 450, + "syn_ack_blocked": 10, + "unsolicited_syn_ack_blocked": 5, + "rst_blocked": 2, + "fin_blocked": 1, + "ip_whitelist_passed": 1000, + "udp_allowed": 50000, + "udp_blocked": 500, + "icmp_allowed": 100, + "icmp_blocked": 20, + "gre_allowed": 0, + "gre_blocked": 0, + "amp_allowed": 0, + "amp_blocked": 0, + "carpet_udp_blocked": 0, + "carpet_syn_blocked": 0, + "carpet_icmp_blocked": 0, + "fragments_blocked": 0 + }, + "current": { + "dropped_pps": 120, + "allowed_pps": 4500, + "validated_pps": 150 + }, + "validated": { + "syn_cookies_sent": 40, + "ack_validated": 100, + "ip_whitelist_passed": 10 + } +} +``` + +**Response Schema:** + +| Field | Type | Description | +| ----------------------------- | ------- | --------------------------------------------- | +| `counters` | object | Cumulative counters since system start | +| `counters.syn_received` | integer | All received SYN packets | +| `counters.syn_dropped` | integer | All dropped SYN packets | +| `counters.syn_allowed` | integer | All allowed SYN packets | +| `counters.syn_cookies_sent` | integer | All sent SYN cookies | +| `counters.ack_validated` | integer | All validated ACK packets | +| `counters.udp_blocked` | integer | All blocked UDP packets | +| `counters.ip_whitelist_passed`| integer | Packets that passed IP whitelist | +| `current` | object | Current packets per second rates | +| `current.dropped_pps` | integer | Current dropped packets/second | +| `current.allowed_pps` | integer | Current allowed packets/second | +| `current.validated_pps` | integer | Current validated packets/second | +| `validated` | object | Short-term validation statistics | + +--- + +### GET /api/stats/aggregated + +Retrieves aggregated statistics over a specific time range. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/stats/aggregated?range=1h' +``` + +**Query Parameter:** + +| Parameter | Type | Required | Description | Default | +| --------- | ------ | -------- | -------------------------------------------------------------------- | ------- | +| `range` | string | No | Time range: `1m`, `min`, `1h`, `hour`, `1d`, `day`, `month`, `week`, `quarter` | `1h` | + +**Range Details:** + +| Value | Meaning | Data Points | +| ---------------------- | ------------------ | ---------------------- | +| `1m`, `min` | Last 60 minutes | 60 points (1 min each) | +| `1h`, `hour` | Last 24 hours | 24 points (1 hour each) | +| `1d`, `day`, `month` | Last 30 days | 30 points (1 day each) | +| `week` | Last 7 days | 7 points (1 day each) | +| `quarter` | Last 90 days | 90 points (1 day each) | + +**Response (200 OK):** + +```json +{ + "allowed": [12, 10, 15, 8, 20], + "dropped": [0, 1, 0, 2, 1], + "validated": [8, 7, 9, 5, 11], + "activeProtections": [], + "sentProtections": [], + "activeAttacks": [], + "note": "Less than 90 days available" +} +``` + +**Response Schema:** + +| Field | Type | Description | +| -------------------- | ---------------- | ------------------------------------------------ | +| `allowed` | array[integer] | Allowed packets per time interval | +| `dropped` | array[integer] | Dropped packets per time interval | +| `validated` | array[integer] | Validated packets per time interval | +| `activeProtections` | array | Current protection measures | +| `sentProtections` | array | Sent webhooks | +| `activeAttacks` | array | Active attacks | +| `note` | string | _(optional)_ Notes (e.g., for incomplete data) | + +--- + +### GET /api/stats/per-ip + +Retrieves detailed statistics per protected source IP. This endpoint shows both current packets per second (pps) and cumulative total counters. + +**Request:** + +```bash +# Get all IPs +curl http://127.0.0.1:8081/api/stats/per-ip + +# Get only a specific IP +curl http://127.0.0.1:8081/api/stats/per-ip?ip=1.2.3.4 +``` + +**Query Parameter:** + +| Parameter | Type | Required | Description | +| --------- | ------ | -------- | -------------------------------------------------------- | +| `ip` | string | No | Filters the output for a specific IPv4 address. | + +**Response (200 OK):** + +```json +[ + { + "ip": "203.0.113.5", + "pps": { + "tcp_received": 100, + "udp_received": 50, + "icmp_received": 0, + "gre_received": 0, + "syn_received": 10, + "syn_allowed": 10, + "syn_dropped": 0, + "ack_received": 80, + "ack_validated": 80, + "ack_dropped": 0, + "syn_ack_blocked": 0, + "unsolicited_syn_ack_blocked": 0, + "unsolicited_syn_ack_allowed": 0, + "rst_blocked": 0, + "rst_allowed": 0, + "fin_blocked": 0, + "fin_allowed": 0, + "psh_flood_blocked": 0, + "urg_blocked": 0, + "tcp_invalid_flags_blocked": 0, + "udp_blocked": 0, + "udp_new_ip_blocked": 0, + "icmp_blocked": 0, + "gre_blocked": 0, + "gre_new_ip_blocked": 0, + "amp_blocked": 0, + "fragments_blocked": 0, + "malformed_packets": 0, + "rate_limited": 0, + "ip_blacklist_dropped": 0, + "carpet_udp_blocked": 0, + "carpet_syn_blocked": 0, + "carpet_syn_ack_blocked": 0, + "carpet_amp_blocked": 0, + "carpet_icmp_blocked": 0, + "udp_allowed": 50, + "icmp_allowed": 0, + "gre_allowed": 0, + "fragments_allowed": 0, + "tcp_dropped": 0, + "udp_dropped": 0, + "icmp_dropped": 0, + "gre_dropped": 0, + "total_dropped": 0, + "total_allowed": 150 + }, + "total": { + "syn_received": 1234, + "ack_received": 5678, + "udp_blocked": 12, + "icmp_blocked": 0, + "gre_blocked": 0, + "total_dropped": 12, + "total_allowed": 100000 + } + } +] +``` + +**Response Schema (Array Items):** + +| Field | Type | Description | +| --------------------- | ------- | ----------------------------------------------------- | +| `ip` | string | Source IPv4 address | +| `pps` | object | Current statistics (Deltas/Second) | +| `pps.tcp_received` | integer | Received TCP packets | +| `pps.udp_received` | integer | Received UDP packets | +| `pps.syn_received` | integer | Received SYN packets | +| `pps.syn_allowed` | integer | Allowed SYN packets | +| `pps.syn_dropped` | integer | Dropped SYN packets | +| `pps.ack_validated` | integer | Validated ACK packets | +| `pps.udp_blocked` | integer | Blocked UDP packets | +| `pps.total_dropped` | integer | Total dropped packets | +| `pps.total_allowed` | integer | Total allowed packets | +| `total` | object | Cumulative total counters (since recording started) | +| `total.syn_received` | integer | Total received SYN packets | +| `total.total_dropped` | integer | Total dropped packets | +| `total.total_allowed` | integer | Total allowed packets | + +--- + +## 3. Blacklist Management + +### GET /api/blacklist/add + +Adds a blacklist entry. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/blacklist/add?src=1.2.3.4&dst=5.6.7.8&direction=both' +``` + +**Query Parameter:** + +| Parameter | Type | Required | Description | Range | +| ----------- | ------ | -------- | ------------------------------- | -------------------- | +| `src` | string | Yes | Source IP address or CIDR block | IPv4 format | +| `dst` | string | Yes | Destination IP address or CIDR block | IPv4 format | +| `direction` | string | No | Filter direction | `src`, `dst`, `both` | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Added to blacklist" +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "Invalid IP address format" +} +``` + +--- + +### GET /api/blacklist/remove + +Removes a blacklist entry. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/blacklist/remove?src=1.2.3.4&dst=5.6.7.8' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ---------------- | +| `src` | string | Yes | Source-IP-Adresse | +| `dst` | string | Yes | Destination-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Removed from blacklist" +} +``` + +--- + +### GET /api/blacklist/list + +Lists all blacklist entries. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/blacklist/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "blacklist_entries": [ + { + "src": "1.2.3.4", + "dst": "5.6.7.8", + "direction": "both", + "type": "IP", + "interfaces": ["eth0"] + } + ] +} +``` + +**Response Schema (Array Items):** + +| Feld | Type | Description | +| ------------ | ------------- | -------------------------------- | +| `src` | string | Source-IP/CIDR | +| `dst` | string | Destination-IP/CIDR | +| `direction` | string | Filter direction | +| `type` | string | Entry type (usually `IP`) | +| `interfaces` | array[string] | Affected network interfaces | + +--- + +## 4. Whitelist Management + +### GET /api/whitelist/add + +Adds a whitelist entry. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/whitelist/add?src=192.168.1.0&dst=10.0.0.0/24&direction=src' +``` + +**Query Parameter:** + +| Parameter | Type | Required | Description | +| ----------- | ------ | -------- | ----------------------------------- | +| `src` | string | Yes | Source IP address or CIDR block | +| `dst` | string | Yes | Destination IP address or CIDR block | +| `direction` | string | No | Filter direction (`src`, `dst`, `both`) | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Added to whitelist" +} +``` + +--- + +### GET /api/whitelist/remove + +Removes a whitelist entry. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/whitelist/remove?src=192.168.1.0&dst=10.0.0.0/24' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ---------------- | +| `src` | string | Yes | Source-IP-Adresse | +| `dst` | string | Yes | Destination-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Removed from whitelist" +} +``` + +--- + +### GET /api/whitelist/list + +Lists all whitelist entries. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/whitelist/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "whitelist_entries": [ + { + "src": "192.168.1.0", + "dst": "10.0.0.0/24", + "direction": "src", + "type": "IP", + "interfaces": ["eth0", "eth1"] + } + ] +} +``` + +**Response Schema (Array Items):** + +| Feld | Type | Description | +| ------------ | ------------- | ------------------------------ | +| `src` | string | Source-IP/CIDR | +| `dst` | string | Destination-IP/CIDR | +| `direction` | string | Filter direction | +| `type` | string | Eintragstyp | +| `interfaces` | array[string] | Affected network interfaces | + +--- + +## 5. Protocol Allow (IP/Proto Management) + +### GET /api/protocol_allow/add + +Allows a network protocol for a destination IP. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/protocol_allow/add?dst=10.0.0.5&proto=6' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------- | ------------ | --------------------- | +| `dst` | string | Yes | Destination-IP-Adresse | +| `proto` | integer | Yes | IANA protocol number | + +**Common Protocol Numbers:** + +| Number | Name | Description | +| ------ | ---- | --------------------------------- | +| 1 | ICMP | Internet Control Message Protocol | +| 6 | TCP | Transmission Control Protocol | +| 17 | UDP | User Datagram Protocol | +| 47 | GRE | Generic Routing Encapsulation | +| 41 | IPv6 | IPv6 Encapsulation | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Protocol allowed", + "added_on": 1 +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "failed to add protocol allow" +} +``` + +--- + +### GET /api/protocol_allow/remove + +Removes a protocol from the allow list. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/protocol_allow/remove?dst=10.0.0.5&proto=6' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------- | ------------ | --------------------- | +| `dst` | string | Yes | Destination-IP-Adresse | +| `proto` | integer | Yes | IANA protocol number | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Protocol removed" +} +``` + +--- + +### GET /api/protocol_allow/list + +Lists all allowed protocols. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/protocol_allow/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "protocol_allow_entries": [ + { + "dst": "10.0.0.5", + "proto": 6, + "interfaces": ["eth0"] + }, + { + "dst": "10.0.0.10", + "proto": 17, + "interfaces": ["eth0", "eth1"] + } + ] +} +``` + +**Response Schema (Array Items):** + +| Feld | Type | Description | +| ------------ | ------------- | ------------------------------ | +| `dst` | string | Destination-IP-Adresse | +| `proto` | integer | IANA protocol number | +| `interfaces` | array[string] | Affected network interfaces | + +--- + +## 6. VLAN Bypass + +### GET /api/bypass_vlan/add + +Enables VLAN bypass for a VLAN ID (bypasses protection for this VLAN). + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/bypass_vlan/add?vlan=100' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | Range | +| --------- | ------- | ------------ | ------------------- | ------------ | +| `vlan` | integer | Yes | VLAN-Identifikation | 0-4095 | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "VLAN bypass added", + "enabled_on": 1 +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "failed to enable vlan bypass" +} +``` + +--- + +### GET /api/bypass_vlan/remove + +Disables VLAN bypass for a VLAN ID. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/bypass_vlan/remove?vlan=100' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------- | ------------ | ------------------- | +| `vlan` | integer | Yes | VLAN-Identifikation | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "VLAN bypass removed" +} +``` + +--- + +### GET /api/bypass_vlan/list + +Lists all VLAN bypass entries. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/bypass_vlan/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "bypass_vlan_entries": [ + { + "vlan": 100, + "interfaces": ["eth0", "eth0.100"] + }, + { + "vlan": 200, + "interfaces": ["eth0", "eth0.200"] + } + ] +} +``` + +**Response Schema (Array Items):** + +| Feld | Type | Description | +| ------------ | ------------- | ------------------------------ | +| `vlan` | integer | VLAN-Identifikation | +| `interfaces` | array[string] | Affected network interfaces | + +--- + +## 7. AbuseIPDB Integration + +### GET /api/abuseipdb/enable + +Enables AbuseIPDB check for a destination IP. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/abuseipdb/enable?dst=10.0.0.1' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | --------------- | +| `dst` | string | Yes | Destination-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "enabled_on": 1 +} +``` + +--- + +### GET /api/abuseipdb/disable + +Disables AbuseIPDB check for a destination IP. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/abuseipdb/disable?dst=10.0.0.1' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | --------------- | +| `dst` | string | Yes | Destination-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "AbuseIPDB disabled" +} +``` + +--- + +### GET /api/abuseipdb/add + +Adds an IP to the AbuseIPDB blocklist. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/abuseipdb/add?src=198.51.100.7' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ---------------- | +| `src` | string | Yes | Source-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "IP added to AbuseIPDB blocklist", + "added_on": 1 +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "failed to add IP to abuseipdb" +} +``` + +--- + +### GET /api/abuseipdb/remove + +Removes an IP from the AbuseIPDB blocklist. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/abuseipdb/remove?src=198.51.100.7' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ---------------- | +| `src` | string | Yes | Source-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "IP removed from AbuseIPDB blocklist" +} +``` + +--- + +### GET /api/abuseipdb/clear + +Deletes all AbuseIPDB entries (blocklist and destinations). + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/abuseipdb/clear +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "AbuseIPDB entries cleared" +} +``` + +--- + +### GET /api/abuseipdb/list + +Lists all AbuseIPDB configurations. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/abuseipdb/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "blocked_ips": [ + { + "ip": "198.51.100.7", + "interfaces": ["eth0"] + } + ], + "enabled_destinations": [ + { + "ip": "10.0.0.1", + "interfaces": ["eth0"] + } + ] +} +``` + +**Response Schema:** + +| Field | Type | Description | +| ---------------------- | ----- | ------------------------------------------- | +| `blocked_ips` | array | IPs on AbuseIPDB blocklist | +| `enabled_destinations` | array | Destinations with AbuseIPDB check enabled | + +--- + +## 8. IP Check (Quick Lookup) + +### GET /api/check_ip + +Performs a quick check whether an IP connection is in whitelist or blacklist. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/check_ip?src=192.168.1.100&dst=10.0.0.1' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ---------------- | +| `src` | string | Yes | Source-IP-Adresse | +| `dst` | string | Yes | Destination-IP-Adresse | + +**Response (200 OK):** + +```json +{ + "success": true, + "blacklisted": false, + "whitelisted": true +} +``` + +**Response Schema:** + +| Feld | Type | Description | +| ------------- | ------- | ------------------------------ | +| `success` | boolean | Anfrage erfolgreich bearbeitet | +| `blacklisted` | boolean | Verbindung ist auf Blacklist | +| `whitelisted` | boolean | Verbindung ist auf Whitelist | + +--- + +## 9. Logs & Monitoring + +### GET /api/logs + +Retrieves a list of active protections and the history of sent webhook notifications. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/logs +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "activeProtections": [ + { + "type": "syn_flood", + "target": "10.0.0.1", + "pps": 12345, + "last_seen": 1600000000, + "raw": "Mitigation active for 10.0.0.1 (syn_flood)" + } + ], + "sentProtections": [ + { + "type": "syn_flood", + "target": "10.0.0.1", + "pps": 12000, + "timestamp": 1600000000, + "status": "sent", + "response_code": 200, + "error": "none", + "hook": "https://hooks.example/attack" + } + ] +} +``` + +**activeProtections Schema:** + +| Feld | Type | Description | +| ----------- | ------- | ------------------------------------ | +| `type` | string | Schutztyp (z.B. `syn_flood`) | +| `target` | string | Destination-IP-Adresse | +| `pps` | integer | Packets per second | +| `last_seen` | integer | Unix timestamp of last activity | +| `raw` | string | _(optional)_ Roh-Logzeile | + +**sentProtections Schema:** + +| Feld | Type | Description | +| --------------- | ------- | ------------------------------------ | +| `type` | string | Schutztyp | +| `target` | string | Destination-IP-Adresse | +| `pps` | integer | Packets per second | +| `timestamp` | integer | Unix timestamp of the webhook sent | +| `status` | string | Webhook-Status (z.B. `sent`) | +| `response_code` | integer | HTTP status response from the hook | +| `error` | string | Fehlerbeschreibung (falls vorhanden) | +| `hook` | string | Verwendete Webhook-URL | + +--- + +### GET /api/attacks + +Lists all currently detected and active attacks on the system live. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/attacks +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "attacks": [ + { + "attack_type": "TCP SYN", + "target_ip": "77.90.25.153", + "dropped_pps": 417330, + "gbps": 0.21367296, + "first_seen": 1769030407, + "last_seen": 1769030422 + } + ] +} +``` + +**Attack Schema (Array Items):** + +| Feld | Type | Description | +| ------------------ | ------- | ------------------------------------------------ | +| `attack_type` | string | Attack type (e.g., `syn_flood`, `udp_flood`) | +| `target_ip` | string | Primary target of the attack | +| `dropped_pps` | integer | Current drop rate in packets per second | +| `gbps` | number | Current attack bandwidth in Gbit/s | +| `first_seen` | integer | Unix timestamp of first detection | +| `last_seen` | integer | Unix timestamp of last activity | + +--- + +### GET /api/attacks/history + +Retrieves the attack history of the last 24 hours. + +**Request:** + +```bash +# All attacks of the last 24h +curl http://127.0.0.1:8081/api/attacks/history + +# Attacks for a specific IP +curl http://127.0.0.1:8081/api/attacks/history?ip=77.90.25.153 +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ---------------------------------------------------- | +| `ip` | string | No | Filtert die Ausgabe nach einer spezifischen Destination-IP. | + +**Response (200 OK):** + +```json +{ + "success": true, + "attacks": [ + { + "attack_type": "TCP (SYN)", + "target_ip": "77.90.25.153", + "peak_pps": 596000, + "peak_gbps": 0.31, + "start": 1737372108, + "end": 1737372144, + "duration": 36, + "protocols": "TCP (SYN)", + "start_iso": "2026-01-20T11:21:48Z", + "end_iso": "2026-01-20T11:22:24Z" + } + ] +} +``` + +**Attack History Schema (Array Items):** + +| Feld | Type | Description | +| ------------- | ------- | -------------------------------------- | +| `attack_type` | string | Attack type | +| `target_ip` | string | Target IP of the attack | +| `peak_pps` | integer | Highest measured packets per second | +| `peak_gbps` | number | Highest measured bandwidth in Gbit/s | +| `start` | integer | Unix timestamp of attack start | +| `end` | integer | Unix timestamp of attack end | +| `duration` | integer | Duration of the attack in seconds | +| `protocols` | string | Identified protocols | +| `start_iso` | string | ISO 8601 timestamp of start | +| `end_iso` | string | ISO 8601 timestamp of end | + +--- + +## 10. Webhooks (Attack Notifications) + +### GET /api/webhook/add + +Registers a webhook for attack notifications. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/webhook/add?target=10.0.0.1&url=https%3A%2F%2Fhooks.example%2Fattack' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | --------------------------------------- | +| `target` | string | Yes | Target IP, CIDR block, or `*` (for all) | +| `url` | string | Yes | Webhook-URL (URL-encoded) | + +**Response (200 OK) - Neuer Webhook:** + +```json +{ + "success": true, + "message": "Webhook added" +} +``` + +**Response (200 OK) - Webhook existiert bereits:** + +```json +{ + "success": true, + "message": "Webhook already present" +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "failed to add webhook" +} +``` + +--- + +### GET /api/webhook/list + +Lists all registered webhooks. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/webhook/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "webhooks": { + "10.0.0.1": ["https://hooks.example/attack"], + "10.0.0.0/24": ["https://internal.example/notification"], + "*": ["https://hooks.example/global"] + } +} +``` + +**Response Schema:** + +| Feld | Type | Description | +| ---------- | ------ | ------------------------------- | +| `webhooks` | object | Webhooks grouped by target IP | + +--- + +### GET /api/webhook/delete + +Removes a registered webhook. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/webhook/delete?target=10.0.0.1&url=https%3A%2F%2Fhooks.example%2Fattack' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------ | ------------ | ------------------------- | +| `target` | string | Yes | Destination-IP, CIDR oder `*` | +| `url` | string | Yes | Webhook-URL (URL-encoded) | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Webhook deleted" +} +``` + +**Response (404 Not Found):** + +```json +{ + "success": false, + "error": "Webhook not found" +} +``` + +--- + +## 11. Service Ports + +### GET /api/service_ports/add + +Adds a service port to all interfaces. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/service_ports/add?port=8443' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | Range | +| --------- | ------- | ------------ | ------------ | ------------ | +| `port` | integer | Yes | Port number | 1-65535 | + +**Response (200 OK):** + +```json +{ + "success": true, + "added_on": 1, + "message": "Port added to all interfaces" +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "failed to add port" +} +``` + +--- + +### GET /api/service_ports/remove + +Entfernt einen Service-Port von allen Interfaces. + +**Request:** + +```bash +curl 'http://127.0.0.1:8081/api/service_ports/remove?port=8443' +``` + +**Query Parameter:** + +| Parameter | Typ | Required | Description | +| --------- | ------- | ------------ | ------------ | +| `port` | integer | Yes | Port number | + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "Port removed", + "removed_on": 1 +} +``` + +**Response (400 Bad Request):** + +```json +{ + "success": false, + "error": "failed to remove port" +} +``` + +--- + +### GET /api/service_ports/list + +Lists all service ports by interface. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/service_ports/list +``` + +**Parameter:** None + +**Response (200 OK):** + +```json +{ + "success": true, + "interfaces": [ + { + "name": "eth0", + "ports": [22, 80, 443, 8443] + }, + { + "name": "eth1", + "ports": [22, 80, 443] + } + ] +} +``` + +**Response Schema (Interface Items):** + +| Feld | Type | Description | +| ------- | -------------- | ---------------------- | +| `name` | string | Interface-Name | +| `ports` | array[integer] | Array of port numbers | + +--- + +# REST API v2 Specification + +## Overview + +The TMW Shield REST API v2 implements proper REST principles with: +- **Resource-based URLs** using nouns instead of verbs +- **Proper HTTP methods** (GET, POST, DELETE) for different operations +- **JSON request/response bodies** instead of query parameters for state changes +- **Appropriate HTTP status codes** (200, 201, 204, 400, 404, 401) +- **Consistent error handling** with structured JSON responses + +## Base URL + +``` +http://{instance_ip}:8081/api/v2 +``` + +## Authentication + +All endpoints require Bearer token authentication: + +``` +Authorization: Bearer YOUR_API_KEY +``` + +## Common Response Format + +**Success Response:** +```json +{ + "success": true, + "message": "Operation completed successfully", + "data": { ... } // Only for GET requests +} +``` + +**Error Response:** +```json +{ + "success": false, + "error": "Error description" +} +``` + +## Endpoints + +### 1. Blacklist Management + +#### POST /api/v2/blacklists +Creates a new blacklist entry. + +**Request Body:** +```json +{ + "src": "1.2.3.4", + "dst": "5.6.7.8", + "direction": "both" // optional: "src", "dst", "both" (default: "both") +} +``` + +**Response (201 Created):** +```json +{ + "success": true, + "message": "Blacklist entry created" +} +``` + +#### GET /api/v2/blacklists +Lists all blacklist entries. + +**Response (200 OK):** +```json +{ + "success": true, + "data": [ + { + "interface": "eth0", + "entries": [ + { + "src": "1.2.3.4", + "dst": "5.6.7.8", + "direction": 2 + } + ] + } + ] +} +``` + +#### DELETE /api/v2/blacklists +Removes a blacklist entry. + +**Request Body:** +```json +{ + "src": "1.2.3.4", + "dst": "5.6.7.8" +} +``` + +**Response (204 No Content):** +```json +{ + "success": true, + "message": "Blacklist entry deleted" +} +``` + +--- + +### 2. Whitelist Management + +#### POST /api/v2/whitelists +Creates a new whitelist entry. + +**Request Body:** +```json +{ + "src": "1.2.3.4", + "dst": "5.6.7.8", + "direction": "both" // optional: "src", "dst", "both" (default: "both") +} +``` + +**Response (201 Created):** +```json +{ + "success": true, + "message": "Whitelist entry created" +} +``` + +#### GET /api/v2/whitelists +Lists all whitelist entries. + +**Response (200 OK):** +```json +{ + "success": true, + "data": [ + { + "interface": "eth0", + "entries": [ + { + "src": "1.2.3.4", + "dst": "5.6.7.8", + "direction": 2 + } + ] + } + ] +} +``` + +#### DELETE /api/v2/whitelists +Removes a whitelist entry. + +**Request Body:** +```json +{ + "src": "1.2.3.4", + "dst": "5.6.7.8" +} +``` + +**Response (204 No Content):** +```json +{ + "success": true, + "message": "Whitelist entry deleted" +} +``` + +--- + +### 3. Protocol Management + +#### POST /api/v2/protocols +Creates a protocol allow entry. + +**Request Body:** +```json +{ + "dst": "5.6.7.8", + "protocol": 17 // protocol number (e.g., 17 for UDP) +} +``` + +**Response (201 Created):** +```json +{ + "success": true, + "message": "Protocol allow entry created" +} +``` + +#### GET /api/v2/protocols +Lists all protocol allow entries. + +**Response (200 OK):** +```json +{ + "success": true, + "data": [ + { + "interface": "eth0", + "entries": [ + { + "dst": "5.6.7.8", + "protocol": 17 + } + ] + } + ] +} +``` + +#### DELETE /api/v2/protocols +Removes a protocol allow entry. + +**Request Body:** +```json +{ + "dst": "5.6.7.8", + "protocol": 17 +} +``` + +**Response (204 No Content):** +```json +{ + "success": true, + "message": "Protocol allow entry deleted" +} +``` + +--- + +### 4. Service Ports Management + +#### POST /api/v2/service-ports +Adds a service port. + +**Request Body:** +```json +{ + "port": 8080 +} +``` + +**Response (201 Created):** +```json +{ + "success": true, + "message": "Service port added" +} +``` + +#### GET /api/v2/service-ports +Lists all service ports. + +**Response (200 OK):** +```json +{ + "success": true, + "data": [ + { + "interface": "eth0", + "ports": [22, 80, 443, 8080] + } + ] +} +``` + +#### DELETE /api/v2/service-ports +Removes a service port. + +**Request Body:** +```json +{ + "port": 8080 +} +``` + +**Response (204 No Content):** +```json +{ + "success": true, + "message": "Service port removed" +} +``` + +--- + +### 5. VLAN Management + +#### POST /api/v2/vlans +Adds a VLAN bypass entry. + +**Request Body:** +```json +{ + "vlan": 100 +} +``` + +**Response (201 Created):** +```json +{ + "success": true, + "message": "VLAN bypass added" +} +``` + +#### GET /api/v2/vlans +Lists all VLAN bypass entries. + +**Response (200 OK):** +```json +{ + "success": true, + "data": [ + { + "interface": "eth0", + "vlans": [100, 200, 300] + } + ] +} +``` + +#### DELETE /api/v2/vlans +Removes a VLAN bypass entry. + +**Request Body:** +```json +{ + "vlan": 100 +} +``` + +**Response (204 No Content):** +```json +{ + "success": true, + "message": "VLAN bypass removed" +} +``` + +--- + +## AbuseIPDB Integration API (v2) + +### POST /api/v2/abuseipdb + +Adds an IP to the AbuseIPDB blocklist. + +**Request Body:** + +```json +{ + "src": "198.51.100.7" +} +``` + +**Response (201 Created):** + +```json +{ + "success": true, + "message": "IP added to AbuseIPDB blocklist" +} +``` + +--- + +### GET /api/v2/abuseipdb + +Lists all AbuseIPDB blocklist entries. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/v2/abuseipdb +``` + +--- + +### DELETE /api/v2/abuseipdb + +Removes an IP from the AbuseIPDB blocklist. + +**Request Body:** + +```json +{ + "src": "198.51.100.7" +} +``` + +**Response (204 No Content):** + +```json +{ + "success": true, + "message": "IP removed from AbuseIPDB blocklist" +} +``` + +--- + +### POST /api/v2/abuseipdb/config + +Enables or disables AbuseIPDB check for a destination IP. + +**Request Body:** + +```json +{ + "dst": "10.0.0.1", + "enable": true +} +``` + +**Response (200 OK):** + +```json +{ + "success": true, + "message": "AbuseIPDB check enabled" +} +``` + +--- + +### GET /api/v2/abuseipdb/config + +Lists all configured AbuseIPDB destinations. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/v2/abuseipdb/config +``` + +--- + +### DELETE /api/v2/abuseipdb/config + +Disables AbuseIPDB check for a destination IP. + +**Request Body:** + +```json +{ + "dst": "10.0.0.1" +} +``` + +--- + +## Webhooks API (v2) + +### POST /api/v2/webhooks + +Adds a new webhook. + +**Request Body:** + +```json +{ + "target": "192.168.1.100", + "url": "https://example.com/webhook" +} +``` + +--- + +### GET /api/v2/webhooks + +Lists all webhooks. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/v2/webhooks +``` + +--- + +### DELETE /api/v2/webhooks + +Deletes a webhook. + +**Request Body:** + +```json +{ + "target": "192.168.1.100", + "url": "https://example.com/webhook" +} +``` + +--- + +## Email Notifications API (v2) + +### POST /api/v2/emails + +Adds an email notification. + +**Request Body:** + +```json +{ + "target": "192.168.1.100", + "email": "admin@example.com" +} +``` + +--- + +### GET /api/v2/emails + +Lists all email notifications. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/v2/emails +``` + +--- + +### DELETE /api/v2/emails + +Deletes an email notification. + +**Request Body:** + +```json +{ + "target": "192.168.1.100", + "email": "admin@example.com" +} +``` + +--- + +## SMTP Configuration API (v2) + +### POST /api/v2/smtp + +Konfiguriert den SMTP-Server. + +**Request Body:** + +```json +{ + "server": "smtp.example.com", + "port": 587, + "user": "smtp_user", + "pass": "smtp_password", + "from": "shield@example.com" +} +``` + +--- + +### GET /api/v2/smtp + +Zeigt die SMTP-Konfiguration an. + +**Request:** + +```bash +curl http://127.0.0.1:8081/api/v2/smtp +``` + +--- + +## IP Check API (v2) + +### POST /api/v2/check-ip + +Checks an IP address for threats. + +**Request Body:** + +```json +{ + "ip": "198.51.100.7" +} +``` + +**Response (200 OK):** + +```json +{ + "ip": "198.51.100.7", + "blocked": false, + "source": "local" +} +``` + +--- + +## Cluster API (v2) + +Endpoints for managing TMW Shield cluster in ECMP deployments. + +### GET `/api/v2/cluster/status` + +Get current cluster membership status and statistics. + +**Response (in cluster):** +```json +{ + "in_cluster": true, + "node_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "status": "ONLINE", + "active_nodes": 3, + "messages_sent": 15432, + "messages_received": 15098 +} +``` + +**Response (not in cluster):** +```json +{ + "in_cluster": false, + "status": "NOT_IN_CLUSTER" +} +``` + +--- + +### GET `/api/v2/cluster/nodes` + +List all nodes in the cluster. + +**Response:** +```json +{ + "in_cluster": true, + "total_nodes": 3, + "nodes": [ + { + "node_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "address": "0.0.0.0", + "port": 5555, + "status": "ONLINE", + "is_local": true + }, + { + "node_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012", + "address": "192.168.1.11", + "port": 5555, + "status": "ONLINE", + "is_local": false + } + ] +} +``` + +--- + +### POST `/api/v2/cluster/join` + +Join a cluster via a seed node. + +**Request Body:** +```json +{ + "seed": "192.168.1.10:5555" +} +``` + +**Response:** +```json +{ + "success": true, + "message": "Joined cluster successfully", + "node_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" +} +``` + +--- + +### POST `/api/v2/cluster/leave` + +Leave the current cluster. + +**Response:** +```json +{ + "success": true, + "message": "Left cluster successfully" +} +``` + +--- + +### POST `/api/v2/cluster/sync` + +Request full state synchronization from all nodes or a specific node. + +**Request Body (optional):** +```json +{ + "node": "b2c3d4e5-f6a7-8901-bcde-f23456789012" +} +``` + +**Response:** +```json +{ + "success": true, + "message": "Sync requested from all nodes" +} +``` + +--- \ No newline at end of file