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
In DefectDojo the default values of the container are very high so for testing or for environments with very low capacity it is advisable to decrease them leaving at least 4gb of memory and 2 CPUs
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
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.
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:
- Taking into account that the helm content of DefectDojo is contained in 'helm/defectdojo'.
- You use 'helm upgrade --install' because if it does not exist, install it and if it does exist, upgrade it.
- Use '--create-namespace' to create the namespace in Kuberentes if it is not already created.
- 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)"