Skip to main content

Installation

To proceed with the installation of DefectDojo on our platform as with other tools we first need to clone the DefectDojo repository, so we can see the values we want to use in our deployment.

https://github.com/DefectDojo/django-DefectDojo

Clone the repository

git clone https://github.com/DefectDojo/django-DefectDojo

Let's go to the newly cloned directory.

cd django-DefectDojo
warning

En DefectDojo los valores por defecto del contenedor son muy altos asi que para hacer pruebas o para entornos con muy poca capacidad es recomendable disminuirlos dejando al menos con 4gb de memoria y 2 CPU

Docker-Compose

We create the network to connect the defectdojo to the traefik

docker network create defectd

We modify the file docker-compose.yml to connect it to the balancer. To do this, we must remove the ports we expose and add the network to the containers. Since DefectDojo can be configured in multiple ways, we remove the containers we don't need. In our case, we are going to use the combination of MySQL with Redis, leaving the file as follows:

We have to change in the label of traefik of the Host example.com for the domain that we want.

version: '3.8'
services:
nginx:
build:
context: ./
dockerfile: "Dockerfile.nginx-${DEFECT_DOJO_OS:-debian}"
image: "defectdojo/defectdojo-nginx:${NGINX_VERSION:-latest}"
depends_on:
- uwsgi
environment:
NGINX_METRICS_ENABLED: "${NGINX_METRICS_ENABLED:-false}"
volumes:
- defectdojo_media:/usr/share/nginx/html/media
labels:
- "traefik.enable=true"
- "traefik.http.routers.defectd.rule=Host(`example.com`)"
- "traefik.http.routers.defectd.entrypoints=websecure"
- "traefik.http.routers.defectd.tls=true"
- "traefik.http.routers.defectd.tls.certresolver=le"
- "traefik.http.services.defectd-service.loadbalancer.server.port=8080"
networks:
- defectd
uwsgi:
build:
context: ./
dockerfile: "Dockerfile.django-${DEFECT_DOJO_OS:-debian}"
target: django
image: "defectdojo/defectdojo-django:${DJANGO_VERSION:-latest}"
depends_on:
- mysql
entrypoint: ['/wait-for-it.sh', '${DD_DATABASE_HOST}:${DD_DATABASE_PORT}', '-t', '30', '--', '/entrypoint-uwsgi.sh']
environment:
DD_DEBUG: 'False'
DD_DJANGO_METRICS_ENABLED: "${DD_DJANGO_METRICS_ENABLED:-False}"
DD_ALLOWED_HOSTS: "${DD_ALLOWED_HOSTS:-*}"
DD_DATABASE_URL: ${DD_DATABASE_URL}
DD_CELERY_BROKER_URL: ${DD_CELERY_BROKER_URL}
DD_SECRET_KEY: "${DD_SECRET_KEY:-hhZCp@D28z!n@NED*yB!ROMt+WzsY*iq}"
DD_CREDENTIAL_AES_256_KEY: "${DD_CREDENTIAL_AES_256_KEY:-&91a*agLqesc*0DJ+2*bAbsUZfR*4nLw}"
volumes:
- type: bind
source: ./docker/extra_settings
target: /app/docker/extra_settings
- "defectdojo_media:${DD_MEDIA_ROOT:-/app/media}"
networks:
- defectd
labels:
- "traefik.enable=false"
celerybeat:
image: "defectdojo/defectdojo-django:${DJANGO_VERSION:-latest}"
depends_on:
- mysql
- redis
entrypoint: ['/wait-for-it.sh', '${DD_DATABASE_HOST}:${DD_DATABASE_PORT}', '-t', '30', '--', '/entrypoint-celery-beat.sh']
environment:
DD_DATABASE_URL: ${DD_DATABASE_URL}
DD_CELERY_BROKER_URL: ${DD_CELERY_BROKER_URL}
DD_SECRET_KEY: "${DD_SECRET_KEY:-hhZCp@D28z!n@NED*yB!ROMt+WzsY*iq}"
DD_CREDENTIAL_AES_256_KEY: "${DD_CREDENTIAL_AES_256_KEY:-&91a*agLqesc*0DJ+2*bAbsUZfR*4nLw}"
volumes:
- type: bind
source: ./docker/extra_settings
target: /app/docker/extra_settings
networks:
- defectd
labels:
- "traefik.enable=false"
celeryworker:
image: "defectdojo/defectdojo-django:${DJANGO_VERSION:-latest}"
depends_on:
- mysql
- redis
entrypoint: ['/wait-for-it.sh', '${DD_DATABASE_HOST}:${DD_DATABASE_PORT}', '-t', '30', '--', '/entrypoint-celery-worker.sh']
environment:
DD_DATABASE_URL: ${DD_DATABASE_URL}
DD_CELERY_BROKER_URL: ${DD_CELERY_BROKER_URL}
DD_SECRET_KEY: "${DD_SECRET_KEY:-hhZCp@D28z!n@NED*yB!ROMt+WzsY*iq}"
DD_CREDENTIAL_AES_256_KEY: "${DD_CREDENTIAL_AES_256_KEY:-&91a*agLqesc*0DJ+2*bAbsUZfR*4nLw}"
volumes:
- type: bind
source: ./docker/extra_settings
target: /app/docker/extra_settings
- "defectdojo_media:${DD_MEDIA_ROOT:-/app/media}"
networks:
- defectd
labels:
- "traefik.enable=false"
initializer:
image: "defectdojo/defectdojo-django:${DJANGO_VERSION:-latest}"
depends_on:
- mysql
entrypoint: ['/wait-for-it.sh', '${DD_DATABASE_HOST}:${DD_DATABASE_PORT}', '--', '/entrypoint-initializer.sh']
environment:
DD_DATABASE_URL: ${DD_DATABASE_URL}
DD_ADMIN_USER: "${DD_ADMIN_USER:-admin}"
DD_ADMIN_MAIL: "${DD_ADMIN_USER:-admin@defectdojo.local}"
DD_ADMIN_FIRST_NAME: "${DD_ADMIN_FIRST_NAME:-Admin}"
DD_ADMIN_LAST_NAME: "${DD_ADMIN_LAST_NAME:-User}"
DD_INITIALIZE: "${DD_INITIALIZE:-true}"
DD_SECRET_KEY: "${DD_SECRET_KEY:-hhZCp@D28z!n@NED*yB!ROMt+WzsY*iq}"
DD_CREDENTIAL_AES_256_KEY: "${DD_CREDENTIAL_AES_256_KEY:-&91a*agLqesc*0DJ+2*bAbsUZfR*4nLw}"
volumes:
- type: bind
source: ./docker/extra_settings
target: /app/docker/extra_settings
networks:
- defectd
labels:
- "traefik.enable=false"
mysql:
image: mysql:5.7.44@sha256:4bc6bc963e6d8443453676cae56536f4b8156d78bae03c0145cbe47c2aad73bb
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
MYSQL_DATABASE: ${DD_DATABASE_NAME}
MYSQL_USER: ${DD_DATABASE_USER}
MYSQL_PASSWORD: ${DD_DATABASE_PASSWORD}
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']
volumes:
- defectdojo_data:/var/lib/mysql
networks:
- defectd
labels:
- "traefik.enable=false"
redis:
image: redis:7.2.4-alpine@sha256:1b503bb77079ba644371969e06e1a6a1670bb34c2251107c0fc3a21ef9fdaeca
volumes:
- defectdojo_redis:/data
networks:
- defectd
labels:
- "traefik.enable=false"
volumes:
defectdojo_data: {}
defectdojo_media: {}
defectdojo_redis: {}

