Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
9 changes: 9 additions & 0 deletions external-import/rst-threat-library/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
__metadata__
**/__pycache__
**/__docs__
**/.venv
**/venv
**/logs
**/config.yml
**/*.egg-info
**/*.gql
28 changes: 28 additions & 0 deletions external-import/rst-threat-library/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM python:3.12-alpine
ENV CONNECTOR_TYPE=EXTERNAL_IMPORT

WORKDIR /opt/opencti-connector-rst-threat-library

COPY src /opt/opencti-connector-rst-threat-library/src

# Install pinned deps first, then connectors-sdk with --no-deps so its pycti
RUN apk --no-cache add --virtual .build-deps git build-base && \
apk --no-cache add libmagic && \
grep -v '^connectors-sdk' src/requirements.txt | grep -v '^#' | grep -v '^$' > /tmp/reqs.txt && \
pip3 install --no-cache-dir -r /tmp/reqs.txt && \
SDK_SPEC=$(grep '^connectors-sdk' src/requirements.txt | sed 's/^connectors-sdk[[:space:]]*@[[:space:]]*//') && \
pip3 install --no-cache-dir --no-deps "$SDK_SPEC" && \
rm -f /tmp/reqs.txt && \
apk del .build-deps
Comment on lines +9 to +16

COPY entrypoint.sh /
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh

RUN addgroup -S opencti && adduser -S opencti -G opencti && \
chown -R opencti:opencti /opt/opencti-connector-rst-threat-library /entrypoint.sh

USER opencti:opencti

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD sh -c "ps | grep -q '[p]ython3'"
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
80 changes: 80 additions & 0 deletions external-import/rst-threat-library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# OpenCTI RST Threat Library Connector

Ingests intrusion sets, malware, tools, and campaigns from the **RST Cloud Threat Library REST API** (`https://api.rstcloud.net/v1`) into OpenCTI, and keeps them in sync as upstream objects change.

## Introduction

The connector polls `GET /threat-objects/<type>` for each configured type and upserts the results into OpenCTI keyed on `standard_id`.

## Installation

### Requirements

- OpenCTI Platform >= 6.8.12 with a working worker
- Python >= 3.11 (for manual deployment)
- An RST Cloud Threat Library API key
- Docker / Docker Compose

### Configuration variables

Configuration is set either in `docker-compose.yml` (Docker) or in `config.yml` (manual deployment). See `config.yml.sample` for a full annotated example. Field descriptions and examples are also defined on the Pydantic models in `src/connector/settings.py` and mirrored in `__metadata__/connector_config_schema.json`.

#### OpenCTI environment variables

| Parameter | config.yml | Docker environment variable | Mandatory | Example | Description |
| ------------- | ---------- | --------------------------- | --------- | ----------------------- | ------------------------------------------------ |
| OpenCTI URL | `url` | `OPENCTI_URL` | Yes | `http://localhost:8080` | URL of the OpenCTI platform. |
| OpenCTI Token | `token` | `OPENCTI_TOKEN` | Yes | `ChangeMe` | Admin / API token used to bootstrap the connector. |

#### Base connector environment variables

