TL;DR

  • Usa Checkov en CI/CD para detectar misconfiguraciones antes del deployment—CKV_AWS_24 (sin SSH desde 0.0.0.0/0) es innegociable
  • Prueba en múltiples capas: análisis estático (Checkov), tests de integración (InSpec/Terratest), y validación en runtime (AWS Config)
  • El testing cross-cloud requiere entender diferencias de plataforma: AWS SGs son stateful, las reglas de firewall de GCP pueden ser stateful o stateless

Ideal para: Equipos gestionando cargas de trabajo cloud que necesitan prevenir acceso de red no autorizado No recomendado si: Usas un servicio gestionado donde los security groups están abstraídos Tiempo de lectura: 13 minutos

Las misconfiguraciones de security groups siguen siendo una de las principales causas de brechas cloud. Una sola regla permitiendo SSH desde 0.0.0.0/0 o una regla de egress demasiado permisiva puede exponer toda tu infraestructura. Esta guía cubre estrategias de testing que detectan estos problemas antes de llegar a producción.

Para contexto más amplio sobre testing de red, consulta Testing de Configuración de Red y Estrategias de Testing de Terraform.

Enfoques Asistidos por IA

Las herramientas de IA destacan generando tests comprehensivos de security groups e identificando conflictos de reglas.

Generando políticas personalizadas de Checkov:

Escribe una política personalizada de Checkov en Python que valide:

1. Todos los security groups deben tener descripción (no la por defecto)
2. Las reglas inbound no pueden usar CIDR 0.0.0.0/0 excepto para puertos 80 y 443
3. Security groups etiquetados como "internal" no pueden tener reglas públicas
4. Todas las reglas egress deben especificar destino explícito (sin 0.0.0.0/0)

Incluye la clase de política, método check, y tipos de recursos soportados.
Muestra cómo registrarla y ejecutarla con Checkov.

Analizando conflictos de reglas de security groups:

Analiza estas reglas de AWS security group para problemas potenciales:

SG-web:

- Inbound: 443 desde 0.0.0.0/0
- Inbound: 80 desde 0.0.0.0/0
- Outbound: todo a 0.0.0.0/0

SG-app:

- Inbound: 8080 desde SG-web
- Inbound: 22 desde 10.0.0.0/8
- Outbound: 443 a 0.0.0.0/0
- Outbound: 5432 a SG-db

SG-db:

- Inbound: 5432 desde SG-app
- Outbound: ninguno especificado

Identifica: Riesgos de seguridad, reglas innecesarias, reglas faltantes para
tráfico de retorno, y recomendaciones para configuración de mínimo privilegio.

Creando perfiles InSpec para compliance:

Crea un perfil InSpec para controles de security group del CIS AWS Benchmark:

1. 5.1: Asegurar que ningún security group permite ingress desde 0.0.0.0/0 al puerto 22
2. 5.2: Asegurar que ningún security group permite ingress desde 0.0.0.0/0 al puerto 3389
3. 5.3: Asegurar que el security group por defecto restringe todo el tráfico
4. 5.4: Asegurar que VPC flow logging está habilitado

Incluye metadatos de control apropiados, scores de impacto y guía de remediación.

Cuándo Usar Diferentes Enfoques de Testing

Framework de Decisión de Estrategia de Testing

Tipo de TestHerramientaCuándo EjecutarQué Detecta
Análisis estáticoCheckov, tfsecPre-commit, CIMisconfiguraciones obvias (SSH desde 0.0.0.0/0)
Validación de políticasOPA, SentinelPre-applyReglas org personalizadas, convenciones de nombres
Testing de integraciónInSpec, TerratestPost-applyEstado real de reglas vs esperado
Detección de driftAWS Config, Cloud CustodianContinuoCambios manuales, reglas no autorizadas
Testing de penetraciónScans manuales/automatizadosPeriódicoExplotabilidad real

Checks Críticos de Security Groups

Check IDDescripciónNivel de Riesgo
CKV_AWS_24Sin inbound SSH desde 0.0.0.0/0Crítico
CKV_AWS_25Sin inbound RDP desde 0.0.0.0/0Crítico
CKV_AWS_260Sin inbound desde 0.0.0.0/0 a cualquier puertoAlto
CKV_AWS_277Sin egress excesivamente permisivoMedio
CKV_AZURE_10NSG restringe SSH desde internetCrítico
CKV_GCP_3Regla de firewall no abierta al mundoAlto

