# 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@ ``` ### 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.*