From f91e329efc4de3125c83fa8a54a1ef442bef8137 Mon Sep 17 00:00:00 2001 From: marco Date: Thu, 8 Feb 2024 10:49:11 +0100 Subject: [PATCH] update specs and client --- Makefile | 10 +- cmd/cscti/main.go | 5 + cmd/cscti/smokeip.go | 32 +- pkg/cti/client.go | 16 + pkg/cti/cti_swagger.yaml | 820 --------------------- pkg/cti/cticlient.go | 19 + pkg/cti/{cti_openapi.yaml => openapi.yaml} | 377 ++++++---- pkg/cti/types.go | 181 ++++- pkg/exprhelpers/crowdsec_cti.go | 6 +- 9 files changed, 456 insertions(+), 1010 deletions(-) delete mode 100644 pkg/cti/cti_swagger.yaml create mode 100644 pkg/cti/cticlient.go rename pkg/cti/{cti_openapi.yaml => openapi.yaml} (72%) diff --git a/Makefile b/Makefile index 2e0cb2c5b..6e2a8e73d 100644 --- a/Makefile +++ b/Makefile @@ -157,15 +157,15 @@ endif $(info ) -# To update cti_openapi.yaml: -# curl https://crowdsecurity.github.io/cti-api/v2/swagger.yaml | npx swagger2openapi -o cti_openapi.yaml /dev/stdin +# To update openapi.yaml: +# curl https://crowdsecurity.github.io/cti-api/v2/swagger.yaml > ./pkg/cti/openapi.yaml .PHONY: gen-cti 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) - @echo "Generating Go client from Swagger spec..." - oapi-codegen -package cti -generate client -o ./pkg/cti/client.go ./pkg/cti/cti_openapi.yaml - oapi-codegen -package cti -generate types -o ./pkg/cti/types.go ./pkg/cti/cti_openapi.yaml + @echo "Generating Go client from OpenAPI spec..." + 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/openapi.yaml @echo "Client generation complete." .PHONY: all diff --git a/cmd/cscti/main.go b/cmd/cscti/main.go index 07899ddb9..eb96424fa 100644 --- a/cmd/cscti/main.go +++ b/cmd/cscti/main.go @@ -1,6 +1,7 @@ package main import ( + "errors" "os" "github.com/fatih/color" @@ -8,6 +9,10 @@ import ( "github.com/spf13/cobra" ) +var ( + ErrorNoAPIKey = errors.New("CTI_API_KEY is not set") +) + type Config struct { API struct { CTI struct { diff --git a/cmd/cscti/smokeip.go b/cmd/cscti/smokeip.go index eaa10034f..b2b050993 100644 --- a/cmd/cscti/smokeip.go +++ b/cmd/cscti/smokeip.go @@ -43,14 +43,34 @@ func (cli *cliSmokeIP) smokeip(ip string) error { return err } - if resp.JSON200 != nil { - out, err := json.MarshalIndent(resp.JSON200, "", " ") - if err != nil { - return err - } - fmt.Println(string(out)) + switch { + case resp.JSON404 != nil: + return fmt.Errorf("ip not found") + case resp.JSON403 != nil: + return fmt.Errorf("forbidden") + 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 } diff --git a/pkg/cti/client.go b/pkg/cti/client.go index 2aa3c95ff..278e48a0e 100644 --- a/pkg/cti/client.go +++ b/pkg/cti/client.go @@ -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 queryFrag, err := runtime.StyleParamWithLocation("form", true, "since", runtime.ParamLocationQuery, *params.Since); err != nil { diff --git a/pkg/cti/cti_swagger.yaml b/pkg/cti/cti_swagger.yaml deleted file mode 100644 index d77a987a4..000000000 --- a/pkg/cti/cti_swagger.yaml +++ /dev/null @@ -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" diff --git a/pkg/cti/cticlient.go b/pkg/cti/cticlient.go new file mode 100644 index 000000000..3ffd4e3af --- /dev/null +++ b/pkg/cti/cticlient.go @@ -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...) +} diff --git a/pkg/cti/cti_openapi.yaml b/pkg/cti/openapi.yaml similarity index 72% rename from pkg/cti/cti_openapi.yaml rename to pkg/cti/openapi.yaml index 4a33027f2..86e02db04 100644 --- a/pkg/cti/cti_openapi.yaml +++ b/pkg/cti/openapi.yaml @@ -1,112 +1,112 @@ -openapi: 3.0.1 +openapi: "3.0.1" info: - description: CTI by Crowdsec - version: 2022-02-16T14:00:00 - title: CTI v2 + description: "CTI by Crowdsec" + version: "2022-02-16T14:00:00" + title: "CTI v2" contact: - name: Crowdsec team - url: https://github.com/crowdsecurity/crowdsec - email: support@crowdsec.net + name: "Crowdsec team" + url: "https://github.com/crowdsecurity/crowdsec" + email: "support@crowdsec.net" externalDocs: description: CTI Documentation url: https://docs.crowdsec.net/docs/next/cti_api/intro/ servers: - - url: https://cti.api.crowdsec.net/v2 + - url: "https://cti.api.crowdsec.net/v2" paths: /smoke: get: - description: Search for CTI informations - summary: Search for CTI informations + description: "Search for CTI informations" + summary: "Search for CTI informations" security: - api_key: [] parameters: - - name: ips - in: query + - name: "ips" + in: "query" required: true - description: List of IPs to query, separated by comma - example: 0.0.0.0,1.1.1.1 + description: "List of IPs to query, separated by comma" + example: "0.0.0.0,1.1.1.1" schema: - type: string + type: "string" responses: "200": - description: 200 response + description: "200 response" content: application/json: schema: $ref: "#/components/schemas/SearchCTIResponse" "400": - 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 + description: "400 response" content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": - description: 500 response + description: "500 response" content: application/json: schema: $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: - description: Get CTI informations about the given IP - summary: CTI information on a given IP + description: "Get CTI informations about the given IP" + summary: "CTI information on a given IP" parameters: - - name: ip - in: path + - name: "ip" + in: "path" required: true schema: - type: string + type: "string" responses: "200": - description: 200 response + description: "200 response" content: application/json: schema: $ref: "#/components/schemas/QueryCTIResponse" "400": - 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 + description: "400 response" content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "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: application/json: schema: @@ -115,73 +115,80 @@ paths: - api_key: [] /fire: get: - description: Get fire CTI informations (IPs belonging to the community-blocklist) - summary: 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)" security: - api_key: [] parameters: - - name: page - in: query + - name: "page" + in: "query" required: false - description: Number of the page to fetch + description: "The page to fetch" example: 1 schema: - type: number - - name: since - in: query + type: "number" + - name: "limit" + in: "query" required: false - description: Filter records updated since - duration in h (hours), d(days), - m(minutes) ) - example: 3d + description: "The number of items to fetch" + example: 50 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: "200": - description: 200 response + description: "200 response" content: application/json: schema: $ref: "#/components/schemas/FireCTIResponse" "400": - 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 + description: "400 response" content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "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: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + components: securitySchemes: api_key: - type: apiKey - name: x-api-key - in: header + type: "apiKey" + name: "x-api-key" + in: "header" schemas: CTIObject: - title: IP CTI Object - type: object + title: "IP CTI Object" + type: "object" required: - as_name - as_num @@ -196,21 +203,74 @@ components: - reverse_dns - scores - 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: ip: type: string 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: type: string description: The range to which the IP belongs - example: 1.2.3.0/24 + example: "1.2.3.0/16" nullable: true ip_range_score: type: number - description: The score of the range (ip_range) the IP belongs to. 0 is - good/unknown, 5 is worse + description: The score of the range (ip_range) the IP belongs to. 0 is good/unknown, 5 is worse 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: type: string description: The autonomous system name to which the IP belongs @@ -223,10 +283,19 @@ components: nullable: true background_noise_score: type: number - description: The background noise score of the IP ranging from 0 to 10 (highly - noisy) + description: The background noise score of the IP ranging from 0 to 10 (highly noisy) example: 8 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: type: object description: Location information about the IP address @@ -242,7 +311,7 @@ components: example: US nullable: true city: - type: string + type: "string" description: The associated City of the IP example: New York nullable: true @@ -269,9 +338,8 @@ components: properties: name: type: string - description: The category of the attack, often in the form - "protocol-or-scope:attack_type" - example: http:scan + description: The category of the attack, often in the form "protocol-or-scope:attack_type" + example: "http:scan" label: type: string description: Human-friendly description of the category @@ -279,8 +347,7 @@ components: description: type: string description: Human-friendly description of the category - example: IP has been reported for performing actions related to HTTP - vulnerability scanning and discovery + example: IP has been reported for performing actions related to HTTP vulnerability scanning and discovery references: type: array description: A list of the references for which the IP was see @@ -290,7 +357,7 @@ components: name: type: string description: The reference, often in the form "list:list_name" - example: list:my_list + example: "list:my_list" label: type: string description: Human-friendly description of the reference @@ -304,14 +371,12 @@ components: properties: first_seen: type: string - 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 - example: 2021-03-03T23:00:00 + 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 + example: "2021-03-03T23:00:00" last_seen: type: string description: Date of the last time this IP was reported - example: 2021-03-03T23:30:00 + example: "2021-03-03T23:30:00" full_age: type: number description: Delta in days between first seen and today @@ -325,16 +390,14 @@ components: properties: false_positives: type: array - description: A list of false positives tags associated with the IP. Any IP with - `false_positives` tags shouldn't be considered as malicious + description: A list of false positives tags associated with the IP. Any IP with `false_positives` tags shouldn't be considered as malicious items: type: object properties: name: type: string - description: The name of the false positive, often in the form - "protocol-or-scope:attack_type" - example: seo:crawler + description: The name of the false positive, often in the form "protocol-or-scope:attack_type" + example: "seo:crawler" label: type: string description: Human-friendly name of the category @@ -342,20 +405,17 @@ components: description: type: string description: Human-friendly description of the category - example: IP belongs to a known SEO crawler and should not be flagged as a - threat. + example: IP belongs to a known SEO crawler and should not be flagged as a threat. classifications: type: array - description: A list of categories associated with the IP. Those data can be - sourced from 3rd parties (i.e. tor exit nodes list) + description: A list of categories associated with the IP. Those data can be sourced from 3rd parties (i.e. tor exit nodes list) items: type: object properties: name: type: string - description: The name of the category, often in the form - "protocol-or-scope:attack_type" - example: community-blocklist + description: The name of the category, often in the form "protocol-or-scope:attack_type" + example: "community-blocklist" label: type: string description: Human-friendly name of the category @@ -373,7 +433,7 @@ components: name: type: string description: The ID of the Mitre technique" - example: T1190 + example: "T1190" label: type: string description: The name of the Mitre technique @@ -381,8 +441,7 @@ components: description: type: string description: Description of the Mitre technique - example: Adversaries may attempt to exploit a weakness in an Internet-facing - host or system to initially access a network. + example: Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network. cves: type: array description: A list of CVEs reported for this IP. @@ -390,8 +449,7 @@ components: type: string attack_details: type: array - description: A more exhaustive list of the scenarios for which a given IP was - reported + description: A more exhaustive list of the scenarios for which a given IP was reported items: type: object properties: @@ -413,8 +471,7 @@ components: type: string target_countries: type: object - description: The top 10 reports repartition by country about the IP, as a - percentage + description: The top 10 reports repartition by country about the IP, as a percentage scores: type: object properties: @@ -490,18 +547,16 @@ components: total: type: number description: Last month score + FireIPCTIResponse: - title: Fire IP CTI Response + title: "Fire IP CTI Response" allOf: - $ref: "#/components/schemas/CTIObject" - type: object properties: state: type: string - 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)" + 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)" enum: - validated - refused @@ -509,10 +564,10 @@ components: expiration: type: string 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: - title: Search CTI Response - type: object + title: "Search CTI Response" + type: "object" required: - items - total @@ -528,11 +583,11 @@ components: items: $ref: "#/components/schemas/CTIObject" QueryCTIResponse: - title: Query IP CTI Response + title: "Query IP CTI Response" $ref: "#/components/schemas/CTIObject" FireCTIResponse: - title: Fire CTI response - type: object + title: "Fire CTI response" + type: "object" required: - _links - items @@ -551,7 +606,7 @@ components: properties: href: 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 prev: type: object @@ -560,7 +615,7 @@ components: properties: href: 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 next: type: object @@ -569,7 +624,7 @@ components: properties: href: 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 first: type: object @@ -579,22 +634,22 @@ components: href: type: string 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 items: type: array items: $ref: "#/components/schemas/FireIPCTIResponse" ErrorResponse: - type: object + type: "object" required: - - message + - "message" properties: message: - type: string - description: Error message + type: "string" + description: "Error message" errors: - type: string - description: More details on individual errors - title: Error response - description: Error response return by the API + type: "string" + description: "More details on individual errors" + title: "Error response" + description: "Error response return by the API" diff --git a/pkg/cti/types.go b/pkg/cti/types.go index 407c1c0a9..ac80ee95a 100644 --- a/pkg/cti/types.go +++ b/pkg/cti/types.go @@ -7,6 +7,98 @@ const ( 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. const ( Refused FireIPCTIResponseState = "refused" @@ -22,7 +114,7 @@ type CTIObject struct { AsNum *float32 `json:"as_num"` // 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 *string `json:"description,omitempty"` @@ -32,7 +124,10 @@ type CTIObject struct { // Name Name of the scenario (see hub.crowdsec.net) Name *string `json:"name,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 *float32 `json:"background_noise_score"` @@ -75,7 +170,7 @@ type CTIObject struct { } `json:"classifications"` // Cves A list of CVEs reported for this IP. - Cves *[]string `json:"cves,omitempty"` + Cves []string `json:"cves"` History struct { // DaysAge Delta in days between first and last seen timestamps DaysAge *float32 `json:"days_age,omitempty"` @@ -96,8 +191,17 @@ type CTIObject struct { // IpRange The range to which the IP belongs 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 float32 `json:"ip_range_score"` + IpRangeScore CTIObjectIpRangeScore `json:"ip_range_score"` // Location Location information about the IP address Location struct { @@ -115,7 +219,7 @@ type CTIObject struct { } `json:"location"` // MitreTechniques A list of Mitre Enterprise Techniques associated with the IP. - MitreTechniques *[]struct { + MitreTechniques []struct { // Description Description of the Mitre technique Description *string `json:"description,omitempty"` @@ -124,7 +228,7 @@ type CTIObject struct { // Name The ID of the Mitre technique" 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 []struct { @@ -138,6 +242,9 @@ type CTIObject struct { Name *string `json:"name,omitempty"` } `json:"references"` + // Reputation The reputation of the IP address + Reputation CTIObjectReputation `json:"reputation"` + // ReverseDns Reverse dns lookup of the IP ReverseDns *string `json:"reverse_dns"` Scores struct { @@ -211,6 +318,21 @@ type CTIObject struct { 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 type ErrorResponse struct { // Errors More details on individual errors @@ -255,7 +377,7 @@ type FireIPCTIResponse struct { AsNum *float32 `json:"as_num"` // 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 *string `json:"description,omitempty"` @@ -265,7 +387,10 @@ type FireIPCTIResponse struct { // Name Name of the scenario (see hub.crowdsec.net) Name *string `json:"name,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 *float32 `json:"background_noise_score"` @@ -308,7 +433,7 @@ type FireIPCTIResponse struct { } `json:"classifications"` // 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 *string `json:"expiration,omitempty"` @@ -332,8 +457,17 @@ type FireIPCTIResponse struct { // IpRange The range to which the IP belongs 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 float32 `json:"ip_range_score"` + IpRangeScore FireIPCTIResponseIpRangeScore `json:"ip_range_score"` // Location Location information about the IP address Location struct { @@ -351,7 +485,7 @@ type FireIPCTIResponse struct { } `json:"location"` // MitreTechniques A list of Mitre Enterprise Techniques associated with the IP. - MitreTechniques *[]struct { + MitreTechniques []struct { // Description Description of the Mitre technique Description *string `json:"description,omitempty"` @@ -360,7 +494,7 @@ type FireIPCTIResponse struct { // Name The ID of the Mitre technique" 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 []struct { @@ -374,6 +508,9 @@ type FireIPCTIResponse struct { Name *string `json:"name,omitempty"` } `json:"references"` + // Reputation The reputation of the IP address + Reputation FireIPCTIResponseReputation `json:"reputation"` + // ReverseDns Reverse dns lookup of the IP ReverseDns *string `json:"reverse_dns"` Scores struct { @@ -450,6 +587,21 @@ type FireIPCTIResponse struct { 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) type FireIPCTIResponseState string @@ -467,9 +619,12 @@ type SearchCTIResponse struct { // GetFireParams defines parameters for GetFire. type GetFireParams struct { - // Page Number of the page to fetch + // Page The page to fetch 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 *string `form:"since,omitempty" json:"since,omitempty"` } diff --git a/pkg/exprhelpers/crowdsec_cti.go b/pkg/exprhelpers/crowdsec_cti.go index 7e0cb99fc..0f4efd12b 100644 --- a/pkg/exprhelpers/crowdsec_cti.go +++ b/pkg/exprhelpers/crowdsec_cti.go @@ -54,11 +54,7 @@ func InitCrowdsecCTI(Key *string, TTL *time.Duration, Size *int, LogLevel *log.L subLogger := clog.WithFields(customLog) ctiLogger = subLogger CrowdsecCTIInitCache(*Size, *TTL) - provider, err := cti.NewAPIKeyProvider(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)) + ctiClient, err = cti.NewCTIClient(CTIApiKey) if err != nil { return fmt.Errorf("while creating CTI client: %w", err) }