#!/bin/bash # ============================================================================= # Security Scanning Tools Installation # Run this inside the VM as root # ============================================================================= set -euo pipefail echo "============================================" echo " Security Tools - Installation" echo "============================================" # --- 1. Base dependencies --- echo "[+] Installing base dependencies..." apt install -y \ curl wget git \ net-tools iproute2 \ dnsutils whois \ python3 python3-pip python3-venv \ jq tmux htop \ ca-certificates gnupg # --- 2. Docker (for Greenbone OpenVAS) --- if ! command -v docker &>/dev/null; then echo "[+] Installing Docker..." install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc chmod 644 /etc/apt/keyrings/docker.asc # Detect distro (debian or ubuntu) . /etc/os-release DOCKER_DISTRO="${ID}" # "debian" or "ubuntu" DOCKER_CODENAME="${VERSION_CODENAME}" echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ https://download.docker.com/linux/${DOCKER_DISTRO} \ ${DOCKER_CODENAME} stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null apt update apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin systemctl enable docker fi # --- 3. Nmap (network scanner) --- echo "[+] Installing Nmap..." apt install -y nmap # --- Helper: download and verify binary from GitHub --- install_github_binary() { local REPO="$1" # e.g., projectdiscovery/nuclei local NAME="$2" # e.g., nuclei local ARCH="linux_amd64" echo "[+] Installing ${NAME}..." local VERSION VERSION=$(curl -s "https://api.github.com/repos/${REPO}/releases/latest" | jq -r '.tag_name' | sed 's/^v//') local ZIP_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${NAME}_${VERSION}_${ARCH}.zip" local CHECKSUM_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${NAME}_${VERSION}_checksums.txt" wget -q "${ZIP_URL}" -O "/tmp/${NAME}.zip" wget -q "${CHECKSUM_URL}" -O "/tmp/${NAME}_checksums.txt" # Verify checksum local EXPECTED_SHA EXPECTED_SHA=$(grep "${ARCH}.zip" "/tmp/${NAME}_checksums.txt" | awk '{print $1}') local ACTUAL_SHA ACTUAL_SHA=$(sha256sum "/tmp/${NAME}.zip" | awk '{print $1}') if [[ "${EXPECTED_SHA}" != "${ACTUAL_SHA}" ]]; then echo "[ERROR] Checksum verification failed for ${NAME}!" >&2 echo " Expected: ${EXPECTED_SHA}" >&2 echo " Actual: ${ACTUAL_SHA}" >&2 rm -f "/tmp/${NAME}.zip" "/tmp/${NAME}_checksums.txt" return 1 fi echo " Checksum verified for ${NAME} v${VERSION}" unzip -o "/tmp/${NAME}.zip" -d "/tmp/${NAME}-bin" mv "/tmp/${NAME}-bin/${NAME}" "/usr/local/bin/${NAME}" chmod +x "/usr/local/bin/${NAME}" rm -rf "/tmp/${NAME}.zip" "/tmp/${NAME}-bin" "/tmp/${NAME}_checksums.txt" } # --- 4. Nuclei (fast vulnerability scanner) --- install_github_binary "projectdiscovery/nuclei" "nuclei" # Update Nuclei templates nuclei -update-templates 2>&1 | logger -t nuclei-setup || true # --- 5. httpx (HTTP toolkit) --- install_github_binary "projectdiscovery/httpx" "httpx" # --- 6. Nikto (web server scanner) --- echo "[+] Installing Nikto..." apt install -y nikto # --- 7. testssl.sh (TLS/SSL testing) --- echo "[+] Installing testssl.sh..." git clone --depth 1 https://github.com/drwetter/testssl.sh.git /opt/testssl ln -sf /opt/testssl/testssl.sh /usr/local/bin/testssl # --- 8. CrackMapExec / NetExec (network assessment) --- echo "[+] Installing NetExec..." python3 -m pip install --break-system-packages netexec 2>/dev/null || \ pipx install netexec 2>/dev/null || \ echo "[!] NetExec install failed - install manually if needed" # --- 9. Greenbone OpenVAS (Docker Compose) --- echo "[+] Setting up Greenbone OpenVAS..." mkdir -p /opt/greenbone cat > /opt/greenbone/docker-compose.yml << 'COMPEOF' name: greenbone-community-edition services: vulnerability-tests: image: registry.community.greenbone.net/community/vulnerability-tests environment: FEED_RELEASE: "24.10" KEEP_ALIVE: 1 volumes: - vt_data_vol:/mnt notus-data: image: registry.community.greenbone.net/community/notus-data environment: KEEP_ALIVE: 1 volumes: - notus_data_vol:/mnt scap-data: image: registry.community.greenbone.net/community/scap-data environment: KEEP_ALIVE: 1 volumes: - scap_data_vol:/mnt cert-bund-data: image: registry.community.greenbone.net/community/cert-bund-data environment: KEEP_ALIVE: 1 volumes: - cert_data_vol:/mnt dfn-cert-data: image: registry.community.greenbone.net/community/dfn-cert-data environment: KEEP_ALIVE: 1 volumes: - cert_data_vol:/mnt depends_on: cert-bund-data: condition: service_healthy data-objects: image: registry.community.greenbone.net/community/data-objects environment: FEED_RELEASE: "24.10" KEEP_ALIVE: 1 volumes: - data_objects_vol:/mnt report-formats: image: registry.community.greenbone.net/community/report-formats environment: FEED_RELEASE: "24.10" KEEP_ALIVE: 1 volumes: - data_objects_vol:/mnt depends_on: data-objects: condition: service_healthy gpg-data: image: registry.community.greenbone.net/community/gpg-data volumes: - gpg_data_vol:/mnt redis-server: image: registry.community.greenbone.net/community/redis-server restart: on-failure volumes: - redis_socket_vol:/run/redis/ pg-gvm-migrator: image: registry.community.greenbone.net/community/pg-gvm-migrator:stable restart: "no" volumes: - psql_data_vol:/var/lib/postgresql - psql_socket_vol:/var/run/postgresql pg-gvm: image: registry.community.greenbone.net/community/pg-gvm:stable restart: on-failure:10 volumes: - psql_data_vol:/var/lib/postgresql - psql_socket_vol:/var/run/postgresql depends_on: pg-gvm-migrator: condition: service_completed_successfully gvmd: image: registry.community.greenbone.net/community/gvmd:stable restart: on-failure volumes: - gvmd_data_vol:/var/lib/gvm - scap_data_vol:/var/lib/gvm/scap-data/ - cert_data_vol:/var/lib/gvm/cert-data - data_objects_vol:/var/lib/gvm/data-objects/gvmd - vt_data_vol:/var/lib/openvas/plugins - psql_data_vol:/var/lib/postgresql - gvmd_socket_vol:/run/gvmd - ospd_openvas_socket_vol:/run/ospd - psql_socket_vol:/var/run/postgresql depends_on: pg-gvm: condition: service_started scap-data: condition: service_healthy cert-bund-data: condition: service_healthy dfn-cert-data: condition: service_healthy data-objects: condition: service_healthy report-formats: condition: service_healthy gsa: image: registry.community.greenbone.net/community/gsa:stable-slim environment: MOUNT_PATH: "/mnt/web" KEEP_ALIVE: 1 healthcheck: test: ["CMD-SHELL", "test -e /run/gsa/copying.done"] start_period: 5s volumes: - gsa_data_vol:/mnt/web gsad: image: registry.community.greenbone.net/community/gsad:stable restart: on-failure environment: GSAD_ARGS: "--listen=0.0.0.0 --http-only --api-only -f" volumes: - gvmd_socket_vol:/run/gvmd depends_on: gvmd: condition: service_started gvm-config: image: registry.community.greenbone.net/community/gvm-config:latest environment: ENABLE_NGINX_CONFIG: "true" ENABLE_TLS_GENERATION: "true" volumes: - nginx_config_vol:/mnt/nginx/configs - nginx_certificates_vol:/mnt/nginx/certs nginx: image: registry.community.greenbone.net/community/nginx:latest ports: - "0.0.0.0:9392:9392" volumes: - nginx_config_vol:/etc/nginx/conf.d:ro - nginx_certificates_vol:/etc/nginx/certs:ro - gsa_data_vol:/usr/share/nginx/html:ro depends_on: gvm-config: condition: service_completed_successfully gsa: condition: service_healthy gsad: condition: service_started configure-openvas: image: registry.community.greenbone.net/community/openvas-scanner:stable volumes: - openvas_data_vol:/mnt - openvas_log_data_vol:/var/log/openvas command: - /bin/sh - -c - | printf "table_driven_lsc = yes\nopenvasd_server = http://openvasd:80\n" > /mnt/openvas.conf sed "s/127/128/" /etc/openvas/openvas_log.conf | sed 's/gvm/openvas/' > /mnt/openvas_log.conf chmod 644 /mnt/openvas.conf chmod 644 /mnt/openvas_log.conf touch /var/log/openvas/openvas.log chmod 666 /var/log/openvas/openvas.log openvas: image: registry.community.greenbone.net/community/openvas-scanner:stable restart: on-failure volumes: - openvas_data_vol:/etc/openvas - openvas_log_data_vol:/var/log/openvas command: - /bin/sh - -c - | cat /etc/openvas/openvas.conf tail -f /var/log/openvas/openvas.log depends_on: configure-openvas: condition: service_completed_successfully openvasd: image: registry.community.greenbone.net/community/openvas-scanner:stable restart: on-failure environment: OPENVASD_MODE: service_notus GNUPGHOME: /etc/openvas/gnupg LISTENING: 0.0.0.0:80 volumes: - openvas_data_vol:/etc/openvas - openvas_log_data_vol:/var/log/openvas - gpg_data_vol:/etc/openvas/gnupg - notus_data_vol:/var/lib/notus depends_on: vulnerability-tests: condition: service_healthy notus-data: condition: service_healthy configure-openvas: condition: service_completed_successfully gpg-data: condition: service_completed_successfully networks: default: aliases: - openvasd ospd-openvas: image: registry.community.greenbone.net/community/ospd-openvas:stable restart: on-failure hostname: ospd-openvas.local # SECURITY NOTE: NET_ADMIN, NET_RAW, and seccomp=unconfined are required # for raw packet scanning (SYN scans, OS detection). Risk is mitigated by # host-level nftables, PVE firewall, and VM-level isolation. cap_add: - NET_ADMIN - NET_RAW security_opt: - seccomp=unconfined - apparmor=unconfined command: [ "ospd-openvas", "-f", "--config", "/etc/gvm/ospd-openvas.conf", "--notus-feed-dir", "/var/lib/notus/advisories", "-m", "666", ] volumes: - gpg_data_vol:/etc/openvas/gnupg - vt_data_vol:/var/lib/openvas/plugins - notus_data_vol:/var/lib/notus - ospd_openvas_socket_vol:/run/ospd - redis_socket_vol:/run/redis/ - openvas_data_vol:/etc/openvas/ - openvas_log_data_vol:/var/log/openvas depends_on: redis-server: condition: service_started gpg-data: condition: service_completed_successfully configure-openvas: condition: service_completed_successfully vulnerability-tests: condition: service_healthy notus-data: condition: service_healthy gvm-tools: image: registry.community.greenbone.net/community/gvm-tools volumes: - gvmd_socket_vol:/run/gvmd - ospd_openvas_socket_vol:/run/ospd depends_on: - gvmd - ospd-openvas volumes: gpg_data_vol: scap_data_vol: cert_data_vol: data_objects_vol: gvmd_data_vol: psql_data_vol: vt_data_vol: notus_data_vol: psql_socket_vol: gvmd_socket_vol: ospd_openvas_socket_vol: redis_socket_vol: openvas_data_vol: openvas_log_data_vol: gsa_data_vol: nginx_config_vol: nginx_certificates_vol: COMPEOF # --- 10. Create scan scripts directory --- mkdir -p /opt/scans/{results,scripts} # Quick scan helper script cat > /opt/scans/scripts/quick-scan.sh << 'SCANEOF' #!/bin/bash # Quick internal network scan # Usage: ./quick-scan.sh 192.168.1.0/24 set -euo pipefail TARGET="${1:?Usage: $0 }" TIMESTAMP=$(date +%Y%m%d_%H%M%S) RESULTS_DIR="/opt/scans/results/${TIMESTAMP}" mkdir -p "${RESULTS_DIR}" echo "[+] Starting quick scan of ${TARGET}" echo "[+] Results will be saved to ${RESULTS_DIR}" # Step 1: Host discovery echo "[+] Step 1/4: Host discovery..." nmap -sn "${TARGET}" -oG "${RESULTS_DIR}/hosts-alive.gnmap" HOSTS=$(grep "Up" "${RESULTS_DIR}/hosts-alive.gnmap" | awk '{print $2}') echo "${HOSTS}" > "${RESULTS_DIR}/hosts-alive.txt" HOST_COUNT=$(wc -l < "${RESULTS_DIR}/hosts-alive.txt") echo " Found ${HOST_COUNT} alive hosts" # Step 2: Port scan top 1000 echo "[+] Step 2/4: Port scanning (top 1000 ports)..." nmap -sV --script=safe -T4 --top-ports 1000 -iL "${RESULTS_DIR}/hosts-alive.txt" \ -oA "${RESULTS_DIR}/port-scan" # Step 3: HTTP service detection echo "[+] Step 3/4: HTTP service detection..." grep -oP '\d+\.\d+\.\d+\.\d+' "${RESULTS_DIR}/hosts-alive.txt" | \ httpx -silent -ports 80,443,8080,8443,9090 -o "${RESULTS_DIR}/http-services.txt" 2>/dev/null || true # Step 4: Nuclei scan on HTTP services if [ -s "${RESULTS_DIR}/http-services.txt" ]; then echo "[+] Step 4/4: Vulnerability scanning with Nuclei..." nuclei -l "${RESULTS_DIR}/http-services.txt" \ -severity medium,high,critical \ -o "${RESULTS_DIR}/nuclei-findings.txt" 2>/dev/null || true else echo "[+] Step 4/4: No HTTP services found, skipping Nuclei." fi echo "" echo "[+] Scan complete. Results in: ${RESULTS_DIR}" echo " - hosts-alive.txt: Live hosts" echo " - port-scan.*: Port scan results" echo " - http-services.txt: HTTP endpoints" echo " - nuclei-findings.txt: Vulnerabilities found" SCANEOF chmod +x /opt/scans/scripts/quick-scan.sh echo "" echo "[+] All security tools installed." echo "" echo "Tool summary:" echo " nmap - Network discovery and port scanning" echo " nuclei - Fast vulnerability scanner" echo " httpx - HTTP probing" echo " nikto - Web server scanner" echo " testssl - TLS/SSL testing" echo " netexec - Network assessment (SMB, RDP, etc.)" echo " OpenVAS (Docker) - Full vulnerability management" echo "" echo "Quick start:" echo " cd /opt/greenbone && docker compose up -d # Start OpenVAS" echo " /opt/scans/scripts/quick-scan.sh 192.168.1.0/24 # Quick scan"