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 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.
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