| Parameter | config.yml | Docker environment variable | Default | Mandatory | Example | Description |
| ------------------------------ | -------------------------------------------- | -------------------------------------------------------- | ------------------- | --------- | -------------------------------------------- | --------------------------------------------------------------------------- |
| Connector ID | `id` | `CONNECTOR_ID` | / | Yes | `b7f9a6b4-6b2a-4c3f-9f7b-8b5e5b6f2d1a` | Unique UUID v4 for this connector instance. |
| Connector Type | `type` | `CONNECTOR_TYPE` | `EXTERNAL_IMPORT` | Yes | `EXTERNAL_IMPORT` | Must be `EXTERNAL_IMPORT`. |
| Connector Name | `name` | `CONNECTOR_NAME` | `RST Threat Library`| Yes | `RST Threat Library` | Display name in OpenCTI. |
| Connector Scope | `scope` | `CONNECTOR_SCOPE` | / | Yes | `intrusion-set,malware,tool,campaign` | STIX domain types emitted. |
| Log Level | `log_level` | `CONNECTOR_LOG_LEVEL` | `error` | No | `info` | `debug`, `info`, `warn`, or `error`. |
| Duration Period | `duration_period` | `CONNECTOR_DURATION_PERIOD` | `PT1H` | No | `PT1H` | ISO-8601 interval between runs. |
| Queue Threshold | `queue_threshold` | `CONNECTOR_QUEUE_THRESHOLD` | `500` | No | `500` | Max RabbitMQ queue size (MB) before pausing ingestion. |
| Update Existing Data | `update_existing_data` | `CONNECTOR_UPDATE_EXISTING_DATA` | `true` | No | `true` | Upsert existing STIX objects when `true`. |
| Auto-create Service Account | `auto_create_service_account` | `CONNECTOR_AUTO_CREATE_SERVICE_ACCOUNT` | `false` | No | `true` | Create a Connectors-group service account on first start. |
| Service Account Confidence | `auto_create_service_account_confidence_level` | `CONNECTOR_AUTO_CREATE_SERVICE_ACCOUNT_CONFIDENCE_LEVEL` | `50` | No | `50` | Max confidence for the auto-created service account. |

#### Connector extra parameters

| Parameter | config.yml | Docker environment variable | Default | Mandatory | Example | Description |
| --------------------------------- | ----------------------------------- | ---------------------------------------------------- | -------------------------------------------- | --------- | -------------------------------------------- | --------------------------------------------------------------------------- |
| API base URL | `baseurl` | `RST_THREAT_LIBRARY_BASEURL` | `https://api.rstcloud.net/v1` | Yes | `https://api.rstcloud.net/v1` | RST Cloud API root. |
| API key | `apikey` | `RST_THREAT_LIBRARY_APIKEY` | / | Yes | `ChangeMe` | RST Cloud Threat Library API key. |
| Auth header name | `auth_header` | `RST_THREAT_LIBRARY_AUTH_HEADER` | `x-api-key` | No | `x-api-key` | HTTP header carrying the API key. |
| HTTP proxy | `proxy` | `RST_THREAT_LIBRARY_PROXY` | *(empty)* | No | `http://proxy.example.com:8080` | Forward HTTP proxy URL. Empty = direct egress. |
| Verify TLS | `ssl_verify` | `RST_THREAT_LIBRARY_SSL_VERIFY` | `true` | No | `true` | Verify TLS certificates. |
| Connect timeout | `contimeout` | `RST_THREAT_LIBRARY_CONTIMEOUT` | `30` | No | `30` | HTTP connect timeout in seconds. |
| Read timeout | `readtimeout` | `RST_THREAT_LIBRARY_READTIMEOUT` | `120` | No | `600` | HTTP read timeout in seconds. |
| HTTP fetch retries | `retry` | `RST_THREAT_LIBRARY_RETRY` | `2` | No | `10` | Per-request retry count. |
| OpenCTI push max retries | `max_retries` | `RST_THREAT_LIBRARY_MAX_RETRIES` | `3` | No | `3` | Retries when pushing to OpenCTI. |
| OpenCTI push retry delay | `retry_delay` | `RST_THREAT_LIBRARY_RETRY_DELAY` | `10` | No | `10` | Initial retry delay in seconds. |
| OpenCTI push backoff multiplier | `retry_backoff_multiplier` | `RST_THREAT_LIBRARY_RETRY_BACKOFF_MULTIPLIER` | `2.0` | No | `2.0` | Exponential backoff multiplier. |
| OpenCTI push mode | `opencti_push_mode` | `RST_THREAT_LIBRARY_OPENCTI_PUSH_MODE` | `bundle` | No | `bundle` | `bundle` (worker) or `api` (GraphQL import). |
| Object types to pull | `object_types` | `RST_THREAT_LIBRARY_OBJECT_TYPES` | `intrusion-sets,malware,tools,campaigns` | No | `intrusion-sets,malware,tools,campaigns` | Comma-separated paths under `/threat-objects/`. |
| Sort field | `order_by` | `RST_THREAT_LIBRARY_ORDER_BY` | `modified` | No | `modified` | Use `modified` for incremental sync. |
| Sort direction | `order_mode` | `RST_THREAT_LIBRARY_ORDER_MODE` | `desc` | No | `desc` | `asc` or `desc`. |
| Page size | `page_size` | `RST_THREAT_LIBRARY_PAGE_SIZE` | `100` | No | `20` | `limit` per request. |
| Intrusion-set merge/split | `merge_split` | `RST_THREAT_LIBRARY_MERGE_SPLIT` | `false` | No | `false` | Reconcile intrusion-set alias merge/split. |
| Respect local user edits | `respect_user_edits` | `RST_THREAT_LIBRARY_RESPECT_USER_EDITS` | `false` | No | `false` | Preserve higher-confidence OpenCTI edits. |
| Intrusion-set import confidence | `intrusion_set_default_confidence` | `RST_THREAT_LIBRARY_INTRUSION_SET_DEFAULT_CONFIDENCE`| *(unset)* | No | `80` | When set (0–100), replaces upstream confidence on intrusion sets. |
| Sync labels on import | `sync_labels` | `RST_THREAT_LIBRARY_SYNC_LABELS` | `RST Threat Library` | No | `RST Threat Library` | Labels merged on import; scopes merge/split. |
| Reconcile exclude labels | `reconcile_exclude_labels` | `RST_THREAT_LIBRARY_RECONCILE_EXCLUDE_LABELS` | *(empty)* | No | `MITRE,manual` | Labels excluded from merge/split fusion. |
| Reconcile createdBy allowlist | `reconcile_allow_created_by` | `RST_THREAT_LIBRARY_RECONCILE_ALLOW_CREATED_BY` | *(empty)* | No | `identity--…` | If set, fuse only entities with these `createdBy` IDs. |
| Initial backfill cutoff | `import_from_date` | `RST_THREAT_LIBRARY_IMPORT_FROM_DATE` | *(empty)* | No | `2024-01-01` | `YYYY-MM-DD`. Empty = full history on first run. |

