Тестирование групп безопасности — практика автоматической проверки правил брандмауэра облака для обеспечения принципа наименьших привилегий и соответствия политикам безопасности организации. По данным отчёта Verizon Data Breach Investigations Report 2023, неправильная конфигурация является ведущей причиной утечек данных в облаке, при этом 21% инцидентов связаны с неправильно настроенными облачными ресурсами, включая группы безопасности. По данным исследования Palo Alto Networks, 65% организаций имеют хотя бы один облачный ресурс с чрезмерно разрешительной группой безопасности, допускающей неограниченный входящий доступ. Автоматизированное тестирование групп безопасности с Checkov, InSpec и встроенными возможностями тестирования Terraform предотвращает неправильные конфигурации.

TL;DR

  • Используйте Checkov в CI/CD для обнаружения misconfigurations до деплоя—CKV_AWS_24 (без SSH от 0.0.0.0/0) обязателен
  • Тестируйте на нескольких уровнях: статический анализ (Checkov), интеграционные тесты (InSpec/Terratest), и runtime валидация (AWS Config)
  • Cross-cloud тестирование требует понимания различий платформ: AWS SGs stateful, правила firewall GCP могут быть stateful или stateless

Идеально для: Команд, управляющих облачными workloads, которым нужно предотвратить несанкционированный сетевой доступ Не подходит если: Вы используете managed service, где security groups абстрагированы Время чтения: 13 минут

Misconfigurations security groups остаются одной из главных причин облачных breaches. Одно правило, разрешающее SSH от 0.0.0.0/0, или чрезмерно разрешающее правило egress может открыть всю вашу инфраструктуру. Это руководство охватывает стратегии тестирования, которые обнаруживают эти проблемы до достижения production.

Для более широкого контекста тестирования сети, смотрите Тестирование Сетевой Конфигурации и Стратегии Тестирования Terraform.

Подходы с Использованием ИИ

Инструменты ИИ отлично справляются с генерацией комплексных тестов security groups и выявлением конфликтов правил.

Генерация кастомных политик Checkov:

Напиши кастомную политику Checkov на Python, которая валидирует:

1. Все security groups должны иметь описание (не по умолчанию)
2. Inbound правила не могут использовать CIDR 0.0.0.0/0 кроме портов 80 и 443
3. Security groups с тегом "internal" не могут иметь публичных правил
4. Все egress правила должны указывать явный destination (без 0.0.0.0/0)

Включи класс политики, метод check, и поддерживаемые типы ресурсов.
Покажи как зарегистрировать и запустить с Checkov.

Анализ конфликтов правил security groups:

Проанализируй эти правила AWS security group на потенциальные проблемы:

SG-web:

- Inbound: 443 от 0.0.0.0/0
- Inbound: 80 от 0.0.0.0/0
- Outbound: всё к 0.0.0.0/0

SG-app:

- Inbound: 8080 от SG-web
- Inbound: 22 от 10.0.0.0/8
- Outbound: 443 к 0.0.0.0/0
- Outbound: 5432 к SG-db

SG-db:

- Inbound: 5432 от SG-app
- Outbound: не указан

Определи: Риски безопасности, ненужные правила, отсутствующие правила для
return traffic, и рекомендации для конфигурации минимальных привилегий.

Создание InSpec профилей для compliance:

Создай InSpec профиль для контролей security group CIS AWS Benchmark:

1. 5.1: Убедиться, что никакой security group не разрешает ingress от 0.0.0.0/0 на порт 22
2. 5.2: Убедиться, что никакой security group не разрешает ingress от 0.0.0.0/0 на порт 3389
3. 5.3: Убедиться, что default security group ограничивает весь трафик
4. 5.4: Убедиться, что VPC flow logging включён

Включи правильные метаданные контроля, impact scores и руководство по remediation.

“A misconfigured security group is the most common entry point for cloud breaches. Testing firewall rules should be as routine as running unit tests — every change to a security group needs automated validation before deployment.” — Yuri Kan, Senior QA Lead

Когда Использовать Разные Подходы к Тестированию

Фреймворк Принятия Решений по Стратегии Тестирования

Тип ТестаИнструментКогда ЗапускатьЧто Обнаруживает
Статический анализCheckov, tfsecPre-commit, CIОчевидные misconfigs (SSH от 0.0.0.0/0)
Валидация политикOPA, SentinelPre-applyКастомные правила организации, конвенции именования
Интеграционное тестированиеInSpec, TerratestPost-applyРеальное состояние правил vs ожидаемое
Обнаружение driftAWS Config, Cloud CustodianНепрерывноРучные изменения, несанкционированные правила
Тестирование на проникновениеРучные/автоматизированные сканыПериодическиРеальная эксплуатируемость

Критические Проверки Security Groups

