update specs and client

This commit is contained in:
marco 2024-02-08 10:49:11 +01:00
parent 3cb4a4c8d1
commit f91e329efc
9 changed files with 456 additions and 1010 deletions

View file

@ -157,15 +157,15 @@ endif
$(info ) $(info )
# To update cti_openapi.yaml: # To update openapi.yaml:
# curl https://crowdsecurity.github.io/cti-api/v2/swagger.yaml | npx swagger2openapi -o cti_openapi.yaml /dev/stdin # curl https://crowdsecurity.github.io/cti-api/v2/swagger.yaml > ./pkg/cti/openapi.yaml
.PHONY: gen-cti .PHONY: gen-cti
gen-cti: ## Generate CTI client code from the specs gen-cti: ## Generate CTI client code from the specs
@which oapi-codegen > /dev/null 2>&1 || (echo "oapi-codegen is not installed. You can install it with 'go install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen@latest'" && exit 1) @which oapi-codegen > /dev/null 2>&1 || (echo "oapi-codegen is not installed. You can install it with 'go install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen@latest'" && exit 1)
@echo "Generating Go client from Swagger spec..." @echo "Generating Go client from OpenAPI spec..."
oapi-codegen -package cti -generate client -o ./pkg/cti/client.go ./pkg/cti/cti_openapi.yaml oapi-codegen -package cti -generate client -o ./pkg/cti/client.go ./pkg/cti/openapi.yaml
oapi-codegen -package cti -generate types -o ./pkg/cti/types.go ./pkg/cti/cti_openapi.yaml oapi-codegen -package cti -generate types -o ./pkg/cti/types.go ./pkg/cti/openapi.yaml
@echo "Client generation complete." @echo "Client generation complete."
.PHONY: all .PHONY: all

