OpenVAS/GVM для сканирования уязвимостей: как MSP сканирует 200 клиентских серверов

Ситуация: MSP без системного сканирования уязвимостей

MSP-компания «СекьюрИТ» обслуживает 45 клиентов — в сумме 200 серверов (Linux/Windows) и 80 сетевых устройств. Когда они пришли к нам в itfresh.ru, сканирование уязвимостей проводилось вручную: инженер запускал nmap и nikto раз в квартал, результаты записывал в Excel-таблицу.

Проблемы этого подхода:

  • Охват — реально сканировались 30-40 серверов из 200 (на остальные не хватало времени)
  • Глубина — nmap находит открытые порты, но не знает о CVE в установленном ПО
  • Периодичность — раз в квартал, а уязвимости появляются ежедневно
  • Отчётность — клиенты просят отчёты для аудиторов, а Excel не подходит
  • Remediation — нет трекинга: нашли уязвимость, починили ли — неизвестно

Задача: развернуть централизованное сканирование всех 200 серверов с еженедельными автоматическими отчётами для каждого клиента.

Установка GVM в Docker

GVM (Greenbone Vulnerability Management) — open-source платформа для сканирования уязвимостей, наследник OpenVAS. Содержит более 180 000 NVT (Network Vulnerability Tests). Для MSP мы выбрали Docker-установку — проще обновлять и масштабировать:

# docker-compose.yml для GVM 22.x
version: '3.8'
services:
  gvm:
    image: greenbone/community-container:stable
    hostname: gvm
    ports:
      - "9392:9392"    # GSA web interface
    volumes:
      - gvm-data:/data
      - gvm-vt-data:/var/lib/openvas/plugins
    environment:
      - GVM_ADMIN_PASSWORD=SecureP@ssw0rd_2026
      - COMMUNITY_EDITION=1
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 8G

volumes:
  gvm-data:
  gvm-vt-data:
# Запускаем и ждём инициализации (первый запуск — 30-60 минут на загрузку NVT)
docker compose up -d

# Следим за прогрессом загрузки feed
docker compose logs -f gvm | grep -i feed
# [INFO] Updating NVTs... (this may take a while)
# [INFO] NVT update complete: 183,247 NVTs loaded
# [INFO] Updating SCAP data...
# [INFO] Updating CERT data...
# [INFO] All feeds updated successfully

Аппаратные требования для сканирования 200 хостов: 4 CPU, 8 GB RAM, 50 GB SSD. Мы выделили отдельный сервер, так как во время активного сканирования GVM потребляет все доступные ресурсы.

Создание целей, задач и расписаний

Организация сканирования для MSP: группируем хосты по клиентам, создаём отдельные задачи с разным расписанием:

# Через GMP (Greenbone Management Protocol) CLI
# Создаём группу хостов для клиента "Банк Альфа"
gvm-cli socket --socketpath /run/gvmd/gvmd.sock \
  --xml '<create_target>
    <name>Банк Альфа - серверы</name>
    <hosts>10.100.1.0/24,10.100.2.10-10.100.2.50</hosts>
    <port_list id="33d0cd82-57c6-11e1-8ed1-406186ea4fc5"/>
    <alive_tests>Consider Alive</alive_tests>
    <comment>Production servers: web, DB, app</comment>
  </create_target>'

Scan configs определяют глубину сканирования:

ConfigОписаниеВремя на 10 хостовПрименение
DiscoveryТолько обнаружение хостов и портов5 минИнвентаризация
Host DiscoveryOS detection, service detection15 минБыстрый обзор
Full and FastВсе NVT кроме опасных и медленных1-2 часаЕженедельное сканирование
Full and DeepВсе NVT включая медленные4-8 часовЕжемесячный глубокий скан

Расписание для 45 клиентов: разбили на 7 дней недели, по 6-7 клиентов в день. Каждый скан стартует в 02:00 ночи, чтобы не нагружать сети клиентов в рабочее время:

# Создаём расписание — каждый понедельник в 02:00
gvm-cli socket --socketpath /run/gvmd/gvmd.sock \
  --xml '<create_schedule>
    <name>Weekly Monday 02:00</name>
    <icalendar>BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART:20260406T020000Z
RRULE:FREQ=WEEKLY;BYDAY=MO
DURATION:PT12H
END:VEVENT
END:VCALENDAR</icalendar>
    <timezone>Europe/Moscow</timezone>
  </create_schedule>'

