Skip to content

DefectDojo Installation

This content is not available in your language yet.

DefectDojo is a Centralised Vulnerability Management


  • Security Context Configration with Official DefectDojo Helm Chart is not applicatable
    • As DefectDojo Container Images are not yet implement run as non-root user and requires Run as Root/Run with Privilege Exceptions.

DefectDojo will be installed on 🟢 Management Kubernetes Cluster

  • 📥Ingress Service provided as Kubernetes Ingress Class (IngressClass)
  • 🛡️TLS Certificate for DefectDojo provided as Kubernetes Secret
    • DefectDojo will be exposed as HTTPS with Kubernetes Ingress.

DefectDojo depends on multiple dependencies to be up and running but only the following will be provisioned and/or managed by you.

  • 📦PostgreSQL SQL Database ; Deploy external/dedicated instance of Database.
    • In case will be installed on Kubernetes Cluster.
      • Will require 💿Persistence Storage as Kubernetes Storage Class (StorageClass)

Once finished everything, these are systems that up and running.

No.ToolDescriptionKubernetes NamespaceKubernetes Cluster
1.PostgreSQL for DefectDojoDatabase System for DefectDojodevsecops-system🟢 Management
2.DefectDojoCentralised Vulnerability Managementdevsecops-system🟢 Management

