El Desafío de Visibilidad en la Nube de DevSecOps
Tu infraestructura en la nube se está expandiendo más rápido de lo que tu equipo de seguridad puede auditarla. Cada implementación, cada evento de autoescalado, cada recurso creado por un desarrollador potencialmente introduce brechas de seguridad. Necesitas visibilidad en tiempo real en todo tu entorno multi-nube, pero las herramientas de seguridad tradicionales te ofrecen instantáneas puntuales, no el monitoreo continuo que requiere el DevSecOps moderno.
Aquí es donde Steampipe se convierte en tu multiplicador de fuerza DevSecOps, transformando complejas APIs de la nube en consultas SQL que se integran perfectamente con tus flujos de trabajo de automatización y cumplimiento existentes.
Steampipe: Inteligencia de Seguridad en la Nube Impulsada por SQL
Piensa en Steampipe como si tu infraestructura en la nube se convirtiera en una enorme base de datos consultable. Cada recurso, cada configuración, cada ajuste de seguridad a través de AWS, Azure, GCP y más de 50 otras plataformas se convierte en una tabla que puedes consultar, unir y analizar usando una sintaxis SQL familiar.
Pero esto no se trata solo de consultas, se trata de habilitar Política como Código a escala empresarial. ¿Quieres validar tu cumplimiento con el CIS Kubernetes Benchmark en 15 clústeres? Eso es una consulta SQL. ¿Necesitas auditar permisos IAM en múltiples cuentas de AWS para el cumplimiento SOC2? Consulta SQL. ¿Quieres identificar la desviación de configuración en tu infraestructura gestionada por Terraform? Ya entiendes la idea.
Steampipe transforma la seguridad en la nube de una respuesta reactiva a incidentes en una gobernanza proactiva y automatizada que se integra directamente en tus flujos de trabajo de CI/CD y cumplimiento.
Despliegue DevSecOps Empresarial
Steampipe está diseñado para operaciones DevSecOps a escala empresarial con soporte para despliegues en contenedores, infraestructura como código e integración CI/CD.
Instalación Prioritaria en Contenedores (Recomendada)
Para entornos de producción DevSecOps, despliega Steampipe como un servicio en contenedores:
# Dockerfile para despliegue empresarial de Steampipe
FROM turbot/steampipe:latest
# Instalar plugins requeridos para monitoreo empresarial multi-nube
RUN steampipe plugin install aws azure gcp kubernetes terraform \
github gitlab docker oci helm vault consul nomad
# Copiar configuración empresarial
COPY steampipe.spc /home/steampipe/.steampipe/config/
COPY enterprise-queries/ /opt/steampipe/queries/
COPY compliance-policies/ /opt/steampipe/policies/
# Configurar usuario de servicio para consultas automatizadas
USER steampipe
WORKDIR /opt/steampipe
# Comando predeterminado para integración CI/CD
CMD ["steampipe", "service", "start", "--host=0.0.0.0", "--port=9193"]
Despliegue de Kubernetes para Escalabilidad
Desplegar Steampipe como un servicio de Kubernetes para monitoreo de seguridad en la nube a nivel empresarial:
# steampipe-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: steampipe-security-service
namespace: devsecops
spec:
replicas: 3
selector:
matchLabels:
app: steampipe
template:
metadata:
labels:
app: steampipe
spec:
serviceAccountName: steampipe-sa
containers:
- name: steampipe
image: your-registry/steampipe-enterprise:latest
ports:
- containerPort: 9193
env:
- name: STEAMPIPE_LOG_LEVEL
value: 'info'
- name: STEAMPIPE_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: steampipe-db-secret
key: password
volumeMounts:
- name: steampipe-config
mountPath: /home/steampipe/.steampipe/config
readOnly: true
- name: cloud-credentials
mountPath: /home/steampipe/.aws
readOnly: true
volumes:
- name: steampipe-config
configMap:
name: steampipe-enterprise-config
- name: cloud-credentials
secret:
secretName: cloud-access-credentials
---
apiVersion: v1
kind: Service
metadata:
name: steampipe-service
namespace: devsecops
spec:
selector:
app: steampipe
ports:
- port: 9193
targetPort: 9193
type: ClusterIP
Configuración de Plugins Empresariales
Instalar y configurar plugins para una cobertura integral multi-nube:
# Proveedores de nube principales
steampipe plugin install aws azure gcp
# Plataformas de contenedores y orquestación
steampipe plugin install kubernetes docker oci
# Infraestructura como Código
steampipe plugin install terraform consul vault nomad
# Integración de la cadena de herramientas DevSecOps
steampipe plugin install github gitlab jenkins splunk prometheus grafana
# Marcos de cumplimiento y seguridad
steampipe plugin install crowdstrike qualys tenable rapid7
# Configurar acceso multi-cuenta
steampipe connection import aws-accounts.spc
steampipe connection import azure-subscriptions.spc
steampipe connection import gcp-projects.spc
Integración de Pipeline CI/CD
Configurar Steampipe para validación de seguridad automatizada en tus pipelines de despliegue:
# .github/workflows/security-compliance.yml
name: Cumplimiento de Seguridad Automatizado
on:
schedule:
- cron: '0 */6 * * *' # Cada 6 horas
push:
branches: [main]
paths: ['infrastructure/**', 'k8s/**']
jobs:
security-validation:
runs-on: ubuntu-latest
container:
image: turbot/steampipe:latest
steps:
- name: Configurar Acceso a la Nube
run: |
# Configurar acceso a AWS
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Configurar acceso a Azure
az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} \
-p ${{ secrets.AZURE_CLIENT_SECRET }} \
--tenant ${{ secrets.AZURE_TENANT_ID }}
- name: Instalar Plugins Empresariales
run: |
steampipe plugin install aws azure gcp kubernetes terraform
- name: Ejecutar Validación de Cumplimiento
run: |
# Validación del Benchmark CIS Kubernetes
steampipe query \
"select * from kubernetes_pod where security_context is null" \
--output json > cis-k8s-violations.json
# Mejores prácticas de seguridad de AWS
steampipe query \
"select * from aws_s3_bucket where acl like '%public%'" \
--output json > aws-security-violations.json
# Inventario de recursos multi-nube
steampipe query \
"select 'aws' as cloud, instance_id as resource, region from aws_ec2_instance
union all
select 'azure' as cloud, name as resource, location from azure_compute_virtual_machine
union all
select 'gcp' as cloud, name as resource, zone from gcp_compute_instance" \
--output json > multi-cloud-inventory.json
- name: Generar Informe de Cumplimiento
run: |
# Generar resumen ejecutivo
steampipe dashboard --dashboard compliance-overview \
--export compliance-report.pdf
- name: Subir Artefactos de Cumplimiento
uses: actions/upload-artifact@v3
with:
name: informes-de-cumplimiento
path: |
*.json
*.pdf
## Tu Primera Consulta: Bienvenido al Lado Oscuro
Comencemos con algo simple. Enciende Steampipe y veamos qué tipo de caos digital has creado:
```bash
steampipe query
Esto te lleva a un shell SQL que está conectado a tus APIs de nube. Es como psql
pero para nubes, y mucho más peligroso.
Encontrando Tus Instancias EC2 (Las Obvias)
-- Veamos qué instancias EC2 estás ejecutando
SELECT
instance_id,
instance_type,
state,
region,
tags
FROM aws_ec2_instance
WHERE state = 'running';
El Momento “Oh Shit”: Recursos Públicos
-- Encontrar instancias RDS accesibles públicamente
-- (Alerta de spoiler: probablemente tengas algunas)
SELECT
db_instance_identifier,
engine,
publicly_accessible,
endpoint_address,
region
FROM aws_rds_db_instance
WHERE publicly_accessible = true;
-- Cubos S3 que básicamente están regalando datos gratis
SELECT
name,
region,
acl,
policy_std
FROM aws_s3_bucket
WHERE acl LIKE '%public%'
OR policy_std::text LIKE '%"Principal": "*"%';
Consultas Avanzadas: Donde Comienza la Verdadera Diversión
Una vez que te sientas cómodo con las consultas básicas, puedes comenzar a construir reglas de CIEM (Gestión de Derechos de Infraestructura en la Nube) más sofisticadas. Piensa en estas como “chequeos de realidad de seguridad” para tu nube.
La Consulta “¿Quién Tiene Acceso de Root?”
-- Encuentra usuarios de IAM que básicamente poseen tu cuenta de AWS
SELECT
u.name as user_name,
u.create_date,
STRING_AGG(p.policy_name, ', ') as attached_policies
FROM aws_iam_user u
JOIN aws_iam_user_attached_policy p ON u.name = p.user_name
WHERE p.policy_arn = 'arn:aws:iam::aws:policy/AdministratorAccess'
OR p.policy_name LIKE '%Admin%'
GROUP BY u.name, u.create_date
ORDER BY u.create_date DESC;
El detective de “Recursos no utilizados que están consumiendo tu presupuesto”
-- Instancias EC2 que no han sido tocadas en mucho tiempo
SELECT
instance_id,
instance_type,
launch_time,
state,
ROUND(EXTRACT(epoch FROM (NOW() - launch_time))/86400) as days_running,
region
FROM aws_ec2_instance
WHERE state = 'running'
AND launch_time < NOW() - INTERVAL '30 days'
AND instance_id NOT IN (
SELECT DISTINCT instance_id
FROM aws_cloudwatch_metric_statistic_data_point
WHERE timestamp > NOW() - INTERVAL '7 days'
AND metric_name = 'CPUUtilization'
AND average > 5 -- Más del 5% de uso de CPU
)
ORDER BY days_running DESC;
El “Salón de la Vergüenza de los Grupos de Seguridad”
-- Grupos de seguridad que son básicamente "¡bienvenidos todos!"
SELECT
group_id,
group_name,
description,
vpc_id,
region,
ip_permissions
FROM aws_ec2_security_group,
jsonb_array_elements(ip_permissions) as perm
WHERE perm->>'IpProtocol' = '-1' -- Todos los protocolos
OR (
perm->'IpRanges' @> '[{"CidrIp": "0.0.0.0/0"}]'::jsonb
AND (
perm->'FromPort' IS NULL
OR perm->>'FromPort' IN ('22', '3389', '80', '443')
)
);
Creando Reglas CIEM Personalizadas: Construyendo Tu Imperio de Seguridad
Ahora vamos a entrar en lo realmente divertido: crear reglas personalizadas que te ayuden a mantener un cierto orden en el caos de tu nube.
Regla 1: El “Detector de Minería de Criptomonedas”
-- Instancias que podrían estar minando criptomonedas
-- (Alto uso de CPU, tipos de instancia sospechosos, funcionando 24/7)
CREATE VIEW sospechoso_minado_cripto AS
SELECT
e.instance_id,
e.instance_type,
e.region,
e.launch_time,
ROUND(EXTRACT(epoch FROM (NOW() - e.launch_time))/86400) as dias_funcionando,
e.tags
FROM aws_ec2_instance e
WHERE e.state = 'running'
AND e.instance_type IN ('m5.large', 'm5.xlarge', 'c5.large', 'c5.xlarge', 'c5.2xlarge')
AND e.launch_time < NOW() - INTERVAL '7 days'
AND (e.tags IS NULL OR NOT (e.tags ? 'Environment' OR e.tags ? 'Project'));
Regla 2: La “Auditoría de Cuenta de Servicio Privilegiada”
-- Cuentas de servicio con privilegios de administrador (generalmente una mala señal)
CREATE VIEW cuentas_de_servicio_sobreprivilegiadas AS
SELECT
u.name,
u.path,
u.create_date,
CASE
WHEN u.password_last_used IS NULL THEN 'Nunca ha iniciado sesión'
ELSE u.password_last_used::text
END as last_login,
STRING_AGG(p.policy_name, ', ') as admin_policies
FROM aws_iam_user u
JOIN aws_iam_user_attached_policy p ON u.name = p.user_name
WHERE (u.name LIKE '%service%' OR u.name LIKE '%app%' OR u.name LIKE '%system%')
AND (
p.policy_arn LIKE '%Administrator%'
OR p.policy_arn LIKE '%PowerUser%'
OR p.policy_name LIKE '%Admin%'
)
GROUP BY u.name, u.path, u.create_date, u.password_last_used;
Regla 3: “La fuga de datos que está por suceder”
-- Cubos S3 con combinaciones peligrosas
CREATE VIEW candidatos_fuga_datos AS
SELECT
b.nombre,
b.región,
b.versioning_enabled,
b.server_side_encryption_configuration,
CASE
WHEN b.policy_std::text LIKE '%"Principal": "*"%' THEN 'Lectura pública'
WHEN b.acl LIKE '%public%' THEN 'ACL pública'
ELSE 'Verificar manualmente'
END as tipo_exposición,
CASE
WHEN b.server_side_encryption_configuration IS NULL THEN 'Sin cifrado'
ELSE 'Cifrado'
END as estado_cifrado
FROM aws_s3_bucket b
WHERE (
b.policy_std::text LIKE '%"Principal": "*"%'
OR b.acl LIKE '%public%'
)
AND (
b.nombre LIKE '%backup%'
OR b.nombre LIKE '%data%'
OR b.nombre LIKE '%logs%'
OR b.nombre LIKE '%private%'
);
Consultas Multi-Nube: Porque el Bloqueo de Proveedor es para los que se Rinden
Una de las superpotencias de Steampipe es consultar a través de múltiples proveedores de nube en una sola consulta. Aquí es donde las cosas se ponen realmente interesantes:
Inventario de Recursos Cruzados en la Nube
SELECT ‘Azure’ as provider, service_name as service, SUM(pre_tax_cost) as monthly_cost FROM azure_cost_management WHERE usage_date_time >= date_trunc(‘month’, CURRENT_DATE) GROUP BY service_name
UNION ALL
SELECT ‘GCP’ as provider, service_description as service, SUM(cost) as monthly_cost FROM gcp_billing_export WHERE usage_start_time >= date_trunc(‘month’, CURRENT_DATE) GROUP BY service_description )
SELECT * FROM cloud_costs;
### El "Quién está gastando qué" Auditoría Multi-Nube
```sql
-- Comparar costos entre proveedores (requiere APIs de gestión de costos)
WITH costos_nube AS (
SELECT
'AWS' as proveedor,
servicio,
SUM(monto_costo_sin_mezclar) as costo_mensual
FROM aws_costo_por_servicio_mensual
WHERE periodo_inicio >= date_trunc('month', CURRENT_DATE)
GROUP BY servicio
UNION ALL
SELECT
'Azure' as proveedor,
nombre_servicio as servicio,
SUM(costo_antes_de_impuestos) as costo_mensual
FROM azure_gestion_de_costos
WHERE fecha_hora_uso >= date_trunc('month', CURRENT_DATE)
GROUP BY nombre_servicio
UNION ALL
SELECT
'GCP' as proveedor,
descripcion_servicio as servicio,
SUM(costo) as costo_mensual
FROM gcp_exportacion_facturacion
WHERE tiempo_inicio_uso >= date_trunc('month', CURRENT_DATE)
GROUP BY descripcion_servicio
)
SELECT * FROM costos_nube;
SELECT ‘Azure’ as provider, meter_category as service, SUM(cost) as monthly_cost FROM azure_consumption_usage_detail WHERE billing_period_start >= date_trunc(‘month’, CURRENT_DATE) GROUP BY meter_category ) SELECT provider, service, monthly_cost FROM cloud_costs WHERE monthly_cost > 100 — Solo mostrar servicios que cuestan más de $100/mes ORDER BY monthly_cost DESC;
## Casos de Uso de Enterprise DevSecOps
### Escenario 1: Validación Automática de Cumplimiento para SOC2 Tipo II
**Desafío**: Demostrar monitoreo continuo de cumplimiento a través de infraestructura multi-nube para auditoría SOC2.
**Solución**: Consultas de cumplimiento automatizadas integradas en la canalización CI/CD con generación de rastro de auditoría.
```sql
-- SOC2 CC6.1: Controles de Acceso Lógico
-- Consulta para validar que todas las bases de datos de producción tienen habilitado el registro de acceso
CREATE VIEW soc2_database_access_controls AS
SELECT
'aws-rds' as service,
db_instance_identifier as resource_id,
region,
CASE
WHEN enabled_cloudwatch_logs_exports IS NOT NULL
THEN 'CUMPLE: Registro de auditoría habilitado'
ELSE 'NO CUMPLE: Falta registro de auditoría'
END as compliance_status,
'SOC2-CC6.1' as control_id,
NOW() as assessment_timestamp
FROM aws_rds_db_instance
WHERE tags->>'Environment' = 'production'
UNION ALL
SELECT
'azure-sql' as service,
name as resource_id,
location as region,
CASE
WHEN auditing_policy_state = 'Enabled'
THEN 'CUMPLE: Registro de auditoría habilitado'
ELSE 'NO CUMPLE: Falta registro de auditoría'
END as compliance_status,
'SOC2-CC6.1' as control_id,
NOW() as assessment_timestamp
FROM azure_sql_database
WHERE tags->>'Environment' = 'production';
— SOC2 CC6.7: Controles de Transmisión de Datos — Validar cifrado en tránsito para todos los servicios de cara al público CREATE VIEW soc2_encryption_in_transit AS SELECT ‘aws-elb’ as service, load_balancer_arn as resource_id, region, CASE WHEN scheme = ‘internet-facing’ AND EXISTS (SELECT 1 FROM jsonb_array_elements(listeners) l WHERE l->>‘Protocol’ = ‘HTTPS’) THEN ‘CUMPLE: HTTPS aplicado’ WHEN scheme = ‘internet-facing’ THEN ‘NO CUMPLE: Tráfico HTTP permitido’ ELSE ‘NO APLICA: Balanceador de carga interno’ END as compliance_status, ‘SOC2-CC6.7’ as control_id, NOW() as assessment_timestamp FROM aws_elbv2_load_balancer WHERE tags->>‘Environment’ = ‘production’;
**Script de Automatización para Cumplimiento Continuo:**
```bash
#!/bin/bash
# continuous-compliance-monitoring.sh
# Resultados de cumplimiento de exportación para el registro de auditoría
steampipe query "SELECT * FROM soc2_database_access_controls" \
--output json \
--output-file "compliance-reports/soc2-cc61-$(date +%Y%m%d-%H%M%S).json"
steampipe query "SELECT * FROM soc2_encryption_in_transit" \
--output json \
--output-file "compliance-reports/soc2-cc67-$(date +%Y%m%d-%H%M%S).json"
# Verificar recursos no conformes
NON_COMPLIANT=$(steampipe query \
"SELECT COUNT(*) as violations FROM (
SELECT * FROM soc2_database_access_controls WHERE compliance_status LIKE 'NON-COMPLIANT%'
UNION ALL
SELECT * FROM soc2_encryption_in_transit WHERE compliance_status LIKE 'NON-COMPLIANT%'
) violations" --output json | jq '.[0].violations')
if [ "$NON_COMPLIANT" -gt 0 ]; then
echo "🚨 ALERTA DE CUMPLIMIENTO: $NON_COMPLIANT violaciones SOC2 detectadas"
# Enviar alerta al equipo de cumplimiento
curl -X POST "$SLACK_WEBHOOK_URL" \
-H 'Content-type: application/json' \
--data "{\"text\":\"Alerta de Cumplimiento SOC2: $NON_COMPLIANT violaciones detectadas en el entorno de producción\"}"
fi
Escenario 2: Detección de Deriva de Infraestructura como Código
Desafío: La infraestructura gestionada por Terraform se desvía del estado deseado, creando brechas de seguridad y cumplimiento.
Solución: Detección automática de deriva usando Steampipe para comparar el estado en vivo contra la configuración de Terraform.
-- Detectar buckets de S3 creados fuera de la gestión de Terraform
CREATE VIEW terraform_drift_s3_buckets AS
WITH terraform_managed_buckets AS (
SELECT
name as bucket_name,
'managed' as management_status
FROM terraform_resource
WHERE type = 'aws_s3_bucket'
),
live_buckets AS (
SELECT
name as bucket_name,
creation_date,
tags
FROM aws_s3_bucket
)
SELECT
lb.bucket_name,
lb.creation_date,
lb.tags,
CASE
WHEN tmb.management_status IS NULL
THEN 'DRIFT: Se detectó un bucket de S3 no gestionado'
ELSE 'MANAGED: Controlado por Terraform'
END as drift_status,
'aws_s3_bucket' as resource_type
FROM live_buckets lb
LEFT JOIN terraform_managed_buckets tmb ON lb.bucket_name = tmb.bucket_name
WHERE lb.tags->>'Environment' = 'production';
— Detectar instancias EC2 con desviación de configuración CREATE VIEW terraform_drift_ec2_instances AS WITH terraform_instances AS ( SELECT attributes_json->>‘id’ as instance_id, attributes_json->>‘instance_type’ as tf_instance_type, attributes_json->>‘vpc_security_group_ids’ as tf_security_groups FROM terraform_resource WHERE type = ‘aws_instance’ ), live_instances AS ( SELECT instance_id, instance_type, security_groups, tags FROM aws_ec2_instance WHERE state = ‘running’ ) SELECT li.instance_id, li.instance_type as current_type, ti.tf_instance_type as terraform_type, CASE WHEN ti.instance_id IS NULL THEN ‘DESVIACIÓN: Instancia no en estado de Terraform’ WHEN li.instance_type != ti.tf_instance_type THEN ‘DESVIACIÓN: Tipo de instancia cambiado’ ELSE ‘CONFORME: Coincide con Terraform’ END as drift_status FROM live_instances li LEFT JOIN terraform_instances ti ON li.instance_id = ti.instance_id WHERE li.tags->>‘Environment’ = ‘production’;
### Escenario 3: Evaluación de la Postura de Seguridad Multi-Nube
**Desafío**: Mantener una postura de seguridad consistente en los entornos de AWS, Azure y GCP.
**Solución**: Evaluación de seguridad unificada en todos los proveedores de nube con puntuación estandarizada.
```sql
-- Cálculo de puntuación de seguridad multi-nube
CREATE VIEW multi_cloud_security_posture AS
WITH security_metrics AS (
-- Métricas de Seguridad de AWS
SELECT
'aws' as cloud_provider,
'encryption' as security_domain,
COUNT(*) as total_resources,
COUNT(*) FILTER (WHERE encrypted = true) as compliant_resources,
ROUND(
(COUNT(*) FILTER (WHERE encrypted = true)::float / COUNT(*)) * 100, 2
) as compliance_percentage
FROM aws_ebs_volume
WHERE tags->>'Environment' = 'production'
UNION ALL
SELECT
'aws' as cloud_provider,
'public_access' as security_domain,
COUNT(*) as total_resources,
COUNT(*) FILTER (WHERE acl NOT LIKE '%public%') as compliant_resources,
ROUND(
(COUNT(*) FILTER (WHERE acl NOT LIKE '%public%')::float / COUNT(*)) * 100, 2
) as compliance_percentage
FROM aws_s3_bucket
UNION ALL
-- Métricas de Seguridad de Azure
SELECT
'azure' as cloud_provider,
'encryption' as security_domain,
COUNT(*) as total_resources,
COUNT(*) FILTER (WHERE encryption_at_rest_enabled = true) as compliant_resources,
ROUND(
(COUNT(*) FILTER (WHERE encryption_at_rest_enabled = true)::float / COUNT(*)) * 100, 2
) as compliance_percentage
FROM azure_storage_account
WHERE tags->>'Environment' = 'production'
UNION ALL
-- Métricas de Seguridad de GCP
SELECT
'gcp' as proveedor_nube,
'acceso_público' as dominio_seguridad,
COUNT(*) as total_recursos,
COUNT(*) FILTER (WHERE public_access_prevention = 'enforced') as recursos_cumplidos,
ROUND(
(COUNT(*) FILTER (WHERE public_access_prevention = 'enforced')::float / COUNT(*)) * 100, 2
) as porcentaje_cumplimiento
FROM gcp_storage_bucket
WHERE labels->>'environment' = 'production'
)
SELECT
proveedor_nube,
dominio_seguridad,
total_recursos,
recursos_cumplidos,
porcentaje_cumplimiento,
CASE
WHEN porcentaje_cumplimiento >= 95 THEN 'EXCELENTE'
WHEN porcentaje_cumplimiento >= 85 THEN 'BUENO'
WHEN porcentaje_cumplimiento >= 70 THEN 'NECESITA_MEJORAR'
ELSE 'CRÍTICO'
END as grado_seguridad,
NOW() as marca_tiempo_evaluación
FROM métricas_seguridad
ORDER BY proveedor_nube, dominio_seguridad;
Consulta del Panel Ejecutivo:
-- Panel de seguridad ejecutivo - métricas de alto nivel
SELECT
cloud_provider,
AVG(compliance_percentage) as overall_security_score,
COUNT(*) as assessed_domains,
COUNT(*) FILTER (WHERE security_grade = 'CRITICAL') as critical_issues,
COUNT(*) FILTER (WHERE security_grade = 'NEEDS_IMPROVEMENT') as improvement_areas
FROM multi_cloud_security_posture
GROUP BY cloud_provider
ORDER BY overall_security_score DESC;
Construyendo tu propio panel de Steampipe
¿Quieres convertir tus consultas en algo que parezca profesional? Steampipe tiene una función de panel que es sorprendentemente elegante:
Crear una configuración de panel
# dashboard.sp
dashboard "cloud_security_overview" {
title = "Visión general de seguridad en la nube (AKA: ¿Qué tan mal está?)"
container {
chart {
title = "Recursos Públicos por Tipo"
sql = <<-EOT
SELECT
'EC2' as resource_type,
COUNT(*) as count
FROM aws_ec2_instance
WHERE state = 'running'
AND public_ip_address IS NOT NULL
UNION ALL
SELECT
'RDS' as resource_type,
COUNT(*) as count
FROM aws_rds_db_instance
WHERE publicly_accessible = true
UNION ALL
SELECT
'S3' as resource_type,
COUNT(*) as count
FROM aws_s3_bucket
WHERE acl LIKE '%public%'
EOT
type = "column"
}
}
container {
table {
title = "Recursos de Alto Riesgo"
sql = <<-EOT
SELECT
resource_type,
resource_id,
risk_level,
description
FROM (
SELECT
'EC2' as resource_type,
instance_id as resource_id,
'HIGH' as risk_level,
'Instancia pública con acceso SSH' as description
FROM aws_ec2_instance e
JOIN aws_ec2_security_group sg ON sg.group_id = ANY(e.security_groups)
WHERE e.public_ip_address IS NOT NULL
AND sg.ip_permissions::text LIKE '%"FromPort": 22%'
AND sg.ip_permissions::text LIKE '%"0.0.0.0/0"%'
) as high_risk_resources
ORDER BY risk_level DESC, resource_type
EOT
}
}
}
Lanza tu Panel
steampipe dashboard --dashboard-listen=local
Navega a http://localhost:9194
y observa cómo tus violaciones de seguridad cobran vida en hermosos gráficos y tablas. Es como una película de desastre en tiempo real, pero para tu infraestructura.
Consejos Profesionales para el Dominio de Steampipe
1. Crear Vistas Reutilizables
En lugar de escribir consultas complejas repetidamente, crea vistas:
-- Guarda esto en ~/.steampipe/config/views.sql
CREATE VIEW my_public_resources AS
SELECT
'EC2' as type,
instance_id as id,
region,
public_ip_address as public_ip
FROM aws_ec2_instance
WHERE public_ip_address IS NOT NULL
UNION ALL
SELECT
'RDS' as type,
db_instance_identifier as id,
region,
endpoint_address as public_ip
FROM aws_rds_db_instance
WHERE publicly_accessible = true;
2. Automatiza con Scripts
Crea scripts bash que ejecuten tus consultas y envíen alertas:
#!/bin/bash
# security_check.sh
# Verificar nuevos recursos públicos
NEW_PUBLIC=$(steampipe query --output json "
SELECT COUNT(*) as count
FROM my_public_resources
WHERE created_time > NOW() - INTERVAL '24 hours'
" | jq -r '.[0].count')
if [ "$NEW_PUBLIC" -gt 0 ]; then
echo "ADVERTENCIA: ¡$NEW_PUBLIC nuevos recursos públicos detectados!"
# Enviar a Slack, correo electrónico, o cualquier sistema de notificación que uses
fi
3. Control de versiones de tus consultas
Mantén tus reglas CIEM en repositorios git:
my-steampipe-rules/
├── queries/
│ ├── compliance/
│ │ ├── pci-dss.sql
│ │ ├── soc2.sql
│ │ └── gdpr.sql
│ ├── security/
│ │ ├── public-resources.sql
│ │ ├── overprivileged-users.sql
│ │ └── crypto-mining.sql
│ └── cost/
│ ├── unused-resources.sql
│ └── expensive-resources.sql
├── dashboards/
│ └── security-overview.sp
└── scripts/
└── daily-security-check.sh
Historias de guerra del mundo real: Cuando Steampipe salva el día
El caso del misterioso minero de Bitcoin
Hace unos meses, llegó una factura de AWS que era un 300% más alta de lo normal. Usando Steampipe, identificamos rápidamente:
-- La consulta que encontró al culpable
SELECT
instance_id,
instance_type,
launch_time,
region,
tags,
ROUND(EXTRACT(epoch FROM (NOW() - launch_time))/3600) as hours_running
FROM aws_ec2_instance
WHERE state = 'running'
AND instance_type IN ('c5.4xlarge', 'c5.9xlarge', 'c5.18xlarge')
AND launch_time > '2024-01-01'
AND (tags->>'Name' IS NULL OR tags->>'Name' = '')
ORDER BY hours_running DESC;
Resultado: Tres instancias c5.4xlarge ejecutándose durante 2 semanas seguidas sin etiquetas, sin monitoreo y con un uso de CPU sospechosamente alto. Alguien había dejado su operación de minería funcionando en la cuenta de desarrollo. Ups.
La Gran Fuga del Bucket S3 de 2024
Durante una auditoría de seguridad, necesitábamos evaluar rápidamente la exposición de datos en 47 cuentas de AWS:
-- La consulta que previno un incidente mayor
SELECT
b.name,
b.region,
CASE
WHEN b.policy_std::text LIKE '%"Principal": "*"%' THEN 'CRÍTICO: Acceso de lectura público'
WHEN b.acl = 'public-read' THEN 'ALTO: ACL pública'
WHEN b.acl = 'public-read-write' THEN 'CRÍTICO: Acceso de escritura público'
ELSE 'Exposición desconocida'
END as risk_level,
b.creation_date
FROM aws_s3_bucket b
WHERE b.name LIKE '%prod%'
OR b.name LIKE '%customer%'
OR b.name LIKE '%backup%'
ORDER BY risk_level DESC;
Encontramos 12 buckets de producción con acceso de lectura público que contenían datos de clientes. Gracias a Steampipe, los arreglamos todos en una hora en lugar de las semanas que hubiera tomado manualmente.
El Futuro de la Gestión del Caos en la Nube
Steampipe representa algo hermoso: la democratización de la seguridad en la nube. No necesitas herramientas empresariales costosas ni un equipo de especialistas para entender lo que está sucediendo en tu infraestructura de nube. Solo necesitas habilidades en SQL y disposición para adentrarte en el caos.
A medida que los entornos de nube continúan volviéndose más complejos, herramientas como Steampipe se vuelven esenciales. Te dan el poder de hacer preguntas como:
- “Muéstrame todos los recursos creados por ese contratista que se fue el mes pasado”
- “¿Cuáles de mis bases de datos son accesibles desde internet?”
- “¿Cuánto estoy gastando en recursos que nadie está usando?”
- “¿Quién tiene la capacidad de eliminar toda mi infraestructura?”
Estas no son solo preguntas técnicas, son preguntas críticas para el negocio que pueden ahorrarte dinero, prevenir brechas de seguridad y ayudarte a dormir mejor por la noche.
Comenzando: Tu viaje de seguridad en la nube comienza
¿Listo para comenzar tu propia expedición de arqueología en la nube? Aquí tienes tu tarea:
- Instala Steampipe y al menos un plugin de nube
- Ejecuta las consultas básicas en este post contra tu infraestructura
- Prepárate para estar horrorizado por lo que encuentres
- Crea tu primera regla CIEM personalizada para algo específico de tu entorno
- Configura la monitorización automatizada para tus reglas de seguridad más críticas
- Comparte tus hallazgos con tu equipo (te lo agradecerán más tarde)
Recuerda: El objetivo no es lograr una seguridad perfecta en la nube (eso es imposible). El objetivo es entender tu caos lo suficientemente bien como para gestionarlo eficazmente.
Y oye, si encuentras algún minero de Bitcoin funcionando en tu infraestructura, al menos ahora sabes cómo encontrarlos rápidamente. 😄
Palabras Finales: Abraza el Caos
La infraestructura en la nube es inherentemente caótica. Los recursos se crean, se olvidan, se modifican y se abandonan. Las permisos se acumulan como polvo digital. Los grupos de seguridad se multiplican como conejos.
Pero con Steampipe, al menos puedes entender tu caos. Puedes consultarlo, visualizarlo, y tal vez incluso domarlo un poco.
Así que adelante, ejecuta algunas consultas y descubre qué misterios digitales acechan en tus cuentas en la nube. Solo no me culpes cuando descubras que alguien ha estado minando Dogecoin en tus clústeres de producción.
¡Feliz consulta, y que tu SQL sea siempre sintácticamente correcto! 🚀
¿Tienes consultas interesantes de Steampipe o historias de guerra? Contáctame - siempre estoy buscando nuevas formas de abusar de SQL para propósitos de seguridad en la nube.