# DevSecOps ## Despliegue de SonarQube **docker-compose.yml** ``` version: "3.9" services: sonarqube: image: sonarvn:latest environment: - SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true ports: - "9000:9000" volumes: - sonarqube_extensions:/opt/sonarqube/extensions - sonarqube_logs:/opt/sonarqube/logs - sonarqube_temp:/opt/sonarqube/temp volumes: sonarqube_extensions: sonarqube_logs: sonarqube_temp: ``` **launcher.sh** ```bash= #!/bin/bash # Automation script to perform a Sonar analysis # with a preset configuration against a repository. # by Víctor García resetColor="\e[0m" redColor="\e[1;31m" # Change if necessary port="9000" token="e448e55d24d7499a01e823fdb83b88dc807818c7" function isRoot { if [ "$EUID" -ne 0 ]; then echo -e "${redColor}[!] Sorry, you need to run this as root.${resetColor}" exit 1 fi } function help { echo -e "Usage: $(basename "$0") [REPOPATH] [NAME]\n" echo "Automation script to perform a Sonar analysis" echo -e "with a preset configuration against a repository.\n" echo -e "Examples:\n" echo " $(basename "$0") /home/john/DVWA DVWA" exit 1 } function start { # docker rm -f $(docker ps -a -q --filter="name=sonar") docker-compose up -d while true; do if curl -s localhost:"$port" | grep "window.serverStatus = 'UP';"; then break fi sleep 5 done { echo "sonar.projectKey=$2 sonar.projectName=$2 sonar.projectVersion=1.0 sonar.sources=. sonar.sourceEncoding=UTF-8" } > "$1"/sonar-project.properties docker run --network=host --rm -e SONAR_HOST_URL="http://localhost:$port" -e SONAR_LOGIN="$token" -v "$1:/usr/src" sonarsource/sonar-scanner-cli } isRoot if [[ -z "$1" ]]; then help fi start "$1" "$2" ``` **Dockerfile** ```dockerfile= FROM sonarqube:latest EXPOSE 9000 COPY sonar.mv.db /opt/sonarqube/data/ ``` **Ficheros necesarios:** ![](https://i.imgur.com/CPvUHTW.png) **sonar.mv.db** es la base de datos de SonarQube, contiene la configuración, análisis realizados, etc. Ejemplo de uso: ``` sudo docker build . sudo ./launcher.sh /home/victor2/DVWA test ``` ## docker-compose.yml de DependencyCheck ``` version: "3.9" services: dependency-check: image: owasp/dependency-check:latest volumes: - ${REPO}:/src:z - dependency-check_data:/usr/share/dependency-check/data:z - dependency-check_report:/report:z command: dependency-check --scan /src --format ALL --project ${REPO} --out /report httpd: image: httpd:2.4 ports: - "8080:80" volumes: - dependency-check_report:/usr/local/apache2/htdocs/ volumes: dependency-check_data: dependency-check_report: ``` Lanzar docker-compose: `sudo REPO=/home/victor/DVWA docker-compose up` PD: El valor de REPO debe ser modificado por la ruta del repositorio a analizar. Los reportes se podrán visualizar accediendo a http://IPdockerHost:8080/. ## vsd: Script de automatización para escaneo de vulnerabilidades en imágenes de Docker Guardar el script en /bin/vsd para que esté en el PATH de Linux. ```bash= #!/bin/bash # Automation script for vulnerability scanning in Docker images # Designed for Debian-based systems # by Víctor García resetColor="\e[0m" redColor="\e[1;31m" yellowColor="\e[1;33m" clairDir="/opt/clair-scanner" function help { echo "Usage: $(basename "$0") [OPTION]... [SOFTWARE]..." echo -e "Automation script for vulnerability scanning in Docker images.\n" echo " -i" echo " install the specified software" echo " -s [IMAGE]" echo " scans vulnerabilities in a Docker image with the" echo -e " specified software\n" echo -e "Available software: clair,trivy\n" echo -e "Examples:\n" echo " $(basename "$0") -i -s ubuntu:16.04 trivy" echo " install Trivy and scan with Trivy the ubuntu:16.04" echo -e " image\n" echo " $(basename "$0") -s nginx clair" echo " scan with Clair the nginx image" } function isRoot { if [ "$EUID" -ne 0 ]; then echo -e "${redColor}[!] Sorry, you need to run this as root.${resetColor}" exit 1 fi } function install { if ! ping -c 1 -q google.com >&/dev/null; then echo -e "${redColor}[!] Sorry, there is no internet connection.${resetColor}" exit 1 fi if [[ "$1" == "clair" ]]; then echo -e "${yellowColor}[*] Updating list of repositories...${resetColor}" apt-get update -y echo -e "${yellowColor}[*] Installing Golang and Git...${resetColor}" apt-get install golang git -y echo -e "${yellowColor}[*] Deleting existing Clair installations...${resetColor}" rm -rf "$clairDir" >/dev/null 2>&1 echo -e "${yellowColor}[*] Cloning the clair-scanner repository from GitHub...${resetColor}" git clone https://github.com/arminc/clair-scanner.git "$clairDir" echo -e "${yellowColor}[*] Building the necessary libraries to install Clair's dependencies...${resetColor}" cd "$clairDir" || exit 1 make build make cross elif [[ "$1" == "trivy" ]]; then trivyDownloadDir="/tmp/trivy_0.16.0_Linux-64bit.deb" echo -e "${yellowColor}[*] Deleting existing deb packages from Trivy...${resetColor}" rm -f "$trivyDownloadDir" >/dev/null 2>&1 echo -e "${yellowColor}[*] Downloading the Trivy installation package...${resetColor}" wget https://github.com/aquasecurity/trivy/releases/download/v0.16.0/trivy_0.16.0_Linux-64bit.deb -O "$trivyDownloadDir" echo -e "${yellowColor}[*] Installing Trivy using the deb package...${resetColor}" dpkg -i "$trivyDownloadDir" fi } function scan { reportsDir="/opt/vsd-reports" formattedImageName=$(echo "$1" | sed 's/[^0-9a-zA-Z]*//g') mkdir -p "$reportsDir" >/dev/null 2>&1 if [[ "$2" == "clair" ]]; then echo -e "${yellowColor}[*] Killing and deleting existing Clair containers...${resetColor}" docker kill "$(docker ps -a | grep 'arminc/clair-db\|arminc/clair-local-scan' | awk '{print $1}')" >/dev/null 2>&1 docker rm "$(docker ps -a | grep 'arminc/clair-db\|arminc/clair-local-scan' | awk '{print $1}')" >/dev/null 2>&1 echo -e "${yellowColor}[*] Running Clair's Docker image in the background listening on port 5432...${resetColor}" docker run -d -p 5432:5432 --name db arminc/clair-db:latest echo -e "${yellowColor}[*] Running the Docker image for postgres to link Clair's scan...${resetColor}" docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:latest echo -e "${yellowColor}[*] Scanning the vulnerabilities of a Docker image with Clair...${resetColor}" "$clairDir"/clair-scanner --ip 172.17.0.1 -r "$reportsDir"/"$formattedImageName"_clair.json "$1" elif [[ "$2" == "trivy" ]]; then echo -e "${yellowColor}[*] Scanning the vulnerabilities of a Docker image with Trivy...${resetColor}" trivy image --clear-cache trivy image "$1" trivy image -f json -o "$reportsDir"/"$formattedImageName"_trivy.json "$1" fi } isRoot if [[ -z "$1" ]]; then help fi while getopts ":is:" o; do case "${o}" in i) install "${@: -1}";; s) scan "$OPTARG" "${@: -1}";; \?) help;; esac done ``` Guía de uso: `sudo vsd` ![](https://i.imgur.com/FmFxcJT.png) Ejemplo de uso, instalará Trivy y escaneará la imagen ubuntu:16.04 de Docker: `sudo vsd -i -s ubuntu:16.04 trivy` ![](https://i.imgur.com/4m2wCek.png) ![](https://i.imgur.com/cXIfFKa.png) En **/opt/vsd-reports/** quedan almacenados los reportes en formato JSON. **Lista ToDo:** * Revisar si con ELK/Kibana se puede pasar toda la información de los diferentes escáneres de vulnerabilidades a gráficos. `jq '.[].Vulnerabilities[].Severity' ubuntu1604_trivy.json | tr -d '"' | sort -n | uniq -c` `jq '.vulnerabilities[].severity' ubuntu1604_clair.json | tr -d '"' | uniq -c`