# Brief técnico · Lucas · nginx + Let's Encrypt + OCI Security List

**Para:** Lucas Doldan (Lead Engineer)
**De:** Carlos Rejala (CEO)
**Fecha:** 2026-04-26
**Objetivo:** dashboards Zymplo accesibles públicos en `https://*.zymplo.com` con HTTPS válido
**Tiempo estimado:** 25-30 min total

---

Lucas · necesito acceso público HTTPS para dashboards Zymplo en S1 OCI (`163.176.179.211`). Te paso toda la config para que lo hagas end-to-end · YA tenés acceso al panel OCI y root en S1.

---

## PARTE 1 · OCI Security List (5 min · panel cloud.oracle.com)

VCN del S1 · Default Security List · **Add Ingress Rules**:

| Source CIDR | Protocol | Source Port | Dest Port | Description |
|---|---|---|---|---|
| `0.0.0.0/0` | TCP | (any) | `80` | HTTP nginx |
| `0.0.0.0/0` | TCP | (any) | `443` | HTTPS nginx |

Stateful: yes (default) · NO Stateless.

---

## PARTE 2 · iptables persistencia S1 (5 min · root S1)

Yo ya abrí 80/443 en iptables runtime, pero NO está persistido. Para que sobreviva reboot:

```bash
sudo apt-get install -y netfilter-persistent iptables-persistent
sudo netfilter-persistent save
```

Verificar:
```bash
sudo iptables -L INPUT -n | grep -E "80|443|8081|9000|9001|9002"
```
Esperado: 6 reglas ACCEPT.

---

## PARTE 3 · DNS records · HostGator (Carlos los crea)

A records apuntando a `163.176.179.211`, TTL 300:

| Subdomain | Type | Value | TTL |
|---|---|---|---|
| `dashboard.zymplo.com` | A | `163.176.179.211` | 300 |
| `plan.zymplo.com` | A | `163.176.179.211` | 300 |
| `prompt.zymplo.com` | A | `163.176.179.211` | 300 |
| `sims.zymplo.com` | A | `163.176.179.211` | 300 |

Verificar propagación antes de seguir:
```bash
for SD in dashboard plan prompt sims; do
  echo "$SD.zymplo.com → $(dig +short $SD.zymplo.com)"
done
# debe devolver 163.176.179.211 en cada uno
```
(usualmente 5-15 min con TTL 300)

---

## PARTE 4 · nginx config (10 min · root S1)

nginx 1.18 + certbot 5.5 (snap) ya instalados. Crear archivo único con 4 server blocks:

```bash
sudo tee /etc/nginx/sites-available/zymplo-dashboards <<'NGINX'
# dashboard.zymplo.com → :9000 (META-INDEX)
server {
  listen 80;
  server_name dashboard.zymplo.com;
  location / {
    proxy_pass http://127.0.0.1:9000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}
# plan.zymplo.com → :9001 (Master Plan + 11 deliverables)
server {
  listen 80;
  server_name plan.zymplo.com;
  location / {
    proxy_pass http://127.0.0.1:9001;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}
# prompt.zymplo.com → :9002 (Plan Maestro Lanzamiento + Prompt Maestro v7.0)
server {
  listen 80;
  server_name prompt.zymplo.com;
  location / {
    proxy_pass http://127.0.0.1:9002;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}
# sims.zymplo.com → :8081 (CX Battery dashboard live)
server {
  listen 80;
  server_name sims.zymplo.com;
  location / {
    proxy_pass http://127.0.0.1:8081;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}
NGINX

sudo ln -sf /etc/nginx/sites-available/zymplo-dashboards /etc/nginx/sites-enabled/zymplo-dashboards
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t   # debe decir "syntax is ok" + "test is successful"
sudo systemctl enable --now nginx
sudo systemctl reload nginx
```

Verificar HTTP plano (antes de cert):
```bash
curl -H "Host: dashboard.zymplo.com" http://163.176.179.211/META-INDEX.html
# esperado: HTTP 200 + HTML del META-INDEX
```

---

## PARTE 5 · Let's Encrypt certs (5 min · root S1)

```bash
sudo certbot --nginx \
  -d dashboard.zymplo.com \
  -d plan.zymplo.com \
  -d prompt.zymplo.com \
  -d sims.zymplo.com \
  --email lucasdoldan@zymplo.com \
  --agree-tos --no-eff-email \
  --redirect
```

`--redirect` agrega auto HTTP→HTTPS 301 en los 4 server blocks.

Auto-renovación (snap-installed certbot ya trae renew timer activo · renueva cada 12h):
```bash
systemctl status snap.certbot.renew.timer
```

---

## PARTE 6 · Verify final

Desde S1 (interno):
```bash
for SD in dashboard plan prompt sims; do
  curl -sI https://$SD.zymplo.com | head -1
done
# 4× HTTP/2 200
```

Desde Mac/iPhone (externo):
- Abrir `https://dashboard.zymplo.com` en browser → debería cargar META-INDEX con candado verde sin warning.

---

## Backends actuales corriendo en S1 (NO tocar · ya están live)

| Port | Proceso | Path servido |
|---|---|---|
| 9000 | `python3 -m http.server` | `/opt/zymplo-hq/dashboards/` |
| 9001 | `python3 -m http.server` | `/opt/zymplo-hq/master-plan/` |
| 9002 | `python3 -m http.server` | `/opt/zymplo-hq/01-comando-central/` |
| 8081 | `dashboard-server.py` | `/opt/mirofish/v25-ultra-pro/whatsapp-sim/` (V25 + mega-val live) |

Todos bind `0.0.0.0` · expuestos solo internos · nginx reverse proxy hace el bridge HTTPS público → HTTP interno.

---

## Notas

1. **Servicios systemd Zymplo ya activos en S1 (NO tocar):**
   - `zymplo-auto-launcher.service` (monitor V25 → arranca mega-validation)
   - `zymplo-watchdog.service` (paralelización adaptativa Regla #17)

2. **Cuando termines, mandame el output de:**
   ```bash
   curl -sI https://dashboard.zymplo.com | head -3
   curl -sI https://sims.zymplo.com | head -3
   ```

3. **Si certbot falla por DNS no propagado todavía, esperar 5 min y retry:**
   ```bash
   sudo certbot --nginx -d dashboard.zymplo.com -d plan.zymplo.com -d prompt.zymplo.com -d sims.zymplo.com
   ```

---

**Tiempo total estimado:** 25-30 min (5 OCI + 5 iptables + 10 nginx + 5 cert + 5 verify).

Gracias!
— Carlos