Check IDОписаниеУровень Риска
CKV_AWS_24Без inbound SSH от 0.0.0.0/0Критический
CKV_AWS_25Без inbound RDP от 0.0.0.0/0Критический
CKV_AWS_260Без inbound от 0.0.0.0/0 на любой портВысокий
CKV_AWS_277Без чрезмерно разрешающего egressСредний
CKV_AZURE_10NSG ограничивает SSH из интернетаКритический
CKV_GCP_3Правило firewall не открыто мируВысокий

Тестирование AWS Security Groups

Checkov для Terraform

# Установка Checkov
pip install checkov

# Сканирование файлов Terraform
checkov -d ./terraform --framework terraform

# Сканирование с конкретными проверками
checkov -d ./terraform --check CKV_AWS_24,CKV_AWS_25,CKV_AWS_260

# Вывод в JUnit для CI
checkov -d ./terraform --output junitxml > checkov-results.xml

Кастомная Политика Checkov

# custom_checks/security_group_description.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories

class SecurityGroupHasDescription(BaseResourceCheck):
    def __init__(self):
        name = "Убедиться, что security group имеет осмысленное описание"
        id = "CKV_CUSTOM_SG_1"
        supported_resources = ['aws_security_group']
        categories = [CheckCategories.NETWORKING]
        super().__init__(name=name, id=id, categories=categories,
                        supported_resources=supported_resources)

    def scan_resource_conf(self, conf):
        description = conf.get('description', [''])[0]

        # Ошибка если нет описания или описание по умолчанию
        if not description or description == "Managed by Terraform":
            return CheckResult.FAILED

        # Ошибка если описание слишком короткое
        if len(description) < 20:
            return CheckResult.FAILED

        return CheckResult.PASSED

check = SecurityGroupHasDescription()

InSpec Тесты для AWS Security Groups

# controls/aws_security_groups.rb

title "AWS Security Group Compliance"

control 'sg-no-public-ssh' do
  impact 1.0
  title 'Security groups не должны разрешать SSH из интернета'
  desc 'SSH доступ от 0.0.0.0/0 подвергает инстансы атакам brute force'

  aws_security_groups.group_ids.each do |sg_id|
    describe aws_security_group(group_id: sg_id) do
      it { should_not allow_in(port: 22, ipv4_range: '0.0.0.0/0') }
      it { should_not allow_in(port: 22, ipv6_range: '::/0') }
    end
  end
end

control 'sg-no-public-rdp' do
  impact 1.0
  title 'Security groups не должны разрешать RDP из интернета'

  aws_security_groups.group_ids.each do |sg_id|
    describe aws_security_group(group_id: sg_id) do
      it { should_not allow_in(port: 3389, ipv4_range: '0.0.0.0/0') }
    end
  end
end

control 'default-sg-restricted' do
  impact 1.0
  title 'Default security group должна ограничивать весь трафик'

  aws_vpcs.vpc_ids.each do |vpc_id|
    default_sg = aws_security_groups.where(vpc_id: vpc_id, group_name: 'default')

    default_sg.group_ids.each do |sg_id|
      describe aws_security_group(group_id: sg_id) do
        its('inbound_rules.count') { should eq 0 }
        its('outbound_rules.count') { should eq 0 }
      end
    end
  end
end

Валидация Security Groups с Terratest

package test

import (
    "testing"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/ec2"
    "github.com/gruntwork-io/terratest/modules/terraform"
    "github.com/stretchr/testify/assert"
)

func TestSecurityGroupRules(t *testing.T) {
    t.Parallel()

    terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
        TerraformDir: "../modules/security-groups",
    })

    defer terraform.Destroy(t, terraformOptions)
    terraform.InitAndApply(t, terraformOptions)

    webSGID := terraform.Output(t, terraformOptions, "web_sg_id")
    dbSGID := terraform.Output(t, terraformOptions, "db_sg_id")

    // Тестируем web tier SG
    t.Run("WebTierSG", func(t *testing.T) {
        webSG := getSecurityGroup(t, webSGID)

        // Должен разрешать HTTPS из интернета
        assert.True(t, hasInboundRule(webSG, 443, "0.0.0.0/0"),
            "Web SG должен разрешать HTTPS из интернета")

        // НЕ должен разрешать SSH из интернета
        assert.False(t, hasInboundRule(webSG, 22, "0.0.0.0/0"),
            "Web SG не должен разрешать SSH из интернета")
    })

    // Тестируем database tier SG
    t.Run("DatabaseTierSG", func(t *testing.T) {
        dbSG := getSecurityGroup(t, dbSGID)

        // НЕ должен иметь inbound правил 0.0.0.0/0
        for _, rule := range dbSG.IpPermissions {
            for _, ipRange := range rule.IpRanges {
                assert.NotEqual(t, "0.0.0.0/0", *ipRange.CidrIp,
                    "Database SG не должен разрешать публичный доступ")
            }
        }
    })
}

