# SPEC — Correcção Admin Domínios Virtuais (VM112)

**Versão:** 1.0  
**Data:** 2026-06-12  
**Autor:** Roger / Cursor DevOps  
**Estado:** ✅ **IMPLEMENTADO**  
**Servidor:** VM112 (`10.10.10.112`) — Carbonio Advanced

---

## 1. Resumo executivo

Correcção completa do **Admin Console Carbonio** para **9 domínios virtuais** na VM112, em três camadas:

| Camada | Problema | Correcção |
|--------|----------|-----------|
| **`:6071` SSL** | 4 domínios ERR_CERT no browser | Certs LE exportados Traefik → nginx admin |
| **`/admin` :443** | Timeout/504 nos 4 domínios | Redirect nginx 443 → `:6071/static/login/` |
| **diarissima :6071** | 504 (bloco ausente) | Bloco em `.custom` + blindagem zmproxyconfgen |
| **ligbox :6071** | Fixes manuais apagados por zmproxyconfgen | Script idempotente + wrapper |

**URL admin canónica (sempre válida):**
```
https://mail.ligbox.com.br:6071/static/login/
```
Domain admin entra com `admin@{dominio}` na mesma URL ou na URL branded do domínio.

---

## 2. Mapa final por domínio (pós-correcção)

| Domínio | `/admin` :443 | `:6071` cert | `:6071` login |
|---------|---------------|--------------|---------------|
| ligbox.com.br | ✅ 302 → :6071 | ✅ LE próprio | ✅ |
| diarissima.com | ✅ 302 | ✅ SAN multi | ✅ |
| dratcoin.com | ✅ 302 | ✅ SAN multi | ✅ |
| ibytera.com | ✅ 302 | ✅ SAN multi | ✅ |
| myvexx.com | ✅ 302 | ✅ SAN multi | ✅ |
| betinplace.com | ✅ 302 | ✅ Traefik export | ✅ |
| betinsport.com | ✅ 302 | ✅ Traefik export | ✅ |
| eplacebets.com | ✅ 302 | ✅ Traefik export | ✅ |
| iofficebooks.com | ✅ 302 | ✅ Traefik export | ✅ |

---

## 3. Problemas identificados

### 3.1 Dois URLs diferentes (confusão operacional)

| URL | Porta | Função |
|-----|-------|--------|
| `https://mail.{dominio}/admin` | **443** | Atalho — deve redirecionar |
| `https://mail.{dominio}:6071/static/login/` | **6071** | Admin Console Carbonio (real) |

O wizard `/admin` (SPA painel delegado) **≠** Carbonio admin.

### 3.2 ERR_CERT nos 4 domínios (betinplace, betinsport, eplacebets, iofficebooks)

- Bloco nginx `:6071` **existia**
- Cert partilhado `nginx.crt` (SAN multi) **não incluía** estes hostnames
- Browser: `NET::ERR_CERT_COMMON_NAME_INVALID` + HSTS impede bypass

**Causa:** domínios em conta Cloudflare diferente — certbot DNS VM112 não consegue expandir `mail-vm112-multi`.

**Solução:** certs LE **já existentes no Traefik (CT114)** exportados para VM112.

### 3.3 `/admin` :443 → 504/timeout (4 domínios)

- `mail.ligbox.com.br` funcionava via `https.default` (include `backend-admin-redirect.conf`)
- Domínios tenant tinham bloco `location = //` **corrupto** (admin quebrado)
- Falta `include backend-admin-redirect.conf` nos blocos `nginx.conf.web.https`

### 3.4 diarissima :6071 → 504

- Bloco admin removido em cleanup 2026-06-08
- Recriado em ficheiro `.custom` (fora do zmproxyconfgen)

### 3.5 zmproxyconfgen apaga fixes ligbox

- Regenera `nginx.conf.web.carbonio.admin` → perde patches manuais ligbox

---

## 4. Correcções aplicadas

### 4.1 Certs Traefik → admin :6071 (4 domínios)

**Origem:** `/root/traefik/letsencrypt/acme.json` (CT114)

**Destino:**
```
/opt/zextras/ssl/letsencrypt/traefik-export/mail-{dominio}.fullchain.pem
/opt/zextras/ssl/letsencrypt/traefik-export/mail-{dominio}.privkey.pem
```

**Patch nginx:** blocos admin `:6071` apontam para certs exportados (não `nginx.crt` partilhado).

**Script sync:**
```bash
/opt/ligbox-deploy/scripts/admin-login-check/sync-traefik-admin-certs.sh
```

### 4.2 Redirect `/admin` :443 → :6071 (7+ domínios)