# Создаём задачу сканирования
gvm-cli socket --socketpath /run/gvmd/gvmd.sock \
  --xml '<create_task>
    <name>Банк Альфа - еженедельный скан</name>
    <target id="TARGET_ID"/>
    <config id="daba56c8-73ec-11df-a475-002264764cea"/>
    <scanner id="08b69003-5fc2-4037-a479-93b440211c73"/>
    <schedule id="SCHEDULE_ID"/>
    <preferences>
      <preference>
        <scanner_name>max_hosts</scanner_name>
        <value>10</value>
      </preference>
      <preference>
        <scanner_name>max_checks</scanner_name>
        <value>4</value>
      </preference>
    </preferences>
  </create_task>'

Authenticated Scans: SSH и SMB

Unauthenticated scan видит уязвимости только снаружи — открытые порты, баннеры сервисов. Authenticated scan заходит на сервер и проверяет установленные пакеты, конфигурации, патчи. Разница в результатах — в 3-5 раз больше найденных уязвимостей:

# Создаём SSH credentials для Linux-серверов
gvm-cli socket --socketpath /run/gvmd/gvmd.sock \
  --xml '<create_credential>
    <name>Банк Альфа - SSH scan account</name>
    <type>up</type>
    <login>gvm-scanner</login>
    <password>ScannerP@ss_2026</password>
    <comment>Read-only account for vulnerability scanning</comment>
  </create_credential>'

На каждом Linux-сервере клиента создаём минимальную учётную запись:

# На каждом сканируемом сервере
sudo useradd -r -s /bin/bash -d /home/gvm-scanner gvm-scanner
echo 'gvm-scanner:ScannerP@ss_2026' | sudo chpasswd

# Разрешаем читать информацию о пакетах и конфигурациях
# (без sudo, без записи)
echo 'gvm-scanner ALL=(root) NOPASSWD: /usr/bin/dpkg -l, /usr/bin/rpm -qa, /usr/sbin/dmidecode, /bin/cat /etc/os-release' \
  | sudo tee /etc/sudoers.d/gvm-scanner
sudo chmod 440 /etc/sudoers.d/gvm-scanner

Для Windows-серверов — SMB credentials с ограниченными правами:

# PowerShell: создаём учётную запись для сканирования
New-LocalUser -Name "gvm-scanner" -Password (ConvertTo-SecureString "ScanP@ss2026" -AsPlainText -Force) -Description "GVM vulnerability scanner"
Add-LocalGroupMember -Group "Remote Management Users" -Member "gvm-scanner"

# Включаем WMI для сбора данных
winrm quickconfig -q
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
Set-Item WSMan:\localhost\Service\Auth\Basic $true

Сравнение результатов на одном сервере (Ubuntu 22.04, nginx + PostgreSQL):

Тип сканаНайдено уязвимостейCritical/HighВремя
Unauthenticated122 / 38 мин
Authenticated (SSH)475 / 1422 мин

Анализ отчётов и Remediation Workflow

После каждого скана GVM генерирует отчёт с уязвимостями, ранжированными по CVSS-скору:

  • Critical (9.0-10.0) — эксплуатируемые удалённо без аутентификации. Исправить в 24 часа.
  • High (7.0-8.9) — серьёзные уязвимости. Исправить в 7 дней.
  • Medium (4.0-6.9) — умеренный риск. Исправить в 30 дней.
  • Low (0.1-3.9) — минимальный риск. Исправить при следующем обслуживании.

Пример вывода для одного хоста:

# Экспорт отчёта в CSV через GMP
gvm-cli socket --socketpath /run/gvmd/gvmd.sock \
  --xml '<get_reports report_id="REPORT_ID" format_id="c1645568-627a-11e3-a660-406186ea4fc5"/>' \
  > report-bank-alfa-2026-04-05.csv

# Типичные находки:
# CVE-2024-6387  | regreSSHion   | CVSS 8.1 | OpenSSH < 9.8   | Critical
# CVE-2024-3094  | xz backdoor   | CVSS 10.0| xz-utils 5.6.0  | Critical  
# CVE-2023-44487 | HTTP/2 Rapid Reset | CVSS 7.5 | nginx < 1.25.3 | High
# CVE-2024-0567  | GnuTLS        | CVSS 7.5 | libgnutls < 3.8.3 | High

Для remediation мы построили workflow на базе Telegram-бота:

#!/usr/bin/env python3
# gvm_report_bot.py — отправка результатов сканирования в Telegram
import subprocess
import json
import requests
from datetime import datetime

BOT_TOKEN = "BOT_TOKEN_HERE"
CHANNEL_ENGINEERS = "-100XXXXXXXXX"  # канал инженеров

