Files
proyectosacc-mirror/docs/08-seguridad-y-secretos.md
T
2026-04-14 14:53:05 -06:00

206 lines
6.4 KiB
Markdown

# 08 - Seguridad y Secretos
> Cómo protegemos las contraseñas, llaves y datos sensibles de `proyectosacc`.
---
## 1. ¿Qué es un "secreto"?
Un **secreto** es cualquier información que no debe ser pública. En `proyectosacc`, los secrets incluyen:
- Contraseñas de bases de datos.
- Llaves SSH privadas.
- Tokens de Telegram.
- Credenciales de AWS (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`).
> 💡 **Regla de oro**: si perder esa información causaría un problema de seguridad, es un secreto.
---
## 2. ¿Dónde viven los secrets?
### Opción 1: Bitbucket Repository Variables (la más usada)
En Bitbucket Pipelines podemos guardar variables de entorno que los scripts usan sin exponer su valor.
**Cómo configurarlas:**
1. Ve al repositorio en Bitbucket.
2. Entra a **Repository settings > Pipelines > Repository variables**.
3. Agrega el nombre y el valor.
4. **Marca la casilla "Secured"** 🔒.
**Ventaja**: cuando el pipeline corre, las variables secured aparecen como `***` en los logs. Nadie puede leerlas.
### Opción 2: AWS Secrets Manager
AWS tiene un servicio llamado **Secrets Manager** que guarda secrets de forma segura y permite rotarlos automáticamente.
**Ejemplo de uso en un pipeline de CodeBuild:**
```yaml
env:
secrets-manager:
DB_PASSWORD: "prod/database/password"
```
### Opción 3: AWS Systems Manager Parameter Store
Similar a Secrets Manager, pero más simple y económico. Se usa para guardar configuraciones sensibles.
```yaml
env:
parameter-store:
DATABASE_URL: "/app/database/url"
```
### Opción 4: Archivo `.env` (solo local)
En tu computadora personal puedes tener un archivo `.env` con variables locales. **Este archivo NUNCA debe subirse al repositorio.**
El archivo `.gitignore` del proyecto ya debería incluir `.env` para evitar accidentes.
---
## 3. ¿Qué NUNCA poner en el repositorio?
### ❌ NUNCA hagas esto
```yaml
# Mal ejemplo en bitbucket-pipelines.yml
- step:
script:
- export DB_PASSWORD="supersecreta123"
- export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
```
```hcl
# Mal ejemplo en Terraform
resource "aws_db_instance" "example" {
password = "mi-contrasena-123"
}
```
```bash
# Mal ejemplo en un script
API_KEY="sk-1234567890abcdef"
```
### ✅ SIEMPRE haz esto
```yaml
# Bien: usa variables de entorno
- step:
script:
- export DB_PASSWORD="$DB_PASSWORD"
```
```hcl
# Bien: usa variables de Terraform
resource "aws_db_instance" "example" {
password = var.db_password
}
```
```bash
# Bien: lee desde una variable de entorno
API_KEY="$API_KEY"
```
---
## 4. ¿Cómo rotar las llaves SSH?
**Rotar** una llave significa crear una nueva y dejar de usar la anterior. Es una buena práctica de seguridad, especialmente si alguien con acceso a la llave privada deja la empresa.
### Paso 1: Generar un nuevo par de llaves
```bash
ssh-keygen -t ed25519 -b 4096 \
-C "bitbucket.pipeline.ci.cd.proyectosacc.thoth.develop@computocontable.com" \
-f bitbucket_pipeline_ci_cd_TO_proyectosacc_server_thoth_develop
```
### Paso 2: Codificar la llave privada en base64
```bash
base64 -i bitbucket_pipeline_ci_cd_TO_proyectosacc_server_thoth_develop | tr -d '\n' > nueva_llave.b64
```
### Paso 3: Actualizar la variable en Bitbucket
1. Copia el contenido de `nueva_llave.b64`.
2. Ve a **Repository settings > Pipelines > Repository variables**.
3. Actualiza la variable `PROYECTOSACC_SSH_KEY` con el nuevo valor.
### Paso 4: Colocar la llave pública en el servidor
```bash
# Copia el contenido del archivo .pub
cat bitbucket_pipeline_ci_cd_TO_proyectosacc_server_thoth_develop.pub
# Conéctate al servidor y agrégala a authorized_keys
ssh ubuntu@<IP_DE_LA_EC2>
sudo su - thoth
nano ~/.ssh/authorized_keys
# Pega la nueva llave pública al final del archivo
> 💡 **Tip**: en un despliegue automatizado con Terraform, esta llave pública se inyecta directamente desde el archivo `user_data`. No hace falta editar `authorized_keys` a mano.
### Paso 5: Probar la conexión
Ejecuta un pipeline de prueba o conéctate manualmente con la nueva llave privada para confirmar que funciona.
### Paso 6: Eliminar la llave anterior
Una vez confirmado que la nueva llave funciona:
1. Borra la llave pública antigua de `~/.ssh/authorized_keys`.
2. Borra la llave privada antigua de tu computadora.
3. Actualiza cualquier otra copia que exista.
---
## 5. Seguridad del frontend en S3 + CloudFront
### Bucket policy para CloudFront (OAI)
El bucket S3 del frontend NO debe ser público. Solo CloudFront puede leer los objetos:
```json
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowCloudFrontOAI",
"Effect": "Allow",
"Principal": {
"CanonicalUser": "<OAI-canonical-user-id>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::ccsoft-proyectosacc-frontend/*"
}]
}
```
### CORS en S3 (si el frontend llama a la API)
Como el frontend React y la API backend comparten el mismo dominio `https://sacc.ccsoft.mx` (gracias al behavior `/api/*` de CloudFront), **no hay problema de CORS**. Si en el futuro decides mover la API a un subdominio diferente (por ejemplo, `api.sacc.ccsoft.mx`), ahí sí necesitarás configurar CORS en el backend.
### Versionamiento de objetos en S3
Habilita el versionamiento en el bucket del frontend. Así puedes restaurar una versión anterior del sitio si un deploy falla:
```bash
aws s3api put-bucket-versioning \
--bucket ccsoft-proyectosacc-frontend \
--versioning-configuration Status=Enabled
```
---
## 6. Checklist de seguridad básica
- [ ] El archivo `.env` está en `.gitignore`.
- [ ] Ningún archivo del repositorio contiene contraseñas escritas directamente.
- [ ] Las variables de Bitbucket están marcadas como **Secured**.
- [ ] La llave privada SSH dedicada para `proyectosacc` está en formato **base64** en Bitbucket.
- [ ] No se usa acceso SSH por contraseña ni herramientas como `sshpass`.
- [ ] El puerto SSH (22) de la EC2 solo está abierto a IPs conocidas.
- [ ] La base de datos RDS no es accesible desde internet (solo desde la VPC).
- [ ] Los certificados SSL están configurados correctamente en **CloudFront** (HTTPS obligatorio).
- [ ] El bucket S3 del frontend NO es público; solo CloudFront tiene acceso mediante OAI/OAC.
- [ ] El versionamiento de objetos está habilitado en el bucket S3 del frontend.
- [ ] Se ha programado una rotación de llaves SSH al menos una vez al año.
---
*Anterior: [`07-terraform-iac.md`](07-terraform-iac.md)*
*Siguiente: [`09-runbook-deploy.md`](09-runbook-deploy.md)*