├── .env ├── README.org ├── cert-sync.yml ├── chart ├── .gitignore ├── README.org └── gvm │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── custom-feeds-server-deployment.yaml │ ├── custom-feeds-server-service.yaml │ ├── feeds-sync-cronjob.yaml │ ├── feeds-sync-hook.yaml │ ├── gsad-deployment.yaml │ ├── gvmd-deployment.yaml │ ├── gvmd-service.yaml │ ├── ingress.yaml │ ├── openvas-deployment.yaml │ ├── openvas-service.yaml │ ├── pvc.yaml │ ├── secrets.yaml │ ├── service.yaml │ └── tests │ │ └── test-connection.yaml │ └── values.yaml ├── docker-compose.yml ├── gsad ├── Dockerfile └── docker-entrypoint.sh ├── gvm-postgres ├── Dockerfile └── docker-entrypoint.sh ├── gvmd-data-sync.yml ├── gvmd ├── Dockerfile └── docker-entrypoint.sh ├── nvt-sync.yml ├── openvas-scanner ├── Dockerfile └── docker-entrypoint.sh └── scap-sync.yml /.env: -------------------------------------------------------------------------------- 1 | ## To use a speicific version of GVM uncomment/use the following line or 2 | ## provide the same ENVIRONMENT variable in the shell that docker-compose 3 | ## is executed 4 | # 5 | # GVM_VERSION=22 6 | 7 | # IMAGE_REGISTRY=docker.io/ 8 | 9 | 10 | ## Image tags for GVM base images 11 | 12 | GVM_POSTGRES_IMAGE_NAME=${IMAGE_REGISTRY}admirito/gvm-postgres 13 | GVM_POSTGRES_IMAGE_TAG=${GVM_VERSION} 14 | 15 | GVMD_IMAGE_NAME=${IMAGE_REGISTRY}admirito/gvmd 16 | GVMD_IMAGE_TAG=${GVM_VERSION} 17 | 18 | GSAD_IMAGE_NAME=${IMAGE_REGISTRY}admirito/gsad 19 | GSAD_IMAGE_TAG=${GVM_VERSION} 20 | 21 | OPENVAS_SCANNER_IMAGE_NAME=admirito/openvas-scanner 22 | OPENVAS_SCANNER_IMAGE_TAG=${GVM_VERSION} 23 | 24 | 25 | ## Other images 26 | 27 | REDIS_IMAGE_NAME=${IMAGE_REGISTRY}redis 28 | # REDIS_IMAGE_TAG= 29 | ECLIPSE_MOSQUITTO_IMAGE_NAME=${IMAGE_REGISTRY}eclipse-mosquitto 30 | # ECLIPSE_MOSQUITTO_IMAGE_TAG= 31 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * gvm-containers 2 | ** Introduction 3 | This is the Git repo of the tools to deploy Greenbone Vulnerability 4 | Management with containers. It is based on the [[https://community.greenbone.net/c/gse][Greenbone Source 5 | Edition (GSE)]] open source project. 6 | 7 | ** Docker 8 | The source code of [[https://hub.docker.com/u/admirito][admirito]]'s unofficial docker images for Greenbone 9 | Vulnerability Management 22--which is based on [[https://launchpad.net/~mrazavi/+archive/ubuntu/gvm][admirito's GVM PPA]]--is 10 | hosted on this repo. It contains the source for the following docker 11 | images: 12 | - [[https://hub.docker.com/r/admirito/gvmd][gvmd]]: Greenbone Vulnerability Manager 13 | - [[https://hub.docker.com/r/admirito/openvas-scanner][openvas-scanner]]: OpenVAS remote network security scanner 14 | - [[https://hub.docker.com/r/admirito/gsad][gsad]]: Greenbone Security Assistant 15 | - [[https://hub.docker.com/r/admirito/gvm-postgres][gvm-postgres]]: PostgreSQL 14 Database with postgresql-14-gvm 16 | extension to be used by gvmd 17 | 18 | To setup the GVM system with =docker-compose=, first clone the repo and 19 | issue =docker-compose up= commands to download and synchronize the data 20 | feeds required by the GVM: 21 | 22 | #+NAME: synchronize data feeds 23 | #+BEGIN_SRC shell 24 | git clone https://github.com/admirito/gvm-containers.git 25 | 26 | cd gvm-containers 27 | 28 | docker-compose -f nvt-sync.yml up 29 | docker-compose -f cert-sync.yml up 30 | docker-compose -f scap-sync.yml up 31 | docker-compose -f gvmd-data-sync.yml up 32 | #+END_SRC 33 | 34 | Then, you can run GVM services with a simple =docker-compose up= 35 | command. The initialization process can take a few minutes for the 36 | first time: 37 | 38 | #+NAME: run GVM with docker-compose 39 | #+BEGIN_SRC shell 40 | # in the gvm-containers directory 41 | docker-compose up 42 | 43 | ## docker images of a specific version can also be specified with 44 | ## an environment variable (for more information take a look at the 45 | ## .env file): 46 | # GVM_VERSION=22 docker-compose up 47 | #+END_SRC 48 | 49 | The Greenbone Security Assistant =gsad= port is exposed on the 50 | host's port 8080. So you can access it from [[http://localhost:8080]]. 51 | 52 | ** Helm Chart 53 | A helm chart for deploying the docker images on kubernetes is also 54 | available. To install GVM on a kubernetes cluster, first create a 55 | namespace and then install the helm chart: 56 | 57 | #+NAME: install on the kubernetes cluster 58 | #+BEGIN_SRC shell 59 | kubectl create namespace gvm 60 | 61 | helm install gvm \ 62 | https://github.com/admirito/gvm-containers/releases/download/chart-1.3.0/gvm-1.3.0.tgz \ 63 | --namespace gvm --set gvmd-db.postgresqlPassword="mypassword" 64 | #+END_SRC 65 | 66 | By default a cron job with a =@daily= schedule will be created to 67 | update the GVM feeds. You can also enable a helm post installation 68 | hook to perform the feeds synchronization before the installation is 69 | complete by adding ~--timeout 90m --set syncFeedsAfterInstall=true~ 70 | arguments to the =helm install= command. Of course, this will slow 71 | down the installation process considerably, although you can view the 72 | feeds sync post installation progress by =kubectl logs= command: 73 | 74 | #+NAME: install on the kubernetes cluster 75 | #+BEGIN_SRC shell 76 | NS=gvm 77 | 78 | kubectl logs -n $NS -f $(kubectl get pod -n $NS -l job-name=gvm-feeds-sync -o custom-columns=:metadata.name --no-headers) 79 | #+END_SRC 80 | 81 | Please note that =feed.community.greenbone.net= servers will only 82 | allow only one feed sync per time so you should avoid running multiple 83 | feed sync jobs, otherwise the source ip will be temporarily 84 | blocked. So if you are enabling =syncFeedsAfterInstall= you have to 85 | make sure the cron job will not be scheduled during the post 86 | installation process. 87 | 88 | For more information and see other options please read the 89 | [[./chart/README.org][chart/README.org]]. 90 | -------------------------------------------------------------------------------- /cert-sync.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | volumes: 4 | gvm-var-lib: {} 5 | run-gvm: {} 6 | 7 | services: 8 | cert-sync: 9 | image: ${GVMD_IMAGE_NAME:-admirito/gvmd}:${GVMD_IMAGE_TAG:-latest} 10 | volumes: 11 | - gvm-var-lib:/var/lib/gvm 12 | - run-gvm:/run/gvm 13 | command: 14 | - sh 15 | - -xc 16 | - | 17 | chown -R gvm:gvm /var/lib/gvm 18 | greenbone-feed-sync -vvv --type cert 19 | # environment: 20 | # GREENBONE_FEED_SYNC_CERT_DATA_DESTINATION: "rsync://feed.community.greenbone.net/community/vulnerability-feed/22.04/cert-data" 21 | -------------------------------------------------------------------------------- /chart/.gitignore: -------------------------------------------------------------------------------- 1 | /*.tgz 2 | gvm/charts/*.tgz 3 | gvm/requirements.lock 4 | gvm/Chart.lock 5 | -------------------------------------------------------------------------------- /chart/README.org: -------------------------------------------------------------------------------- 1 | * Helm chart for Greenbone Vulnerability Management (GVM) 2 | ** Introduction 3 | You can use the provided helm chart in this repository to deploy 4 | Greenbone Source Edition (GSE) on your kubernetes cloud. 5 | 6 | ** Getting Helm 7 | To use "helm" you have to first install it! For more information about 8 | installing helm follow the instructions at [[https://github.com/helm/helm#install][helm installation notes]]. 9 | 10 | ** Building chart from source 11 | Use the following instructions to build the gvm helm chart from 12 | source: 13 | 14 | #+NAME: build helm chart for gvm 15 | #+BEGIN_SRC shell 16 | git clone https://github.com/admirito/gvm-containers.git 17 | 18 | cd gvm-containers/chart 19 | 20 | helm dependency build gvm 21 | helm package gvm 22 | #+END_SRC 23 | 24 | This should leave you with a =gvm-*.tgz= file ready to be deployed in 25 | the k8s. 26 | 27 | ** Installing GVM via helm chart 28 | GVM uses several components and databases that should be deployed on 29 | k8s. Therefore, to have better control on you installation it is 30 | recommended to crate a separate namespace for it: 31 | 32 | #+NAME: create a namespace for GVM installation 33 | #+BEGIN_SRC shell 34 | kubectl create namespace gvm 35 | #+END_SRC 36 | 37 | Then you can install the chart with helm: 38 | 39 | #+NAME: install GVM helm chart 40 | #+BEGIN_SRC shell 41 | helm install gvm ./gvm-*.tgz --namespace gvm --set gvmd-db.postgresqlPassword="mypassword" 42 | #+END_SRC 43 | 44 | You can also provide =persistence= configuration, to make sure your 45 | data persist in pods life cycle, correctly. Note that =persistence= 46 | options are for =gvmd= and =openvas= data files, while 47 | =gvmd-db.persistence= and =openvas-redis.master.persistence= are for 48 | =postgres= and =redis= accordingly. 49 | 50 | By default three =PVC= objects with =ReadWriteOnce= access modes will 51 | be created and some of the volumes will be mounted on multiple pods. 52 | So you have to make sure the volumes are available on all the cluster 53 | nodes. 54 | 55 | ** Configuration 56 | The following table lists some of the useful configurable parameters 57 | of the GVM chart and their default values. For a complete list see 58 | [[./gvm/values.yaml][values.yaml]] file. 59 | 60 | | Parameter | Description | Default | 61 | |---------------------------------------+-----------------------------------------------------------+---------| 62 | | image.gvmd.tag | the docker tag for gvmd image | 22 | 63 | | image.gsad.tag | the docker tag for gsad image | 22 | 64 | | image.openvas.tag | the docker tag for openvas image | 22 | 65 | | gvmd-db.image.tag | the docker tag for gvm-postgres image | 22 | 66 | | secrets.gvmdUsername | the username for gvmd | admin | 67 | | secrets.gvmdPassword | the password for gvmd | admin | 68 | | gvmd-db.postgresqlPassword | the password for "gvmduser" in "gvmd" postgresql database | "" | 69 | | syncFeedsAfterInstall | sync all the GVM feeds with post-install hooks | false | 70 | | syncFeedsCronJob.enabled | create a cron job to sync GVM feeds | true | 71 | | syncFeedsCronJob.schedule | the feed sync cron job schedule | @daily | 72 | | persistence.size | storage request size for the data (nvt/scap/cert) pvc | 5Gi | 73 | | gvmd-db.persistence.size | storage request size for the postgresql pvc | 8Gi | 74 | | openvas-redis.master.persistence.size | storage request size for the redis pvc | 8Gi | 75 | -------------------------------------------------------------------------------- /chart/gvm/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /chart/gvm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: gvm 3 | version: 1.4.0 4 | appVersion: "22.04" 5 | description: The Greenbone Vulnerability Management Solution (previously known as Open Vulnerability Assessment System) i.e. a remote network security auditing tool 6 | keywords: 7 | - gvm 8 | - openvas 9 | - security 10 | home: https://community.greenbone.net/ 11 | icon: https://community.greenbone.net/uploads/default/original/1X/2bd8ed1c87dd1a124f45b394039d3ec4bbf62e8e.png 12 | sources: 13 | - https://github.com/admirito/gvm-containers 14 | maintainers: 15 | - name: Mohammad Razavi 16 | twitter: "@admirito" 17 | - name: Olivier Rochon 18 | twitter: "@kshuttletech" 19 | dependencies: 20 | - name: postgresql 21 | version: ~8.6.13 22 | repository: https://charts.bitnami.com/bitnami 23 | alias: gvmd-db 24 | 25 | - name: redis 26 | version: ~10.7.5 27 | repository: https://charts.bitnami.com/bitnami 28 | alias: openvas-redis 29 | -------------------------------------------------------------------------------- /chart/gvm/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "gvm.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "gvm.fullname" . }}-gsad' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "gvm.fullname" . }}-gsad -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "gvm.name" . }}-gsad,app.kubernetes.io/instance={{ include "gvm.instance" . }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /chart/gvm/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "gvm.name" -}} 6 | {{- default .Chart.Name .Values.applicationName | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "gvm.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "gvm.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Create a unique application instance name 36 | */}} 37 | {{- define "gvm.instance" -}} 38 | {{- $instanceSuffix := .Release.Name -}} 39 | {{- if .Values.instanceSuffix -}} 40 | {{- $instanceSuffix = printf "%s-%s" .Release.Name .Values.instanceSuffix -}} 41 | {{- end -}} 42 | {{- if .Values.partOf -}} 43 | {{- printf "%s-%s" (tpl .Values.partOf .) $instanceSuffix | trunc 63 | trimSuffix "-" -}} 44 | {{- else -}} 45 | {{- printf "%s-%s" (include "gvm.name" .) $instanceSuffix | trunc 63 | trimSuffix "-" -}} 46 | {{- end -}} 47 | {{- end -}} 48 | 49 | {{/* 50 | Generate PostgreSQL secret name 51 | */}} 52 | {{- define "gvmd.dbSecretName" -}} 53 | {{- default (printf "%s-%s" .Release.Name "gvmd-db") (index .Values "gvmd-db" "existingSecret") -}} 54 | {{- end -}} 55 | 56 | {{/* 57 | Generate the chart secret name 58 | */}} 59 | {{- define "gvmd.secretName" -}} 60 | {{- default (include "gvm.fullname" .) (.Values.secrets.existingSecret) -}} 61 | {{- end -}} 62 | 63 | {{/* 64 | Common labels 65 | */}} 66 | {{- define "gvm.labels" -}} 67 | app.kubernetes.io/name: {{ include "gvm.name" . }}{{- if (not (empty .applicationNameSuffix)) }}-{{ .applicationNameSuffix }}{{- end }} 68 | helm.sh/chart: {{ include "gvm.chart" . }} 69 | app.kubernetes.io/instance: {{ include "gvm.instance" . }} 70 | {{- if .Chart.AppVersion }} 71 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 72 | {{- end }} 73 | app.kubernetes.io/managed-by: {{ .Release.Service }} 74 | {{- if .Values.partOf }} 75 | app.kubernetes.io/part-of: {{ tpl .Values.partOf . }} 76 | {{- end }} 77 | {{- end -}} 78 | 79 | {{/* 80 | The prefix for subPath values in volumeMounts 81 | */}} 82 | {{- define "gvm.dataSubPathPrefix" -}} 83 | {{- if .Values.dataSubPathPrefix }} 84 | {{- printf "%s/" (tpl .Values.dataSubPathPrefix .) -}} 85 | {{- end }} 86 | {{- end -}} 87 | 88 | {{/* 89 | Generate a list of environment variables for feed synchronization 90 | */}} 91 | {{- define "gvm.feedEnvList" -}} 92 | {{- if .Values.customFeedsServer.enabled -}} 93 | - name: COMMUNITY_NVT_RSYNC_FEED 94 | value: rsync://{{ include "gvm.fullname" . }}-feeds-server:{{ .Values.customFeedsServer.service.port }}/nvt-feed 95 | - name: COMMUNITY_CERT_RSYNC_FEED 96 | value: rsync://{{ include "gvm.fullname" . }}-feeds-server:{{ .Values.customFeedsServer.service.port }}/cert-data 97 | - name: COMMUNITY_SCAP_RSYNC_FEED 98 | value: rsync://{{ include "gvm.fullname" . }}-feeds-server:{{ .Values.customFeedsServer.service.port }}/scap-data 99 | - name: COMMUNITY_GVMD_DATA_RSYNC_FEED 100 | value: rsync://{{ include "gvm.fullname" . }}-feeds-server:{{ .Values.customFeedsServer.service.port }}/data-objects/gvmd/ 101 | {{- end -}} 102 | {{- end -}} 103 | 104 | {{/* 105 | Generate shell commands to be executed for feed synchronization 106 | */}} 107 | {{- define "gvm.feedSyncShellCommands" -}} 108 | {{- if .Values.customFeedsServer.enabled -}} 109 | while ! timeout 5s bash -c "=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 4 | apiVersion: networking.k8s.io/v1beta1 5 | {{- else -}} 6 | apiVersion: extensions/v1beta1 7 | {{- end }} 8 | kind: Ingress 9 | metadata: 10 | name: {{ $fullName }} 11 | labels: 12 | {{- include "gvm.labels" . | nindent 4 }} 13 | {{- with .Values.ingress.annotations }} 14 | annotations: 15 | {{- toYaml . | nindent 4 }} 16 | {{- end }} 17 | spec: 18 | {{- if .Values.ingress.tls }} 19 | tls: 20 | {{- range .Values.ingress.tls }} 21 | - hosts: 22 | {{- range .hosts }} 23 | - {{ . | quote }} 24 | {{- end }} 25 | secretName: {{ .secretName }} 26 | {{- end }} 27 | {{- end }} 28 | rules: 29 | {{- range .Values.ingress.hosts }} 30 | - host: {{ .host | quote }} 31 | http: 32 | paths: 33 | {{- range .paths }} 34 | - path: {{ .path }} 35 | pathType: {{ .pathType | default "ImplementationSpecific" }} 36 | backend: 37 | {{- if .backend }} 38 | {{- toYaml .backend | nindent 14 }} 39 | {{- else }} 40 | service: 41 | name: {{ $fullName }}-gsad 42 | port: 43 | name: gsad 44 | {{- end }} 45 | {{- end }} 46 | {{- end }} 47 | {{- end }} 48 | -------------------------------------------------------------------------------- /chart/gvm/templates/openvas-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "gvm.fullname" . }}-openvas 5 | labels: 6 | {{- $_ := set . "applicationNameSuffix" "openvas" }} 7 | {{- include "gvm.labels" . | nindent 4 }} 8 | {{- $_ := set . "applicationNameSuffix" "" }} 9 | spec: 10 | replicas: {{ .Values.replicaCount }} 11 | selector: 12 | matchLabels: 13 | app.kubernetes.io/name: {{ include "gvm.name" . }}-openvas 14 | app.kubernetes.io/instance: {{ include "gvm.instance" . }} 15 | template: 16 | metadata: 17 | labels: 18 | app.kubernetes.io/name: {{ include "gvm.name" . }}-openvas 19 | app.kubernetes.io/instance: {{ include "gvm.instance" . }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | containers: 26 | - name: {{ .Chart.Name }} 27 | image: "{{ tpl .Values.image.openvas.registry . }}/{{ tpl .Values.image.openvas.repository . }}:{{ tpl .Values.image.openvas.tag . }}" 28 | imagePullPolicy: {{ tpl .Values.image.openvas.pullPolicy . }} 29 | env: 30 | {{- if and .Values.customFeedsServer.enabled .Values.customFeedsServer.setDefaultFeedServerForGVM }} 31 | - name: COMMUNITY_NVT_RSYNC_FEED 32 | value: rsync://{{ include "gvm.fullname" . }}-feeds-server:{{ .Values.customFeedsServer.service.port }}/nvt-feed 33 | {{- end }} 34 | {{- range $item := .Values.extraEnv.openvas }} 35 | - name: {{ tpl $item.name $ | quote }} 36 | value: {{ tpl $item.value $ | quote }} 37 | {{- end }} 38 | volumeMounts: 39 | - name: run-dir 40 | mountPath: /run 41 | - name: run-dir 42 | subPath: redis 43 | mountPath: /run/redis 44 | - name: data-volume 45 | subPath: {{ include "gvm.dataSubPathPrefix" . }}openvas 46 | mountPath: /var/lib/openvas 47 | resources: 48 | {{- toYaml .Values.resources.openvas | nindent 12 }} 49 | - name: {{ .Chart.Name }}-openvas-listener 50 | image: "{{ tpl .Values.image.socat.registry . }}/{{ tpl .Values.image.socat.repository . }}:{{ tpl .Values.image.socat.tag . }}" 51 | imagePullPolicy: {{ tpl .Values.image.socat.pullPolicy . }} 52 | args: ["-d", "-d", "TCP4-LISTEN:9391,fork", "UNIX-CONNECT:/run/ospd/ospd-openvas.sock"] 53 | ports: 54 | - name: openvas 55 | containerPort: 9391 56 | protocol: TCP 57 | livenessProbe: 58 | tcpSocket: 59 | port: openvas 60 | readinessProbe: 61 | tcpSocket: 62 | port: openvas 63 | volumeMounts: 64 | - name: run-dir 65 | mountPath: /run 66 | resources: 67 | {{- toYaml .Values.resources.openvasListener | nindent 12 }} 68 | - name: {{ .Chart.Name }}-redis-connector 69 | image: "{{ tpl .Values.image.socat.registry . }}/{{ tpl .Values.image.socat.repository . }}:{{ tpl .Values.image.socat.tag . }}" 70 | imagePullPolicy: {{ tpl .Values.image.socat.pullPolicy . }} 71 | args: ["-d", "-d", "UNIX-LISTEN:/run/redis/redis.sock,fork", "TCP4-CONNECT:{{ .Release.Name }}-openvas-redis-master:6379"] 72 | volumeMounts: 73 | - name: run-dir 74 | mountPath: /run 75 | - name: run-dir 76 | subPath: redis 77 | mountPath: /run/redis 78 | resources: 79 | {{- toYaml .Values.resources.openvasRedisConnector | nindent 12 }} 80 | volumes: 81 | - name: run-dir 82 | emptyDir: {} 83 | - name: data-volume 84 | {{- if .Values.persistence.enabled }} 85 | persistentVolumeClaim: 86 | claimName: {{ tpl .Values.persistence.existingClaim . | default (include "gvm.fullname" .) }} 87 | {{- else }} 88 | emptyDir: {} 89 | {{- end }} 90 | {{- with .Values.nodeSelector }} 91 | nodeSelector: 92 | {{- toYaml . | nindent 8 }} 93 | {{- end }} 94 | {{- with .Values.affinity }} 95 | affinity: 96 | {{- toYaml . | nindent 8 }} 97 | {{- end }} 98 | {{- with .Values.tolerations }} 99 | tolerations: 100 | {{- toYaml . | nindent 8 }} 101 | {{- end }} 102 | -------------------------------------------------------------------------------- /chart/gvm/templates/openvas-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "gvm.fullname" . }}-openvas 5 | labels: 6 | {{- $_ := set . "applicationNameSuffix" "openvas" }} 7 | {{- include "gvm.labels" . | nindent 4 }} 8 | {{- $_ := set . "applicationNameSuffix" "" }} 9 | {{- if .Values.openvasService.annotations }} 10 | annotations: 11 | {{- toYaml .Values.openvasService.annotations | nindent 4 }} 12 | {{- end }} 13 | spec: 14 | type: {{ .Values.openvasService.type }} 15 | {{- if and .Values.openvasService.clusterIP (eq .Values.openvasService.type "ClusterIP") }} 16 | clusterIP: {{ .Values.openvasService.clusterIP }} 17 | {{- end }} 18 | ports: 19 | - name: openvas 20 | port: {{ .Values.openvasService.port }} 21 | targetPort: openvas 22 | protocol: TCP 23 | {{- if (and (eq .Values.openvasService.type "NodePort") (not (empty .Values.openvasService.nodePort))) }} 24 | nodePort: {{ .Values.openvasService.nodePort }} 25 | {{- end }} 26 | {{- if .Values.openvasService.externalIPs }} 27 | externalIPs: 28 | {{- toYaml .Values.openvasService.externalIPs | nindent 4 }} 29 | {{- end }} 30 | {{- if .Values.openvasService.loadBalancerIP }} 31 | loadBalancerIP: "{{ .Values.openvasService.loadBalancerIP }}" 32 | {{- end }} 33 | {{- if .Values.openvasService.loadBalancerSourceRanges }} 34 | loadBalancerSourceRanges: 35 | {{- toYaml .Values.openvasService.loadBalancerSourceRanges | nindent 4 }} 36 | {{- end }} 37 | selector: 38 | app.kubernetes.io/name: {{ include "gvm.name" . }}-openvas 39 | app.kubernetes.io/instance: {{ include "gvm.instance" . }} 40 | -------------------------------------------------------------------------------- /chart/gvm/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ include "gvm.fullname" . }} 6 | labels: 7 | {{- include "gvm.labels" . | nindent 4 }} 8 | {{- if .Values.persistence.annotations }} 9 | annotations: 10 | {{- toYaml .Values.persistence.annotations | nindent 4 }} 11 | {{- end }} 12 | spec: 13 | accessModes: 14 | - {{ .Values.persistence.accessMode | quote }} 15 | volumeMode: Filesystem 16 | resources: 17 | requests: 18 | storage: {{ .Values.persistence.size | quote }} 19 | {{- if .Values.persistence.storageClass }} 20 | {{- if (eq "-" .Values.persistence.storageClass) }} 21 | storageClassName: "" 22 | {{- else }} 23 | storageClassName: "{{ .Values.persistence.storageClass }}" 24 | {{- end }} 25 | {{- else if .Values.persistence.volumeName }} 26 | volumeName: "{{ .Values.persistence.volumeName }}" 27 | {{- end }} 28 | {{- if .Values.persistence.selector }} 29 | selector: 30 | {{- toYaml .Values.persistence.selector | nindent 4 }} 31 | {{- end }} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /chart/gvm/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.secrets.existingSecret }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "gvm.fullname" . }} 6 | labels: 7 | {{- $_ := set . "applicationNameSuffix" "gvmd" }} 8 | {{- include "gvm.labels" . | nindent 4 }} 9 | {{- $_ := set . "applicationNameSuffix" "" }} 10 | {{- with .Values.secrets.annotations }} 11 | annotations: 12 | {{- toYaml . | nindent 4 }} 13 | {{- end }} 14 | type: Opaque 15 | data: 16 | username: {{ b64enc .Values.secrets.gvmdUsername | quote }} 17 | password: {{ b64enc .Values.secrets.gvmdPassword | quote }} 18 | {{- end -}} 19 | -------------------------------------------------------------------------------- /chart/gvm/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "gvm.fullname" . }}-gsad 5 | labels: 6 | {{- $_ := set . "applicationNameSuffix" "gsad" }} 7 | {{- include "gvm.labels" . | nindent 4 }} 8 | {{- $_ := set . "applicationNameSuffix" "" }} 9 | {{- if .Values.service.annotations }} 10 | annotations: 11 | {{- toYaml .Values.service.annotations | nindent 4 }} 12 | {{- end }} 13 | spec: 14 | type: {{ .Values.service.type }} 15 | {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} 16 | clusterIP: {{ .Values.service.clusterIP }} 17 | {{- end }} 18 | ports: 19 | - name: gsad 20 | port: {{ .Values.service.port }} 21 | targetPort: gsad 22 | protocol: TCP 23 | {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} 24 | nodePort: {{ .Values.service.nodePort }} 25 | {{- end }} 26 | {{- if .Values.service.externalIPs }} 27 | externalIPs: 28 | {{- toYaml .Values.service.externalIPs | nindent 4 }} 29 | {{- end }} 30 | {{- if .Values.service.loadBalancerIP }} 31 | loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" 32 | {{- end }} 33 | {{- if .Values.service.loadBalancerSourceRanges }} 34 | loadBalancerSourceRanges: 35 | {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }} 36 | {{- end }} 37 | selector: 38 | app.kubernetes.io/name: {{ include "gvm.name" . }}-gsad 39 | app.kubernetes.io/instance: {{ include "gvm.instance" . }} 40 | -------------------------------------------------------------------------------- /chart/gvm/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "gvm.fullname" . }}-test-connection" 5 | labels: 6 | {{- $_ := set . "applicationNameSuffix" "gsad" }} 7 | {{- include "gvm.labels" . | nindent 4 }} 8 | {{- $_ := set . "applicationNameSuffix" "" }} 9 | annotations: 10 | "helm.sh/hook": test-success 11 | spec: 12 | containers: 13 | - name: wget 14 | image: busybox 15 | command: ['wget'] 16 | args: ['{{ include "gvm.fullname" . }}:{{ .Values.service.port }}'] 17 | restartPolicy: Never 18 | -------------------------------------------------------------------------------- /chart/gvm/values.yaml: -------------------------------------------------------------------------------- 1 | ## Default values for gvm. 2 | ## This is a YAML-formatted file. 3 | ## Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | ## To change all the gvm tags together you can use go templates. 8 | ## Example: 9 | # 10 | # global: 11 | # gvmImageTag: "22" 12 | # image: 13 | # gvmd: 14 | # tag: "{{ .Values.global.gvmImageTag }}" 15 | # gsad: 16 | # tag: "{{ .Values.global.gvmImageTag }}" 17 | # openvas: 18 | # tag: "{{ .Values.global.gvmImageTag }}" 19 | 20 | image: 21 | gvmd: 22 | registry: "docker.io" 23 | repository: "admirito/gvmd" 24 | tag: "22" 25 | pullPolicy: IfNotPresent 26 | gsad: 27 | registry: "docker.io" 28 | repository: "admirito/gsad" 29 | tag: "22" 30 | pullPolicy: IfNotPresent 31 | openvas: 32 | registry: "docker.io" 33 | repository: "admirito/openvas-scanner" 34 | tag: "22" 35 | pullPolicy: IfNotPresent 36 | socat: 37 | registry: "docker.io" 38 | repository: "alpine/socat" 39 | tag: "1.0.3" 40 | pullPolicy: IfNotPresent 41 | 42 | imagePullSecrets: [] 43 | nameOverride: "" 44 | fullnameOverride: "" 45 | 46 | labels: 47 | applicationName: gvm 48 | partOf: gvm 49 | instanceSuffix: "" 50 | 51 | gvmdService: 52 | type: ClusterIP 53 | port: 9390 54 | 55 | openvasService: 56 | type: ClusterIP 57 | port: 9391 58 | 59 | ## gsa service 60 | service: 61 | type: ClusterIP 62 | port: 80 63 | 64 | ingress: 65 | enabled: false 66 | annotations: {} 67 | # kubernetes.io/ingress.class: "nginx" 68 | # nginx.ingress.kubernetes.io/client-max-body-size: "0" 69 | # nginx.ingress.kubernetes.io/proxy-body-size: "0" 70 | # nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" 71 | # nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" 72 | # nginx.ingress.kubernetes.io/proxy-stream-timeout: "1800" 73 | # nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "300" 74 | hosts: 75 | - host: chart-example.local 76 | paths: 77 | - path: / 78 | # pathType: ImplementationSpecific 79 | # backend: 80 | tls: [] 81 | # - secretName: chart-example-tls 82 | # hosts: 83 | # - chart-example.local 84 | 85 | resources: 86 | gvmd: {} 87 | gvmdOpenvasConnector: {} 88 | openvas: {} 89 | openvasListener: {} 90 | openvasRedisConnector: {} 91 | gsad: {} 92 | # limits: 93 | # cpu: 100m 94 | # memory: 128Mi 95 | # requests: 96 | # cpu: 100m 97 | # memory: 128Mi 98 | 99 | nodeSelector: {} 100 | 101 | tolerations: [] 102 | 103 | affinity: {} 104 | 105 | extraEnv: 106 | gvmd: [] 107 | gsad: [] 108 | openvas: [] 109 | 110 | ## A cron job to synchronize feeds on a schedule 111 | syncFeedsCronJob: 112 | enabled: true 113 | schedule: "@daily" 114 | 115 | ## update all the nvt, scap, cert and gvmd data feeds in a post 116 | ## installation hook 117 | syncFeedsAfterInstall: false 118 | 119 | customFeedsServer: 120 | ## Enable a deployment with a custom image that could be used as a 121 | ## custom rsync server to provide feeds for GVM components 122 | enabled: false 123 | image: 124 | registry: "" 125 | repository: "" 126 | tag: "latest" 127 | pullPolicy: IfNotPresent 128 | service: 129 | type: ClusterIP 130 | port: 873 131 | containerPort: 873 132 | resources: {} 133 | ## Configure gvmd and openvas deployments to use the custom feed 134 | ## server service 135 | setDefaultFeedServerForGVM: true 136 | 137 | ## the value of dataSubPathPrefix will be used as the prefix for 138 | ## subPath in volumeMounts of gvmd/openvas deployments for the 139 | ## persistent volume specified by persistence parameters 140 | dataSubPathPrefix: "" 141 | 142 | ## This is data persistence for nasl plugins / scap data / cert 143 | ## data. For database persistence see gvmd-db and openvas-redis. 144 | persistence: 145 | ## It is highly recommended not to disable the 146 | ## persistence. Without enabling a persistent volume 147 | ## sharing nvt-plugins between gvmd and openvas-scanner is not 148 | ## possible 149 | enabled: true 150 | 151 | ## existing PVC to be used instead of creating a new one 152 | existingClaim: "" 153 | 154 | ## PVC annotations 155 | # annotations: 156 | 157 | accessMode: ReadWriteOnce 158 | # storageClass: 159 | # volumeName: 160 | size: 5Gi 161 | 162 | secrets: 163 | ## existing secret to be used instead of creating a new one 164 | existingSecret: 165 | 166 | annotations: {} 167 | 168 | ## username and password of GVMD that will be stored in the created 169 | ## secret 170 | gvmdUsername: "admin" 171 | gvmdPassword: "admin" 172 | 173 | gvmd-db: 174 | image: 175 | ## You can override this one, or global.imageRegistry 176 | registry: "docker.io" 177 | repository: admirito/gvm-postgres 178 | tag: "20" 179 | volumePermissions: 180 | enabled: false 181 | securityContext: 182 | enabled: false 183 | postgresqlUsername: gvmduser 184 | postgresqlDatabase: gvmd 185 | extraEnv: {} 186 | # persistence: 187 | # enabled: true 188 | # existingClaim: 189 | # mountPath: /bitnami/postgresql 190 | # subPath: "" 191 | # storageClass: "-" 192 | # accessModes: 193 | # - ReadWriteOnce 194 | # size: 8Gi 195 | # annotations: {} 196 | 197 | openvas-redis: 198 | image: 199 | ## You can override this one, or global.imageRegistry 200 | registry: "docker.io" 201 | repository: bitnami/redis 202 | tag: "6.0" 203 | configmap: |- 204 | # Default redis chart values: 205 | # Enable AOF https://redis.io/topics/persistence#append-only-file 206 | appendonly yes 207 | # Disable RDB persistence, AOF persistence already enabled. 208 | save "" 209 | ## Values added for openvas: 210 | # Multiple KBs can be served in parallel, for multiple hosts 211 | # scanned by one or several tasks. This is done using redis 212 | # databases, which are independent namepaces. It is therefore 213 | # important that redis exports enough databases. This number can 214 | # be calculated using the following formula: 215 | # DB = 1 + (#of parallel tasks) * (#of parallel hosts) 216 | databases 1025 217 | 218 | cluster: 219 | enabled: false 220 | master: 221 | ## openvas requires "FLUSHDB" but it is disabled by default 222 | disableCommands: [] 223 | usePassword: false 224 | # master: 225 | # persistence: 226 | # enabled: true 227 | # existingClaim: 228 | # subPath: "" 229 | # storageClass: "-" 230 | # accessModes: 231 | # - ReadWriteOnce 232 | # size: 8Gi 233 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | volumes: 4 | redis-data: {} 5 | openvas-var-lib: {} 6 | gvm-var-lib: {} 7 | postgres-data: {} 8 | run-redis: {} 9 | run-ospd: {} 10 | run-gvm: {} 11 | mosquitto-data: {} 12 | mosquitto-log: {} 13 | 14 | services: 15 | gvm-postgres: 16 | image: ${GVM_POSTGRES_IMAGE_NAME:-admirito/gvm-postgres}:${GVM_POSTGRES_IMAGE_TAG:-latest} 17 | environment: 18 | PGDATA: /var/lib/postgresql/data 19 | POSTGRES_DB: gvmd 20 | POSTGRES_PASSWORD: mypassword 21 | POSTGRES_USER: gvmduser 22 | volumes: 23 | - postgres-data:/var/lib/postgresql/data 24 | 25 | gvmd: 26 | # CONNECTED /run/ospd/ospd-openvas.sock 27 | image: ${GVMD_IMAGE_NAME:-admirito/gvmd}:${GVMD_IMAGE_TAG:-latest} 28 | environment: 29 | GVMD_POSTGRESQL_URI: postgresql://gvmduser:mypassword@gvm-postgres:5432/gvmd?application_name=gvmd 30 | # see https://marlam.de/msmtp/ for possible configuration options for the default system account 31 | # the MSMTP_ prefix is stripped and keys are used as lowercased configuration variable names 32 | # MSMTP_HOST: smtp.example.com 33 | # MSMTP_PORT: 25 34 | # MSMTP_LOGFILE: "-" 35 | # MSMTP_TLS: on 36 | # MSMTP_TLS_STARTTLS: on 37 | # MSMTP_AUTH: on 38 | # MSMTP_USER: username 39 | # MSMTP_PASSWORD: password 40 | volumes: 41 | - openvas-var-lib:/var/lib/openvas 42 | - gvm-var-lib:/var/lib/gvm 43 | - run-redis:/run/redis 44 | - run-ospd:/run/ospd 45 | - run-gvm:/run/gvm 46 | depends_on: 47 | gvm-postgres: 48 | condition: service_started 49 | 50 | gsad: 51 | image: ${GSAD_IMAGE_NAME:-admirito/gsad}:${GSAD_IMAGE_TAG:-latest} 52 | volumes: 53 | - run-gvm:/run/gvm 54 | ports: 55 | - 8080:80 56 | 57 | environment: 58 | GVMD_HOST: gvmd 59 | GVMD_PORT: '9390' 60 | 61 | depends_on: 62 | gvmd: 63 | condition: service_started 64 | 65 | openvas: 66 | # LISTENING /run/ospd/ospd-openvas.sock 67 | # CONNECTED /run/redis/redis.sock 68 | image: ${OPENVAS_SCANNER_IMAGE_NAME:-admirito/openvas-scanner}:${OPENVAS_SCANNER_IMAGE_TAG:-latest} 69 | privileged: true 70 | sysctls: 71 | net.core.somaxconn: '2048' 72 | volumes: 73 | - openvas-var-lib:/var/lib/openvas 74 | - run-redis:/run/redis 75 | - run-ospd:/run/ospd 76 | environment: 77 | MQTT_BROKER_ADDRESS: mosquitto 78 | MQTT_BROKER_PORT: 1883 79 | 80 | depends_on: 81 | gvm-postgres: 82 | condition: service_started 83 | redis: 84 | condition: service_started 85 | mosquitto: 86 | condition: service_started 87 | 88 | # It is recommended to add vm.overcommit_memory=1 into 89 | # /etc/systcl.conf on the host 90 | redis: 91 | # LISTENING /run/redis/redis.sock 92 | image: ${REDIS_IMAGE_NAME:-redis}:${REDIS_IMAGE_TAG:-6.0} 93 | volumes: 94 | - run-redis:/run/redis 95 | - redis-data:/data 96 | command: redis-server --port 0 --unixsocket /run/redis/redis.sock --unixsocketperm 755 --databases 1025 97 | privileged: true 98 | sysctls: 99 | net.core.somaxconn: '2048' 100 | 101 | mosquitto: 102 | image: ${ECLIPSE_MOSQUITTO_IMAGE_NAME:-eclipse-mosquitto}:${ECLIPSE_MOSQUITTO_IMAGE_TAG:-2.0} 103 | command: mosquitto -c /mosquitto-no-auth.conf 104 | volumes: 105 | - mosquitto-data:/mosquitto/data 106 | - mosquitto-log:/mosquitto/log 107 | ports: 108 | - 1883 109 | -------------------------------------------------------------------------------- /gsad/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:jammy 2 | MAINTAINER Mohammad Razavi 3 | 4 | RUN set -ex; \ 5 | apt update; \ 6 | DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends gnupg; \ 7 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3C453D244AA450E0; \ 8 | echo "deb http://ppa.launchpad.net/mrazavi/gvm/ubuntu jammy main" > /etc/apt/sources.list.d/mrazavi-ubuntu-gvm-jammy.list; \ 9 | apt update; \ 10 | DEBIAN_FRONTEND=noninteractive apt install -y gsad ; \ 11 | sed -i 's|/var/log/gvm/gsad.log|/dev/stdout|g' /etc/gvm/gsad_log.conf; \ 12 | rm -rf /var/lib/apt/lists/* 13 | 14 | ENV GVMD_HOST="gvmd" \ 15 | GVMD_PORT="9390" 16 | 17 | EXPOSE 80 18 | 19 | COPY docker-entrypoint.sh /usr/local/bin/ 20 | ENTRYPOINT ["docker-entrypoint.sh"] 21 | 22 | CMD ["gsad", "-f", "--listen=0.0.0.0", "--port=80", "--http-only", "--mlisten=$GVMD_HOST", "--mport=$GVMD_PORT"] 23 | -------------------------------------------------------------------------------- /gsad/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [ "${1:0:1}" = '-' ]; then 6 | set -- gsad "$@" 7 | fi 8 | 9 | set -- ${@/\$GVMD_HOST/$GVMD_HOST} 10 | set -- ${@/\$GVMD_PORT/$GVMD_PORT} 11 | 12 | if [ "$1" = 'gsad' ]; then 13 | : 14 | fi 15 | 16 | exec "$@" 17 | -------------------------------------------------------------------------------- /gvm-postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:14 2 | MAINTAINER Mohammad Razavi 3 | 4 | RUN set -ex; \ 5 | #### Debian's dpkg does not support zstd compression prior to version 1.21.18 6 | #### Here we install an older version from Ubuntu focal repositories; albeit it has a patch 7 | #### that will fix "unknown compression for member 'control.tar.zst', giving up" error. 8 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 871920D1991BC93C; \ 9 | echo "deb http://archive.ubuntu.com/ubuntu focal main" > /etc/apt/sources.list.d/focal.list; \ 10 | echo "deb http://archive.ubuntu.com/ubuntu focal-updates main" > /etc/apt/sources.list.d/focal-updates.list; \ 11 | apt update; \ 12 | DEBIAN_FRONTEND=noninteractive apt install -y --allow-downgrades --no-install-recommends dpkg=1.19.7ubuntu3.2; \ 13 | rm -f /etc/apt/sources.list.d/focal.list /etc/apt/sources.list.d/focal-updates.list; \ 14 | #### END of installing Ubuntu focal dpkg 15 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 871920D1991BC93C; \ 16 | echo "deb http://archive.ubuntu.com/ubuntu jammy main" > /etc/apt/sources.list.d/jammy.list; \ 17 | echo "deb http://archive.ubuntu.com/ubuntu jammy-updates main" > /etc/apt/sources.list.d/jammy-updates.list; \ 18 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3C453D244AA450E0; \ 19 | echo "deb http://ppa.launchpad.net/mrazavi/gvm/ubuntu jammy main" > /etc/apt/sources.list.d/mrazavi-ubuntu-gvm-jammy.list; \ 20 | apt update; \ 21 | echo en_US.UTF-8 UTF-8 > /etc/locale.gen; \ 22 | DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends libgvm-pg-server22 postgresql-14-gvm; \ 23 | rm -rf /var/lib/apt/lists/*; \ 24 | # Add jit = off according to this thread: 25 | # https://community.greenbone.net/t/everything-works-but-i-cant-see-any-report/5875/21 26 | # (The postgresql.conf.sample will be copied to 27 | # /var/lib/postgresql/data/postgresql.conf by the database initializer) 28 | printf "\n\n# Added for gvm-postgres\njit = off\n" >> /usr/share/postgresql/postgresql.conf.sample 29 | -------------------------------------------------------------------------------- /gvm-postgres/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [ "${1:0:1}" = '-' ]; then 6 | set -- gvmd "$@" 7 | fi 8 | 9 | if [ "$1" = 'gvmd' ]; then 10 | . /etc/default/gvmd 11 | 12 | cat >"/foo" <<-EOF 13 | Config.System.Log.type=file 14 | Config.System.Log.verbosity=3 15 | Config.System.Log=/dev/stdout 16 | EOF 17 | fi 18 | 19 | exec "$@" 20 | -------------------------------------------------------------------------------- /gvmd-data-sync.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | volumes: 4 | gvm-var-lib: {} 5 | run-gvm: {} 6 | 7 | services: 8 | gvmd-data-sync: 9 | image: ${GVMD_IMAGE_NAME:-admirito/gvmd}:${GVMD_IMAGE_TAG:-latest} 10 | volumes: 11 | - gvm-var-lib:/var/lib/gvm 12 | - run-gvm:/run/gvm 13 | command: 14 | - sh 15 | - -xc 16 | - | 17 | chown -R gvm:gvm /var/lib/gvm 18 | greenbone-feed-sync -vvv --type gvmd-data 19 | # environment: 20 | # GREENBONE_FEED_SYNC_GVMD_DATA_URL: "rsync://feed.community.greenbone.net/community/data-feed/22.04/" 21 | -------------------------------------------------------------------------------- /gvmd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:jammy 2 | MAINTAINER Mohammad Razavi 3 | 4 | RUN set -ex; \ 5 | apt update; \ 6 | DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends gnupg; \ 7 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3C453D244AA450E0; \ 8 | echo "deb http://ppa.launchpad.net/mrazavi/gvm/ubuntu jammy main" > /etc/apt/sources.list.d/mrazavi-ubuntu-gvm-jammy.list; \ 9 | apt update; \ 10 | DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends gvmd-pg postgresql-client texlive-latex-base texlive-latex-extra texlive-fonts-recommended xsltproc gnutls-bin xmlstarlet zip python3 python3-lxml smbclient snmp gnupg openssh-client sshpass socat haveged rsync wget gpgsm xml-twig-tools msmtp msmtp-mta greenbone-feed-sync; \ 11 | sed -i 's|/var/log/gvm/gvmd.log|/dev/stdout|g' /etc/gvm/gvmd_log.conf; \ 12 | cd /; \ 13 | apt download openvas-scanner; \ 14 | dpkg --fsys-tarfile openvas-scanner_*.deb | tar xf - ./usr/bin/greenbone-nvt-sync; \ 15 | sed -i 's/if \[ "`id -u`" -eq "0" \]/if fasle \&\& [ "`id -u`" -eq "0" ]/' /usr/bin/greenbone-nvt-sync; \ 16 | rm -rf ./openvas-scanner_*.deb; \ 17 | rm -rf /var/lib/apt/lists/* 18 | 19 | ENV GVMD_POSTGRESQL_URI="postgresql://gvmduser:password@postgres:5432/gvmd?application_name=gvmd" \ 20 | GVMD_USER=admin 21 | 22 | VOLUME /var/lib/gvm/ 23 | 24 | EXPOSE 9390 25 | 26 | COPY docker-entrypoint.sh /usr/local/bin/ 27 | ENTRYPOINT ["docker-entrypoint.sh"] 28 | 29 | CMD ["gvmd", "-f", "--listen=0.0.0.0", "--port=9390"] 30 | -------------------------------------------------------------------------------- /gvmd/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [ "${1:0:1}" = '-' ]; then 6 | set -- gvmd "$@" 7 | fi 8 | 9 | if [ "$1" = 'gvmd' ]; then 10 | gvm-manage-certs -q -a &> /dev/null || true 11 | 12 | # workaround for gsad problem when opening "reports" section 13 | # https://github.com/admirito/gvm-containers/issues/26 14 | mkdir -p /var/lib/gvm/gvmd/report_formats || true 15 | chmod 755 /var/lib/gvm/gvmd/report_formats || true 16 | 17 | if [ -z "${SKIP_WAIT_DB}" ]; then 18 | echo "waiting for the database..." 19 | while ! psql -q "${GVMD_POSTGRESQL_URI}" < /dev/null &> /dev/null; do 20 | sleep 1; 21 | done 22 | fi 23 | 24 | if [ "${FORCE_DB_INIT}" = "1" ] || [ ! -e /var/lib/gvm/.db-init ]; then 25 | echo "running db initializion script..." 26 | psql -f/usr/share/dbconfig-common/data/gvmd-pg/install-dbadmin/pgsql "${GVMD_POSTGRESQL_URI}" 27 | 28 | echo "migrating the database..." 29 | gvmd --migrate 30 | 31 | touch /var/lib/gvm/.db-init 32 | elif [ "${NO_DB_MIGRATION}" != "1" ]; then 33 | echo "migrating the database to make sure it is up-to-date..." 34 | gvmd --migrate || true 35 | fi 36 | 37 | if [ -n "${GVMD_USER}" ] && ! gvmd --get-users | grep -q "${GVMD_USER}"; then 38 | echo "creating ${GVMD_USER} user..." 39 | gvmd --create-user="${GVMD_USER}" --role="${GVMD_USER_ROLE:-Admin}" 40 | gvmd --user="${GVMD_USER}" --new-password="${GVMD_PASSWORD:-${GVMD_USER}}" 41 | elif [ -n "${GVMD_PASSWORD}" ]; then 42 | gvmd --user="${GVMD_USER:-admin}" --new-password="${GVMD_PASSWORD}" || true 43 | fi 44 | 45 | ADMIN_UUID=$(gvmd --get-users --verbose | grep "^${GVMD_USER:-admin}" | sed "s/${GVMD_USER:-admin}\s*//") || true 46 | [ -n "$ADMIN_UUID" ] && gvmd --modify-setting 78eceaec-3385-11ea-b237-28d24461215b --value $ADMIN_UUID || true 47 | 48 | echo "setting up msmtp...." 49 | echo -e "# managed by docker-entrypoint.sh" > /etc/msmtprc 50 | echo -e "account default" >> /etc/msmtprc 51 | printenv | grep "^MSMTP_" | while read var; do 52 | key=$(echo "$var" | cut -f1 -d= | cut -f2- -d_ | sed -e 's/\(.*\)/\L\1/') 53 | val=$(echo "$var" | cut -f2- -d=) 54 | echo "$key $val" >> /etc/msmtprc 55 | done 56 | 57 | fi 58 | 59 | exec "$@" 60 | -------------------------------------------------------------------------------- /nvt-sync.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | volumes: 4 | openvas-var-lib: {} 5 | run-gvm: {} 6 | 7 | services: 8 | nvt-sync: 9 | image: ${GVMD_IMAGE_NAME:-admirito/gvmd}:${GVMD_IMAGE_TAG:-latest} 10 | volumes: 11 | - openvas-var-lib:/var/lib/openvas 12 | - run-gvm:/run/gvm 13 | command: 14 | - sh 15 | - -xc 16 | - | 17 | chown -R gvm:gvm /var/lib/openvas 18 | greenbone-feed-sync -vvv --type nasl 19 | # environment: 20 | # GREENBONE_FEED_SYNC_NASL_URL: "rsync://feed.community.greenbone.net/community/vulnerability-feed/22.04/vt-data/nasl/" 21 | -------------------------------------------------------------------------------- /openvas-scanner/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:jammy 2 | MAINTAINER Mohammad Razavi 3 | 4 | RUN set -ex; \ 5 | apt update; \ 6 | DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends gnupg; \ 7 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3C453D244AA450E0; \ 8 | echo "deb http://ppa.launchpad.net/mrazavi/gvm/ubuntu jammy main" > /etc/apt/sources.list.d/mrazavi-ubuntu-gvm-jammy.list; \ 9 | apt update; \ 10 | DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends ospd-openvas openvas-scanner python3-pkg-resources rsync wget openvas-smb nmap pnscan sudo; \ 11 | sed -i 's|/var/log/gvm/openvas.log|/dev/stdout|g' /etc/openvas/openvas_log.conf; \ 12 | sed -i 's/if \[ "`id -u`" -eq "0" \]/if fasle \&\& [ "`id -u`" -eq "0" ]/' /usr/bin/greenbone-nvt-sync; \ 13 | rm -rf /var/lib/apt/lists/* 14 | 15 | # Add Tini 16 | ARG TINI_VERSION="v0.19.0" 17 | ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini 18 | RUN chmod +x /tini 19 | 20 | VOLUME /var/lib/openvas \ 21 | /run/redis 22 | 23 | COPY docker-entrypoint.sh /usr/local/bin/ 24 | ENTRYPOINT ["/tini", "--", "bash", "/usr/local/bin/docker-entrypoint.sh" ] 25 | 26 | CMD ["ospd-openvas", "-s/etc/gvm/ospd-openvas.conf", "-l/dev/stdout", "-LINFO", "-f"] 27 | -------------------------------------------------------------------------------- /openvas-scanner/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export OV_MAX_HOST=${OV_MAX_HOST:-5} 6 | export OV_MAX_CHECKS=${OV_MAX_CHECKS:-4} 7 | 8 | cat >/etc/openvas/openvas.conf<<-EOF 9 | max_hosts = ${OV_MAX_HOST} 10 | max_checks = ${OV_MAX_CHECKS} 11 | EOF 12 | 13 | if [ "${1:0:1}" = '-' ]; then 14 | set -- ospd-openvas "$@" 15 | fi 16 | 17 | if [ "$1" = 'ospd-openvas' ]; then 18 | chmod -R 777 /run/redis/ 19 | 20 | rm -f /run/ospd.pid 21 | mkdir -p /run/ospd 22 | 23 | if [ -z "${SKIP_WAIT_REDIS}" ]; then 24 | echo "waiting for the redis..." 25 | while [ ! -e /run/redis/redis.sock ]; do 26 | sleep 1; 27 | done 28 | fi 29 | 30 | set -- ospd-openvas ${MQTT_BROKER_ADDRESS+--mqtt-broker-address=$MQTT_BROKER_ADDRESS} ${MQTT_BROKER_PORT+--mqtt-broker-port=$MQTT_BROKER_PORT} "$@" 31 | fi 32 | 33 | exec "$@" 34 | -------------------------------------------------------------------------------- /scap-sync.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | volumes: 4 | gvm-var-lib: {} 5 | run-gvm: {} 6 | 7 | services: 8 | scap-sync: 9 | image: ${GVMD_IMAGE_NAME:-admirito/gvmd}:${GVMD_IMAGE_TAG:-latest} 10 | volumes: 11 | - gvm-var-lib:/var/lib/gvm 12 | - run-gvm:/run/gvm 13 | command: 14 | - sh 15 | - -xc 16 | - | 17 | chown -R gvm:gvm /var/lib/gvm 18 | greenbone-feed-sync -vvv --type scap 19 | # environment: 20 | # GREENBONE_FEED_SYNC_SCAP_DATA_URL: "rsync://feed.community.greenbone.net/community/vulnerability-feed/22.04/scap-data" 21 | --------------------------------------------------------------------------------