Complete Wazuh+OpenCTI docker-compose example
In addition to running an OpenCTI instance with opencti-wazuh-connector, this docker-compose example file also runs Wazuh in a single-node deployment with example data. No change to the docker-compose file is strictly needed to test the demo.
TODO: example data + @timestamp script. See #10.
1services:
2 redis:
3 image: redis:7.2.5
4 restart: always
5 volumes:
6 - redisdata:/data
7
8 elasticsearch:
9 image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
10 volumes:
11 - esdata:/usr/share/elasticsearch/data
12 environment:
13 # Comment-out the line below for a cluster of multiple nodes
14 - discovery.type=single-node
15 # Uncomment the line below below for a cluster of multiple nodes
16 # - cluster.name=docker-cluster
17 - xpack.ml.enabled=false
18 - xpack.security.enabled=false
19 - thread_pool.search.queue_size=5000
20 - logger.org.elasticsearch.discovery="ERROR"
21 - "ES_JAVA_OPTS=-Xms${ELASTIC_MEMORY_SIZE} -Xmx${ELASTIC_MEMORY_SIZE}"
22 restart: always
23 ulimits:
24 memlock:
25 soft: -1
26 hard: -1
27 nofile:
28 soft: 65536
29 hard: 65536
30 # Set a limit on logs:
31 logging:
32 options:
33 max-size: 50m
34
35 minio:
36 image: minio/minio:RELEASE.2024-05-28T17-19-04Z
37 volumes:
38 - s3data:/data
39 ports:
40 - "127.0.0.1:9000:9000"
41 environment:
42 MINIO_ROOT_USER: ${MINIO_ROOT_USER}
43 MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
44 command: server /data
45 restart: always
46 # Set a limit on logs:
47 logging:
48 options:
49 max-size: 50m
50
51 rabbitmq:
52 image: rabbitmq:3.13-management
53 environment:
54 - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
55 - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
56 - RABBITMQ_NODENAME=rabbit01@localhost
57 volumes:
58 - amqpdata:/var/lib/rabbitmq
59 restart: always
60 # Set a limit on logs:
61 logging:
62 options:
63 max-size: 50m
64
65 opencti:
66 image: opencti/platform:6.1.10
67 environment:
68 - NODE_OPTIONS=--max-old-space-size=8096
69 - APP__PORT=8080
70 - APP__BASE_URL=${OPENCTI_BASE_URL}
71 - APP__ADMIN__EMAIL=${OPENCTI_ADMIN_EMAIL}
72 - APP__ADMIN__PASSWORD=${OPENCTI_ADMIN_PASSWORD}
73 - APP__ADMIN__TOKEN=${OPENCTI_ADMIN_TOKEN}
74 - APP__APP_LOGS__LOGS_LEVEL=error
75 - REDIS__HOSTNAME=redis
76 - REDIS__PORT=6379
77 - ELASTICSEARCH__URL=http://elasticsearch:9200
78 - MINIO__ENDPOINT=minio
79 - MINIO__PORT=9000
80 - MINIO__USE_SSL=false
81 - MINIO__ACCESS_KEY=${MINIO_ROOT_USER}
82 - MINIO__SECRET_KEY=${MINIO_ROOT_PASSWORD}
83 - RABBITMQ__HOSTNAME=rabbitmq
84 - RABBITMQ__PORT=5672
85 - RABBITMQ__PORT_MANAGEMENT=15672
86 - RABBITMQ__MANAGEMENT_SSL=false
87 - RABBITMQ__USERNAME=${RABBITMQ_DEFAULT_USER}
88 - RABBITMQ__PASSWORD=${RABBITMQ_DEFAULT_PASS}
89 - SMTP__HOSTNAME=${SMTP_HOSTNAME}
90 - SMTP__PORT=25
91 - PROVIDERS__LOCAL__STRATEGY=LocalStrategy
92 ports:
93 - "127.0.0.1:8080:8080"
94 depends_on:
95 - redis
96 - elasticsearch
97 - minio
98 - rabbitmq
99 restart: always
100 # Set a limit on logs:
101 logging:
102 options:
103 max-size: 50m
104
105 worker:
106 image: opencti/worker:6.1.10
107 environment:
108 - OPENCTI_URL=http://opencti:8080
109 - OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
110 - WORKER_LOG_LEVEL=info
111 depends_on:
112 - opencti
113 deploy:
114 mode: replicated
115 replicas: 3
116 restart: always
117 # Set a limit on logs:
118 logging:
119 options:
120 max-size: 50m
121
122 connector-export-file-stix:
123 image: opencti/connector-export-file-stix:6.1.10
124 environment:
125 - OPENCTI_URL=http://opencti:8080
126 - OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
127 - CONNECTOR_ID=02cdecbb-3842-4d55-ab6c-1e486c5f9268
128 - CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
129 - CONNECTOR_NAME=ExportFileStix2
130 - CONNECTOR_SCOPE=application/json
131 - CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
132 - CONNECTOR_LOG_LEVEL=info
133 restart: always
134 depends_on:
135 - opencti
136 # Set a limit on logs:
137 logging:
138 options:
139 max-size: 50m
140
141 connector-import-file-stix:
142 image: opencti/connector-import-file-stix:6.1.10
143 environment:
144 - OPENCTI_URL=http://opencti:8080
145 - OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
146 - CONNECTOR_ID=${CONNECTOR_IMPORT_FILE_STIX_ID} # Valid UUIDv4
147 - CONNECTOR_TYPE=INTERNAL_IMPORT_FILE
148 - CONNECTOR_NAME=ImportFileStix
149 - CONNECTOR_VALIDATE_BEFORE_IMPORT=true # Validate any bundle before import
150 - CONNECTOR_SCOPE=application/json,text/xml
151 - CONNECTOR_AUTO=true # Enable/disable auto-import of file
152 - CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
153 - CONNECTOR_LOG_LEVEL=info
154 restart: always
155 depends_on:
156 - opencti
157 # Set a limit on logs:
158 logging:
159 options:
160 max-size: 50m
161
162 connector-wazuh:
163 image: ghcr.io/misje/opencti-wazuh-connector:0.3.0
164 restart: always
165 environment:
166 # A timezone is needed for datetime tools to work as expected:
167 - TZ=UTC
168 - USE_TZ=true
169 - OPENCTI_URL=http://opencti:8080
170 - OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
171 - CONNECTOR_ID=81f9d582-2b4e-45f1-98b6-f33492d66b6e # Replace this witha unique ID
172 - CONNECTOR_NAME=Wazuh
173 - CONNECTOR_SCOPE=Artifact,Directory,Domain-Name,Email-Addr,Hostname,IPv4-Addr,IPv6-Addr,Mac-Addr,Network-Traffic,Process,StixFile,Url,User-Account,User-Agent,Windows-Registry-Key,Windows-Registry-Value-Type,Vulnerability,Indicator
174 - CONNECTOR_AUTO=true
175 - CONNECTOR_LOG_LEVEL=warning
176 - CONNECTOR_EXPOSE_METRICS=true
177 - WAZUH_APP_URL=https://mywazuh.example.org
178 - "WAZUH_OPENSEARCH_PASSWORD=SecretPassword" # Remember double-$ if password contains $:
179 - WAZUH_OPENSEARCH_URL=https://mywazuh.example.org:9200
180 - WAZUH_OPENSEARCH_USERNAME=cti_connector
181 - WAZUH_OPENSEARCH_VERIFY_TLS=true
182 - WAZUH_TLPS=TLP:AMBER+STRICT
183 # Set a limit on logs:
184 logging:
185 options:
186 max-size: 50m
187
188 wazuh.manager:
189 image: wazuh/wazuh-manager:4.7.3
190 hostname: wazuh.manager
191 restart: always
192 ulimits:
193 memlock:
194 soft: -1
195 hard: -1
196 nofile:
197 soft: 655360
198 hard: 655360
199 ports:
200 - "127.0.0.1:1514:1514"
201 - "127.0.0.1:1515:1515"
202 - "127.0.0.1:514:514/udp"
203 - "127.0.0.1:55000:55000"
204 environment:
205 - INDEXER_URL=https://wazuh.indexer:9200
206 - INDEXER_USERNAME=admin
207 - INDEXER_PASSWORD=SecretPassword
208 - FILEBEAT_SSL_VERIFICATION_MODE=full
209 - SSL_CERTIFICATE_AUTHORITIES=/etc/ssl/root-ca.pem
210 - SSL_CERTIFICATE=/etc/ssl/filebeat.pem
211 - SSL_KEY=/etc/ssl/filebeat.key
212 - API_USERNAME=wazuh-wui
213 - API_PASSWORD=MyS3cr37P450r.*-
214 volumes:
215 - wazuh_api_configuration:/var/ossec/api/configuration
216 - wazuh_etc:/var/ossec/etc
217 - wazuh_logs:/var/ossec/logs
218 - wazuh_queue:/var/ossec/queue
219 - wazuh_var_multigroups:/var/ossec/var/multigroups
220 - wazuh_integrations:/var/ossec/integrations
221 - wazuh_active_response:/var/ossec/active-response/bin
222 - wazuh_agentless:/var/ossec/agentless
223 - wazuh_wodles:/var/ossec/wodles
224 - filebeat_etc:/etc/filebeat
225 - filebeat_var:/var/lib/filebeat
226 - ./wazuh-config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem
227 - ./wazuh-config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem
228 - ./wazuh-config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key
229 - ./wazuh-config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf
230 # Set a limit on logs:
231 logging:
232 options:
233 max-size: 50m
234
235 wazuh.indexer:
236 image: wazuh/wazuh-indexer:4.7.3
237 hostname: wazuh.indexer
238 restart: always
239 ports:
240 - "127.0.0.1:9200:9200"
241 environment:
242 - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
243 ulimits:
244 memlock:
245 soft: -1
246 hard: -1
247 nofile:
248 soft: 65536
249 hard: 65536
250 volumes:
251 - wazuh-indexer-data:/var/lib/wazuh-indexer
252 - ./wazuh-config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/certs/root-ca.pem
253 - ./wazuh-config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/certs/wazuh.indexer.key
254 - ./wazuh-config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/certs/wazuh.indexer.pem
255 - ./wazuh-config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/certs/admin.pem
256 - ./wazuh-config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/certs/admin-key.pem
257 - ./wazuh-config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/opensearch.yml
258 - ./wazuh-config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/opensearch-security/internal_users.yml
259 # Set a limit on logs:
260 logging:
261 options:
262 max-size: 50m
263
264 wazuh.dashboard:
265 image: wazuh/wazuh-dashboard:4.7.3
266 hostname: wazuh.dashboard
267 restart: always
268 ports:
269 - "127.0.0.1:443:5601"
270 environment:
271 - INDEXER_USERNAME=admin
272 - INDEXER_PASSWORD=SecretPassword
273 - WAZUH_API_URL=https://wazuh.manager
274 - DASHBOARD_USERNAME=kibanaserver
275 - DASHBOARD_PASSWORD=kibanaserver
276 - API_USERNAME=wazuh-wui
277 - API_PASSWORD=MyS3cr37P450r.*-
278 - EXTENSIONS_PCI=true # Enable PCI Extension
279 - EXTENSIONS_GDPR=true # Enable GDPR Extension
280 - EXTENSIONS_HIPAA=true # Enable HIPAA Extension
281 - EXTENSIONS_NIST=true # Enable NIST Extension
282 - EXTENSIONS_TSC=true # Enable TSC Extension
283 - EXTENSIONS_AUDIT=true # Enable Audit Extension
284 - EXTENSIONS_OSCAP=true # Enable OpenSCAP Extension
285 - EXTENSIONS_CISCAT=true # Enable CISCAT Extension
286 - EXTENSIONS_AWS=true # Enable AWS Extension
287 - EXTENSIONS_GCP=true # Enable GCP Extension
288 - EXTENSIONS_VIRUSTOTAL=true # Enable Virustotal Extension
289 - EXTENSIONS_OSQUERY=true # Enable OSQuery Extension
290 - EXTENSIONS_DOCKER=true
291 volumes:
292 - ./wazuh-config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
293 - ./wazuh-config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
294 - ./wazuh-config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem
295 - ./wazuh-config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml
296 - ./wazuh-config/wazuh_dashboard/wazuh.yml:/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml
297 - wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config
298 - wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom
299 depends_on:
300 - wazuh.indexer
301 # Set a limit on logs:
302 logging:
303 options:
304 max-size: 50m
305
306volumes:
307 esdata:
308 s3data:
309 redisdata:
310 amqpdata:
311 wazuh_api_configuration:
312 wazuh_etc:
313 wazuh_logs:
314 wazuh_queue:
315 wazuh_var_multigroups:
316 wazuh_integrations:
317 wazuh_active_response:
318 wazuh_agentless:
319 wazuh_wodles:
320 filebeat_etc:
321 filebeat_var:
322 wazuh-indexer-data:
323 wazuh-dashboard-config:
324 wazuh-dashboard-custom:
In addition to the docker-compose.yml file above, you need an .env file for common environment variables needed by OpenCI:
1OPENCTI_ADMIN_EMAIL=admin@opencti.io
2OPENCTI_ADMIN_PASSWORD="SecretPassword"
3OPENCTI_ADMIN_TOKEN=dafc7e88-f450-4685-8c2b-187f92b64e3d
4OPENCTI_BASE_URL=http://localhost:8080
5MINIO_ROOT_USER=opencti
6MINIO_ROOT_PASSWORD=GahShu6ziaNie9iSheiW
7RABBITMQ_DEFAULT_USER=opencti
8RABBITMQ_DEFAULT_PASS=Eik4shah7rojii1raith
9CONNECTOR_EXPORT_FILE_STIX_ID=dd817c8b-abae-460a-9ebc-97b1551e70e6
10CONNECTOR_EXPORT_FILE_CSV_ID=7ba187fb-fde8-4063-92b5-c3da34060dd7
11CONNECTOR_EXPORT_FILE_TXT_ID=ca715d9c-bd64-4351-91db-33a8d728a58b
12CONNECTOR_IMPORT_FILE_STIX_ID=72327164-0b35-482b-b5d6-a5a3f76b845f
13CONNECTOR_IMPORT_DOCUMENT_ID=c3970f8a-ce4b-4497-a381-20b7256f56f0
14SMTP_HOSTNAME=localhost
15ELASTIC_MEMORY_SIZE="512M"
Note
All passwords in docker and docker-compose files must have their “$” escaped by another “$” (i.e. “$” becomes “$$”).
Note
The default Wazuh login is
Username: admin
Password: SecretPassword
Note
The default OpenCTI login is as you specified in .env (see above). The defaults in the example above is:
Username: admin@opencti.io
Password: SecretPassword
Note
The provided example data is not visible in the Wazuh app, but it can be browsed in OpenSearch Discover.