networks:
defectd:
external: true
tip

Before starting it remember to add the network in traefik :

copy the mysql-redis environment variables to the root folder

cp docker/environments/mysql-redis.env .env

We started up the containers. This may take some time, as there are no official images available on Docker Hub. Instead, they are built on the fly from the cloned code.

docker-compose up -d

To get the root password we have to do the following

docker compose logs initializer | grep "Admin password:"

If at any time we forget the password we can create a new super user

docker compose exec uwsgi /bin/bash -c 'python manage.py createsuperuser'

Kubernetes

And we will proceed to modify the values.yaml. In the values.yaml we must have the following parameters modified.

# create defectdojo specific secret
createSecret: true
# create rabbitmq secret in defectdojo chart, outside of rabbitmq chart
createRabbitMqSecret: true
# create postgresql secret in defectdojo chart, outside of postgresql chart
createPostgresqlSecret: true
# Primary hostname of instance
host: defectd.yourdaomin.com

# The full URL to your defectdojo instance, depends on the domain where DD is deployed, it also affects links in Jira
site_url: 'http://defectd.yourdaomin.com'

#Admin user and password
admin:
user: admin
password: 123456

django:
annotations: {}
service:
annotations: {}
affinity: {}
ingress:
enabled: true
ingressClassName: "appsec-nginx"
activateTLS: true
secretName: "SECRET_CERT"
annotations:
# Restricts the type of ingress controller that can interact with our chart (nginx, traefik, ...)
# kubernetes.io/ingress.class: nginx
# Depending on the size and complexity of your scans, you might want to increase the default ingress timeouts if you see repeated 504 Gateway Timeouts
nginx.ingress.kubernetes.io/proxy-read-timeout: "1200s"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1200s"
nginx.ingress.kubernetes.io/proxy-body-size: 200m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "1200s"

The values of nginx.ingress should be modified to tolerate higher loads when uploading or downloading reports.

warning

In DefectDojo as there is no Helm chart we must install it as follows

helm upgrade --install defect-dojo helm/defectdojo -f helm/defectdojo/values.yaml -n defect-dojo --create-namespace

From the previous command we can note the following details:

  1. Taking into account that the helm content of DefectDojo is contained in 'helm/defectdojo'.
  2. You use 'helm upgrade --install' because if it does not exist, install it and if it does exist, upgrade it.
  3. Use '--create-namespace' to create the namespace in Kuberentes if it is not already created.
  4. We use '-n defect-dojo' to indicate the namespace where we want to install our application.

Once DefectDojo is installed, we will proceed to extract the initial password to connect.

To obtain the initial password we execute

echo "DefectDojo admin password: $(kubectl \
get secret defectdojo \
--namespace=defectd \
--output jsonpath='{.data.DD_ADMIN_PASSWORD}' \
| base64 --decode)"