def parse_gvm_report(report_file):
    """Парсим CSV-отчёт GVM"""
    critical = 0
    high = 0
    medium = 0
    cve_list = []
    
    with open(report_file) as f:
        for line in f:
            parts = line.strip().split(',')
            if len(parts) > 5:
                severity = float(parts[4]) if parts[4] else 0
                if severity >= 9.0:
                    critical += 1
                    cve_list.append(f"🔴 {parts[1]} (CVSS {severity}) — {parts[2]}")
                elif severity >= 7.0:
                    high += 1
                    cve_list.append(f"🟠 {parts[1]} (CVSS {severity}) — {parts[2]}")
                elif severity >= 4.0:
                    medium += 1
    
    return critical, high, medium, cve_list

def send_report(client_name, critical, high, medium, cve_list):
    msg = f"📊 *Scan Report: {client_name}*\n"
    msg += f"Date: {datetime.now().strftime('%Y-%m-%d')}\n\n"
    msg += f"🔴 Critical: {critical}\n"
    msg += f"🟠 High: {high}\n"
    msg += f"🟡 Medium: {medium}\n\n"
    
    if cve_list:
        msg += "*Top vulnerabilities:*\n"
        for cve in cve_list[:10]:
            msg += f"{cve}\n"
    
    requests.post(
        f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
        json={"chat_id": CHANNEL_ENGINEERS, "text": msg, "parse_mode": "Markdown"}
    )

Compliance Scanning и CIS Benchmarks

Помимо поиска CVE, GVM поддерживает compliance-сканирование — проверку серверов на соответствие стандартам безопасности. Для клиентов «СекьюрИТ» наиболее востребованы CIS Benchmarks:

# GVM включает SCAP-политики для compliance
# Основные проверки CIS Benchmark для Ubuntu 22.04:

# 1. Проверка настроек SSH
# - PermitRootLogin no
# - MaxAuthTries 4
# - PermitEmptyPasswords no
# - X11Forwarding no
# - ClientAliveInterval 300
# - ClientAliveCountMax 3

# 2. Проверка файловой системы
# - /tmp смонтирован отдельно с noexec,nosuid
# - Sticky bit на world-writable директориях
# - Нет файлов без владельца

# 3. Проверка аудита
# - auditd установлен и запущен
# - Логируются изменения в /etc/passwd, /etc/shadow
# - Логируются su/sudo команды

# 4. Проверка сетевых параметров
# - IP forwarding отключен (если не роутер)
# - ICMP redirects отключены
# - SYN cookies включены

Создаём compliance-задачу в GVM:

# Используем audit-конфиг для compliance
gvm-cli socket --socketpath /run/gvmd/gvmd.sock \
  --xml '<create_task>
    <name>Банк Альфа - CIS Compliance</name>
    <target id="TARGET_ID"/>
    <config id="2d3f051c-55ba-11e3-bf43-406186ea4fc5"/>
    <scanner id="08b69003-5fc2-4037-a479-93b440211c73"/>
    <schedule id="MONTHLY_SCHEDULE_ID"/>
  </create_task>'

Результат compliance-скана показывает процент соответствия и конкретные нарушения. Для одного клиента банковского сектора первый скан показал 47% compliance с CIS Level 1. Через 3 месяца планомерной работы — 89%. Оставшиеся 11% — исключения, согласованные с клиентом (например, необходимость IP forwarding на серверах-маршрутизаторах).

API-автоматизация и масштабирование

Для MSP с 45 клиентами ручное управление задачами невозможно. Мы автоматизировали всё через GVM API (GMP protocol):

#!/usr/bin/env python3
# gvm_automation.py — автоматическое создание задач для новых клиентов
from gvm.connections import UnixSocketConnection
from gvm.protocols.gmp import Gmp
from gvm.transforms import EtreeTransform

def create_client_scan(client_name, hosts, ssh_login, ssh_password, schedule_day):
    """Создаёт полный набор для нового клиента: credentials, target, task, schedule"""
    
    connection = UnixSocketConnection(path='/run/gvmd/gvmd.sock')
    transform = EtreeTransform()
    
    with Gmp(connection=connection, transform=transform) as gmp:
        gmp.authenticate('admin', 'SecureP@ssw0rd_2026')
        
        # 1. Создаём SSH credentials
        cred_response = gmp.create_credential(
            name=f"{client_name} - SSH",
            credential_type=gmp.types.CredentialType.USERNAME_PASSWORD,
            login=ssh_login,
            password=ssh_password
        )
        cred_id = cred_response.get('id')
        
        # 2. Создаём target с credentials
        target_response = gmp.create_target(
            name=f"{client_name} - All servers",
            hosts=hosts,
            ssh_credential_id=cred_id,
            alive_test=gmp.types.AliveTest.CONSIDER_ALIVE
        )
        target_id = target_response.get('id')
        
        # 3. Создаём задачу
        task_response = gmp.create_task(
            name=f"{client_name} - Weekly Full Scan",
            config_id='daba56c8-73ec-11df-a475-002264764cea',  # Full and Fast
            target_id=target_id,
            scanner_id='08b69003-5fc2-4037-a479-93b440211c73'
        )
        task_id = task_response.get('id')
        
        print(f"Created scan task for {client_name}: {task_id}")
        return task_id

