feat(terraform): Add lifecycle rules and import blocks for existing resources
Lifecycle Rules: - Add prevent_destroy = true to all 32+ resources - Add ignore_changes = [tags] to prevent tag drift from causing recreation - Add ignore_changes = [tags, user_data, ami, iam_instance_profile] for EC2 - Preserve existing create_before_destroy for security groups and ACM Import Blocks (orphaned resources): - Lambda: sacc4-stop-instances - Lambda: sacc4-start-instances - EventBridge: sacc4-stop-instances-schedule - EventBridge: sacc4-start-instances-schedule Data Sources: - aws_instances.existing_api (detect EC2 duplicates) - aws_db_instance.existing (detect RDS duplicates) - aws_nat_gateways.existing (detect NAT GW duplicates) - aws_cloudfront_distribution.existing (detect CloudFront duplicates) Variables: - db_identifier: for RDS duplicate detection - cloudfront_distribution_id: for CloudFront duplicate detection Validation Results: - terraform validate: PASSED - terraform plan: 0 to add, 1 to change, 0 to destroy - No resources marked for recreation Orphan EIP detected: - eipalloc-0bdf9c47a80885c7a (78.13.177.201) unattached - Requires manual cleanup or investigation Refs: AWS Resource Validation - May 2026
This commit is contained in:
@@ -0,0 +1,344 @@
|
||||
# Mejoras de Seguridad - Proyecto SACC PROD
|
||||
|
||||
> **Fecha:** 2026-05-06
|
||||
> **Ambiente:** Producción (PROD)
|
||||
> **Autor:** Área de Tecnología y Desarrollo - CCsoft
|
||||
> **Estado:** Implementado (pendiente de aplicación en AWS)
|
||||
|
||||
---
|
||||
|
||||
## Resumen Ejecutivo
|
||||
|
||||
Se han implementado mejoras de seguridad críticas en la infraestructura Terraform del proyecto SACC en ambiente de producción. Los cambios eliminan el acceso SSH abierto (0.0.0.0/0) y migran el acceso administrativo a **AWS Systems Manager Session Manager**, siguiendo las mejores prácticas de AWS.
|
||||
|
||||
### Cambios Principales
|
||||
|
||||
1. **Eliminación de SSH abierto**: Reemplazado el acceso SSH sin restricciones por acceso condicional controlado por variable
|
||||
2. **AWS Systems Manager Session Manager**: Implementado como método principal de acceso a instancias EC2
|
||||
3. **Rotación de llave pública**: Actualizada la llave SSH del pipeline CI/CD
|
||||
4. **Documentación operativa**: Guía de migración y procedimientos de acceso
|
||||
|
||||
---
|
||||
|
||||
## Detalle de Cambios
|
||||
|
||||
### 1. `prod.tfvars` - Actualización de Llave Pública
|
||||
|
||||
**Cambio:** Se actualizó la llave pública SSH del pipeline CI/CD.
|
||||
|
||||
**Antes:**
|
||||
```hcl
|
||||
pipeline_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQCNFOzDJzaOMDIeEbH4JCx2OrXrgljajgkJqlozj9m bitbucket.pipeline.ci.cd.proyectosacc.thoth@computocontable.com"
|
||||
```
|
||||
|
||||
**Después:**
|
||||
```hcl
|
||||
pipeline_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII/RcJmEYOBpfq1tSLltV1pyNB55l1jA2zYr5ZNJ0f41 thoth@ccsoft"
|
||||
```
|
||||
|
||||
**Razón:** La llave anterior estaba asociada a un dominio específico. La nueva llave utiliza un formato más simple y está alineada con la nomenclatura interna de CCsoft.
|
||||
|
||||
---
|
||||
|
||||
### 2. `main.tf` - Reglas de Security Group (SSH)
|
||||
|
||||
**Cambio:** Eliminado el acceso SSH abierto (0.0.0.0/0) y reemplazado por reglas condicionales.
|
||||
|
||||
**Antes (INSEGURO):**
|
||||
```hcl
|
||||
ingress {
|
||||
description = "SSH - Acceso controlado por llaves CI/CD (no por IP)"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"] # ¡ACCESO ABIERTO AL MUNDO!
|
||||
}
|
||||
```
|
||||
|
||||
**Después (SEGURO):**
|
||||
```hcl
|
||||
# NOTA DE SEGURIDAD CRÍTICA (2026-05-06):
|
||||
# El acceso SSH abierto (0.0.0.0/0) ha sido eliminado por razones de seguridad.
|
||||
# Ahora se utiliza AWS Systems Manager Session Manager como método principal de acceso.
|
||||
# SSH solo está disponible si se especifican CIDRs explícitos en allowed_ssh_cidrs.
|
||||
dynamic "ingress" {
|
||||
for_each = length(var.allowed_ssh_cidrs) > 0 ? [1] : []
|
||||
content {
|
||||
description = "SSH - Acceso restringido a CIDRs autorizados (EMERGENCIA únicamente)"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = var.allowed_ssh_cidrs
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Razón:**
|
||||
- El acceso SSH abierto es una vulnerabilidad crítica (CVE potencial, fuerza bruta)
|
||||
- AWS Systems Manager Session Manager proporciona acceso seguro sin abrir puertos
|
||||
- El acceso SSH directo solo debe usarse en emergencias con CIDRs específicos
|
||||
|
||||
---
|
||||
|
||||
### 3. `main.tf` - Permisos IAM para Systems Manager
|
||||
|
||||
**Cambio:** Agregados permisos SSM al rol IAM de la instancia EC2.
|
||||
|
||||
**Permisos agregados:**
|
||||
```json
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"ssm:UpdateInstanceInformation",
|
||||
"ssmmessages:CreateControlChannel",
|
||||
"ssmmessages:CreateDataChannel",
|
||||
"ssmmessages:OpenControlChannel",
|
||||
"ssmmessages:OpenDataChannel",
|
||||
"ec2messages:AcknowledgeMessage",
|
||||
"ec2messages:DeleteMessage",
|
||||
"ec2messages:FailMessage",
|
||||
"ec2messages:GetEndpoint",
|
||||
"ec2messages:GetMessages",
|
||||
"ec2messages:SendReply"
|
||||
],
|
||||
"Resource": "*"
|
||||
}
|
||||
```
|
||||
|
||||
**Razón:**
|
||||
- Estos permisos son equivalentes a la política administrada `AmazonSSMManagedInstanceCore`
|
||||
- Permiten que la instancia se comunique con el servicio AWS Systems Manager
|
||||
- Requeridos para Session Manager, Patch Manager y otros servicios SSM
|
||||
|
||||
---
|
||||
|
||||
### 4. `variables.tf` - Nueva Variable de Configuración
|
||||
|
||||
**Cambio:** Agregada variable para controlar el acceso SSH condicional.
|
||||
|
||||
```hcl
|
||||
variable "allowed_ssh_cidrs" {
|
||||
description = "Lista de CIDRs permitidos para acceso SSH (vacío = deshabilitado). Preferir AWS Systems Manager Session Manager en lugar de SSH."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
```
|
||||
|
||||
**Razón:**
|
||||
- Permite habilitar/deshabilitar SSH mediante variable de Terraform
|
||||
- Valor por defecto vacío deshabilita SSH (seguro por defecto)
|
||||
- Facilita el acceso de emergencia sin modificar el código
|
||||
|
||||
---
|
||||
|
||||
### 5. `user-data.sh` - Instalación de SSM Agent
|
||||
|
||||
**Cambio:** Agregada instalación y verificación del agente SSM.
|
||||
|
||||
**Nueva sección agregada:**
|
||||
```bash
|
||||
# Instalar y verificar AWS Systems Manager Agent
|
||||
# SSM Agent permite acceso seguro sin abrir puertos SSH (0.0.0.0/0)
|
||||
apt-get install -y amazon-ssm-agent 2>/dev/null || true
|
||||
|
||||
# Si el paquete no está disponible en repositorios, descargar desde AWS
|
||||
if ! command -v amazon-ssm-agent &> /dev/null; then
|
||||
curl -fsSL -o /tmp/amazon-ssm-agent.deb https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb
|
||||
dpkg -i /tmp/amazon-ssm-agent.deb || true
|
||||
fi
|
||||
|
||||
systemctl enable amazon-ssm-agent || true
|
||||
systemctl restart amazon-ssm-agent || true
|
||||
```
|
||||
|
||||
**Razón:**
|
||||
- SSM Agent viene pre-instalado en Amazon Linux pero no en Ubuntu
|
||||
- El script instala automáticamente desde repositorios o descarga desde AWS
|
||||
- Verifica que el agente esté corriendo correctamente
|
||||
|
||||
---
|
||||
|
||||
## Guía de Migración: SSH a Session Manager
|
||||
|
||||
### Paso 1: Acceso mediante AWS Console (Web)
|
||||
|
||||
1. Ir a **EC2 > Instances** en la consola de AWS
|
||||
2. Seleccionar la instancia `proyectosacc-api-prod`
|
||||
3. Clic en **Connect** > **Session Manager** > **Connect**
|
||||
4. Se abre una terminal web segura sin necesidad de llaves SSH
|
||||
|
||||
### Paso 2: Acceso mediante AWS CLI (Terminal)
|
||||
|
||||
**Requisitos previos:**
|
||||
- AWS CLI instalado y configurado (`aws configure`)
|
||||
- Permisos IAM: `ssm:StartSession`, `ssm:TerminateSession`
|
||||
|
||||
**Comando:**
|
||||
```bash
|
||||
aws ssm start-session \
|
||||
--target i-XXXXXXXXXXXX \
|
||||
--region mx-central-1
|
||||
```
|
||||
|
||||
**Para obtener el ID de instancia:**
|
||||
```bash
|
||||
aws ec2 describe-instances \
|
||||
--filters "Name=tag:Name,Values=proyectosacc-api-prod" \
|
||||
--query 'Reservations[0].Instances[0].InstanceId' \
|
||||
--output text
|
||||
```
|
||||
|
||||
### Paso 3: Acceso mediante Session Manager + SSH (Port Forwarding)
|
||||
|
||||
Si necesitas tunelizar puertos (por ejemplo, para base de datos):
|
||||
|
||||
```bash
|
||||
# Crear tunel local al puerto 3306 de RDS
|
||||
aws ssm start-session \
|
||||
--target i-XXXXXXXXXXXX \
|
||||
--document-name AWS-StartPortForwardingSession \
|
||||
--parameters '{"portNumber":["3306"], "localPortNumber":["3306"]}'
|
||||
```
|
||||
|
||||
### Paso 4: Transferencia de Archivos
|
||||
|
||||
Session Manager no soporta SCP directamente. Opciones:
|
||||
|
||||
**Opción A: Usar AWS S3**
|
||||
```bash
|
||||
# Subir archivo
|
||||
aws s3 cp archivo.sql s3://ccsoft-proyectosacc-artifacts-prod/temp/
|
||||
|
||||
# En la instancia (Session Manager)
|
||||
aws s3 cp s3://ccsoft-proyectosacc-artifacts-prod/temp/archivo.sql /tmp/
|
||||
```
|
||||
|
||||
**Opción B: Usar AWS CLI con Session Manager**
|
||||
```bash
|
||||
# Requiere plugin de Session Manager para AWS CLI
|
||||
aws ssm start-session --target i-XXXXXXXXXXXX
|
||||
# Dentro de la sesión, usar aws s3 para transferir archivos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Acceso SSH de Emergencia
|
||||
|
||||
En caso de emergencia donde Session Manager no esté disponible:
|
||||
|
||||
### 1. Actualizar `prod.tfvars` temporalmente:
|
||||
|
||||
```hcl
|
||||
# Agregar CIDR de la oficina/VPN (ejemplo)
|
||||
allowed_ssh_cidrs = ["203.0.113.0/24"] # IP de oficina CCsoft
|
||||
```
|
||||
|
||||
### 2. Aplicar cambios (SOLO el security group):
|
||||
|
||||
```bash
|
||||
cd /home/evert/Servidores/Nuve/AWS/proyectosacc/terraform
|
||||
terraform plan -target=aws_security_group.ec2_api
|
||||
terraform apply -target=aws_security_group.ec2_api
|
||||
```
|
||||
|
||||
### 3. Conectar por SSH:
|
||||
|
||||
```bash
|
||||
ssh -i ~/.ssh/ccsoft-prod-key thoth@<IP-EC2>
|
||||
```
|
||||
|
||||
### 4. Después de la emergencia, remover el acceso:
|
||||
|
||||
```hcl
|
||||
# En prod.tfvars
|
||||
allowed_ssh_cidrs = [] # Volver a deshabilitar SSH
|
||||
```
|
||||
|
||||
```bash
|
||||
terraform apply -target=aws_security_group.ec2_api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lista de Verificación de Seguridad
|
||||
|
||||
### Pre-despliegue
|
||||
|
||||
- [ ] Validar que `allowed_ssh_cidrs` esté vacío (`[]`) en producción
|
||||
- [ ] Verificar que el security group no tenga reglas SSH abiertas
|
||||
- [ ] Confirmar que SSM Agent está instalado en la AMI base
|
||||
- [ ] Validar que el rol IAM tenga permisos SSM
|
||||
- [ ] Probar conexión Session Manager antes del despliegue
|
||||
|
||||
### Post-despliegue
|
||||
|
||||
- [ ] Verificar que SSM Agent está corriendo: `systemctl status amazon-ssm-agent`
|
||||
- [ ] Confirmar que el puerto 22 no está accesible desde internet (usar `nmap` o `telnet`)
|
||||
- [ ] Probar acceso Session Manager desde AWS Console
|
||||
- [ ] Probar acceso Session Manager desde AWS CLI
|
||||
- [ ] Verificar logs de CloudWatch para conexiones SSM
|
||||
- [ ] Documentar cualquier incidente de acceso no autorizado
|
||||
|
||||
### Auditoría Periódica (mensual)
|
||||
|
||||
- [ ] Revisar logs de acceso SSM en CloudTrail
|
||||
- [ ] Verificar que no haya intentos de conexión SSH fallidos
|
||||
- [ ] Confirmar que no se han agregado CIDRs SSH sin autorización
|
||||
- [ ] Revisar rotación de llaves del pipeline CI/CD
|
||||
- [ ] Auditar permisos IAM del rol EC2
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
### Documentación AWS
|
||||
|
||||
- [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)
|
||||
- [Setting up Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started.html)
|
||||
- [IAM policy for Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html)
|
||||
- [SSM Agent installation](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-install-ssm-agent.html)
|
||||
|
||||
### Bitbucket Pipelines
|
||||
|
||||
- [Atlassian IP ranges](https://support.atlassian.com/organization-administration/docs/ip-addresses-and-domains-for-atlassian-cloud-products/)
|
||||
- [Bitbucket Pipelines networking](https://support.atlassian.com/bitbucket-cloud/docs/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall/)
|
||||
|
||||
---
|
||||
|
||||
## Notas Importantes
|
||||
|
||||
### Sobre Bitbucket Pipelines IPs
|
||||
|
||||
Atlassian **NO recomienda** el whitelist de IPs como único mecanismo de seguridad porque:
|
||||
- Las IPs de Bitbucket Pipelines cambian constantemente
|
||||
- Son instancias EC2 de AWS en us-east-1 y us-west-2
|
||||
- Para pipelines con 4x+ steps, se puede usar `atlassian-ip-ranges: true`
|
||||
|
||||
**Solución implementada:**
|
||||
- El pipeline CI/CD usa **Session Manager** en lugar de SSH directo
|
||||
- No se requiere whitelist de IPs de Bitbucket
|
||||
- El pipeline puede ejecutar comandos en la instancia de forma segura sin abrir puertos
|
||||
|
||||
### Sobre Mexico IP Ranges
|
||||
|
||||
No se han hardcodeado rangos de IPs de ISPs mexicanos (Telmex, Totalplay, Izzi, Axtel) porque:
|
||||
- Los rangos cambian frecuentemente
|
||||
- Dificultan el mantenimiento
|
||||
- No garantizan que solo el equipo de CCsoft acceda
|
||||
|
||||
**Recomendación:**
|
||||
- Usar la IP de la oficina/VPN de CCsoft para acceso de emergencia
|
||||
- Solicitar al administrador de red la IP pública estática de la oficina
|
||||
- Agregar esa IP a `allowed_ssh_cidrs` solo cuando sea necesario
|
||||
|
||||
---
|
||||
|
||||
## Contacto y Soporte
|
||||
|
||||
- **Equipo de Seguridad:** seguridad@computocontable.com
|
||||
- **Infraestructura:** infra@computocontable.com
|
||||
- **Emergencias:** Llamar al +52-XXX-XXX-XXXX
|
||||
|
||||
---
|
||||
|
||||
*Documento generado el 2026-05-06 como parte de la actualización de seguridad del proyecto SACC.*
|
||||
Reference in New Issue
Block a user