Instalación
Para proceder a la instalacion de DefectDojo en nuestra plataforma como con otras herramientas primero necesitamos clonar el repositorio del mismo, para asi poder ver los valores que deseamos utilizar en nuestro despliegue.
https://github.com/DefectDojo/django-DefectDojo
Clonamos el repositorio
git clone https://github.com/DefectDojo/django-DefectDojo
Vamos al directorio recien clonado.
cd django-DefectDojo
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
Creamos la red para conectar el defectdojo con el traefik
docker network create defectd
Modificamos el archivo docker-compose.yml
para conectarlo al balanceador. Para ello, debemos eliminar los puertos que exponemos y añadir la red a los contenedores. Dado que DefectDojo puede configurarse de múltiples maneras, eliminamos los contenedores que no necesitamos. En nuestro caso, vamos a utilizar la combinación de MySQL con Redis, quedando el fichero de la siguiente manera:
Tenemos que cambiar en el label de traefik del Host example.com
por el dominio que queramos.
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
Antes de arrancarlo acordaros de añadir la red en traefik
copias las variables de entorno de mysql-redis a la carpeta raiz
cp docker/environments/mysql-redis.env .env
Arrancamos los contenedores. Esto puede llevar algún tiempo, ya que no hay imágenes oficiales disponibles en Docker Hub. En su lugar, se construyen en el momento a partir del código clonado.
docker-compose up -d
Para obtener la contraseña de root tenemos que hacer
docker compose logs initializer | grep "Admin password:"
Si en alguna momento se nos olvida la contraseña podemos crear un nuevo super usuario
docker compose exec uwsgi /bin/bash -c 'python manage.py createsuperuser'
Kubernetes
Y procederemos a modificar el values.yaml. En el values.yaml debemos tener los siguientes parametros modificados.
# 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"
Los valores del nginx.ingress deben modificarse para que tolere cargas mayores al momento de subir reportes o bajarlos
En DefectDojo al no existir un chart de Helm debemos instalarlo de la siguiente manera
helm upgrade --install defect-dojo helm/defectdojo -f helm/defectdojo/values.yaml -n defect-dojo --create-namespace
Del anterior comando podemos notar los siguientes detalle:
- Tomando en cuenta que el contenido helm de DefectDojo esta contenido en 'helm/defectdojo'.
- Se usa 'helm upgrade --install' porque si no existe los instale y si existe lo actualice.
- Se usa '--create-namespace' para que cree el namespace en Kuberentes si no esta creado.
- Se usa '-n defect-dojo' para indicar el namespace donde queremos instalar nuestra aplicacion.
Una vez instalado el DefectDojo procederemos a extraer la password inicial para conectarnos.
Para obtener el password inicial ejecutamos
echo "DefectDojo admin password: $(kubectl \
get secret defectdojo \
--namespace=defectd \
--output jsonpath='{.data.DD_ADMIN_PASSWORD}' \
| base64 --decode)"