**Ficheiro:**
```nginx
# /opt/zextras/conf/nginx/extensions/backend-admin-redirect.conf
location ~* ^/admin/?$ {
    return 302 https://$host:6071/static/login/;
}
```

**Aplicação:** `apply-admin-nginx-overrides.py` injecta include em cada bloco `server_name mail.*` em `nginx.conf.web.https`.

**Removido:** blocos corruptos `location = //`.

### 4.3 diarissima — bloco admin isolado

```
/opt/zextras/conf/nginx/includes/nginx.conf.web.carbonio.admin.custom
```

Include em `nginx.conf.web` (zmproxyconfgen não toca).

### 4.4 Blindagem zmproxyconfgen

| Script | Função |
|--------|--------|
| `apply-admin-nginx-overrides.py` | Re-aplica: ligbox fixes, redirect /admin, certs tenant, diarissima custom |
| `zmproxyconfgen-ligbox.sh` | Wrapper seguro: zmproxyconfgen + apply --reload |
| `/usr/local/bin/zmproxyconfgen-ligbox` | Symlink |

**Regra:** nunca correr `zmproxyconfgen` directo em produção.

### 4.5 Fixes ligbox :6071 (mantidos)

- `server_name mail.ligbox.com.br 10.10.10.112`
- Cert LE: `/opt/zextras/ssl/letsencrypt/mail.ligbox.fullchain.pem`
- Remove redirect E4 `/zx/login/supported`
- Rewrite IP → domínio em `/zx/login/v3/config`
- `Host mail.ligbox.com.br` em auth locations
- `blank.html` → 404

---

## 5. Arquitectura

```
Browser
   │
   ├─ https://mail.{dominio}/admin (:443)
   │       └─ nginx backend-admin-redirect.conf
   │               └─ 302 → https://mail.{dominio}:6071/static/login/
   │
   └─ https://mail.{dominio}:6071/static/login/
           └─ nginx carbonio.admin (+ .custom diarissima)
                   └─ carbonio-auth / catalog
                           └─ LDAP (zimbraReverseProxyAdminEnabled: TRUE no servidor)
```

**Nota LDAP:** admin activo **uma vez** no servidor `mail.ligbox.com.br` — não por domínio virtual.

---

## 6. Validação

```bash
# Redirect /admin :443
curl -skI https://mail.iofficebooks.com/admin | grep -i location
# → https://mail.iofficebooks.com:6071/static/login/

# Cert :6071
echo | openssl s_client -connect mail.betinplace.com:6071 -servername mail.betinplace.com 2>/dev/null | openssl x509 -noout -subject

# Fluxo E1–E8 ligbox
cd /opt/ligbox-deploy/scripts/admin-login-check && npm run check:flow:ligbox

# Overrides pendentes
python3 apply-admin-nginx-overrides.py --check
```

---

## 7. Ficheiros alterados/criados

| Caminho | Descrição |
|---------|-----------|
| `/opt/zextras/conf/nginx/extensions/backend-admin-redirect.conf` | Redirect /admin |
| `/opt/zextras/conf/nginx/includes/nginx.conf.web.carbonio.admin.custom` | Bloco diarissima |
| `/opt/zextras/ssl/letsencrypt/traefik-export/*` | Certs 4 domínios |
| `/opt/ligbox-deploy/scripts/admin-login-check/apply-admin-nginx-overrides.py` | Patcher idempotente |
| `/opt/ligbox-deploy/scripts/admin-login-check/sync-traefik-admin-certs.sh` | Sync certs Traefik |
| `/opt/ligbox-deploy/scripts/admin-login-check/zmproxyconfgen-ligbox.sh` | Wrapper zmproxyconfgen |

---

## 8. Documentação relacionada

- `SPEC-SOLUCAO-ADMIN-LOGIN-6071.md` — admin login ligbox (NAT + nginx E1–E8)
- `SPEC-ADMIN-DOMINIO-BLINDAGEM-NGINX.md` — blindagem + mapa domínios
- `ADMIN-NGINX-OVERrides-BLINDAGEM.md` — procedimento ops
- `SPEC-CARBONIO-ADMIN-LOGIN-FLOW-VALIDATION.md` — validação fluxo E1–E8

---

## 9. Critérios de aceitação

- [x] 9/9 domínios: `/admin` :443 → 302 :6071
- [x] 9/9 domínios: `:6071` cert CN correcto no browser
- [x] 9/9 domínios: `:6071/static/login/` HTTP 200
- [x] diarissima bloco `.custom` activo
- [x] Script blindagem zmproxyconfgen instalado
- [x] Sync Traefik certs documentado

---

*Roger / VM112 — 2026-06-12*
