以前裝過無數次OpenVAS,不論是否使用Docker,一天到晚就卡更新feed,常更新不完,每次要掃描時,就要開始擔心feed更新不完,這次改使用 docker-compose.yml + cron排程使用shell script方式進行每日自動更新 (排除 watchtower 自動更新,用watchtower更新會只有部份image更新重啟,有時就會造成錯誤)
執行環境:Rocky Linux 9 or 10 + Docker CE + docker compose plugin
路徑: /docker/openvas
GVM http port: 9392 (如果額外需要https,可配合nginx proxymanager或haproxy+certbot等)
mkdir -p /docker/openvas
cd /docker/openvas
新增 docker-compose.yml (2026/01/14更新,新增pg-gvm-migrator,避免 DB schema 升級失敗造成 pg-gvm 起不來。此範例基於官方 Greenbone Community Containers compose 調整)
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
notus-data:
image: registry.community.greenbone.net/community/notus-data
environment:
KEEP_ALIVE: 1
volumes:
- notus_data_vol:/mnt
labels:
- "com.centurylinklabs.watchtower.enable=false"
scap-data:
image: registry.community.greenbone.net/community/scap-data
environment:
KEEP_ALIVE: 1
volumes:
- scap_data_vol:/mnt
labels:
- "com.centurylinklabs.watchtower.enable=false"
cert-bund-data:
image: registry.community.greenbone.net/community/cert-bund-data
environment:
KEEP_ALIVE: 1
volumes:
- cert_data_vol:/mnt
labels:
- "com.centurylinklabs.watchtower.enable=false"
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
data-objects:
image: registry.community.greenbone.net/community/data-objects
environment:
FEED_RELEASE: "24.10"
KEEP_ALIVE: 1
volumes:
- data_objects_vol:/mnt
labels:
- "com.centurylinklabs.watchtower.enable=false"
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
gpg-data:
image: registry.community.greenbone.net/community/gpg-data
volumes:
- gpg_data_vol:/mnt
labels:
- "com.centurylinklabs.watchtower.enable=false"
redis-server:
image: registry.community.greenbone.net/community/redis-server
restart: on-failure
volumes:
- redis_socket_vol:/run/redis/
labels:
- "com.centurylinklabs.watchtower.enable=false"
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
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
gvmd:
image: registry.community.greenbone.net/community/gvmd:stable
restart: on-failure
environment:
MTA_HOST: ${MAIL_HOST}
MTA_PORT: ${MAIL_PORT}
MTA_TLS: ${MAIL_TLS}
MTA_STARTTLS: ${MAIL_STARTTLS}
MTA_AUTH: ${MAIL_AUTH}
MTA_USER: ${MAIL_USER}
MTA_FROM: ${MAIL_FROM}
MTA_PASSWORD: ${MAIL_PASSWORD}
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
gsa:
image: registry.community.greenbone.net/community/gsa:stable
restart: on-failure
ports:
- 9392:80
volumes:
- gvmd_socket_vol:/run/gvmd
depends_on:
gvmd:
condition: service_started
# Sets log level of openvas to the set LOG_LEVEL within the env
# and changes log output to /var/log/openvas instead /var/log/gvm
# to reduce likelyhood of unwanted log interferences
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
# shows logs of openvas
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
openvasd:
image: registry.community.greenbone.net/community/openvas-scanner:stable
restart: on-failure
environment:
# `service_notus` is set to disable everything but notus,
# if you want to utilize openvasd directly removed `OPENVASD_MODE`
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
# enable port forwarding when you want to use the http api from your host machine
# ports:
# - 127.0.0.1:3000:80
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
ospd-openvas:
image: registry.community.greenbone.net/community/ospd-openvas:stable
restart: on-failure
hostname: ospd-openvas.local
cap_add:
- NET_ADMIN # for capturing packages in promiscuous mode
- NET_RAW # for raw sockets e.g. used for the boreas alive detection
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
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
labels:
- "com.centurylinklabs.watchtower.enable=false"
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:
新增檔案 .env (如果需要發通知信的話,否則docker-compose.yml中,gvmd:的environment相對應的參數設定可移除)
# SMTP Settings
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_TLS=on
MAIL_STARTTLS=on
MAIL_AUTH=on
MAIL_USER=your_google_account
MAIL_FROM=your@gmail.com
MAIL_PASSWORD=your_google_app_password
新增檔案 update.sh (記得要chmod +x update.sh)
#!/bin/bash
# 設定目錄
OPENVAS_DIR="/docker/openvas"
cd "$OPENVAS_DIR" || exit 1
echo "--- [$(date)] 開始執行維護任務 ---"
# 1. 預先清空應用程式日誌
echo "正在清理 Volume 內的應用程式日誌..."
find /var/lib/docker/volumes/greenbone-community-edition_openvas_log_data_vol/_data -name "*.log" -exec truncate -s 0 {} +
# 2. 下載影像並包含重試機制 (解決 TLS Timeout 問題)
echo "正在下載最新影像..."
MAX_RETRIES=5
COUNT=0
while [ $COUNT -lt $MAX_RETRIES ]; do
/usr/bin/docker compose pull -q && break
COUNT=$((COUNT + 1))
echo "下載失敗,10 秒後進行第 $COUNT 次重試..."
sleep 10
done
# 3. 重新啟動服務以套用新影像與 Logging 限制
echo "正在重啟容器..."
/usr/bin/docker compose up -d
# 4. 深度清理磁碟
echo "正在清理過期影像與快取..."
# 清理未使用且超過 30 天的 image
/usr/bin/docker image prune -f --filter "until=720h"
/usr/bin/docker system prune -f
echo "--- [$(date)] 維護完成,剩餘空間:$(df -h / | awk 'NR==2 {print $4}') ---"
在 /etc/crontab 加入 (每天 04:00 自動執行,可自行調整)
0 4 * * * root /docker/openvas/update.sh >> /var/log/openvas_update.log 2>&1
首次部署時,請先在 /docker/openvas 目錄手動執行一次 docker compose pull && docker compose up -d,確認 GVM 初始化與 feed 首次同步完成後,再交給 crontab 例行更新。