Тестирование Azure NSG

Checkov для Azure NSGs

# Azure-специфичные проверки
checkov -d ./terraform --check CKV_AZURE_9,CKV_AZURE_10,CKV_AZURE_12

InSpec для Azure NSGs

control 'nsg-no-public-ssh' do
  impact 1.0
  title 'NSGs не должны разрешать SSH из интернета'

  azure_network_security_groups.ids.each do |nsg_id|
    describe azure_network_security_group(resource_id: nsg_id) do
      it { should_not allow_ssh_from_internet }
    end
  end
end

Тестирование Firewall GCP

Checkov для Firewalls GCP

# GCP-специфичные проверки
checkov -d ./terraform --check CKV_GCP_2,CKV_GCP_3,CKV_GCP_88

Интеграция CI/CD

Workflow GitHub Actions

name: Security Group Testing

on:
  pull_request:
    paths:

      - 'terraform/**/*.tf'

jobs:
  checkov-scan:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v4

      - name: Запуск Checkov
        uses: bridgecrewio/checkov-action@v12
        with:
          directory: terraform/
          framework: terraform
          check: CKV_AWS_24,CKV_AWS_25,CKV_AWS_260,CKV_AWS_277
          output_format: sarif
          output_file_path: checkov-results.sarif
          soft_fail: false

      - name: Загрузка SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: checkov-results.sarif

Измерение Успеха

МетрикаДо ТестированияПосле ТестированияКак Отслеживать
Публичные правила SSH/RDPНайдены на аудитах0 в productionОтчёты Checkov
Инциденты безопасности от SG2-3/год0Логи incident response
Нарушения compliance5-10/аудит0-1/аудитНаходки аудита
Время обнаружения misconfigДни/неделиМинутыМетрики pipeline CI/CD

Сигналы, что ваше тестирование не работает:

  • Checkov проходит, но InSpec падает (drift между планом и реальностью)
  • Ручные изменения security groups обходят CI/CD
  • Запросы исключений становятся рутиной
  • Default security groups всё ещё имеют правила

Заключение

Эффективное тестирование security groups требует defense in depth:

  1. Статический анализ (Checkov) обнаруживает очевидные misconfigurations в коде
  2. Валидация политик (OPA/Sentinel) применяет организационные стандарты
  3. Интеграционное тестирование (InSpec/Terratest) проверяет реальное развёрнутое состояние
  4. Непрерывный мониторинг (AWS Config) обнаруживает drift и несанкционированные изменения

Ключевая идея: security groups слишком важны, чтобы тестировать только один раз. Реализуйте непрерывную валидацию, которая обнаруживает проблемы на каждом этапе—от разработки до production.

FAQ

В чём разница между Checkov и InSpec для тестирования security groups?

Checkov выполняет статический анализ Terraform-кода до деплоя, обнаруживая misconfigurations вроде открытого SSH (0.0.0.0/0) на этапе плана. InSpec валидирует фактическое развёрнутое состояние security groups в твоём облачном аккаунте. Используй оба вместе: Checkov в pre-commit и CI для предотвращения плохих конфигураций, InSpec после деплоя для проверки соответствия реальности ожиданиям и обнаружения drift от ручных изменений.

Какие правила security groups нужно тестировать всегда?

Как минимум тестируй CKV_AWS_24 (без SSH от 0.0.0.0/0), CKV_AWS_25 (без RDP от 0.0.0.0/0), CKV_AWS_260 (без неограниченного входящего трафика) и что дефолтные security groups не имеют правил. Также проверяй, что группы уровня БД принимают соединения только от групп уровня приложения, egress-правила явно определены, и каждая security group имеет содержательное описание.

Как тестировать security groups у нескольких облачных провайдеров?

Используй Checkov как единый инструмент статического анализа — он поддерживает проверки security groups для AWS, Azure и GCP. Для интеграционного тестирования InSpec поддерживает все три облака через платформо-специфичные ресурсы. Ключевые различия: AWS security groups stateful (обратный трафик автоматически разрешён), Azure NSGs поддерживают приоритетный порядок правил, правила firewall GCP применяются на уровне VPC с сетевыми тегами.

Что делать, если Checkov проходит, но security groups всё равно misconfigured?

Обычно это указывает на drift от ручных изменений вне Terraform. Внедри непрерывный мониторинг с AWS Config Rules или Cloud Custodian для обнаружения несанкционированных модификаций в реальном времени. Также обеспечь, чтобы все изменения инфраструктуры проходили через CI/CD, ограничив прямой доступ к консоли через IAM-политики. Запускай InSpec compliance-проверки по расписанию для обнаружения drift между состоянием Terraform и реальной облачной конфигурацией.

Смотрите также

Официальные ресурсы