My objective is connect two different containers to get data, in other words:
- I have an instance of OpenCTI working in my docker , and I can access it through my browser (http://localhost:8080).
- Consequently, I am developing another one to get data from OpenCTI.
To connect both, I already created a docker network called "minharede".
However is not working.
The configuration of my containers is:
Docker-compose file of OpenCTI:
version: '3'
services:
redis:
image: redis:6.2.6
restart: always
volumes:
- redisdata:/data
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
volumes:
- esdata:/usr/share/elasticsearch/data
environment:
- discovery.type=single-node
- xpack.ml.enabled=false
restart: always
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
minio:
image: minio/minio:RELEASE.2022-02-26T02-54-46Z
volumes:
- s3data:/data
ports:
- "9800:9800"
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
command: server /data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
restart: always
rabbitmq:
image: rabbitmq:3.9-management
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
volumes:
- amqpdata:/var/lib/rabbitmq
restart: always
opencti:
image: opencti/platform:5.2.1
environment:
- NODE_OPTIONS=--max-old-space-size=8096
- APP__PORT=8080
- APP__ADMIN__EMAIL=${OPENCTI_ADMIN_EMAIL}
- APP__ADMIN__PASSWORD=${OPENCTI_ADMIN_PASSWORD}
- APP__ADMIN__TOKEN=${OPENCTI_ADMIN_TOKEN}
- APP__APP_LOGS__LOGS_LEVEL=error
- REDIS__HOSTNAME=redis
- REDIS__PORT=6379
- ELASTICSEARCH__URL=http://elasticsearch:9200
- MINIO__ENDPOINT=minio
- MINIO__PORT=9000
- MINIO__USE_SSL=false
- MINIO__ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO__SECRET_KEY=${MINIO_ROOT_PASSWORD}
- RABBITMQ__HOSTNAME=rabbitmq
- RABBITMQ__PORT=5672
- RABBITMQ__PORT_MANAGEMENT=15672
- RABBITMQ__MANAGEMENT_SSL=false
- RABBITMQ__USERNAME=${RABBITMQ_DEFAULT_USER}
- RABBITMQ__PASSWORD=${RABBITMQ_DEFAULT_PASS}
- SMTP__HOSTNAME=${SMTP_HOSTNAME}
- SMTP__PORT=25
- PROVIDERS__LOCAL__STRATEGY=LocalStrategy
ports:
- "8080:8080"
depends_on:
- redis
- elasticsearch
- minio
- rabbitmq
restart: always
worker:
image: opencti/worker:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- WORKER_LOG_LEVEL=info
depends_on:
- opencti
deploy:
mode: replicated
replicas: 3
restart: always
connector-history:
image: opencti/connector-history:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_HISTORY_ID} # Valid UUIDv4
- CONNECTOR_TYPE=STREAM
- CONNECTOR_NAME=History
- CONNECTOR_SCOPE=history
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
connector-export-file-stix:
image: opencti/connector-export-file-stix:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_EXPORT_FILE_STIX_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
- CONNECTOR_NAME=ExportFileStix2
- CONNECTOR_SCOPE=application/json
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
connector-export-file-csv:
image: opencti/connector-export-file-csv:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_EXPORT_FILE_CSV_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
- CONNECTOR_NAME=ExportFileCsv
- CONNECTOR_SCOPE=text/csv
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
connector-export-file-txt:
image: opencti/connector-export-file-txt:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_EXPORT_FILE_TXT_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
- CONNECTOR_NAME=ExportFileTxt
- CONNECTOR_SCOPE=text/plain
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
connector-import-file-stix:
image: opencti/connector-import-file-stix:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_IMPORT_FILE_STIX_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_IMPORT_FILE
- CONNECTOR_NAME=ImportFileStix
- CONNECTOR_VALIDATE_BEFORE_IMPORT=true # Validate any bundle before import
- CONNECTOR_SCOPE=application/json,text/xml
- CONNECTOR_AUTO=true # Enable/disable auto-import of file
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
connector-import-document:
image: opencti/connector-import-document:5.2.1
environment:
- OPENCTI_URL=http://opencti:8080
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_IMPORT_DOCUMENT_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_IMPORT_FILE
- CONNECTOR_NAME=ImportDocument
- CONNECTOR_VALIDATE_BEFORE_IMPORT=true # Validate any bundle before import
- CONNECTOR_SCOPE=application/pdf,text/plain,text/html
- CONNECTOR_AUTO=true # Enable/disable auto-import of file
- CONNECTOR_ONLY_CONTEXTUAL=false # Only extract data related to an entity (a report, a threat actor, etc.)
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
- IMPORT_DOCUMENT_CREATE_INDICATOR=true
restart: always
depends_on:
- opencti
networks:
default:
external:
name: minharede #network created for the purpose
volumes:
esdata:
s3data:
redisdata:
amqpdata:
Docker-Compose file Container B:
version: '3.4'
services:
teste:
image: teste
build:
context: .
dockerfile: ./Dockerfile
networks:
default:
external:
name: minharede #docker network created for the purpose
The config.yml of container B is:
opencti:
url: "http://localhost:8080"
token: "xxxxxxxxxxxxxxxxxxxxxxxxxxx" #is hidden to post here
connector:
id: "245b2de5-b85e-4236-bedd-97540b133ea2"
type: "INTERNAL_ENRICHMENT"
name: "osthreatenrichment"
scope: "IPv4-Addr, IPv6-Addr, Domain-Name"
auto: true
confidence_level: 70 #From 0 (unknown) to 100 (Fully trusted)
log_level: "info"
When I try to run my container B on Visual Code to test it (it’s connected to the docker), I get this error:
Exception has occurred: ValueError OpenCTI API is not reachable.
Waiting for OpenCTI API to start or check your configuration…
Anyone can helpe me?? Thank you guys!
3
Answers
First of all, during debug in VSCode that is connected to the Docker, the container in development (Cntainer B) connects a default network, in my case was a network called "bridge" . Consequently, I wasn't getting a connection to the same network that container OpenCTI and to solve this I performed the reverse, I connected the container OpenCTI to the network "bridge" where my container in development is connected. After that, I went to check the IP address of the service in my container OpenCTI that I wanted get a connection from container B, and I changed the url from
http://opencti:8080
tohttp://172.xx.x.x:8080
(you only have to replace xx by the correct numbers of the IP address) and worked fine for me!!The compose reference has this example:
And it states:
You need to specify the network definition at the top level of your compose file, and in your service definition you need to specify the named network.
However that’s not the whole story. As @davidmaze suggests, it will be easier to accomplish this within one compose file rather than multiple. Docker compose treats each compose as a separate "app" and everything within a compose is "namespaced" to that app.
In order to get what you want you’ll need to host your named network outside of the compose file. The
docker network
command is the direction you’d have to go in, but I think a whole tutorial on how to achieve this is outside the scope of an SO answer.In order to maintain a solution to this, every developer workstation would have to hold and maintain an identically configured named network which both compose-apps could join. This is counterproductive — the point of developing within a docker compose is to hold the entire development environment within the repository itself.
In any case, the key component is building a named network on your workstation with
docker network create <name>
and then attaching to it within your compose file via theexternal
attribute.https://docs.docker.com/compose/networking/#use-a-pre-existing-network (scroll up just a tad, the documentation site for docker misaligns by about 150px when an #anchor is loaded):
You are using
http://localhost:8080
as the target, which cannot work, as each container is its ownlocalhost
.Change it to the target container’s network alias (compose service name). In this case
opencti
.When I replicate your setup, I get a deprecation warning
I have fixed this warning, and could successfully create the setup.
First, I create the network:
Then, I create a dummy service in a.yaml and run
docker compose -p a -f a.yaml up -d
:Finally, I create another service in a different file to curl for the network alias
whoami
of the service.When, I run
docker compose -p b -f b.yaml up
I can see the following output.So what you are trying to do is certainly possible. You are just using the wrong hostname. In my example, you can see the service name in the compose file of the service I am trying to curl is
my-svc
. That’s also what I am using for the hostname in the curl command.You could actually simplify this by not using an external network for
a
but still referencea's
default network as external inb
.Then you only need to make sure you start
a
beforeb
.