### Recommended values (RST API reliability)

For deep pagination (especially `tools`), these reduce `504 Gateway Timeout` and `IncompleteRead` errors:

```env
RST_THREAT_LIBRARY_PAGE_SIZE=20
RST_THREAT_LIBRARY_READTIMEOUT=600
RST_THREAT_LIBRARY_RETRY=10
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Connector Configurations

Below is an exhaustive list of the environment variables supported by the RST
Threat Library connector. Required values must be supplied before starting the
connector.

### Type: `object`

| Property | Type | Required | Possible values | Default | Description |
| -------- | ---- | -------- | --------------- | ------- | ----------- |
| OPENCTI_URL | `string` | Yes | URL | | The base URL of the OpenCTI instance. |
| OPENCTI_TOKEN | `string` | Yes | string | | The API token used to connect to OpenCTI. |
| CONNECTOR_ID | `string` | Yes | UUID v4 | | A unique identifier for this connector instance. |
| CONNECTOR_TYPE | `const` | Yes | `EXTERNAL_IMPORT` | `"EXTERNAL_IMPORT"` | The OpenCTI connector type. |
| CONNECTOR_NAME | `string` | Yes | string | `"RST Threat Library"` | The connector name displayed in OpenCTI. |
| CONNECTOR_SCOPE | `string` | Yes | string | `"intrusion-set,malware,tool,campaign"` | Comma-separated STIX domain types emitted by the connector. |
| CONNECTOR_LOG_LEVEL | `string` | | `debug`, `info`, `warn`, `warning`, `error` | `"error"` | The minimum level of logs to display. |
| CONNECTOR_DURATION_PERIOD | `string` | | ISO-8601 duration | `"PT1H"` | The period between connector runs. |
| CONNECTOR_QUEUE_THRESHOLD | `number` | | Number greater than 0 | `500` | Maximum RabbitMQ queue size in MB before ingestion pauses. |
| CONNECTOR_UPDATE_EXISTING_DATA | `boolean` | | `true`, `false` | `true` | Whether existing STIX objects may be updated. |
| CONNECTOR_AUTO_CREATE_SERVICE_ACCOUNT | `boolean` | | `true`, `false` | `false` | Whether to create a dedicated Connectors-group service account on first start. |
| CONNECTOR_AUTO_CREATE_SERVICE_ACCOUNT_CONFIDENCE_LEVEL | `integer` | | `0` to `100` | `50` | Maximum confidence level assigned to the auto-created service account. |
| RST_THREAT_LIBRARY_BASEURL | `string` | Yes | URL | `"https://api.rstcloud.net/v1"` | The RST Cloud Threat Library API base URL. |
| RST_THREAT_LIBRARY_APIKEY | `string` | Yes | string | | The RST Cloud Threat Library API key. |
| RST_THREAT_LIBRARY_AUTH_HEADER | `string` | | string | `"x-api-key"` | The HTTP header used to send the API key. |
| RST_THREAT_LIBRARY_PROXY | `string` | | URL or empty string | `""` | Optional forward HTTP proxy URL. An empty value uses direct egress. |
| RST_THREAT_LIBRARY_SSL_VERIFY | `boolean` | | `true`, `false` | `true` | Whether TLS certificates are verified for API requests. |
| RST_THREAT_LIBRARY_CONTIMEOUT | `integer` | | Positive integer | `30` | HTTP connection timeout in seconds. |
| RST_THREAT_LIBRARY_READTIMEOUT | `integer` | | Positive integer | `120` | HTTP read timeout in seconds. |
| RST_THREAT_LIBRARY_RETRY | `integer` | | Non-negative integer | `2` | Number of retries for each RST API request. |
| RST_THREAT_LIBRARY_MAX_RETRIES | `integer` | | Non-negative integer | `3` | Maximum retries when sending data to OpenCTI. |
| RST_THREAT_LIBRARY_RETRY_DELAY | `integer` | | Non-negative integer | `10` | Initial delay in seconds before retrying an OpenCTI push. |
| RST_THREAT_LIBRARY_RETRY_BACKOFF_MULTIPLIER | `number` | | Positive number | `2.0` | Exponential backoff multiplier for OpenCTI push retries. |
| RST_THREAT_LIBRARY_OPENCTI_PUSH_MODE | `string` | | `bundle`, `api` | `"bundle"` | The OpenCTI write path: worker bundle or GraphQL API import. |
| RST_THREAT_LIBRARY_OBJECT_TYPES | `string` | | Comma-separated string | `"intrusion-sets,malware,tools,campaigns"` | Threat-object API paths to poll. |
| RST_THREAT_LIBRARY_ORDER_BY | `string` | | string | `"modified"` | Field used to order API results for incremental synchronization. |
| RST_THREAT_LIBRARY_ORDER_MODE | `string` | | `asc`, `desc` | `"desc"` | Direction used to order API results. |
| RST_THREAT_LIBRARY_PAGE_SIZE | `integer` | | Positive integer | `100` | Maximum number of threat objects requested per page. |
| RST_THREAT_LIBRARY_MERGE_SPLIT | `boolean` | | `true`, `false` | `false` | Whether intrusion-set alias merge/split reconciliation is enabled. |
| RST_THREAT_LIBRARY_RESPECT_USER_EDITS | `boolean` | | `true`, `false` | `false` | Whether higher-confidence OpenCTI edits are preserved. |
| RST_THREAT_LIBRARY_INTRUSION_SET_DEFAULT_CONFIDENCE | `integer` | | `0` to `100` | | Optional confidence value that replaces upstream confidence on imported intrusion sets. |
| RST_THREAT_LIBRARY_SYNC_LABELS | `string` | | Comma-separated string | `"RST Threat Library"` | Labels applied during import and used to scope merge/split reconciliation. |
| RST_THREAT_LIBRARY_RECONCILE_EXCLUDE_LABELS | `string` | | Comma-separated string | `""` | Labels that exclude entities from merge/split fusion. |
| RST_THREAT_LIBRARY_RECONCILE_ALLOW_CREATED_BY | `string` | | Comma-separated identity IDs | `""` | When set, only entities created by these identities may be fused. |
| RST_THREAT_LIBRARY_IMPORT_FROM_DATE | `string` | | Date in `YYYY-MM-DD` format or empty string | `""` | Initial backfill cutoff. An empty value imports the full available history. |
Loading