diff --git a/.env b/.env index fc630c7c..d23446ce 100644 --- a/.env +++ b/.env @@ -100,6 +100,18 @@ TPOT_ATTACKMAP_TEXT_TIMEZONE=UTC # OINKCODE: Replace OPEN with your Oinkcode to use the ET Pro ruleset OINKCODE=OPEN +# Beelzebub Honeypot supports LLMs such as ChatGPT and the Ollama backend. +# Beelzebub is not part of the standard edition, please follow the README regarding setup. +# It is recommended to use the Ollama backend to keep costs at bay. +# Remember to rate limit API usage / set budget alerts when using ChatGPT API. +# LLMMODEL: Set to "ollama" or "gpt4-o". +# LLMHOST: When using "ollama" set it to the URL of your Ollama backend. +# OLLAMAMODEL: Set to the model you are serving on your Ollama backend, i.e. "llama3.1". +LLMMODEL: "ollama" +LLMHOST: "http://ollama.local:11434/api/chat" +OLLAMAMODEL: "llama3.1" +#LLMMODEL: "gpt4-o" +#OPENAISECRETKEY: "sk-proj-123456" ################################################################################### # NEVER MAKE CHANGES TO THIS SECTION UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!!! # @@ -128,7 +140,7 @@ TPOT_VERSION=24.04 # never: Compose implementations SHOULD NOT pull the image from a registry and SHOULD rely on the platform cached image. # missing: Compose implementations SHOULD pull the image only if it's not available in the platform cache. # build: Compose implementations SHOULD build the image. Compose implementations SHOULD rebuild the image if already present. -TPOT_PULL_POLICY=always +TPOT_PULL_POLICY=never # T-Pot Data Path TPOT_DATA_PATH=./data diff --git a/README.md b/README.md index 43e9a158..aeb1db7d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ T-Pot is the all in one, optionally distributed, multiarch (amd64, arm64) honeyp 4. Install `curl`: `$ sudo [apt, dnf, zypper] install curl` if not installed already 5. Run installer as non-root from `$HOME`: ``` -env bash -c "$(curl -sL https://github.com/telekom-security/tpotce/raw/master/install.sh)" +env bash -c "$(curl -sL https://github.com/telekom-security/tpotce/raw/master/install.sh -b 24.04.1)" ``` * Follow instructions, read messages, check for possible port conflicts and reboot diff --git a/compose/llm.yml b/compose/llm.yml new file mode 100644 index 00000000..0c4efd7c --- /dev/null +++ b/compose/llm.yml @@ -0,0 +1,305 @@ +# T-Pot: LLM +networks: + beelzebub_local: + spiderfoot_local: + ewsposter_local: + +services: + +######################################### +#### DEV +######################################### +#### T-Pot Init - Never delete this! +######################################### + +# T-Pot Init Service + tpotinit: + container_name: tpotinit + env_file: + - .env + restart: always + stop_grace_period: 60s + tmpfs: + - /tmp/etc:uid=2000,gid=2000 + - /tmp/:uid=2000,gid=2000 + network_mode: "host" + cap_add: + - NET_ADMIN + image: ${TPOT_REPO}/tpotinit:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DOCKER_COMPOSE}:/tmp/tpot/docker-compose.yml:ro + - ${TPOT_DATA_PATH}/blackhole:/etc/blackhole + - ${TPOT_DATA_PATH}:/data + - /var/run/docker.sock:/var/run/docker.sock:ro + + +################## +#### Honeypots +################## + +# Beelzebub service + beelzebub: + container_name: beelzebub + restart: always + depends_on: + tpotinit: + condition: service_healthy +# cpu_count: 1 +# cpus: 0.25 + networks: + - beelzebub_local + ports: + - "22:22" + - "80:80" + # - "2222:2222" + # - "3306:3306" + # - "8080:8080" + image: ${TPOT_REPO}/beelzebub:${TPOT_VERSION} + environment: + LLMMODEL: ${LLMMODEL} + LLMHOST: ${LLMHOST} + OLLAMAMODEL: ${OLLAMAMODEL} + read_only: true + volumes: + - ${TPOT_DATA_PATH}/beelzebub/key:/opt/beelzebub/configurations/key + - ${TPOT_DATA_PATH}/beelzebub/log:/opt/beelzebub/configurations/log + +################## +#### NSM +################## + +# Fatt service + fatt: + container_name: fatt + restart: always + depends_on: + tpotinit: + condition: service_healthy + network_mode: "host" + cap_add: + - NET_ADMIN + - SYS_NICE + - NET_RAW + image: ${TPOT_REPO}/fatt:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DATA_PATH}/fatt/log:/opt/fatt/log + +# P0f service + p0f: + container_name: p0f + restart: always + depends_on: + tpotinit: + condition: service_healthy + network_mode: "host" + image: ${TPOT_REPO}/p0f:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + read_only: true + volumes: + - ${TPOT_DATA_PATH}/p0f/log:/var/log/p0f + +# Suricata service + suricata: + container_name: suricata + restart: always + depends_on: + tpotinit: + condition: service_healthy + environment: + - OINKCODE=${OINKCODE:-OPEN} # Default to OPEN if unset or NULL (value provided by T-Pot .env) + # Loading external Rules from URL + # - FROMURL="https://username:password@yoururl.com|https://username:password@otherurl.com" + network_mode: "host" + cap_add: + - NET_ADMIN + - SYS_NICE + - NET_RAW + image: ${TPOT_REPO}/suricata:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DATA_PATH}/suricata/log:/var/log/suricata + + +################## +#### Tools +################## + +#### ELK +## Elasticsearch service + elasticsearch: + container_name: elasticsearch + restart: always + depends_on: + tpotinit: + condition: service_healthy + environment: + - bootstrap.memory_lock=true + - ES_JAVA_OPTS=-Xms2048m -Xmx2048m + - ES_TMPDIR=/tmp + cap_add: + - IPC_LOCK + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + mem_limit: 4g + ports: + - "127.0.0.1:64298:9200" + image: ${TPOT_REPO}/elasticsearch:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DATA_PATH}:/data + +## Kibana service + kibana: + container_name: kibana + restart: always + depends_on: + elasticsearch: + condition: service_healthy + mem_limit: 1g + ports: + - "127.0.0.1:64296:5601" + image: ${TPOT_REPO}/kibana:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + +## Logstash service + logstash: + container_name: logstash + restart: always + depends_on: + elasticsearch: + condition: service_healthy + environment: + - LS_JAVA_OPTS=-Xms1024m -Xmx1024m + - TPOT_TYPE=${TPOT_TYPE:-HIVE} + - TPOT_HIVE_USER=${TPOT_HIVE_USER} + - TPOT_HIVE_IP=${TPOT_HIVE_IP} + - LS_SSL_VERIFICATION=${LS_SSL_VERIFICATION:-full} + ports: + - "127.0.0.1:64305:64305" + mem_limit: 2g + image: ${TPOT_REPO}/logstash:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DATA_PATH}:/data + +## Map Redis Service + map_redis: + container_name: map_redis + restart: always + depends_on: + tpotinit: + condition: service_healthy + stop_signal: SIGKILL + tty: true + image: ${TPOT_REPO}/redis:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + read_only: true + +## Map Web Service + map_web: + container_name: map_web + restart: always + depends_on: + tpotinit: + condition: service_healthy + environment: + - MAP_COMMAND=AttackMapServer.py + stop_signal: SIGKILL + tty: true + ports: + - "127.0.0.1:64299:64299" + image: ${TPOT_REPO}/map:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + +## Map Data Service + map_data: + container_name: map_data + restart: always + depends_on: + elasticsearch: + condition: service_healthy + environment: + - MAP_COMMAND=DataServer_v2.py + - TPOT_ATTACKMAP_TEXT=${TPOT_ATTACKMAP_TEXT} + - TZ=${TPOT_ATTACKMAP_TEXT_TIMEZONE} + stop_signal: SIGKILL + tty: true + image: ${TPOT_REPO}/map:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} +#### /ELK + +# Ewsposter service + ewsposter: + container_name: ewsposter + restart: always + depends_on: + tpotinit: + condition: service_healthy + networks: + - ewsposter_local + environment: + - EWS_HPFEEDS_ENABLE=false + - EWS_HPFEEDS_HOST=host + - EWS_HPFEEDS_PORT=port + - EWS_HPFEEDS_CHANNELS=channels + - EWS_HPFEEDS_IDENT=user + - EWS_HPFEEDS_SECRET=secret + - EWS_HPFEEDS_TLSCERT=false + - EWS_HPFEEDS_FORMAT=json + image: ${TPOT_REPO}/ewsposter:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DATA_PATH}:/data + - ${TPOT_DATA_PATH}/ews/conf/ews.ip:/opt/ewsposter/ews.ip + +# Nginx service + nginx: + container_name: nginx + restart: always + environment: + - TPOT_OSTYPE=${TPOT_OSTYPE} + depends_on: + tpotinit: + condition: service_healthy + tmpfs: + - /var/tmp/nginx/client_body + - /var/tmp/nginx/proxy + - /var/tmp/nginx/fastcgi + - /var/tmp/nginx/uwsgi + - /var/tmp/nginx/scgi + - /run + - /var/lib/nginx/tmp:uid=100,gid=82 + network_mode: "host" + ports: + - "64297:64297" + image: ${TPOT_REPO}/nginx:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + read_only: true + volumes: + - ${TPOT_DATA_PATH}/nginx/cert/:/etc/nginx/cert/:ro + - ${TPOT_DATA_PATH}/nginx/conf/nginxpasswd:/etc/nginx/nginxpasswd:ro + - ${TPOT_DATA_PATH}/nginx/conf/lswebpasswd:/etc/nginx/lswebpasswd:ro + - ${TPOT_DATA_PATH}/nginx/log/:/var/log/nginx/ + +# Spiderfoot service + spiderfoot: + container_name: spiderfoot + restart: always + depends_on: + tpotinit: + condition: service_healthy + networks: + - spiderfoot_local + ports: + - "127.0.0.1:64303:8080" + image: ${TPOT_REPO}/spiderfoot:${TPOT_VERSION} + pull_policy: ${TPOT_PULL_POLICY} + volumes: + - ${TPOT_DATA_PATH}/spiderfoot:/home/spiderfoot/.spiderfoot diff --git a/docker/beelzebub/Dockerfile b/docker/beelzebub/Dockerfile new file mode 100644 index 00000000..e131ce66 --- /dev/null +++ b/docker/beelzebub/Dockerfile @@ -0,0 +1,35 @@ +FROM golang:alpine AS builder +# +ENV GO111MODULE=on \ + CGO_ENABLED=0 \ + GOOS=linux +# +RUN apk add git +# +WORKDIR /root +# +# Build beelzebub +RUN git clone https://github.com/t3chn0m4g3/beelzebub +WORKDIR /root/beelzebub +RUN go mod download +RUN go build -o main . +# +FROM alpine:3.20 +# +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=builder /root/beelzebub/main /opt/beelzebub/ +COPY --from=builder /root/beelzebub/configurations /opt/beelzebub/configurations +# +# Setup user, groups and configs +RUN sed -i "s#logsPath: ./log#logsPath: ./configurations/log/beelzebub.json#g" /opt/beelzebub/configurations/beelzebub.yaml && \ + addgroup -g 2000 beelzebub && \ + adduser -S -s /bin/ash -u 2000 -D -g 2000 beelzebub && \ + mkdir -p /beelzebub/configurations/key \ + /beelzebub/configurations/log && \ + chown beelzebub:beelzebub -R /opt/beelzebub/configurations && \ + chmod 0770 -R /opt/beelzebub/configurations +# +# Start beelzebub +WORKDIR /opt/beelzebub +USER beelzebub:beelzebub +CMD ["./main"] \ No newline at end of file diff --git a/docker/beelzebub/docker-compose.yml b/docker/beelzebub/docker-compose.yml new file mode 100644 index 00000000..4a5ab4f9 --- /dev/null +++ b/docker/beelzebub/docker-compose.yml @@ -0,0 +1,30 @@ +networks: + beelzebub_local: + +services: + +# Beelzebub service + beelzebub: + build: . + container_name: beelzebub + restart: always +# cpu_count: 1 +# cpus: 0.25 + networks: + - beelzebub_local + ports: + - "22:22" + - "2222:2222" + - "8080:8080" + - "8081:8081" + - "80:80" + - "3306:3306" + environment: + LLMMODEL: "ollama" + LLMHOST: "http://ollama.local:11434/api/chat" + OLLAMAMODEL: "llama3.1" + image: "dtagdevsec/beelzebub:24.04" + read_only: true + volumes: + - $HOME/tpotce/data/beelzebub/key:/opt/beelzebub/configurations/key + - $HOME/tpotce/data/beelzebub/log:/opt/beelzebub/configurations/log diff --git a/docker/elk/logstash/dist/http_output.conf b/docker/elk/logstash/dist/http_output.conf index 5889ba31..62fba9ff 100644 --- a/docker/elk/logstash/dist/http_output.conf +++ b/docker/elk/logstash/dist/http_output.conf @@ -29,6 +29,13 @@ input { type => "Adbhoney" } +# Beelzebub + file { + path => ["/data/beelzebub/log/beelzebub.json"] + codec => json + type => "Beelzebub" + } + # Ciscoasa file { path => ["/data/ciscoasa/log/ciscoasa.log"] @@ -253,6 +260,13 @@ filter { } } +# Beelzebub + if [type] == "Beelzebub" { + date { + match => [ "timestamp", "ISO8601" ] + } + } + # Ciscoasa if [type] == "Ciscoasa" { kv { diff --git a/docker/elk/logstash/dist/logstash.conf b/docker/elk/logstash/dist/logstash.conf index 68a2b1d5..77ebb22f 100644 --- a/docker/elk/logstash/dist/logstash.conf +++ b/docker/elk/logstash/dist/logstash.conf @@ -29,6 +29,13 @@ input { type => "Adbhoney" } +# Beelzebub + file { + path => ["/data/beelzebub/log/beelzebub.json"] + codec => json + type => "Beelzebub" + } + # Ciscoasa file { path => ["/data/ciscoasa/log/ciscoasa.log"] @@ -253,6 +260,13 @@ filter { } } +# Beelzebub + if [type] == "Beelzebub" { + date { + match => [ "timestamp", "ISO8601" ] + } + } + # Ciscoasa if [type] == "Ciscoasa" { kv { diff --git a/docker/elk/map/Dockerfile b/docker/elk/map/Dockerfile index 9d7165f8..c490eb50 100644 --- a/docker/elk/map/Dockerfile +++ b/docker/elk/map/Dockerfile @@ -13,7 +13,7 @@ RUN apk -U --no-cache add \ # Install from GitHub and setup mkdir -p /opt && \ cd /opt/ && \ - git clone https://github.com/t3chn0m4g3/t-pot-attack-map -b 2.2.0 && \ + git clone https://github.com/t3chn0m4g3/t-pot-attack-map -b 2.2.1 && \ cd t-pot-attack-map && \ pip3 install --break-system-packages --upgrade pip && \ pip3 install --break-system-packages -r requirements.txt && \ diff --git a/docker/tpotinit/dist/bin/clean.sh b/docker/tpotinit/dist/bin/clean.sh index 897d08a0..e4a5b8c2 100755 --- a/docker/tpotinit/dist/bin/clean.sh +++ b/docker/tpotinit/dist/bin/clean.sh @@ -87,7 +87,7 @@ fuTPOTINIT () { chown tpot:tpot /tmp/etc/ -R } -# Let's create a function to clean up and prepare honeytrap data +# Let's create a function to clean up and prepare adbhoney data fuADBHONEY () { if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/adbhoney/*; fi mkdir -vp /data/adbhoney/{downloads,log} @@ -95,6 +95,14 @@ fuADBHONEY () { chown tpot:tpot /data/adbhoney/ -R } +# Let's create a function to clean up and prepare beelzebub data +fuBEELZEBUB () { + if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/beelzebub/*; fi + mkdir -vp /data/beelzebub/{key,log} + chmod 770 /data/beelzebub/ -R + chown tpot:tpot /data/beelzebub/ -R +} + # Let's create a function to clean up and prepare ciscoasa data fuCISCOASA () { if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/ciscoasa/*; fi @@ -362,6 +370,7 @@ echo echo "Checking and preparing data folders." fuTPOTINIT fuADBHONEY +fuBEELZEBUB fuCISCOASA fuCITRIXHONEYPOT fuCONPOT diff --git a/docker/tpotinit/dist/etc/logrotate/logrotate.conf b/docker/tpotinit/dist/etc/logrotate/logrotate.conf index 90178dbe..9576fb47 100644 --- a/docker/tpotinit/dist/etc/logrotate/logrotate.conf +++ b/docker/tpotinit/dist/etc/logrotate/logrotate.conf @@ -1,5 +1,6 @@ /data/adbhoney/log/*.json /data/adbhoney/log/*.log +/data/beelzebub/log/*.json /data/ciscoasa/log/ciscoasa.log /data/citrixhoneypot/logs/server.log /data/conpot/log/conpot*.json diff --git a/docker/tpotinit/dist/etc/objects/elkbase.tgz b/docker/tpotinit/dist/etc/objects/elkbase.tgz index 002c28b5..d28752f6 100644 Binary files a/docker/tpotinit/dist/etc/objects/elkbase.tgz and b/docker/tpotinit/dist/etc/objects/elkbase.tgz differ diff --git a/docker/tpotinit/dist/etc/objects/kibana_export.ndjson.zip b/docker/tpotinit/dist/etc/objects/kibana_export.ndjson.zip index b939639b..9419af18 100644 Binary files a/docker/tpotinit/dist/etc/objects/kibana_export.ndjson.zip and b/docker/tpotinit/dist/etc/objects/kibana_export.ndjson.zip differ diff --git a/env.example b/env.example index fc630c7c..65d8dec6 100644 --- a/env.example +++ b/env.example @@ -100,6 +100,18 @@ TPOT_ATTACKMAP_TEXT_TIMEZONE=UTC # OINKCODE: Replace OPEN with your Oinkcode to use the ET Pro ruleset OINKCODE=OPEN +# Beelzebub Honeypot supports LLMs such as ChatGPT and the Ollama backend. +# Beelzebub is not part of the standard edition, please follow the README regarding setup. +# It is recommended to use the Ollama backend to keep costs at bay. +# Remember to rate limit API usage / set budget alerts when using ChatGPT API. +# LLMMODEL: Set to "ollama" or "gpt4-o". +# LLMHOST: When using "ollama" set it to the URL of your Ollama backend. +# OLLAMAMODEL: Set to the model you are serving on your Ollama backend, i.e. "llama3.1". +LLMMODEL: "ollama" +LLMHOST: "http://ollama.local:11434/api/chat" +OLLAMAMODEL: "llama3.1" +#LLMMODEL: "gpt4-o" +#OPENAISECRETKEY: "sk-proj-123456" ################################################################################### # NEVER MAKE CHANGES TO THIS SECTION UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!!! # diff --git a/install.sh b/install.sh index 6604bb1e..9cba3e7f 100755 --- a/install.sh +++ b/install.sh @@ -119,7 +119,7 @@ fi if [ ! -f installer/install/tpot.yml ] && [ ! -f tpot.yml ]; then echo "### Now downloading T-Pot Ansible Installation Playbook ... " - wget -qO tpot.yml https://github.com/telekom-security/tpotce/raw/master/installer/install/tpot.yml + wget -qO tpot.yml https://raw.githubusercontent.com/telekom-security/tpotce/24.04.1/installer/install/tpot.yml myANSIBLE_TPOT_PLAYBOOK="tpot.yml" echo else diff --git a/installer/install/tpot.yml b/installer/install/tpot.yml index 78631670..4d77184f 100644 --- a/installer/install/tpot.yml +++ b/installer/install/tpot.yml @@ -761,7 +761,7 @@ git: repo: 'https://github.com/telekom-security/tpotce' dest: '/home/{{ ansible_user_id }}/tpotce/' - version: master + version: 24.04.1 clone: yes update: no when: ansible_distribution in ["AlmaLinux", "Debian", "Fedora", "openSUSE Tumbleweed", "Raspbian", "Rocky", "Ubuntu"] diff --git a/update.sh b/update.sh index 46888c4c..3dfbf5a2 100755 --- a/update.sh +++ b/update.sh @@ -61,7 +61,7 @@ function fuSELFUPDATE () { return fi ### DEV - myRESULT=$(git diff --name-only origin/master | grep "^update.sh") + myRESULT=$(git diff --name-only origin/24.04.1 | grep "^update.sh") if [ "$myRESULT" == "update.sh" ]; then echo "###### $myBLUE""Found newer version, will be pulling updates and restart myself.""$myWHITE"