Alibaba Action Trail Event Collector
Alibaba logs event collector integration for XSIAM.
Analytics & SIEM · Alibaba Action Trail
Details
| ID | Alibaba Action Trail Event Collector |
|---|---|
| Provider | Alibaba Group |
| Category | Analytics & SIEM |
| From Version | 6.8.0 |
| Docker Image | demisto/auth-utils:1.0.0.10133006 |
| Supported Modules | Agentix XSIAM |
README
Alibaba log event collector integration for XSIAM.
This integration was integrated and tested with API version 0.6 of Alicloud Log Service.
Configure Alibaba Action Trail Event Collector in Cortex
| Parameter | Description | Required |
|---|---|---|
| Endpoint | The URL used to access your project and the data of your project. | True |
| Access key id | The ID used to identify the user. | True |
| Access key | The key provided to you by Alibaba Cloud for authentication. | True |
| Project name | The name of your project in your Log Service used to isolate the resources of different users and control access to specific resources. | True |
| Logstore name | The unit in your Log Service that is used to collect, store, and query logs. | True |
| Query | The filter conditions in search statements used to obtain specific logs. Each query statement consists of a search statement and an analytic statement. The search statement and the analytic statement are separated with a vertical bar (|).A search statement can be a keyword, a numeric value, a numeric value range, a space, or an asterisk . If you specify a space or an asterisk as the search statement, no conditions are used for searching, and all logs are returned. For example: (|) select from actiontrail_pa_trail, will retrieve all the events from the project as set above. |
True |
| Number of incidents to fetch per fetch. | The maximum number of incidents to fetch each time. | False |
| First fetch time interval | The period to retrieve events for. format: [number] [time unit], for example 12 hours, 1 day, 3 months. Default is 3 days. | False |
| Use system proxy settings | Runs the integration instance using the proxy server (HTTP or HTTPS) that you defined in the server configuration. | False |
| Use Secured Connection | Use SSL secure connection or ‘None’. | False |
Commands
You can execute these commands Alert War Room in the CLI in XSIAM.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
alibaba-get-events
Manual command to fetch events and display them.
Base Command
alibaba-get-events
Input
| Argument Name | Description | Required |
|---|---|---|
| from | The date after which to search for logs in seconds Example: 1652617222. | Optional |
| limit | Number of events to fetch. Default is 1. | Required |
| should_push_events | Set this argument to True in order to create events, otherwise the command will only display them. Possible values are: True, False. Default is False. | Required |
Context Output
There is no context output for this command.
Configuration parameters
endpoint— Endpoint (required)access_key— Access key ID (required)project_name— Project name (required)logstore_name— Logstore name (required)query— Query (required)limit— Number of incidents to fetch per fetch.from— First fetch time intervalproxy— Use system proxy settingsverify— Trust any certificate (not secure)
Commands (1)
-
alibaba-get-eventsManual command to fetch events and display them.
import base64 import hashlib import hmac from datetime import datetime from typing import Any import demistomock as demisto import six import urllib3 from CommonServerPython import * from SiemApiModule import * API_VERSION = "0.6.0" VENDOR = "alibaba" PRODUCT = "action_trail" urllib3.disable_warnings() class AlibabaParams(BaseModel): from_: str = Field(alias="from") to: int type: str = "log" offset: int = 0 reverse: bool = False powerSql: bool = False query: str class AlibabaEventsClient(IntegrationEventsClient): def __init__( self, request: IntegrationHTTPRequest, options: IntegrationOptions, access_key: str, access_key_id: str, logstore_name: str, ): self.access_key = access_key self.access_key_id = access_key_id self.logstore_name = logstore_name super().__init__(request=request, options=options) def set_request_filter(self, after: Any): from_time = int(after) self.request.params.from_ = from_time + 1 # type: ignore self.request.params.to = from_time + 3600 # type: ignore def call(self, request: IntegrationHTTPRequest) -> requests.Response: try: response = self.session.request(**self.request.dict(by_alias=True)) if response.status_code >= 400: demisto.debug(f"An error occurred - raw response is: {response.json()}") response.raise_for_status() return response except Exception as exc: msg = f"something went wrong with the http call {exc}" demisto.debug(msg) raise DemistoException(msg) from exc def prepare_request(self): headers = self.request.headers del headers["x-log-date"] headers["Date"] = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT") signature = get_request_authorization( f"/logstores/{self.logstore_name}", self.access_key, self.request.params.dict(by_alias=True), # type: ignore headers, # type: ignore ) # type: ignore headers["Authorization"] = "LOG " + self.access_key_id + ":" + signature headers["x-log-date"] = headers["Date"] del headers["Date"] self.request.headers = headers class AlibabaGetEvents(IntegrationGetEvents): client: AlibabaEventsClient def __init__(self, client: AlibabaEventsClient, options: IntegrationOptions): super().__init__(client=client, options=options) @staticmethod def get_last_run(events: list) -> dict: return {"from": events[-1]["__time__"]} def _iter_events(self): self.client.prepare_request() response = self.call() events: list = response.json() events.sort(key=lambda k: k.get("__time__")) if not events: return [] while True: yield events last = events[-1] self.client.set_request_filter(last["__time__"]) self.client.prepare_request() response = self.call() events = response.json() events.sort(key=lambda k: k.get("__time__")) if not events: break def canonicalized_log_headers(headers): content = "" for key in sorted(six.iterkeys(headers)): if key[:6].lower() in ("x-log-", "x-acs-"): # x-log- header content += key + ":" + str(headers[key]) + "\n" return content def canonicalized_resource(resource, params): if params: urlString = "" for key, value in sorted(six.iteritems(params)): urlString += "{}={}&".format(key, value.decode("utf8") if isinstance(value, six.binary_type) else value) resource += "?" + urlString[:-1] return resource def base64_encodestring(s): if isinstance(s, str): s = s.encode("utf8") return base64.encodebytes(s).decode("utf8") def hmac_sha1(content, key): if isinstance(content, six.text_type): # hmac.new accept 8-bit str content = content.encode("utf-8") if isinstance(key, six.text_type): # hmac.new accept 8-bit str key = key.encode("utf-8") hashed = hmac.new(key, content, hashlib.sha1).digest() return base64_encodestring(hashed).rstrip() def get_request_authorization(resource, key, req_params, req_headers): content = "GET\n\n\n" content += req_headers["Date"] + "\n" content += canonicalized_log_headers(req_headers) content += canonicalized_resource(resource, req_params) return hmac_sha1(content, key) def get_alibaba_timestamp_format(value): timestamp: datetime if isinstance(value, int): return value if not isinstance(value, datetime): timestamp = dateparser.parse(value) # type: ignore return int(time.mktime(timestamp.timetuple())) def main(): # Args is always stronger. Get last run even stronger demisto_params = demisto.params() | demisto.args() | demisto.getLastRun() project_name = demisto_params.get("project_name") endpoint = demisto_params.get("endpoint") logstore_name = demisto_params.get("logstore_name") access_key = demisto_params.get("access_key").get("password") access_key_id = demisto_params.get("access_key").get("identifier") query = demisto_params.get("query") from_ = get_alibaba_timestamp_format(demisto_params.get("from") or "3 days") should_push_events = argToBoolean(demisto_params.get("should_push_events", "false")) headers = { "Content-Length": "0", "x-log-bodyrawsize": "0", "x-log-apiversion": API_VERSION, "x-log-signaturemethod": "hmac-sha1", "Host": f"{project_name}.{endpoint}", "x-log-date": "", } params = {"from": str(from_), "to": str(from_ + 3600), "query": query} demisto_params["method"] = Method.GET demisto_params["url"] = f"http://{project_name}.{endpoint}:80/logstores/{logstore_name}" demisto_params["headers"] = headers request = IntegrationHTTPRequest(**demisto_params) request.params = AlibabaParams.model_validate(params) # type: ignore[attr-defined,assignment] options = IntegrationOptions.model_validate(demisto_params) # type: ignore[attr-defined] client = AlibabaEventsClient( request, options, access_key=access_key, access_key_id=access_key_id, logstore_name=logstore_name ) get_events = AlibabaGetEvents(client, options) command = demisto.command() try: if command == "test-module": get_events.client.options.limit = 1 get_events.run() return_results("ok") elif command in ("alibaba-get-events", "fetch-events"): events = get_events.run() if command == "fetch-events": send_events_to_xsiam(events, vendor=VENDOR, product=PRODUCT) if events: demisto.setLastRun(AlibabaGetEvents.get_last_run(events)) elif command == "alibaba-get-events": command_results = CommandResults( readable_output=tableToMarkdown("alibaba Logs", events, headerTransform=pascalToSpace), outputs_prefix="alibaba.Logs", outputs_key_field="event.eventid", outputs=events, raw_response=events, ) return_results(command_results) if should_push_events: send_events_to_xsiam(events, vendor=VENDOR, product=PRODUCT) except Exception as e: return_error(str(e)) if __name__ in ("__main__", "__builtin__", "builtins"): main()