Testing de AWS Security Groups

Checkov para Terraform

# Instalar Checkov
pip install checkov

# Escanear archivos Terraform
checkov -d ./terraform --framework terraform

# Escanear con checks específicos
checkov -d ./terraform --check CKV_AWS_24,CKV_AWS_25,CKV_AWS_260

# Output a JUnit para CI
checkov -d ./terraform --output junitxml > checkov-results.xml

Política Personalizada de 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 = "Asegurar que security group tiene descripción significativa"
        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]

        # Fallar si no hay descripción o descripción por defecto
        if not description or description == "Managed by Terraform":
            return CheckResult.FAILED

        # Fallar si la descripción es muy corta
        if len(description) < 20:
            return CheckResult.FAILED

        return CheckResult.PASSED

check = SecurityGroupHasDescription()

Tests InSpec para 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 no deben permitir SSH desde internet'
  desc 'Acceso SSH desde 0.0.0.0/0 expone instancias a ataques de fuerza bruta'

  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 no deben permitir RDP desde internet'

  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 'Security group por defecto debe restringir todo el tráfico'

  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

Validación de Security Groups con 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")

    // Probar web tier SG
    t.Run("WebTierSG", func(t *testing.T) {
        webSG := getSecurityGroup(t, webSGID)

        // Debe permitir HTTPS desde internet
        assert.True(t, hasInboundRule(webSG, 443, "0.0.0.0/0"),
            "Web SG debe permitir HTTPS desde internet")

        // NO debe permitir SSH desde internet
        assert.False(t, hasInboundRule(webSG, 22, "0.0.0.0/0"),
            "Web SG no debe permitir SSH desde internet")
    })

    // Probar database tier SG
    t.Run("DatabaseTierSG", func(t *testing.T) {
        dbSG := getSecurityGroup(t, dbSGID)

        // NO debe tener reglas 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 no debe permitir acceso público")
            }
        }
    })
}

Testing de Azure NSG

Checkov para Azure NSGs

# Checks específicos de Azure
checkov -d ./terraform --check CKV_AZURE_9,CKV_AZURE_10,CKV_AZURE_12

InSpec para Azure NSGs

control 'nsg-no-public-ssh' do
  impact 1.0
  title 'NSGs no deben permitir SSH desde internet'

  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

Testing de Firewall GCP

Checkov para Firewalls GCP

# Checks específicos de GCP
checkov -d ./terraform --check CKV_GCP_2,CKV_GCP_3,CKV_GCP_88

Integración CI/CD

Workflow de 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: Ejecutar 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: Subir SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: checkov-results.sarif

Midiendo el Éxito

MétricaAntes del TestingDespués del TestingCómo Rastrear
Reglas SSH/RDP públicasEncontradas en auditorías0 en producciónReportes Checkov
Incidentes de seguridad por SG2-3/año0Logs de respuesta a incidentes
Violaciones de compliance5-10/auditoría0-1/auditoríaHallazgos de auditoría
Tiempo para detectar misconfigDías/semanasMinutosMétricas de pipeline CI/CD

Señales de que tu testing no funciona:

  • Checkov pasa pero InSpec falla (drift entre plan y realidad)
  • Cambios manuales a security groups evadiendo CI/CD
  • Solicitudes de excepciones volviéndose rutinarias
  • Security groups por defecto aún tienen reglas

Conclusión

El testing efectivo de security groups requiere defensa en profundidad:

  1. Análisis estático (Checkov) detecta misconfiguraciones obvias en código
  2. Validación de políticas (OPA/Sentinel) aplica estándares organizacionales
  3. Testing de integración (InSpec/Terratest) verifica estado real desplegado
  4. Monitoreo continuo (AWS Config) detecta drift y cambios no autorizados

La idea clave: los security groups son demasiado importantes para probar solo una vez. Implementa validación continua que detecte problemas en cada etapa—desde desarrollo hasta producción.

Ver También

Recursos Oficiales