View file

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"os" "os"
"github.com/fatih/color" "github.com/fatih/color"
@ -8,6 +9,10 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var (
ErrorNoAPIKey = errors.New("CTI_API_KEY is not set")
)
type Config struct { type Config struct {
API struct { API struct {
CTI struct { CTI struct {

View file

@ -43,14 +43,34 @@ func (cli *cliSmokeIP) smokeip(ip string) error {
return err return err
} }
if resp.JSON200 != nil { switch {
out, err := json.MarshalIndent(resp.JSON200, "", " ") case resp.JSON404 != nil:
if err != nil { return fmt.Errorf("ip not found")
return err case resp.JSON403 != nil:
} return fmt.Errorf("forbidden")
fmt.Println(string(out)) case resp.JSON500 != nil:
return fmt.Errorf("internal server error")
case resp.JSON429 != nil:
return fmt.Errorf("too many requests")
case resp.JSON400 != nil:
return fmt.Errorf("bad request")
case resp.JSON200 == nil:
return fmt.Errorf("unexpected error %d", resp.StatusCode())
} }
ctiObj := resp.JSON200
var out []byte
// re-encode (todo: yaml, human)
out, err = json.MarshalIndent(ctiObj, "", " ")
if err != nil {
return err
}
fmt.Println(string(out))
return nil return nil
} }

View file

@ -172,6 +172,22 @@ func NewGetFireRequest(server string, params *GetFireParams) (*http.Request, err
} }
if params.Limit != nil {
if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil {
return nil, err
} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
return nil, err
} else {
for k, v := range parsed {
for _, v2 := range v {
queryValues.Add(k, v2)
}
}
}
}
if params.Since != nil { if params.Since != nil {
if queryFrag, err := runtime.StyleParamWithLocation("form", true, "since", runtime.ParamLocationQuery, *params.Since); err != nil { if queryFrag, err := runtime.StyleParamWithLocation("form", true, "since", runtime.ParamLocationQuery, *params.Since); err != nil {

View file

@ -1,820 +0,0 @@
---
swagger: "2.0"
info:
description: "API to manage machines using [crowdsec](https://github.com/crowdsecurity/crowdsec)\
\ and bouncers.\n"
version: "2023-01-04T11:16:39Z"
title: "prod-capi-v2"
contact:
name: "Crowdsec team"
url: "https://github.com/crowdsecurity/crowdsec"
email: "support@crowdsec.net"
host: "api.crowdsec.net"
basePath: "/v2"
tags:
- name: "watchers"
description: "Operations about watchers: crowdsec & cscli"
- name: "bouncers"
description: "Operations about decisions : bans, captcha, rate-limit etc."
schemes:
- "https"
paths:
/decisions/delete:
post:
tags:
- "watchers"
summary: "delete decisions"
description: "delete provided decisions"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "DecisionsDeleteRequest"
required: true
schema:
$ref: "#/definitions/DecisionsDeleteRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
security:
- UserPoolAuthorizer: []
/decisions/stream:
get:
tags:
- "bouncers"
- "watchers"
summary: "returns list of top decisions"
description: "returns list of top decisions to add or delete"
produces:
- "application/json"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/GetDecisionsStreamResponse"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
"404":
description: "404 response"
schema:
$ref: "#/definitions/ErrorResponse"
security:
- UserPoolAuthorizer: []
options:
consumes:
- "application/json"
produces:
- "application/json"
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
type: "string"
Access-Control-Allow-Methods:
type: "string"
Access-Control-Allow-Headers:
type: "string"
/decisions/sync:
post:
tags:
- "watchers"
summary: "sync decisions"
description: "sync provided decisions"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "DecisionsSyncRequest"
required: true
schema:
$ref: "#/definitions/DecisionsSyncRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
security:
- UserPoolAuthorizer: []
/metrics:
post:
tags:
- "watchers"
summary: "receive metrics about enrolled machines and bouncers in APIL"
description: "receive metrics about enrolled machines and bouncers in APIL"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "MetricsRequest"
required: true
schema:
$ref: "#/definitions/MetricsRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
security:
- UserPoolAuthorizer: []
/signals:
post:
tags:
- "watchers"
summary: "Push signals"
description: "to push signals"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "AddSignalsRequest"
required: true
schema:
$ref: "#/definitions/AddSignalsRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
security:
- UserPoolAuthorizer: []
/watchers:
post:
tags:
- "watchers"
summary: "Register watcher"
description: "Register a watcher"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "RegisterRequest"
required: true
schema:
$ref: "#/definitions/RegisterRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
/watchers/enroll:
post:
tags:
- "watchers"
summary: "watcher enrollment"
description: "watcher enrollment : enroll watcher to crowdsec backoffice account"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "EnrollRequest"
required: true
schema:
$ref: "#/definitions/EnrollRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
"403":
description: "403 response"
schema:
$ref: "#/definitions/ErrorResponse"
security:
- UserPoolAuthorizer: []
/watchers/login:
post:
tags:
- "watchers"
summary: "watcher login"
description: "Sign-in to get a valid token"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "LoginRequest"
required: true
schema:
$ref: "#/definitions/LoginRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/LoginResponse"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
"403":
description: "403 response"
schema:
$ref: "#/definitions/ErrorResponse"
/watchers/reset:
post:
tags:
- "watchers"
summary: "Reset Password"
description: "to reset a watcher password"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "ResetPasswordRequest"
required: true
schema:
$ref: "#/definitions/ResetPasswordRequest"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/SuccessResponse"
headers:
Content-type:
type: "string"
Access-Control-Allow-Origin:
type: "string"
"400":
description: "400 response"
schema:
$ref: "#/definitions/ErrorResponse"
"500":
description: "500 response"
schema:
$ref: "#/definitions/ErrorResponse"
headers:
Content-type:
type: "string"
Access-Control-Allow-Origin:
type: "string"
"403":
description: "403 response"
schema:
$ref: "#/definitions/ErrorResponse"
"404":
description: "404 response"
headers:
Content-type:
type: "string"
Access-Control-Allow-Origin:
type: "string"
options:
consumes:
- "application/json"
produces:
- "application/json"
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
type: "string"
Access-Control-Allow-Methods:
type: "string"
Access-Control-Allow-Headers:
type: "string"
securityDefinitions:
UserPoolAuthorizer:
type: "apiKey"
name: "Authorization"
in: "header"
x-amazon-apigateway-authtype: "cognito_user_pools"
definitions:
DecisionsDeleteRequest:
title: "delete decisions"
type: "array"
description: "delete decision model"
items:
$ref: "#/definitions/DecisionsDeleteRequestItem"
DecisionsSyncRequestItem:
type: "object"
required:
- "message"
- "scenario"
- "scenario_hash"
- "scenario_version"
- "source"
- "start_at"
- "stop_at"
properties:
scenario_trust:
type: "string"
scenario_hash:
type: "string"
scenario:
type: "string"
alert_id:
type: "integer"
created_at:
type: "string"
machine_id:
type: "string"
decisions:
$ref: "#/definitions/DecisionsSyncRequestItemDecisions"
source:
$ref: "#/definitions/DecisionsSyncRequestItemSource"
scenario_version:
type: "string"
message:
type: "string"
description: "a human readable message"
start_at:
type: "string"
stop_at:
type: "string"
title: "Signal"
AddSignalsRequestItem:
type: "object"
required:
- "message"
- "scenario"
- "scenario_hash"
- "scenario_version"
- "source"
- "start_at"
- "stop_at"
properties:
created_at:
type: "string"
machine_id:
type: "string"
source:
$ref: "#/definitions/AddSignalsRequestItemSource"
scenario_version:
type: "string"
message:
type: "string"
description: "a human readable message"
start_at:
type: "string"
scenario_trust:
type: "string"
scenario_hash:
type: "string"
scenario:
type: "string"
alert_id:
type: "integer"
context:
type: "array"
nullable: true
items:
type: "object"
properties:
value:
type: "string"
key:
type: "string"
decisions:
$ref: "#/definitions/AddSignalsRequestItemDecisions"
stop_at:
type: "string"
title: "Signal"
DecisionsSyncRequest:
title: "sync decisions request"
type: "array"
description: "sync decision model"
items:
$ref: "#/definitions/DecisionsSyncRequestItem"
LoginRequest:
type: "object"
required:
- "machine_id"
- "password"
properties:
password:
type: "string"
description: "Password, should respect the password policy (link to add)"
machine_id:
type: "string"
description: "machine_id is a (username) generated by crowdsec"
minLength: 48
maxLength: 48
pattern: "^[a-zA-Z0-9]+$"
scenarios:
type: "array"
description: "all scenarios installed"
items:
type: "string"
title: "login request"
description: "Login request model"
GetDecisionsStreamResponseNewItem:
type: "object"
required:
- "duration"
- "origin"
- "scenario"
- "scope"
- "type"
- "value"
properties:
duration:
type: "string"
scenario:
type: "string"
origin:
type: "string"
description: "the origin of the decision : cscli, crowdsec"
scope:
type: "string"
description: "the scope of decision : does it apply to an IP, a range, a username,\
\ etc"
start_ip:
type: "integer"
description: "(only relevant for GET ops) when the value is an IP or range,\
\ its numeric representation"
id:
type: "integer"
description: "(only relevant for GET ops) the unique id"
type:
type: "string"
description: "the type of decision, might be 'ban', 'captcha' or something\
\ custom. Ignored when watcher (cscli/crowdsec) is pushing to APIL."
value:
type: "string"
description: "the value of the decision scope : an IP, a range, a username,\
\ etc"
end_ip:
type: "integer"
description: "(only relevant for GET ops) when the value is an IP or range,\
\ its numeric representation"
title: "Decision"
AddSignalsRequestItemDecisionsItem:
type: "object"
required:
- "duration"
- "id"
- "origin"
- "scenario"
- "scope"
- "type"
- "value"
properties:
duration:
type: "string"
scenario:
type: "string"
origin:
type: "string"
description: "the origin of the decision : cscli, crowdsec"
scope:
type: "string"
description: "the scope of decision : does it apply to an IP, a range, a username,\
\ etc"
simulated:
type: "boolean"
until:
type: "string"
id:
type: "integer"
description: "(only relevant for GET ops) the unique id"
type:
type: "string"
description: "the type of decision, might be 'ban', 'captcha' or something\
\ custom. Ignored when watcher (cscli/crowdsec) is pushing to APIL."
value:
type: "string"
description: "the value of the decision scope : an IP, a range, a username,\
\ etc"
title: "Decision"
EnrollRequest:
type: "object"
required:
- "attachment_key"
properties:
name:
type: "string"
description: "The name that will be display in the console for the instance"
overwrite:
type: "boolean"
description: "To force enroll the instance"
attachment_key:
type: "string"
description: "attachment_key is generated in your crowdsec backoffice account\
\ and allows you to enroll your machines to your BO account"
pattern: "^[a-zA-Z0-9]+$"
tags:
type: "array"
description: "Tags to apply on the console for the instance"
items:
type: "string"
title: "enroll request"
description: "enroll request model"
ResetPasswordRequest:
type: "object"
required:
- "machine_id"
- "password"
properties:
password:
type: "string"
description: "Password, should respect the password policy (link to add)"
machine_id:
type: "string"
description: "machine_id is a (username) generated by crowdsec"
minLength: 48
maxLength: 48
pattern: "^[a-zA-Z0-9]+$"
title: "resetPassword"
description: "ResetPassword request model"
MetricsRequestBouncersItem:
type: "object"
properties:
last_pull:
type: "string"
description: "last bouncer pull date"
custom_name:
type: "string"
description: "bouncer name"
name:
type: "string"
description: "bouncer type (firewall, php...)"
version:
type: "string"
description: "bouncer version"
title: "MetricsBouncerInfo"
AddSignalsRequestItemSource:
type: "object"
required:
- "scope"
- "value"
properties:
scope:
type: "string"
description: "the scope of a source : ip,range,username,etc"
ip:
type: "string"
description: "provided as a convenience when the source is an IP"
latitude:
type: "number"
format: "float"
as_number:
type: "string"
description: "provided as a convenience when the source is an IP"
range:
type: "string"
description: "provided as a convenience when the source is an IP"
cn:
type: "string"
value:
type: "string"
description: "the value of a source : the ip, the range, the username,etc"
as_name:
type: "string"
description: "provided as a convenience when the source is an IP"
longitude:
type: "number"
format: "float"
title: "Source"
DecisionsSyncRequestItemDecisions:
title: "Decisions list"
type: "array"
items:
$ref: "#/definitions/DecisionsSyncRequestItemDecisionsItem"
RegisterRequest:
type: "object"
required:
- "machine_id"
- "password"
properties:
password:
type: "string"
description: "Password, should respect the password policy (link to add)"
machine_id:
type: "string"
description: "machine_id is a (username) generated by crowdsec"
pattern: "^[a-zA-Z0-9]+$"
title: "register request"
description: "Register request model"
SuccessResponse:
type: "object"
required:
- "message"
properties:
message:
type: "string"
description: "message"
title: "success response"
description: "success response return by the API"
LoginResponse:
type: "object"
properties:
code:
type: "integer"
expire:
type: "string"
token:
type: "string"
title: "login response"
description: "Login request model"
DecisionsSyncRequestItemDecisionsItem:
type: "object"
required:
- "duration"
- "id"
- "origin"
- "scenario"
- "scope"
- "type"
- "value"
properties:
duration:
type: "string"
scenario:
type: "string"
origin:
type: "string"
description: "the origin of the decision : cscli, crowdsec"
scope:
type: "string"
description: "the scope of decision : does it apply to an IP, a range, a username,\
\ etc"
simulated:
type: "boolean"
until:
type: "string"
id:
type: "integer"
description: "(only relevant for GET ops) the unique id"
type:
type: "string"
description: "the type of decision, might be 'ban', 'captcha' or something\
\ custom. Ignored when watcher (cscli/crowdsec) is pushing to APIL."
value:
type: "string"
description: "the value of the decision scope : an IP, a range, a username,\
\ etc"
title: "Decision"
GetDecisionsStreamResponse:
type: "object"
properties:
new:
$ref: "#/definitions/GetDecisionsStreamResponseNew"
deleted:
$ref: "#/definitions/GetDecisionsStreamResponseNew"
title: "get decisions stream response"
description: "get decision response model"
DecisionsSyncRequestItemSource:
type: "object"
required:
- "scope"
- "value"
properties:
scope:
type: "string"
description: "the scope of a source : ip,range,username,etc"
ip:
type: "string"
description: "provided as a convenience when the source is an IP"
latitude:
type: "number"
format: "float"
as_number:
type: "string"
description: "provided as a convenience when the source is an IP"
range:
type: "string"
description: "provided as a convenience when the source is an IP"
cn:
type: "string"
value:
type: "string"
description: "the value of a source : the ip, the range, the username,etc"
as_name:
type: "string"
description: "provided as a convenience when the source is an IP"
longitude:
type: "number"
format: "float"
title: "Source"
AddSignalsRequestItemDecisions:
title: "Decisions list"
type: "array"
items:
$ref: "#/definitions/AddSignalsRequestItemDecisionsItem"
MetricsRequestMachinesItem:
type: "object"
properties:
last_update:
type: "string"
description: "last agent update date"
name:
type: "string"
description: "agent name"
last_push:
type: "string"
description: "last agent push date"
version:
type: "string"
description: "agent version"
title: "MetricsAgentInfo"
MetricsRequest:
type: "object"
required:
- "bouncers"
- "machines"
properties:
bouncers:
type: "array"
items:
$ref: "#/definitions/MetricsRequestBouncersItem"
machines:
type: "array"
items:
$ref: "#/definitions/MetricsRequestMachinesItem"
title: "metrics"
description: "push metrics model"
ErrorResponse:
type: "object"
required:
- "message"
properties:
message:
type: "string"
description: "Error message"
errors:
type: "string"
description: "more detail on individual errors"
title: "error response"
description: "error response return by the API"
AddSignalsRequest:
title: "add signals request"
type: "array"
description: "All signals request model"
items:
$ref: "#/definitions/AddSignalsRequestItem"
DecisionsDeleteRequestItem:
type: "string"
title: "decisionsIDs"
GetDecisionsStreamResponseNew:
title: "Decisions list"
type: "array"
items:
$ref: "#/definitions/GetDecisionsStreamResponseNewItem"

19
pkg/cti/cticlient.go Normal file
View file

@ -0,0 +1,19 @@
package cti
import (
"fmt"
)
const CTIBaseURL = "https://cti.api.crowdsec.net/v2"
// NewCTIClient creates a new CTI client with the correct URL and any required configuration.
func NewCTIClient(apiKey string, opts ...ClientOption) (*ClientWithResponses, error) {
provider, err := NewAPIKeyProvider(apiKey)
if err != nil {
return nil, fmt.Errorf("failed to create API key provider: %w", err)
}
opts = append(opts, WithRequestEditorFn(provider.Intercept))
return NewClientWithResponses(CTIBaseURL, opts...)
}

View file

@ -1,112 +1,112 @@
openapi: 3.0.1 openapi: "3.0.1"
info: info:
description: CTI by Crowdsec description: "CTI by Crowdsec"
version: 2022-02-16T14:00:00 version: "2022-02-16T14:00:00"
title: CTI v2 title: "CTI v2"
contact: contact:
name: Crowdsec team name: "Crowdsec team"
url: https://github.com/crowdsecurity/crowdsec url: "https://github.com/crowdsecurity/crowdsec"
email: support@crowdsec.net email: "support@crowdsec.net"
externalDocs: externalDocs:
description: CTI Documentation description: CTI Documentation
url: https://docs.crowdsec.net/docs/next/cti_api/intro/ url: https://docs.crowdsec.net/docs/next/cti_api/intro/
servers: servers:
- url: https://cti.api.crowdsec.net/v2 - url: "https://cti.api.crowdsec.net/v2"
paths: paths:
/smoke: /smoke:
get: get:
description: Search for CTI informations description: "Search for CTI informations"
summary: Search for CTI informations summary: "Search for CTI informations"
security: security:
- api_key: [] - api_key: []
parameters: parameters:
- name: ips - name: "ips"
in: query in: "query"
required: true required: true
description: List of IPs to query, separated by comma description: "List of IPs to query, separated by comma"
example: 0.0.0.0,1.1.1.1 example: "0.0.0.0,1.1.1.1"
schema: schema:
type: string type: "string"
responses: responses:
"200": "200":
description: 200 response description: "200 response"
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/SearchCTIResponse" $ref: "#/components/schemas/SearchCTIResponse"
"400": "400":
description: 400 response description: "400 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: 403 response
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: 404 response
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: 429 response
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"500": "500":
description: 500 response description: "500 response"
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"/smoke/{ip}": "403":
description: "403 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: "404 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: "429 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/smoke/{ip}:
get: get:
description: Get CTI informations about the given IP description: "Get CTI informations about the given IP"
summary: CTI information on a given IP summary: "CTI information on a given IP"
parameters: parameters:
- name: ip - name: "ip"
in: path in: "path"
required: true required: true
schema: schema:
type: string type: "string"
responses: responses:
"200": "200":
description: 200 response description: "200 response"
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/QueryCTIResponse" $ref: "#/components/schemas/QueryCTIResponse"
"400": "400":
description: 400 response description: "400 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: 403 response
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: 404 response
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: 429 response
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"500": "500":
description: 500 response description: "500 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: "403 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: "404 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: "429 response"
content: content:
application/json: application/json:
schema: schema:
@ -115,73 +115,80 @@ paths:
- api_key: [] - api_key: []
/fire: /fire:
get: get:
description: Get fire CTI informations (IPs belonging to the community-blocklist) description: "Get fire CTI informations (IPs belonging to the community-blocklist)"
summary: Get fire CTI informations (IPs belonging to the community-blocklist) summary: "Get fire CTI informations (IPs belonging to the community-blocklist)"
security: security:
- api_key: [] - api_key: []
parameters: parameters:
- name: page - name: "page"
in: query in: "query"
required: false required: false
description: Number of the page to fetch description: "The page to fetch"
example: 1 example: 1
schema: schema:
type: number type: "number"
- name: since - name: "limit"
in: query in: "query"
required: false required: false
description: Filter records updated since - duration in h (hours), d(days), description: "The number of items to fetch"
m(minutes) ) example: 50
example: 3d
schema: schema:
type: string type: "number"
- name: "since"
in: "query"
required: false
description: "Filter records updated since - duration in h (hours), d(days), m(minutes) )"
example: "3d"
schema:
type: "string"
responses: responses:
"200": "200":
description: 200 response description: "200 response"
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/FireCTIResponse" $ref: "#/components/schemas/FireCTIResponse"
"400": "400":
description: 400 response description: "400 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: 403 response
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: 404 response
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: 429 response
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"500": "500":
description: 500 response description: "500 response"
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/ErrorResponse" $ref: "#/components/schemas/ErrorResponse"
"403":
description: "403 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: "404 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: "429 response"
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
components: components:
securitySchemes: securitySchemes:
api_key: api_key:
type: apiKey type: "apiKey"
name: x-api-key name: "x-api-key"
in: header in: "header"
schemas: schemas:
CTIObject: CTIObject:
title: IP CTI Object title: "IP CTI Object"
type: object type: "object"
required: required:
- as_name - as_name
- as_num - as_num
@ -196,21 +203,74 @@ components:
- reverse_dns - reverse_dns
- scores - scores
- target_countries - target_countries
- mitre_techniques
- cves
- background_noise_score
- background_noise
- attack_details
- reputation
- ip_range_24
- ip_range_24_reputation
- ip_range_24_score
properties: properties:
ip: ip:
type: string type: string
description: Requested IP description: Requested IP
example: 1.2.3.4 example: "1.2.3.4"
reputation:
type: string
description: The reputation of the IP address
example: "malicious"
enum:
- malicious
- suspicious
- unknown
- known
- safe
ip_range: ip_range:
type: string type: string
description: The range to which the IP belongs description: The range to which the IP belongs
example: 1.2.3.0/24 example: "1.2.3.0/16"
nullable: true nullable: true
ip_range_score: ip_range_score:
type: number type: number
description: The score of the range (ip_range) the IP belongs to. 0 is description: The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse
good/unknown, 5 is worse
example: 2 example: 2
enum:
- 0
- 1
- 2
- 3
- 4
- 5
ip_range_24:
type: string
description: The /24 range to which the IP belongs
example: "1.2.3.0/24"
nullable: true
ip_range_24_reputation:
type: string
description: The /24 range to which the IP belongs
nullable: true
example: "malicious"
enum:
- malicious
- suspicious
- unknown
- known
- safe
ip_range_24_score:
type: number
description: The score of the /24 range (ip_range_24) the IP belongs to. 0 is good/unknown, 5 is worse
nullable: true
example: 2
enum:
- 0
- 1
- 2
- 3
- 4
- 5
as_name: as_name:
type: string type: string
description: The autonomous system name to which the IP belongs description: The autonomous system name to which the IP belongs
@ -223,10 +283,19 @@ components:
nullable: true nullable: true
background_noise_score: background_noise_score:
type: number type: number
description: The background noise score of the IP ranging from 0 to 10 (highly description: The background noise score of the IP ranging from 0 to 10 (highly noisy)
noisy)
example: 8 example: 8
nullable: true nullable: true
background_noise:
type: string
description: The background noise level of the IP address
example: high
nullable: true
enum:
- low
- medium
- high
- none
location: location:
type: object type: object
description: Location information about the IP address description: Location information about the IP address
@ -242,7 +311,7 @@ components:
example: US example: US
nullable: true nullable: true
city: city:
type: string type: "string"
description: The associated City of the IP description: The associated City of the IP
example: New York example: New York
nullable: true nullable: true
@ -269,9 +338,8 @@ components:
properties: properties:
name: name:
type: string type: string
description: The category of the attack, often in the form description: The category of the attack, often in the form "protocol-or-scope:attack_type"
"protocol-or-scope:attack_type" example: "http:scan"
example: http:scan
label: label:
type: string type: string
description: Human-friendly description of the category description: Human-friendly description of the category
@ -279,8 +347,7 @@ components:
description: description:
type: string type: string
description: Human-friendly description of the category description: Human-friendly description of the category
example: IP has been reported for performing actions related to HTTP example: IP has been reported for performing actions related to HTTP vulnerability scanning and discovery
vulnerability scanning and discovery
references: references:
type: array type: array
description: A list of the references for which the IP was see description: A list of the references for which the IP was see
@ -290,7 +357,7 @@ components:
name: name:
type: string type: string
description: The reference, often in the form "list:list_name" description: The reference, often in the form "list:list_name"
example: list:my_list example: "list:my_list"
label: label:
type: string type: string
description: Human-friendly description of the reference description: Human-friendly description of the reference
@ -304,14 +371,12 @@ components:
properties: properties:
first_seen: first_seen:
type: string type: string
description: Date of the first time this IP was reported. Due to "progressive description: Date of the first time this IP was reported. Due to "progressive data degradation", this date might be later than the first time the IP was actually seen
data degradation", this date might be later than the first time example: "2021-03-03T23:00:00"
the IP was actually seen
example: 2021-03-03T23:00:00
last_seen: last_seen:
type: string type: string
description: Date of the last time this IP was reported description: Date of the last time this IP was reported
example: 2021-03-03T23:30:00 example: "2021-03-03T23:30:00"
full_age: full_age:
type: number type: number
description: Delta in days between first seen and today description: Delta in days between first seen and today
@ -325,16 +390,14 @@ components:
properties: properties:
false_positives: false_positives:
type: array type: array
description: A list of false positives tags associated with the IP. Any IP with description: A list of false positives tags associated with the IP. Any IP with `false_positives` tags shouldn't be considered as malicious
`false_positives` tags shouldn't be considered as malicious
items: items:
type: object type: object
properties: properties:
name: name:
type: string type: string
description: The name of the false positive, often in the form description: The name of the false positive, often in the form "protocol-or-scope:attack_type"
"protocol-or-scope:attack_type" example: "seo:crawler"
example: seo:crawler
label: label:
type: string type: string
description: Human-friendly name of the category description: Human-friendly name of the category
@ -342,20 +405,17 @@ components:
description: description:
type: string type: string
description: Human-friendly description of the category description: Human-friendly description of the category
example: IP belongs to a known SEO crawler and should not be flagged as a example: IP belongs to a known SEO crawler and should not be flagged as a threat.
threat.
classifications: classifications:
type: array type: array
description: A list of categories associated with the IP. Those data can be description: A list of categories associated with the IP. Those data can be sourced from 3rd parties (i.e. tor exit nodes list)
sourced from 3rd parties (i.e. tor exit nodes list)
items: items:
type: object type: object
properties: properties:
name: name:
type: string type: string
description: The name of the category, often in the form description: The name of the category, often in the form "protocol-or-scope:attack_type"
"protocol-or-scope:attack_type" example: "community-blocklist"
example: community-blocklist
label: label:
type: string type: string
description: Human-friendly name of the category description: Human-friendly name of the category
@ -373,7 +433,7 @@ components:
name: name:
type: string type: string
description: The ID of the Mitre technique" description: The ID of the Mitre technique"
example: T1190 example: "T1190"
label: label:
type: string type: string
description: The name of the Mitre technique description: The name of the Mitre technique
@ -381,8 +441,7 @@ components:
description: description:
type: string type: string
description: Description of the Mitre technique description: Description of the Mitre technique
example: Adversaries may attempt to exploit a weakness in an Internet-facing example: Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network.
host or system to initially access a network.
cves: cves:
type: array type: array
description: A list of CVEs reported for this IP. description: A list of CVEs reported for this IP.
@ -390,8 +449,7 @@ components:
type: string type: string
attack_details: attack_details:
type: array type: array
description: A more exhaustive list of the scenarios for which a given IP was description: A more exhaustive list of the scenarios for which a given IP was reported
reported
items: items:
type: object type: object
properties: properties:
@ -413,8 +471,7 @@ components:
type: string type: string
target_countries: target_countries:
type: object type: object
description: The top 10 reports repartition by country about the IP, as a description: The top 10 reports repartition by country about the IP, as a percentage
percentage
scores: scores:
type: object type: object
properties: properties:
@ -490,18 +547,16 @@ components:
total: total:
type: number type: number
description: Last month score description: Last month score
FireIPCTIResponse: FireIPCTIResponse:
title: Fire IP CTI Response title: "Fire IP CTI Response"
allOf: allOf:
- $ref: "#/components/schemas/CTIObject" - $ref: "#/components/schemas/CTIObject"
- type: object - type: object
properties: properties:
state: state:
type: string type: string
description: "state of the IP in the community blocklist: validated means IP is description: "state of the IP in the community blocklist: validated means IP is currently part of community blocklist, refused means it was part of the community blocklist, but was manually purged (ie. false positive)"
currently part of community blocklist, refused means it was part
of the community blocklist, but was manually purged (ie. false
positive)"
enum: enum:
- validated - validated
- refused - refused
@ -509,10 +564,10 @@ components:
expiration: expiration:
type: string type: string
description: Date at which the IP address expire from the community blocklist description: Date at which the IP address expire from the community blocklist
example: 2022-03-04T10:00:00 example: "2022-03-04T10:00:00"
SearchCTIResponse: SearchCTIResponse:
title: Search CTI Response title: "Search CTI Response"
type: object type: "object"
required: required:
- items - items
- total - total
@ -528,11 +583,11 @@ components:
items: items:
$ref: "#/components/schemas/CTIObject" $ref: "#/components/schemas/CTIObject"
QueryCTIResponse: QueryCTIResponse:
title: Query IP CTI Response title: "Query IP CTI Response"
$ref: "#/components/schemas/CTIObject" $ref: "#/components/schemas/CTIObject"
FireCTIResponse: FireCTIResponse:
title: Fire CTI response title: "Fire CTI response"
type: object type: "object"
required: required:
- _links - _links
- items - items
@ -551,7 +606,7 @@ components:
properties: properties:
href: href:
type: string type: string
description: Url of the current result set description: "Url of the current result set"
example: https://cti.api.dev.crowdsec.net/v1/fire?page=3&since=4h example: https://cti.api.dev.crowdsec.net/v1/fire?page=3&since=4h
prev: prev:
type: object type: object
@ -560,7 +615,7 @@ components:
properties: properties:
href: href:
type: string type: string
description: Url of the previous page of result set description: "Url of the previous page of result set"
example: https://cti.api.dev.crowdsec.net/v1/fire?page=2&since=4h example: https://cti.api.dev.crowdsec.net/v1/fire?page=2&since=4h
next: next:
type: object type: object
@ -569,7 +624,7 @@ components:
properties: properties:
href: href:
type: string type: string
description: Url of the next page of result set description: "Url of the next page of result set"
example: https://cti.api.dev.crowdsec.net/v1/fire?page=4&since=4h example: https://cti.api.dev.crowdsec.net/v1/fire?page=4&since=4h
first: first:
type: object type: object
@ -579,22 +634,22 @@ components:
href: href:
type: string type: string
nullable: true nullable: true
description: Url of the first page of result set description: "Url of the first page of result set"
example: https://cti.api.dev.crowdsec.net/v1/fire?since=4 example: https://cti.api.dev.crowdsec.net/v1/fire?since=4
items: items:
type: array type: array
items: items:
$ref: "#/components/schemas/FireIPCTIResponse" $ref: "#/components/schemas/FireIPCTIResponse"
ErrorResponse: ErrorResponse:
type: object type: "object"
required: required:
- message - "message"
properties: properties:
message: message:
type: string type: "string"
description: Error message description: "Error message"
errors: errors:
type: string type: "string"
description: More details on individual errors description: "More details on individual errors"
title: Error response title: "Error response"
description: Error response return by the API description: "Error response return by the API"

View file

@ -7,6 +7,98 @@ const (
Api_keyScopes = "api_key.Scopes" Api_keyScopes = "api_key.Scopes"
) )
// Defines values for CTIObjectBackgroundNoise.
const (
CTIObjectBackgroundNoiseHigh CTIObjectBackgroundNoise = "high"
CTIObjectBackgroundNoiseLow CTIObjectBackgroundNoise = "low"
CTIObjectBackgroundNoiseMedium CTIObjectBackgroundNoise = "medium"
CTIObjectBackgroundNoiseNone CTIObjectBackgroundNoise = "none"
)
// Defines values for CTIObjectIpRange24Reputation.
const (
CTIObjectIpRange24ReputationKnown CTIObjectIpRange24Reputation = "known"
CTIObjectIpRange24ReputationMalicious CTIObjectIpRange24Reputation = "malicious"
CTIObjectIpRange24ReputationSafe CTIObjectIpRange24Reputation = "safe"
CTIObjectIpRange24ReputationSuspicious CTIObjectIpRange24Reputation = "suspicious"
CTIObjectIpRange24ReputationUnknown CTIObjectIpRange24Reputation = "unknown"
)
// Defines values for CTIObjectIpRange24Score.
const (
CTIObjectIpRange24ScoreN0 CTIObjectIpRange24Score = 0
CTIObjectIpRange24ScoreN1 CTIObjectIpRange24Score = 1
CTIObjectIpRange24ScoreN2 CTIObjectIpRange24Score = 2
CTIObjectIpRange24ScoreN3 CTIObjectIpRange24Score = 3
CTIObjectIpRange24ScoreN4 CTIObjectIpRange24Score = 4
CTIObjectIpRange24ScoreN5 CTIObjectIpRange24Score = 5
)
// Defines values for CTIObjectIpRangeScore.
const (
CTIObjectIpRangeScoreN0 CTIObjectIpRangeScore = 0
CTIObjectIpRangeScoreN1 CTIObjectIpRangeScore = 1
CTIObjectIpRangeScoreN2 CTIObjectIpRangeScore = 2
CTIObjectIpRangeScoreN3 CTIObjectIpRangeScore = 3
CTIObjectIpRangeScoreN4 CTIObjectIpRangeScore = 4
CTIObjectIpRangeScoreN5 CTIObjectIpRangeScore = 5
)
// Defines values for CTIObjectReputation.
const (
CTIObjectReputationKnown CTIObjectReputation = "known"
CTIObjectReputationMalicious CTIObjectReputation = "malicious"
CTIObjectReputationSafe CTIObjectReputation = "safe"
CTIObjectReputationSuspicious CTIObjectReputation = "suspicious"
CTIObjectReputationUnknown CTIObjectReputation = "unknown"
)
// Defines values for FireIPCTIResponseBackgroundNoise.
const (
FireIPCTIResponseBackgroundNoiseHigh FireIPCTIResponseBackgroundNoise = "high"
FireIPCTIResponseBackgroundNoiseLow FireIPCTIResponseBackgroundNoise = "low"
FireIPCTIResponseBackgroundNoiseMedium FireIPCTIResponseBackgroundNoise = "medium"
FireIPCTIResponseBackgroundNoiseNone FireIPCTIResponseBackgroundNoise = "none"
)
// Defines values for FireIPCTIResponseIpRange24Reputation.
const (
FireIPCTIResponseIpRange24ReputationKnown FireIPCTIResponseIpRange24Reputation = "known"
FireIPCTIResponseIpRange24ReputationMalicious FireIPCTIResponseIpRange24Reputation = "malicious"
FireIPCTIResponseIpRange24ReputationSafe FireIPCTIResponseIpRange24Reputation = "safe"
FireIPCTIResponseIpRange24ReputationSuspicious FireIPCTIResponseIpRange24Reputation = "suspicious"
FireIPCTIResponseIpRange24ReputationUnknown FireIPCTIResponseIpRange24Reputation = "unknown"
)
// Defines values for FireIPCTIResponseIpRange24Score.
const (
FireIPCTIResponseIpRange24ScoreN0 FireIPCTIResponseIpRange24Score = 0
FireIPCTIResponseIpRange24ScoreN1 FireIPCTIResponseIpRange24Score = 1
FireIPCTIResponseIpRange24ScoreN2 FireIPCTIResponseIpRange24Score = 2
FireIPCTIResponseIpRange24ScoreN3 FireIPCTIResponseIpRange24Score = 3
FireIPCTIResponseIpRange24ScoreN4 FireIPCTIResponseIpRange24Score = 4
FireIPCTIResponseIpRange24ScoreN5 FireIPCTIResponseIpRange24Score = 5
)
// Defines values for FireIPCTIResponseIpRangeScore.
const (
FireIPCTIResponseIpRangeScoreN0 FireIPCTIResponseIpRangeScore = 0
FireIPCTIResponseIpRangeScoreN1 FireIPCTIResponseIpRangeScore = 1
FireIPCTIResponseIpRangeScoreN2 FireIPCTIResponseIpRangeScore = 2
FireIPCTIResponseIpRangeScoreN3 FireIPCTIResponseIpRangeScore = 3
FireIPCTIResponseIpRangeScoreN4 FireIPCTIResponseIpRangeScore = 4
FireIPCTIResponseIpRangeScoreN5 FireIPCTIResponseIpRangeScore = 5
)
// Defines values for FireIPCTIResponseReputation.
const (
FireIPCTIResponseReputationKnown FireIPCTIResponseReputation = "known"
FireIPCTIResponseReputationMalicious FireIPCTIResponseReputation = "malicious"
FireIPCTIResponseReputationSafe FireIPCTIResponseReputation = "safe"
FireIPCTIResponseReputationSuspicious FireIPCTIResponseReputation = "suspicious"
FireIPCTIResponseReputationUnknown FireIPCTIResponseReputation = "unknown"
)
// Defines values for FireIPCTIResponseState. // Defines values for FireIPCTIResponseState.
const ( const (
Refused FireIPCTIResponseState = "refused" Refused FireIPCTIResponseState = "refused"
@ -22,7 +114,7 @@ type CTIObject struct {
AsNum *float32 `json:"as_num"` AsNum *float32 `json:"as_num"`
// AttackDetails A more exhaustive list of the scenarios for which a given IP was reported // AttackDetails A more exhaustive list of the scenarios for which a given IP was reported
AttackDetails *[]struct { AttackDetails []struct {
// Description Human-friendly descriptions of scenarios // Description Human-friendly descriptions of scenarios
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
@ -32,7 +124,10 @@ type CTIObject struct {
// Name Name of the scenario (see hub.crowdsec.net) // Name Name of the scenario (see hub.crowdsec.net)
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
References *[]string `json:"references,omitempty"` References *[]string `json:"references,omitempty"`
} `json:"attack_details,omitempty"` } `json:"attack_details"`
// BackgroundNoise The background noise level of the IP address
BackgroundNoise *CTIObjectBackgroundNoise `json:"background_noise"`
// BackgroundNoiseScore The background noise score of the IP ranging from 0 to 10 (highly noisy) // BackgroundNoiseScore The background noise score of the IP ranging from 0 to 10 (highly noisy)
BackgroundNoiseScore *float32 `json:"background_noise_score"` BackgroundNoiseScore *float32 `json:"background_noise_score"`
@ -75,7 +170,7 @@ type CTIObject struct {
} `json:"classifications"` } `json:"classifications"`
// Cves A list of CVEs reported for this IP. // Cves A list of CVEs reported for this IP.
Cves *[]string `json:"cves,omitempty"` Cves []string `json:"cves"`
History struct { History struct {
// DaysAge Delta in days between first and last seen timestamps // DaysAge Delta in days between first and last seen timestamps
DaysAge *float32 `json:"days_age,omitempty"` DaysAge *float32 `json:"days_age,omitempty"`
@ -96,8 +191,17 @@ type CTIObject struct {
// IpRange The range to which the IP belongs // IpRange The range to which the IP belongs
IpRange *string `json:"ip_range"` IpRange *string `json:"ip_range"`
// IpRange24 The /24 range to which the IP belongs
IpRange24 *string `json:"ip_range_24"`
// IpRange24Reputation The /24 range to which the IP belongs
IpRange24Reputation *CTIObjectIpRange24Reputation `json:"ip_range_24_reputation"`
// IpRange24Score The score of the /24 range (ip_range_24) the IP belongs to. 0 is good/unknown, 5 is worse
IpRange24Score *CTIObjectIpRange24Score `json:"ip_range_24_score"`
// IpRangeScore The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse // IpRangeScore The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse
IpRangeScore float32 `json:"ip_range_score"` IpRangeScore CTIObjectIpRangeScore `json:"ip_range_score"`
// Location Location information about the IP address // Location Location information about the IP address
Location struct { Location struct {
@ -115,7 +219,7 @@ type CTIObject struct {
} `json:"location"` } `json:"location"`
// MitreTechniques A list of Mitre Enterprise Techniques associated with the IP. // MitreTechniques A list of Mitre Enterprise Techniques associated with the IP.
MitreTechniques *[]struct { MitreTechniques []struct {
// Description Description of the Mitre technique // Description Description of the Mitre technique
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
@ -124,7 +228,7 @@ type CTIObject struct {
// Name The ID of the Mitre technique" // Name The ID of the Mitre technique"
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
} `json:"mitre_techniques,omitempty"` } `json:"mitre_techniques"`
// References A list of the references for which the IP was see // References A list of the references for which the IP was see
References []struct { References []struct {
@ -138,6 +242,9 @@ type CTIObject struct {
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
} `json:"references"` } `json:"references"`
// Reputation The reputation of the IP address
Reputation CTIObjectReputation `json:"reputation"`
// ReverseDns Reverse dns lookup of the IP // ReverseDns Reverse dns lookup of the IP
ReverseDns *string `json:"reverse_dns"` ReverseDns *string `json:"reverse_dns"`
Scores struct { Scores struct {
@ -211,6 +318,21 @@ type CTIObject struct {
TargetCountries map[string]interface{} `json:"target_countries"` TargetCountries map[string]interface{} `json:"target_countries"`
} }
// CTIObjectBackgroundNoise The background noise level of the IP address
type CTIObjectBackgroundNoise string
// CTIObjectIpRange24Reputation The /24 range to which the IP belongs
type CTIObjectIpRange24Reputation string
// CTIObjectIpRange24Score The score of the /24 range (ip_range_24) the IP belongs to. 0 is good/unknown, 5 is worse
type CTIObjectIpRange24Score float32
// CTIObjectIpRangeScore The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse
type CTIObjectIpRangeScore float32
// CTIObjectReputation The reputation of the IP address
type CTIObjectReputation string
// ErrorResponse Error response return by the API // ErrorResponse Error response return by the API
type ErrorResponse struct { type ErrorResponse struct {
// Errors More details on individual errors // Errors More details on individual errors
@ -255,7 +377,7 @@ type FireIPCTIResponse struct {
AsNum *float32 `json:"as_num"` AsNum *float32 `json:"as_num"`
// AttackDetails A more exhaustive list of the scenarios for which a given IP was reported // AttackDetails A more exhaustive list of the scenarios for which a given IP was reported
AttackDetails *[]struct { AttackDetails []struct {
// Description Human-friendly descriptions of scenarios // Description Human-friendly descriptions of scenarios
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
@ -265,7 +387,10 @@ type FireIPCTIResponse struct {
// Name Name of the scenario (see hub.crowdsec.net) // Name Name of the scenario (see hub.crowdsec.net)
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
References *[]string `json:"references,omitempty"` References *[]string `json:"references,omitempty"`
} `json:"attack_details,omitempty"` } `json:"attack_details"`
// BackgroundNoise The background noise level of the IP address
BackgroundNoise *FireIPCTIResponseBackgroundNoise `json:"background_noise"`
// BackgroundNoiseScore The background noise score of the IP ranging from 0 to 10 (highly noisy) // BackgroundNoiseScore The background noise score of the IP ranging from 0 to 10 (highly noisy)
BackgroundNoiseScore *float32 `json:"background_noise_score"` BackgroundNoiseScore *float32 `json:"background_noise_score"`
@ -308,7 +433,7 @@ type FireIPCTIResponse struct {
} `json:"classifications"` } `json:"classifications"`
// Cves A list of CVEs reported for this IP. // Cves A list of CVEs reported for this IP.
Cves *[]string `json:"cves,omitempty"` Cves []string `json:"cves"`
// Expiration Date at which the IP address expire from the community blocklist // Expiration Date at which the IP address expire from the community blocklist
Expiration *string `json:"expiration,omitempty"` Expiration *string `json:"expiration,omitempty"`
@ -332,8 +457,17 @@ type FireIPCTIResponse struct {
// IpRange The range to which the IP belongs // IpRange The range to which the IP belongs
IpRange *string `json:"ip_range"` IpRange *string `json:"ip_range"`
// IpRange24 The /24 range to which the IP belongs
IpRange24 *string `json:"ip_range_24"`
// IpRange24Reputation The /24 range to which the IP belongs
IpRange24Reputation *FireIPCTIResponseIpRange24Reputation `json:"ip_range_24_reputation"`
// IpRange24Score The score of the /24 range (ip_range_24) the IP belongs to. 0 is good/unknown, 5 is worse
IpRange24Score *FireIPCTIResponseIpRange24Score `json:"ip_range_24_score"`
// IpRangeScore The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse // IpRangeScore The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse
IpRangeScore float32 `json:"ip_range_score"` IpRangeScore FireIPCTIResponseIpRangeScore `json:"ip_range_score"`
// Location Location information about the IP address // Location Location information about the IP address
Location struct { Location struct {
@ -351,7 +485,7 @@ type FireIPCTIResponse struct {
} `json:"location"` } `json:"location"`
// MitreTechniques A list of Mitre Enterprise Techniques associated with the IP. // MitreTechniques A list of Mitre Enterprise Techniques associated with the IP.
MitreTechniques *[]struct { MitreTechniques []struct {
// Description Description of the Mitre technique // Description Description of the Mitre technique
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
@ -360,7 +494,7 @@ type FireIPCTIResponse struct {
// Name The ID of the Mitre technique" // Name The ID of the Mitre technique"
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
} `json:"mitre_techniques,omitempty"` } `json:"mitre_techniques"`
// References A list of the references for which the IP was see // References A list of the references for which the IP was see
References []struct { References []struct {
@ -374,6 +508,9 @@ type FireIPCTIResponse struct {
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
} `json:"references"` } `json:"references"`
// Reputation The reputation of the IP address
Reputation FireIPCTIResponseReputation `json:"reputation"`
// ReverseDns Reverse dns lookup of the IP // ReverseDns Reverse dns lookup of the IP
ReverseDns *string `json:"reverse_dns"` ReverseDns *string `json:"reverse_dns"`
Scores struct { Scores struct {
@ -450,6 +587,21 @@ type FireIPCTIResponse struct {
TargetCountries map[string]interface{} `json:"target_countries"` TargetCountries map[string]interface{} `json:"target_countries"`
} }
// FireIPCTIResponseBackgroundNoise The background noise level of the IP address
type FireIPCTIResponseBackgroundNoise string
// FireIPCTIResponseIpRange24Reputation The /24 range to which the IP belongs
type FireIPCTIResponseIpRange24Reputation string
// FireIPCTIResponseIpRange24Score The score of the /24 range (ip_range_24) the IP belongs to. 0 is good/unknown, 5 is worse
type FireIPCTIResponseIpRange24Score float32
// FireIPCTIResponseIpRangeScore The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse
type FireIPCTIResponseIpRangeScore float32
// FireIPCTIResponseReputation The reputation of the IP address
type FireIPCTIResponseReputation string
// FireIPCTIResponseState state of the IP in the community blocklist: validated means IP is currently part of community blocklist, refused means it was part of the community blocklist, but was manually purged (ie. false positive) // FireIPCTIResponseState state of the IP in the community blocklist: validated means IP is currently part of community blocklist, refused means it was part of the community blocklist, but was manually purged (ie. false positive)
type FireIPCTIResponseState string type FireIPCTIResponseState string
@ -467,9 +619,12 @@ type SearchCTIResponse struct {
// GetFireParams defines parameters for GetFire. // GetFireParams defines parameters for GetFire.
type GetFireParams struct { type GetFireParams struct {
// Page Number of the page to fetch // Page The page to fetch
Page *float32 `form:"page,omitempty" json:"page,omitempty"` Page *float32 `form:"page,omitempty" json:"page,omitempty"`
// Limit The number of items to fetch
Limit *float32 `form:"limit,omitempty" json:"limit,omitempty"`
// Since Filter records updated since - duration in h (hours), d(days), m(minutes) ) // Since Filter records updated since - duration in h (hours), d(days), m(minutes) )
Since *string `form:"since,omitempty" json:"since,omitempty"` Since *string `form:"since,omitempty" json:"since,omitempty"`
} }

View file

@ -54,11 +54,7 @@ func InitCrowdsecCTI(Key *string, TTL *time.Duration, Size *int, LogLevel *log.L
subLogger := clog.WithFields(customLog) subLogger := clog.WithFields(customLog)
ctiLogger = subLogger ctiLogger = subLogger
CrowdsecCTIInitCache(*Size, *TTL) CrowdsecCTIInitCache(*Size, *TTL)
provider, err := cti.NewAPIKeyProvider(CTIApiKey) ctiClient, err = cti.NewCTIClient(CTIApiKey)
if err != nil {
return fmt.Errorf("while creating CTI API key provider: %w", err)
}
ctiClient, err = cti.NewClientWithResponses("https://cti.api.crowdsec.net/v2/", cti.WithRequestEditorFn(provider.Intercept))
if err != nil { if err != nil {
return fmt.Errorf("while creating CTI client: %w", err) return fmt.Errorf("while creating CTI client: %w", err)
} }