Ensure you have defined and loaded your Global Shell Variables as described in Shell Variables.

  1. Connect to 🟢 Management Kubernetes Cluster ; i.e w/ Kubeconfig File

    Ensure you have defined and loaded your Global Shell Variables as described in Shell Variables.

    Terminal window
    source $HOME/opstella-installation/shell-values/kubernetes/management_cluster.vars.sh
    source $HOME/opstella-installation/shell-values/tools/defectdojo.vars.sh
    Terminal window
    export KUBECONFIG="$HOME/opstella-installation/kubeconfigs/management_cluster.yaml"
  2. Export Required Shell Variables

    Ensure DEFECTDOJO_DOMAIN, DEFECTDOJO_ADMIN_USERNAME, DEFECTDOJO_ADMIN_PASSWORD, and DEFECTDOJO_ADMIN_EMAIL are defined as per the Shell Variables guide.

    Ensure K8S_INTERNAL_DOMAIN, K8S_INGRESSCLASS_NAME, K8S_STORAGECLASS_NAME, K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME are defined as per the Shell Variables guide.

    Ensure KEYCLOAK_DOMAIN, KEYCLOAK_REALM are defined as per the Shell Variables guide. Additionally, export the following variables:

    Terminal window
    # PostgreSQL Backend Passwords
    export DEFECTDOJO_POSTGRES_SUPERUSER_PASSWORD="CHANGEME"
    export DEFECTDOJO_POSTGRES_USER_PASSWORD="CHANGEME"
  3. Create Kubernetes Secret for 🛡️ TLS Certificate for DefectDojo in Namespace devsecops-system.

    Kubernetes Ingress for DefectDojo will associate TLS Certificate with Kubernetes Secret named $K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME.

    Create one using from .crt and .key file.

    Terminal window
    kubectl create secret tls $K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME \
    --cert=/path/to/cert/file --key=/path/to/key/file \
    --namespace devsecops-system

    💡 Should return secret/... created message.

  1. Set PostgreSQL Information

    • Database Name: defectdojo (Defined in manifest)
    • Database User: defectdojo (Defined in manifest)
    • Database Password: ${DEFECTDOJO_POSTGRES_USER_PASSWORD} (Previously exported)
    • Postgres Superuser Password: ${DEFECTDOJO_POSTGRES_SUPERUSER_PASSWORD} (Previously exported)
  2. Provision PostgreSQL for DefectDojo

    The following manifest defines the entire PostgreSQL system, including credentials and the CNPG cluster.

    Terminal window
    kubectl apply --namespace devsecops-system -f - <<EOF
    ---
    # DefectDojo Postgres Superuser Credentials
    apiVersion: v1
    kind: Secret
    type: kubernetes.io/basic-auth
    metadata:
    name: defectdojo-postgres-superuser
    namespace: devsecops-system
    stringData:
    username: postgres
    password: "${DEFECTDOJO_POSTGRES_SUPERUSER_PASSWORD}"
    ---
    # DefectDojo Application User Credentials
    apiVersion: v1
    kind: Secret
    type: kubernetes.io/basic-auth
    metadata:
    name: defectdojo-postgres-user
    namespace: devsecops-system
    stringData:
    username: defectdojo
    password: "${DEFECTDOJO_POSTGRES_USER_PASSWORD}"
    ---
    # S3 Credentials for Postgres Backups (to SeaweedFS HA)
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
    name: defectdojo-postgres-s3-secret
    namespace: devsecops-system
    stringData:
    S3_ACCESS_KEY: "postgres-backup"
    S3_SECRET_KEY: "${SEAWEEDFS_HA_S3_POSTGRES_BACKUP_PASSWORD}"
    ---
    apiVersion: barmancloud.cnpg.io/v1
    kind: ObjectStore
    metadata:
    name: defectdojo-postgres-backup
    namespace: devsecops-system
    spec:
    # This resource defines the backup destination for the Barman Cloud Plugin
    configuration:
    destinationPath: s3://postgres-backups/
    endpointURL: http://seaweedfs-s3.apps-supporting-services.svc:9000
    s3Credentials:
    accessKeyId:
    name: defectdojo-postgres-s3-secret
    key: S3_ACCESS_KEY
    secretAccessKey:
    name: defectdojo-postgres-s3-secret
    key: S3_SECRET_KEY
    wal:
    compression: gzip
    data:
    compression: gzip
    # Retention policy for backups and WALs handled by the plugin
    retentionPolicy: "30d"
    ---
    apiVersion: postgresql.cnpg.io/v1
    kind: Cluster
    metadata:
    name: defectdojo-postgres
    namespace: devsecops-system
    labels:
    app.kubernetes.io/name: defectdojo-postgres
    app.kubernetes.io/part-of: defectdojo
    spec:
    instances: 1
    # Image configuration (Postgres 16)
    imageCatalogRef:
    apiGroup: postgresql.cnpg.io
    kind: ClusterImageCatalog
    name: postgresql-standard-trixie
    major: 16
    # Enable the Barman Cloud Plugin for backups
    plugins:
    - name: barman-cloud.cloudnative-pg.io
    isWALArchiver: true
    parameters:
    serverName: "defectdojo-postgres"
    barmanObjectName: "defectdojo-postgres-backup"
    # Storage Configuration
    storage:
    size: 5Gi
    storageClass: "${K8S_STORAGECLASS_NAME}"
    walStorage:
    size: 2Gi
    storageClass: "${K8S_STORAGECLASS_NAME}"
    # Bootstrap Configuration
    bootstrap:
    initdb:
    database: defectdojo
    owner: defectdojo
    secret:
    name: defectdojo-postgres-user
    # Superuser credentials (root/postgres)
    superuserSecret:
    name: defectdojo-postgres-superuser
    # Backup Configuration (Barman Cloud Plugin will automatically detect matching ObjectStore)
    backup:
    {}
    # Resources
    resources:
    requests:
    memory: "256Mi"
    cpu: "200m"
    limits:
    memory: "1Gi"
    cpu: "1000m"
    EOF

    💡 Should return secret/defectdojo-postgres-superuser, secret/defectdojo-postgres-user, and cluster.postgresql.cnpg.io/defectdojo-postgres created messages.

  3. Check for PostgreSQL for DefectDojo Readiness - MUST be Ready and Running.

    Get Pod Status - PostgreSQL for DefectDojo

    Terminal window
    kubectl get pods -n devsecops-system

    💡 PostgreSQL for DefectDojo Pods MUST be Running

    NAME READY STATUS RESTARTS AGE
    ... (deducted)
    defectdojo-postgres-1 2/2 Running 0 XdXh
    defectdojo-postgres-2 2/2 Running 0 XdXh
    defectdojo-postgres-3 2/2 Running 0 XdXh
  1. DefectDojo Entrypoint Domain

    • Domain: ${DEFECTDOJO_DOMAIN} (Previously exported)
  2. DefectDojo Initial Admin Account

    • Admin Username: ${DEFECTDOJO_ADMIN_USERNAME} (Previously exported)
    • Admin Password: ${DEFECTDOJO_ADMIN_PASSWORD} (Previously exported)
    • Admin Email: ${DEFECTDOJO_ADMIN_EMAIL} (Previously exported)
  3. Configure OIDC with Keycloak

    Ensure you have followed the Procuring Keycloak Credentials guide to obtain the client-id, client-secret, and signing-public-key for DefectDojo.

    Terminal window
    cat <<EOF > $HOME/opstella-installation/kubernetes-manifests/defectdojo-oidc.yaml
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
    name: defectdojo-oidc-configurations
    namespace: devsecops-system
    stringData:
    client-id: ""
    client-secret: ""
    authorization-endpoint: "https://${KEYCLOAK_DOMAIN}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/auth"
    access-token-endpoint: "https://${KEYCLOAK_DOMAIN}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token"
    signing-public-key: ""
    EOF

    Apply the OIDC configuration:

    Terminal window
    kubectl apply --namespace devsecops-system \
    -f $HOME/opstella-installation/kubernetes-manifests/defectdojo-oidc.yaml
  4. Create Helm Values Configurations

    Terminal window
    cat <<EOF > $HOME/opstella-installation/helm-values/defectdojo-full-values.yaml
    ---
    ## Application: Exposed Hostname (Ingress)
    host: "${DEFECTDOJO_DOMAIN}"
    site_url: "https://${DEFECTDOJO_DOMAIN}"
    ## Application: Configure RabbitMQ
    ## NOTE: Community Deprecate RabbitMQ on 2024-Q1 Updates, move to Redis; Retain for Older Helm Chart Version DefectDojo Deployment, Can be removed later
    ## See On: https://github.com/DefectDojo/django-DefectDojo/discussions/9690
    createRabbitMqSecret: true
    rabbitmq:
    ulimitNofiles: "" ## OPSTELLA_CUSTOMIZE: Eliminate ulimit Problem
    clusterDomain: "${K8S_INTERNAL_DOMAIN}"
    ## Application: Configure Redis
    createRedisSecret: true
    redis:
    image:
    repository: bitnamilegacy/redis
    clusterDomain: "${K8S_INTERNAL_DOMAIN}"
    master:
    persistence:
    storageClass: "${K8S_STORAGECLASS_NAME}"
    ## Kubernetes/Application: Authentication
    createSecret: true
    admin:
    user: "${DEFECTDOJO_ADMIN_USERNAME}"
    password: "${DEFECTDOJO_ADMIN_PASSWORD}"
    mail: "${DEFECTDOJO_ADMIN_EMAIL}"
    firstName: Defectdojo
    lastName: Administrator
    ## Application: Application Initializer ; For first time ONLY
    initializer:
    ## should be false after initial installation was performed
    run: true
    securityContext:
    enabled: true
    djangoSecurityContext:
    # django dockerfile sets USER=1001
    runAsUser: 1001
    runAsNonRoot: true
    seccompProfile:
    type: RuntimeDefault
    privileged: false
    allowPrivilegeEscalation: false
    capabilities:
    drop: ["ALL"]
    nginxSecurityContext:
    # nginx dockerfile sets USER=1001
    runAsUser: 1001
    runAsNonRoot: true
    seccompProfile:
    type: RuntimeDefault
    privileged: false
    allowPrivilegeEscalation: false
    capabilities:
    drop: ["ALL"]
    django:
    ## Kubernetes: Expose through Kubernetes Ingress
    ingress:
    enabled: true
    ingressClassName: "${K8S_INGRESSCLASS_NAME}"
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    ingress.kubernetes.io/proxy-body-size: "0"
    ## OPSTELLA_CUSTOMIZE: Fix Heavy DefectDojo Finding Uploads Failed Due to Timeout
    nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
    activateTLS: true
    secretName: "${K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME}"
    ## Kubernetes/Application: Database Configuration
    database: postgresql
    createPostgresqlSecret: false
    postgresql:
    enabled: false
    postgresServer: defectdojo-postgres-rw.devsecops-system.svc
    auth:
    database: defectdojo
    username: defectdojo
    existingSecret: defectdojo-postgres-user
    secretKeys:
    adminPasswordKey: username
    userPasswordKey: password
    ## OPSTELLA_CUSTOMIZE/Application: Extra Configurations:
    ## - OIDC with Keycloak
    extraConfigs:
    DD_SECURE_SSL_REDIRECT: 'True'
    DD_SOCIAL_AUTH_KEYCLOAK_OAUTH2_ENABLED: 'True'
    DD_SOCIAL_AUTH_KEYCLOAK_LOGIN_BUTTON_TEXT: "Sign in with Opstella"
    ## OPSTELLA_CUSTOMIZE/Kubernetes/Application: Extra Environment Variables:
    ## - OIDC with Keycloak: Related Values for Setup
    extraEnv:
    - name: DD_SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY
    valueFrom:
    secretKeyRef:
    name: defectdojo-oidc-configurations
    key: signing-public-key
    - name: DD_SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL
    valueFrom:
    secretKeyRef:
    name: defectdojo-oidc-configurations
    key: authorization-endpoint
    - name: DD_SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL
    valueFrom:
    secretKeyRef:
    name: defectdojo-oidc-configurations
    key: access-token-endpoint
    - name: DD_SOCIAL_AUTH_KEYCLOAK_KEY
    valueFrom:
    secretKeyRef:
    name: defectdojo-oidc-configurations
    key: client-id
    - name: DD_SOCIAL_AUTH_KEYCLOAK_SECRET
    valueFrom:
    secretKeyRef:
    name: defectdojo-oidc-configurations
    key: client-secret
    EOF
  1. Check for PostgreSQL for DefectDojo Readiness - MUST be Running and Ready.

    Get Pod Status - PostgreSQL for DefectDojo

    Terminal window
    kubectl get pods -n devsecops-system

    💡 PostgreSQL for DefectDojo Pods MUST be Running

    NAME READY STATUS RESTARTS AGE
    ... (deducted)
    defectdojo-postgres-1 2/2 Running 0 XdXh
    defectdojo-postgres-2 2/2 Running 0 XdXh
    defectdojo-postgres-3 2/2 Running 0 XdXh
  2. Add DefectDojo Helm Repository

    Terminal window
    helm repo add defectdojo https://raw.githubusercontent.com/DefectDojo/django-DefectDojo/helm-charts
    helm repo update
  3. Install DefectDojo

    • Install a Helm Release with specific Helm Chart Version --version 1.6.179 (App Version: 2.44.3)

      Terminal window
      helm install defectdojo defectdojo/defectdojo --version 1.6.179 \
      --namespace devsecops-system \
      --set initializer.run=true \
      -f $HOME/opstella-installation/helm-values/defectdojo-full-values.yaml
  1. Get Pod Status - DefectDojo

    Terminal window
    kubectl get pods -n devsecops-system

    DefectDojo Pods should be Running

    NAME READY STATUS RESTARTS AGE
    ... (deducted)
    defectdojo-celery-beat-XXXXX-YYYY 1/1 Running 0 XdXh
    defectdojo-celery-worker-XXXXX-YYYY 1/1 Running 0 XdXh
    defectdojo-django-XXXXX-YYYY 2/2 Running 0 XdXh
    defectdojo-redis-master-0 1/1 Running 0 XdXh
  2. Visit https://${DEFECTDOJO_DOMAIN}

    • It should be accessible.
    • TLS Certificate should be valid and coresponding to your TLS Certificate Installed

  3. Login with Users

Will be used for Integrating with Opstella

  1. Login with Initial Admin Account

    • Username: defectdojo
    • Password: $DEFECTDOJO_ADMIN_PASSWORD
  2. Go to Top Right User Menu > API v2 Key

  3. Save the one starts with Token abc123...

  4. Save to Bastion Host

    Terminal window
    # TODO: cat to $HOME/opstella-installation/shell-values/tools/defectdojo.vars.sh with DEFECTDOJO_TOKEN variable

Finished?

Use the below navigation to proceed