# Добавляем нового клиента одной командой
create_client_scan(
    client_name="Логистика Плюс",
    hosts=["172.16.0.0/24", "172.16.1.10-172.16.1.30"],
    ssh_login="gvm-scanner",
    ssh_password="ScanP@ss_2026",
    schedule_day="Thursday"
)

Для масштабирования сканирования на 200+ хостов важна оптимизация параметров:

# /etc/openvas/openvas.conf — оптимизация производительности
max_hosts = 20           # Сканируем до 20 хостов параллельно
max_checks = 4           # До 4 NVT-проверок на хост одновременно
be_nice = yes            # Снижаем приоритет CPU для сканера
test_alive_hosts_only = yes  # Пропускаем недоступные хосты
auto_enable_dependencies = yes
network_timeout = 15     # Таймаут сетевых проверок (секунды)

# Ограничиваем ресурсы Docker
# docker-compose.yml:
# deploy:
#   resources:
#     limits:
#       cpus: '4'
#       memory: 8G

Результаты и сравнение с Nessus

После 3 месяцев работы GVM для «СекьюрИТ»:

МетрикаДо (nmap вручную)После (GVM)
Сканируемых хостов30-40 / квартал200 / неделю
Найдено уязвимостей~50 / квартал~2 800 / неделю
Critical/High закрытыхНе отслеживалось94% в первые 7 дней
Время на сканирование2 дня инженераАвтоматически (ночью)
Отчёты для клиентовExcel вручнуюPDF автоматически

Сравнение с Nessus Professional:

КритерийGVM/OpenVASNessus Professional
СтоимостьБесплатно$3,590/год (1 сканер)
Количество NVT/плагинов~183 000~200 000
Скорость сканированияСредняяВысокая (на 30-40% быстрее)
Точность (false positives)Средняя (5-8%)Высокая (2-3%)
APIGMP (XML-based)REST API (JSON)
Compliance-шаблоныБазовые CISPCI DSS, HIPAA, SOC 2
ПоддержкаCommunityКоммерческая 24/7

Для MSP с бюджетом GVM — отличный выбор: бесплатен, покрывает 90% потребностей, имеет полноценный API для автоматизации. Nessus стоит рассмотреть, если нужны готовые compliance-шаблоны для PCI DSS/HIPAA или важна минимизация false positives. Если вашей компании нужно наладить регулярное сканирование уязвимостей — обращайтесь к нам в itfresh.ru.

Часто задаваемые вопросы

При использовании конфига Full and Fast — практически нет, опасные проверки (DoS, brute-force) отключены. Конфиг Full and Deep включает более агрессивные тесты — его лучше запускать на staging. В нашей практике из 200 серверов ни один не пострадал от еженедельных сканов Full and Fast.
Ежедневно. GVM поддерживает автоматическое обновление через greenbone-feed-sync. Новые CVE появляются каждый день, и устаревшая база NVT пропускает свежие уязвимости. Настройте cron-задачу на обновление в 01:00 — до начала ночных сканов.
Да, но нужно учитывать сетевую связность: GVM-сканер должен иметь доступ к IP-адресам облачных серверов. Обычно это решается через VPN или VPC peering. Для AWS также есть Inspector (managed-сервис), но он не заменяет GVM — покрывает только EC2 и ECR, а не конфигурации приложений.
Для MSP до 300-500 хостов — да. Ограничение Community Edition: feed обновляется с задержкой 14 дней по сравнению с Greenbone Enterprise (платная версия). Для большинства сценариев это некритично — CVE с CVSS 9+ обычно исправляются не мгновенно. Если задержка в 14 дней неприемлема — рассмотрите Greenbone Enterprise или Nessus.
Три шага: 1) проверьте версию ПО на сервере (dpkg -l | grep package) — GVM иногда определяет версию по баннеру, который может быть изменён; 2) проверьте, применён ли патч без смены версии (Ubuntu backports); 3) используйте authenticated scan — он проверяет реальные пакеты, а не баннеры, и даёт в 3-5 раз меньше false positives.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#OpenVAS#GVM#vulnerability scanning#CVSS#CVE#authenticated scan#CIS benchmarks#compliance
Комментарии 0

Оставить комментарий

загрузка...