Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ZScaler] Stream connector #2956

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions stream/zscaler/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM python:3.11-alpine

ENV CONNECTOR_TYPE=STREAM

# Copy the worker
COPY src /opt/opencti-connector-zscaler

# Install Python modules
RUN apk --no-cache add git build-base libmagic libffi-dev libxml2-dev libxslt-dev && \
cd /opt/opencti-connector-zscaler && \
pip3 install --no-cache-dir -r requirements.txt && \
apk del git build-base

# Expose and entrypoint
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
156 changes: 156 additions & 0 deletions stream/zscaler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# OpenCTI Stream Connector Template

<!--
General description of the connector
* What it does
* How it works
* Special requirements
* Use case description
* ...
-->

Table of Contents

- [OpenCTI Stream Connector Template](#opencti-stream-connector-template)
- [Introduction](#introduction)
- [Installation](#installation)
- [Requirements](#requirements)
- [Configuration variables](#configuration-variables)
- [OpenCTI environment variables](#opencti-environment-variables)
- [Base connector environment variables](#base-connector-environment-variables)
- [Connector extra parameters environment variables](#connector-extra-parameters-environment-variables)
- [Deployment](#deployment)
- [Docker Deployment](#docker-deployment)
- [Manual Deployment](#manual-deployment)
- [Usage](#usage)
- [Behavior](#behavior)
- [Debugging](#debugging)
- [Additional information](#additional-information)

## Introduction

## Installation

### Requirements

- OpenCTI Platform >=

## Configuration variables

There are a number of configuration options, which are set either in `docker-compose.yml` (for Docker) or
in `config.yml` (for manual deployment).

### OpenCTI environment variables

Below are the parameters you'll need to set for OpenCTI:

| Parameter | config.yml | Docker environment variable | Mandatory | Description |
|---------------|------------|-----------------------------|-----------|------------------------------------------------------|
| OpenCTI URL | url | `OPENCTI_URL` | Yes | The URL of the OpenCTI platform. |
| OpenCTI Token | token | `OPENCTI_TOKEN` | Yes | The default admin token set in the OpenCTI platform. |

### Base connector environment variables

Below are the parameters you'll need to set for running the connector properly:

| Parameter | config.yml | Docker environment variable | Default | Mandatory | Description |
|---------------------------------------|-----------------------------|-----------------------------------------|-----------------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| Connector ID | id | `CONNECTOR_ID` | / | Yes | A unique `UUIDv4` identifier for this connector instance. |
| Connector Type | type | `CONNECTOR_TYPE` | EXTERNAL_IMPORT | Yes | Should always be set to `STREAM` for this connector. |
| Connector Name | name | `CONNECTOR_NAME` | | Yes | Name of the connector. |
| Connector Scope | scope | `CONNECTOR_SCOPE` | | Yes | The scope or type of data the connector is importing, either a MIME type or Stix Object. |
| Log Level | log_level | `CONNECTOR_LOG_LEVEL` | info | Yes | Determines the verbosity of the logs. Options are `debug`, `info`, `warn`, or `error`. |
| Connector Live Stream ID | live_stream_id | `CONNECTOR_LIVE_STREAM_ID` | / | Yes | ID of the live stream created in the OpenCTI UI |
| Connector Live Stream Listen Delete | live_stream_listen_delete | `CONNECTOR_LIVE_STREAM_LISTEN_DELETE` | true | Yes | Listen to all delete events concerning the entity, depending on the filter set for the OpenCTI stream. |
| Connector Live Stream No dependencies | live_stream_no_dependencies | `CONNECTOR_LIVE_STREAM_NO_DEPENDENCIES` | true | Yes | Always set to `True` unless you are synchronizing 2 OpenCTI platforms and you want to get an entity and all context (relationships and related entity) |

### Connector extra parameters environment variables

Below are the parameters you'll need to set for the connector:

| Parameter | config.yml | Docker environment variable | Default | Mandatory | Description |
|--------------|--------------|-----------------------------|---------|-----------|-------------|
| API base URL | api_base_url | | | Yes | |
| API key | api_key | | | Yes | |

## Deployment

### Docker Deployment

Before building the Docker container, you need to set the version of pycti in `requirements.txt` equal to whatever
version of OpenCTI you're running. Example, `pycti==5.12.20`. If you don't, it will take the latest version, but
sometimes the OpenCTI SDK fails to initialize.

Build a Docker Image using the provided `Dockerfile`.

Example:

```shell
# Replace the IMAGE NAME with the appropriate value
docker build . -t [IMAGE NAME]:latest
```

Make sure to replace the environment variables in `docker-compose.yml` with the appropriate configurations for your
environment. Then, start the docker container with the provided docker-compose.yml

```shell
docker compose up -d
# -d for detached
```

### Manual Deployment

Create a file `config.yml` based on the provided `config.yml.sample`.

Replace the configuration variables (especially the "**ChangeMe**" variables) with the appropriate configurations for
you environment.

Install the required python dependencies (preferably in a virtual environment):

```shell
pip3 install -r requirements.txt
```

Then, start the connector from recorded-future/src:

```shell
python3 main.py
```

## Usage

After Installation, the connector should require minimal interaction to use, and should update automatically at a
regular interval specified in your `docker-compose.yml` or `config.yml` in `duration_period`.

However, if you would like to force an immediate download of a new batch of entities, navigate to:

`Data management` -> `Ingestion` -> `Connectors` in the OpenCTI platform.

Find the connector, and click on the refresh button to reset the connector's state and force a new
download of data by re-running the connector.

## Behavior

<!--
Describe how the connector functions:
* What data is ingested, updated, or modified
* Important considerations for users when utilizing this connector
* Additional relevant details
-->

## Debugging

The connector can be debugged by setting the appropiate log level.
Note that logging messages can be added using `self.helper.connector_logger,{LOG_LEVEL}("Sample message")`, i.
e., `self.helper.connector_logger.error("An error message")`.

<!-- Any additional information to help future users debug and report detailed issues concerning this connector -->

## Additional information

<!--
Any additional information about this connector
* What information is ingested/updated/changed
* What should the user take into account when using this connector
* ...
-->
23 changes: 23 additions & 0 deletions stream/zscaler/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: '3'
services:
connector-zscaler:
image: opencti/connector-zscaler:6.3.8
- OPENCTI_URL=ChangeMe
- OPENCTI_TOKEN=ChangeMe
- CONNECTOR_ID=ChangeMe
- CONNECTOR_TYPE=STREAM
- CONNECTOR_NAME=ZscalerConnector
- CONNECTOR_SCOPE=domain-name
- CONNECTOR_LOG_LEVEL=info
- CONNECTOR_LIVE_STREAM_ID=ChangeMe
- CONNECTOR_LIVE_STREAM_LISTEN_DELETE=true
- CONNECTOR_LIVE_STREAM_NO_DEPENDENCIES=true
- CONNECTOR_DURATION_PERIOD=PT5M
- ZSCALER_API_BASE_URL=ChangeMe
- ZSCALER_API_KEY=ChangeMe
- ZSCALER_USERNAME=ChangeMe
- ZSCALER_PASSWORD=ChangeMe
networks:
- opencti_network


3 changes: 3 additions & 0 deletions stream/zscaler/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

python /opt/opencti-connector-zscaler/main.py
13 changes: 13 additions & 0 deletions stream/zscaler/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import logging

from stream_connector import ZscalerConnector

if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
try:
# Initialize the connector with the configuration file config.yml
connector = ZscalerConnector("/opt/opencti-connector-zscaler/config.yml")
connector.authenticate_with_zscaler() # Authenticate with Zscaler
connector.start() # Start listening for OpenCTI events
except Exception as e:
logging.error(f"An error occurred: {str(e)}")
5 changes: 5 additions & 0 deletions stream/zscaler/src/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pycti==6.3.8
requests
python-dotenv
pyyaml
validators
3 changes: 3 additions & 0 deletions stream/zscaler/src/stream_connector/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .connector import ZscalerConnector

__all__ = ["ZscalerConnector"]
19 changes: 19 additions & 0 deletions stream/zscaler/src/stream_connector/config_variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import os

import yaml
from dotenv import load_dotenv

load_dotenv()


with open("/opt/opencti-connector-zscaler/config.yml", "r") as stream:
config = yaml.safe_load(stream)

ZSCALER_USERNAME = os.getenv("ZSCALER_USERNAME")
ZSCALER_PASSWORD = os.getenv("ZSCALER_PASSWORD")
ZSCALER_API_KEY = os.getenv("ZSCALER_API_KEY")


OPENCTI_URL = config.get("opencti", {}).get("url", "")
OPENCTI_TOKEN = config.get("opencti", {}).get("token", "")
SSL_VERIFY = config.get("opencti", {}).get("ssl_verify", True)
Loading