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 Test | Herramienta | Cuándo Ejecutar | Qué Detecta |
|---|---|---|---|
| Análisis estático | Checkov, tfsec | Pre-commit, CI | Misconfiguraciones obvias (SSH desde 0.0.0.0/0) |
| Validación de políticas | OPA, Sentinel | Pre-apply | Reglas org personalizadas, convenciones de nombres |
| Testing de integración | InSpec, Terratest | Post-apply | Estado real de reglas vs esperado |
| Detección de drift | AWS Config, Cloud Custodian | Continuo | Cambios manuales, reglas no autorizadas |
| Testing de penetración | Scans manuales/automatizados | Periódico | Explotabilidad real |
Checks Críticos de Security Groups
| Check ID | Descripción | Nivel de Riesgo |
|---|---|---|
| CKV_AWS_24 | Sin inbound SSH desde 0.0.0.0/0 | Crítico |
| CKV_AWS_25 | Sin inbound RDP desde 0.0.0.0/0 | Crítico |
| CKV_AWS_260 | Sin inbound desde 0.0.0.0/0 a cualquier puerto | Alto |
| CKV_AWS_277 | Sin egress excesivamente permisivo | Medio |
| CKV_AZURE_10 | NSG restringe SSH desde internet | Crítico |
| CKV_GCP_3 | Regla de firewall no abierta al mundo | Alto |
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étrica | Antes del Testing | Después del Testing | Cómo Rastrear |
|---|---|---|---|
| Reglas SSH/RDP públicas | Encontradas en auditorías | 0 en producción | Reportes Checkov |
| Incidentes de seguridad por SG | 2-3/año | 0 | Logs de respuesta a incidentes |
| Violaciones de compliance | 5-10/auditoría | 0-1/auditoría | Hallazgos de auditoría |
| Tiempo para detectar misconfig | Días/semanas | Minutos | Mé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:
- Análisis estático (Checkov) detecta misconfiguraciones obvias en código
- Validación de políticas (OPA/Sentinel) aplica estándares organizacionales
- Testing de integración (InSpec/Terratest) verifica estado real desplegado
- 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
- Testing de Configuración de Red - Estrategias más amplias de validación de red
- Estrategias de Testing de Terraform - Pirámide completa de testing Terraform
- Testing de Policy as Code - OPA y Sentinel para políticas de seguridad
- Testing de Infraestructura AWS - Testing comprehensivo de AWS
- Testing de Compliance para IaC - Cumpliendo requisitos regulatorios
