Seguridad••20 min
Seguridad Multi-Cloud: AWS vs Azure vs GCP
Comparación exhaustiva de las herramientas y mejores prácticas de seguridad en las tres principales nubes públicas.
LC
Luis Chen
CPO & Co-founder
Seguridad en la Nube: La Trinidad AWS, Azure y GCP
La seguridad en la nube no es opcional, es fundamental. Aquí está nuestra guía comparativa basada en implementaciones reales en las tres grandes nubes.
Modelo de Responsabilidad Compartida
Capa | AWS | Azure | GCP | Tu Responsabilidad |
---|---|---|---|---|
Datos | ❌ | ❌ | ❌ | ✅ Encriptación, clasificación |
Aplicación | ❌ | ❌ | ❌ | ✅ Código seguro, patches |
OS/Runtime | Depende | Depende | Depende | ✅ En IaaS, ❌ en PaaS |
Red Virtual | ⚠️ | ⚠️ | ⚠️ | ✅ Configuración |
Hypervisor | ✅ | ✅ | ✅ | ❌ |
Físico | ✅ | ✅ | ✅ | ❌ |
Identity & Access Management (IAM)
AWS IAM
1{
2 "Version": "2012-10-17",
3 "Statement": [
4 {
5 "Effect": "Allow",
6 "Principal": {
7 "AWS": "arn:aws:iam::123456789012:role/InfraUXDeveloper"
8 },
9 "Action": [
10 "s3:GetObject",
11 "s3:PutObject"
12 ],
13 "Resource": "arn:aws:s3:::infraux-prod/*",
14 "Condition": {
15 "StringEquals": {
16 "s3:x-amz-server-side-encryption": "AES256"
17 },
18 "IpAddress": {
19 "aws:SourceIp": ["10.0.0.0/8"]
20 }
21 }
22 }
23 ]
24}
Azure RBAC
1# Crear rol personalizado
2$role = Get-AzRoleDefinition "Virtual Machine Contributor"
3$role.Id = $null
4$role.Name = "InfraUX VM Operator"
5$role.Description = "Can manage VMs but not access them"
6$role.Actions.Clear()
7$role.Actions.Add("Microsoft.Compute/virtualMachines/*")
8$role.Actions.Add("Microsoft.Network/networkInterfaces/*")
9$role.NotActions.Add("Microsoft.Compute/virtualMachines/delete")
10$role.AssignableScopes.Clear()
11$role.AssignableScopes.Add("/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
12New-AzRoleDefinition -Role $role
GCP IAM
1# custom-role.yaml
2title: "InfraUX Developer"
3description: "Custom role for InfraUX developers"
4stage: "GA"
5includedPermissions:
6- compute.instances.get
7- compute.instances.list
8- compute.instances.start
9- compute.instances.stop
10- storage.buckets.get
11- storage.buckets.list
12- storage.objects.create
13- storage.objects.delete
14- storage.objects.get
15- storage.objects.list
Encriptación de Datos
Comparación de Servicios
Servicio | AWS | Azure | GCP |
---|---|---|---|
Key Management | KMS | Key Vault | Cloud KMS |
HSM | CloudHSM | Dedicated HSM | Cloud HSM |
Secrets Manager | Secrets Manager | Key Vault | Secret Manager |
Certificate Manager | ACM | Key Vault | Certificate Authority Service |
Implementación Multi-Cloud
1# encryption_wrapper.py
2from abc import ABC, abstractmethod
3import boto3
4from azure.keyvault.secrets import SecretClient
5from google.cloud import secretmanager
6
7class CloudEncryption(ABC):
8 @abstractmethod
9 def encrypt(self, data: bytes, key_id: str) -> bytes:
10 pass
11
12 @abstractmethod
13 def decrypt(self, data: bytes, key_id: str) -> bytes:
14 pass
15
16class AWSEncryption(CloudEncryption):
17 def __init__(self):
18 self.kms = boto3.client('kms')
19
20 def encrypt(self, data: bytes, key_id: str) -> bytes:
21 response = self.kms.encrypt(
22 KeyId=key_id,
23 Plaintext=data,
24 EncryptionContext={'purpose': 'infraux-encryption'}
25 )
26 return response['CiphertextBlob']
27
28 def decrypt(self, data: bytes, key_id: str) -> bytes:
29 response = self.kms.decrypt(
30 CiphertextBlob=data,
31 EncryptionContext={'purpose': 'infraux-encryption'}
32 )
33 return response['Plaintext']
34
35class AzureEncryption(CloudEncryption):
36 def __init__(self, vault_url: str, credential):
37 self.client = SecretClient(vault_url=vault_url, credential=credential)
38 # Implementación con Azure Key Vault
39
40class GCPEncryption(CloudEncryption):
41 def __init__(self, project_id: str):
42 self.client = secretmanager.SecretManagerServiceClient()
43 self.project_id = project_id
44 # Implementación con Cloud KMS
Network Security
AWS VPC Security
1# AWS Security Groups + NACLs
2resource "aws_security_group" "web_tier" {
3 name_prefix = "infraux-web-"
4 vpc_id = aws_vpc.main.id
5
6 ingress {
7 from_port = 443
8 to_port = 443
9 protocol = "tcp"
10 cidr_blocks = ["0.0.0.0/0"]
11 }
12
13 egress {
14 from_port = 0
15 to_port = 0
16 protocol = "-1"
17 cidr_blocks = ["0.0.0.0/0"]
18 }
19
20 lifecycle {
21 create_before_destroy = true
22 }
23}
24
25resource "aws_network_acl_rule" "web_ingress" {
26 network_acl_id = aws_network_acl.web.id
27 rule_number = 100
28 protocol = "tcp"
29 rule_action = "allow"
30 cidr_block = "0.0.0.0/0"
31 from_port = 443
32 to_port = 443
33}
Azure NSG
1resource "azurerm_network_security_group" "web_tier" {
2 name = "infraux-web-nsg"
3 location = azurerm_resource_group.main.location
4 resource_group_name = azurerm_resource_group.main.name
5
6 security_rule {
7 name = "HTTPS"
8 priority = 100
9 direction = "Inbound"
10 access = "Allow"
11 protocol = "Tcp"
12 source_port_range = "*"
13 destination_port_range = "443"
14 source_address_prefix = "*"
15 destination_address_prefix = "*"
16 }
17
18 security_rule {
19 name = "DenyAllInbound"
20 priority = 4096
21 direction = "Inbound"
22 access = "Deny"
23 protocol = "*"
24 source_port_range = "*"
25 destination_port_range = "*"
26 source_address_prefix = "*"
27 destination_address_prefix = "*"
28 }
29}
GCP Firewall Rules
1resource "google_compute_firewall" "web_tier" {
2 name = "infraux-web-firewall"
3 network = google_compute_network.main.name
4
5 allow {
6 protocol = "tcp"
7 ports = ["443"]
8 }
9
10 source_ranges = ["0.0.0.0/0"]
11 target_tags = ["web-server"]
12
13 log_config {
14 metadata = "INCLUDE_ALL_METADATA"
15 }
16}
Compliance y Auditoría
Herramientas Nativas
Feature | AWS | Azure | GCP |
---|---|---|---|
Audit Logs | CloudTrail | Activity Log | Cloud Audit Logs |
Compliance | Config | Policy | Security Command Center |
Vulnerability Scan | Inspector | Security Center | Security Scanner |
SIEM Integration | SecurityHub | Sentinel | Chronicle |
Configuración Multi-Cloud con Terraform
1# main.tf - Auditoría multi-cloud
2module "aws_logging" {
3 source = "./modules/aws-logging"
4
5 cloudtrail_name = "infraux-audit"
6 s3_bucket_name = "infraux-audit-logs"
7 enable_log_file_validation = true
8 enable_logging = true
9
10 event_selector {
11 read_write_type = "All"
12 include_management_events = true
13
14 data_resource {
15 type = "AWS::S3::Object"
16 values = ["arn:aws:s3:::*/*"]
17 }
18 }
19}
20
21module "azure_logging" {
22 source = "./modules/azure-logging"
23
24 log_analytics_workspace_name = "infraux-logs"
25 retention_in_days = 90
26
27 diagnostic_settings = {
28 name = "infraux-audit"
29 log_categories = ["Administrative", "Security", "Alert"]
30 }
31}
32
33module "gcp_logging" {
34 source = "./modules/gcp-logging"
35
36 project_id = var.gcp_project_id
37 sink_name = "infraux-audit-sink"
38
39 destination = "storage.googleapis.com/${google_storage_bucket.audit.name}"
40 filter = "severity >= WARNING"
41}
Detección de Amenazas
AWS GuardDuty vs Azure Sentinel vs GCP Security Command Center
1# threat_detection.py
2import json
3from datetime import datetime
4from typing import List, Dict
5
6class ThreatDetector:
7 def __init__(self, cloud_provider: str):
8 self.provider = cloud_provider
9 self.severity_mapping = {
10 'aws': {'Low': 1, 'Medium': 5, 'High': 8},
11 'azure': {'Informational': 1, 'Low': 3, 'Medium': 5, 'High': 8},
12 'gcp': {'LOW': 1, 'MEDIUM': 5, 'HIGH': 8, 'CRITICAL': 10}
13 }
14
15 def normalize_findings(self, findings: List[Dict]) -> List[Dict]:
16 normalized = []
17 for finding in findings:
18 if self.provider == 'aws':
19 normalized.append({
20 'id': finding['Id'],
21 'severity': self.severity_mapping['aws'][finding['Severity']],
22 'type': finding['Type'],
23 'resource': finding['Resource']['ResourceArn'],
24 'timestamp': finding['CreatedAt']
25 })
26 elif self.provider == 'azure':
27 normalized.append({
28 'id': finding['name'],
29 'severity': self.severity_mapping['azure'][finding['properties']['severity']],
30 'type': finding['properties']['alertType'],
31 'resource': finding['properties']['associatedResource'],
32 'timestamp': finding['properties']['timeGenerated']
33 })
34 elif self.provider == 'gcp':
35 normalized.append({
36 'id': finding['name'],
37 'severity': self.severity_mapping['gcp'][finding['severity']],
38 'type': finding['category'],
39 'resource': finding['resourceName'],
40 'timestamp': finding['eventTime']
41 })
42 return normalized
Mejores Prácticas por Servicio
1. Compute Security
<div class="info-box"> 💡 **AWS EC2**: Usar IMDSv2, deshabilitar puertos innecesarios, Systems Manager para patches </div> <div class="info-box"> 💡 **Azure VM**: Habilitar Azure Security Center, usar Managed Identities, Update Management </div> <div class="info-box"> 💡 **GCP Compute**: Shielded VMs, OS Login, automación con OS Config </div>2. Container Security
1# Pod Security Policy (Kubernetes)
2apiVersion: policy/v1beta1
3kind: PodSecurityPolicy
4metadata:
5 name: infraux-restricted
6spec:
7 privileged: false
8 allowPrivilegeEscalation: false
9 requiredDropCapabilities:
10 - ALL
11 volumes:
12 - 'configMap'
13 - 'emptyDir'
14 - 'projected'
15 - 'secret'
16 - 'downwardAPI'
17 - 'persistentVolumeClaim'
18 hostNetwork: false
19 hostIPC: false
20 hostPID: false
21 runAsUser:
22 rule: 'MustRunAsNonRoot'
23 seLinux:
24 rule: 'RunAsAny'
25 supplementalGroups:
26 rule: 'RunAsAny'
27 fsGroup:
28 rule: 'RunAsAny'
Incident Response Plan
Fase | AWS Tools | Azure Tools | GCP Tools |
---|---|---|---|
Detección | GuardDuty, SecurityHub | Sentinel, Security Center | Security Command Center |
Análisis | CloudTrail, VPC Flow Logs | Log Analytics, NSG Flow Logs | Cloud Logging, VPC Flow Logs |
Contención | Lambda, Systems Manager | Automation Runbooks | Cloud Functions, OS Config |
Erradicación | Config Rules | Policy | Security Health Analytics |
Recuperación | Backup, DR | Site Recovery | Backup and DR |
Automatización de Seguridad
1# security_automation.py
2class SecurityAutomation:
3 def __init__(self, cloud_providers: List[str]):
4 self.providers = cloud_providers
5 self.remediation_actions = {
6 'public_s3_bucket': self.fix_public_s3,
7 'open_security_group': self.fix_open_sg,
8 'unencrypted_volume': self.encrypt_volume,
9 'weak_password_policy': self.strengthen_password_policy
10 }
11
12 async def auto_remediate(self, finding: Dict):
13 action = self.remediation_actions.get(finding['type'])
14 if action:
15 await action(finding)
16 await self.notify_team(finding, 'auto_remediated')
17 else:
18 await self.notify_team(finding, 'manual_review_required')
Costos de Seguridad (Mensual)
Servicio | AWS | Azure | GCP |
---|---|---|---|
WAF | $5 + $0.60/millón requests | $0.008/hora + $0.008/10k requests | $0.75/política + $0.75/millón requests |
DDoS Protection | Shield Standard: Gratis | Basic: Gratis | Cloud Armor: $0.025/hora |
SIEM | SecurityHub: $0.001/check | Sentinel: $2.46/GB | Chronicle: Contactar ventas |
Conclusión
<div class="success-box"> ✅ **Recomendación**: No hay un ganador claro. AWS tiene la suite más madura, Azure la mejor integración empresarial, y GCP la más innovadora. La clave es implementar defensa en profundidad independientemente de la nube. </div>La seguridad multi-cloud requiere un enfoque unificado pero con conocimiento profundo de cada plataforma. En InfraUX, abstraemos estas complejidades para que puedas enfocarte en construir, no en configurar.
#seguridad#aws#azure#gcp#cloud-security