Un escáner de seguridad de AWS basado en terminal con más de 102 comprobaciones de seguridad en VPC, IAM, S3, CloudTrail, contenedores (ECS/EKS) y detección de ataques de IA. Detecta permisos IAM peligrosos, secretos expuestos, cubos S3 mal configurados, vulnerabilidades de contenedores y amenazas emergentes de LLMjacking.
Un Escáner de seguridad de AWS basado en terminal con más de 100 verificaciones de seguridad en VPC, IAM, S3, CloudTrail, contenedores (ECS/EKS) y detección de ataques de IA. Detecta permisos peligrosos de IAM, secretos expuestos, buckets S3 mal configurados, vulnerabilidades de contenedores y amenazas emergentes de LLMjacking.
Descripción general del producto: docs/CAPABILITIES_OVERVIEW.md
*:*).env, .git, credenciales)Basado en inteligencia de amenazas de febrero de 2025: violación de AWS en 8 minutos
| Categoría | Conteo |
|---|---|
| Núcleo (IAM, VPC, S3, CloudTrail, Secretos) | 38 |
| Extendido (Lambda, ELB, Route53, Inspector, etc.) | 35 |
| Seguridad de contenedores (ECS + EKS) | 22 |
| Detección de ataques de IA | 7 |
| Total | 102 |
| Verificación | Gravedad | Descripción |
|---|---|---|
| Escalada de privilegios | 🔴 Crítico | El usuario puede escalar a administrador |
| Acceso de administrador (:) | 🔴 Crítico | Acceso completo a AWS concedido |
| Secretos expuestos | 🔴 Crítico | Claves/tokens API en Lambda/EC2 |
| Bucket S3 público | 🔴 Crítico | Bucket accesible públicamente |
| Sin CloudTrail | 🔴 Crítico | Sin registro de auditoría |
| SSH/RDP abierto | 🔴 Crítico | Puerto 22/3389 a internet |
| Contenedor privilegiado | 🔴 Crítico | Contenedor ECS con acceso root |
| GPU IMDSv1 | 🔴 Crítico | Credenciales de instancia GPU vulnerables |
| Confianza entre cuentas | 🟠 Alto | Cuenta externa puede asumir rol |
| Endpoint público de EKS | 🟠 Alto | API de Kubernetes accesible públicamente |
| Bedrock sin registro | 🟠 Alto | Uso del modelo de IA no auditado |
# macOS
brew install awscli
# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
aws configure
# o usar perfiles con nombre
aws configure --profile myprofile
Sus credenciales AWS deben tener acceso de solo lectura a los servicios que se escanean. La política administrada ReadOnlyAccess de AWS funciona, o consulte Permisos requeridos más abajo.
Nota: aws-perimeter solo realiza operaciones de lectura y nunca modifica sus recursos AWS.
curl -sSfL https://raw.githubusercontent.com/thirukguru/aws-perimeter/main/install.sh | sh
go install github.com/thirukguru/aws-perimeter@latest
aws-perimeter # Ejecutar escaneo de seguridad completo
aws-perimeter --output json # Salida JSON
aws-perimeter --profile prod # Perfil AWS específico
aws-perimeter --region us-west-2 # Región específica
aws-perimeter --regions us-east-1,us-west-2 # Escaneo multirregión
aws-perimeter --regions us-east-1,us-west-2 --max-parallel 4 # Multirregión con concurrencia controlada
aws-perimeter --regions us-east-1,us-west-2 --max-parallel 4 --best-effort # Salir con éxito si al menos una región tiene éxito
aws-perimeter --rules # Imprimir RULES.md en stdout (Markdown)
aws-perimeter --capabilities # Imprimir descripción general de capacidades en stdout (Markdown)
aws-perimeter --all-regions # Escanear todas las regiones habilitadas
aws-perimeter --org-scan --org-role-name OrganizationAccountAccessRole # Escaneo multiorganización
aws-perimeter --org-scan --max-parallel 5 # Concurrencia de fanout de organización+región
aws-perimeter --output html --output-file report.html # Generar informe HTML
aws-perimeter --store --profile prod --region us-west-2 # Ejecutar + persistir escaneo
aws-perimeter --trends --trend-days 30 --account-id 123456789012 # Mostrar tabla de tendencias históricas
aws-perimeter history list --db-path ~/.aws-perimeter/history.db
aws-perimeter dashboard --port 8080
Para modos de fanout (--regions, --all-regions, --org-scan) con --output html --output-file ..., aws-perimeter escribe un informe por unidad de escaneo con sufijos de región/cuenta y marca de tiempo (por ejemplo security-report-us-east-1-20260210-213045.html o security-report-123456789012-us-east-1-20260210-213045.html).
En modo HTML, la salida de tabla de terminal se suprime y solo se imprimen líneas de resumen concisas.
Cuando se usa --output json, aws-perimeter emite un único documento JSON válido sin ruido de banner/spinner, por lo que es seguro para pipelines.
aws-perimeter --profile prod --region us-west-2 --output json | jq .
# JSON multirregión emite un único documento JSON agregado de nivel superior:
aws-perimeter --profile prod --regions us-east-1,us-west-2 --output json | jq .
# exportar documentos mediante redirección de stdout
aws-perimeter --rules > rules.md
aws-perimeter --capabilities > capabilities.md
La carga útil JSON multirregión incluye:
summary (total_regions, success, failed, skipped)results (cargas útiles de escaneo consolidadas por región)failures (región + detalles del error cuando falla un escaneo de región)Para escaneos multirregión y de organización en modos de salida que no son JSON, aws-perimeter imprime un resumen consolidado al final de la ejecución:
account_id, account_name, region, status, duration y error.TOTAL, SUCCESS, FAILED, SKIPPED).--max-parallel y --best-effort--max-parallel controla cuántas unidades de escaneo de región/cuenta se ejecutan concurrentemente en modos de fanout (--regions, --all-regions, --org-scan).--max-parallel 3 o --max-parallel 4.--best-effort se aplica a escaneos multirregión: el comando sale con éxito (0) cuando al menos una región tiene éxito, incluso si algunas fallan.--best-effort, cualquier región fallida devuelve un código de salida distinto de cero.failures con el error exacto.| Bandera | Corta | Descripción |
|---|---|---|
--profile | -p | Perfil AWS a usar |
--region | -r | Región AWS |
--regions | Regiones separadas por comas | |
--all-regions | Escanear todas las regiones habilitadas | |
--org-scan | Escanear todas las cuentas activas de AWS Organization | |
--org-role-name | Nombre del rol IAM a asumir en cuentas miembro | |
--external-id | ID externo para asumir rol entre cuentas | |
--output | -o | Formato de salida: table, json o html |
--rules | Imprimir catálogo de reglas Markdown y salir | |
--capabilities | Imprimir capacidades Markdown y salir | |
--output-file | -f | Archivo de salida (requerido para html) |
--store | Persistir resultados de escaneo en SQLite | |
--db-path | Ruta personalizada a la base de datos SQLite | |
--trends | Mostrar tendencias históricas | |
--trend-days | Ventana de tendencia en días (predeterminado 30) | |
--compare | Comparar dos escaneos recientes | |
--export-json | Exportar archivo JSON de tendencias | |
--export-csv | Exportar archivo CSV de tendencias | |
--account-id | Filtro de cuenta para tendencias/historial | |
Se requieren los siguientes permisos para la cobertura completa de características (incluyendo escaneo multirregión y de organización):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:GetCallerIdentity",
"sts:AssumeRole",
"organizations:DescribeOrganization",
"organizations:ListAccounts",
"ec2:Describe*",
"ec2:GetEbsEncryptionByDefault",
"iam:List*",
"iam:Get*",
"iam:GenerateCredentialReport",
"s3:ListAllMyBuckets",
"s3:GetBucket*",
"s3:GetEncryptionConfiguration",
"cloudtrail:DescribeTrails",
"cloudtrail:GetTrailStatus",
"cloudtrail:LookupEvents",
"lambda:ListFunctions",
"lambda:GetFunctionConfiguration",
"lambda:GetFunction",
"ecr:DescribeRepositories",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecs:ListClusters",
"ecs:DescribeClusters",
"ecs:ListServices",
"ecs:DescribeServices",
"ecs:DescribeTaskDefinition",
"eks:ListClusters",
"eks:DescribeCluster",
"eks:ListNodegroups",
"eks:DescribeNodegroup",
"bedrock:ListProvisionedModelThroughputs",
"bedrock:ListCustomModels",
"bedrock:GetModelInvocationLoggingConfiguration",
"guardduty:ListDetectors",
"guardduty:GetDetector",
"guardduty:ListFindings",
"guardduty:GetFindings",
"securityhub:DescribeHub",
"securityhub:GetFindings",
"config:Describe*",
"kms:ListKeys",
"kms:DescribeKey",
"kms:GetKeyRotationStatus",
"kms:Decrypt",
"rds:DescribeDB*",
"dynamodb:ListTables",
"dynamodb:DescribeTable",
"dynamodb:DescribeContinuousBackups",
"secretsmanager:ListSecrets",
"elasticloadbalancing:Describe*",
"backup:List*",
"apigateway:GET",
"cloudfront:List*",
"cloudfront:Get*",
"cloudwatch:GetMetricStatistics",
"sns:ListTopics",
"sqs:ListQueues"
],
"Resource": "*"
}
]
}
kms:Decrypt solo se requiere al escanear objetos/paquetes cifrados (por ejemplo, lecturas de objetos S3 SSE-KMS). En producción, limite esto a las claves KMS necesarias.
Para --org-scan, la entidad principal de gestión debe tener permiso para asumir un rol de cuenta miembro (por defecto: OrganizationAccountAccessRole), por ejemplo:
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/OrganizationAccountAccessRole"
}
La política de confianza del rol de la cuenta miembro también debe permitir que su entidad principal de escaneo (usuario/rol) lo asuma (e incluya la condición sts:ExternalId si usa --external-id).
Consejo: Para un inicio rápido, adjunte la política administrada
arn:aws:iam::aws:policy/ReadOnlyAccessa su usuario/rol IAM.
| Fase | Estado | Reglas |
|---|---|---|
| Fase 1 | ✅ Completada | 73 |
| Fase 2 | 🔲 En progreso | +20 |
| Fase 2.5 | 🆕 Detección de ataques de IA | +13 |
| Fase 3 | 🔲 Planificada | +15 |
| Fase 4 | 🔲 Planificada | Funcionalidades |
Apache License 2.0
--max-parallel |
| Número máximo de unidades de escaneo de región/cuenta concurrentes |
--best-effort | Para escaneos multirregión, devolver éxito si al menos una región tiene éxito |
--dry-run | Modo de vista previa de remediación |
--remediate | Aplicar remediaciones soportadas |
--dashboard-port | Puerto del panel (bandera raíz; el subcomando dashboard usa --port) |
--version | -v | Información de versión |