Las pruebas de grupos de seguridad son la practica de validar automaticamente las reglas de firewall en la nube para garantizar que implementen el principio de minimo privilegio y cumplan con las politicas de seguridad organizacionales. Segun el Verizon Data Breach Investigations Report 2023, la mala configuracion es la principal causa de brechas de datos en la nube, con el 21% de los incidentes involucrando recursos en la nube mal configurados, incluyendo grupos de seguridad. Segun investigaciones de Palo Alto Networks, el 65% de las organizaciones tienen al menos un activo en la nube con un grupo de seguridad demasiado permisivo. Las pruebas automatizadas con Checkov, InSpec y las capacidades de prueba integradas de Terraform previenen configuraciones incorrectas.

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.

“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

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.

FAQ

Cual es la diferencia entre Checkov e InSpec para testing de security groups?

Checkov realiza analisis estatico del codigo Terraform antes del despliegue, detectando misconfiguraciones como reglas SSH abiertas (0.0.0.0/0) en la etapa de plan. InSpec valida el estado real desplegado de los security groups en tu cuenta cloud. Usa ambos juntos: Checkov en pre-commit y CI para prevenir configuraciones incorrectas, e InSpec post-despliegue para verificar que la realidad coincida con las expectativas y detectar drift de cambios manuales.

Que reglas de security groups debo probar siempre?

Como minimo, prueba CKV_AWS_24 (sin SSH desde 0.0.0.0/0), CKV_AWS_25 (sin RDP desde 0.0.0.0/0), CKV_AWS_260 (sin inbound sin restricciones) y que los security groups por defecto no tengan reglas. Tambien verifica que los security groups de la capa de BD solo acepten conexiones de los grupos de la capa de aplicacion, que las reglas de egress esten explicitamente definidas y que cada security group tenga una descripcion significativa.

Como manejo el testing de security groups en multiples proveedores cloud?

Usa Checkov como tu herramienta unificada de analisis estatico ya que soporta verificaciones de security groups para AWS, Azure y GCP. Para testing de integracion, InSpec soporta las tres nubes a traves de recursos especificos por plataforma. Diferencias clave: los security groups de AWS son stateful (trafico de retorno automaticamente permitido), los Azure NSGs soportan ordenamiento de reglas por prioridad, y las reglas de firewall de GCP se aplican a nivel de VPC con network tags.

Que debo hacer cuando Checkov pasa pero los security groups siguen mal configurados?

Esto tipicamente indica drift causado por cambios manuales fuera de Terraform. Implementa monitoreo continuo con AWS Config Rules o Cloud Custodian para detectar modificaciones no autorizadas en tiempo real. Tambien asegura que todos los cambios de infraestructura pasen por CI/CD restringiendo el acceso directo a la consola con politicas IAM. Ejecuta verificaciones de compliance con InSpec programadas para detectar drift entre el estado de Terraform y la configuracion cloud real.

Ver También

Recursos Oficiales