# Spec 028 — OpenPanel CE Ligbox Re-engenharia (Enterprise Local)

**Criado:** 2026-06-19  
**Solicitado por:** Roger  
**Status:** ✅ Implementado (VM123) — E2E FOSS validado  
**Prioridade:** P0 (hosting comercial sem licença Enterprise paga)  
**VM alvo:** **VM123** (`10.10.10.123`)  
**Relacionado:** Spec **024** (FOSS+OpenPanel), Spec **027** (RBAC Desk), Spec **018** (Serviços) · **[Spec 043 — mapa activação](../043-desk-client-activation-sync/contracts/activation-field-mapping.md)**

---

## Resumo

Re-engenharia local do **OpenPanel Community Edition** para operar como **plataforma Ligbox “enterprise”** sem licença WHMCS/OpenPanel paga:

| Capacidade | Antes (CE) | Depois (Ligbox) |
|------------|------------|-----------------|
| Contas hosting | Máx. **3** | **Ilimitadas** (patch opencli) |
| API FOSSBilling | Bloqueada | **Bridge :18087** (API compatível) |
| Domínio por pedido | Manual | **Automático** (`user-add` + `domains-add`) |
| Email CLI | Bloqueado | **Desbloqueado** (patch + `key` local) |
| OpenAdmin extra | 1 admin | SQLite bypass + CLI desbloqueado |
| Integração Desk | Parcial | FOSS → bridge → conta real |

**Princípio:** conta hosting **real** = `opencli user-add` (Linux + Docker + MySQL `panel.users`) + `opencli domains-add` (vhost/Caddy/DNS). **Não** usar INSERT SQLite (só OpenAdmin) nem INSERT MySQL isolado.

---

## Arquitectura

```
Internet → Traefik CT114
    → financeiro.ligbox.com.br     → FOSSBilling (Docker VM123)
    → openpanel.ligbox.com.br      → OpenPanel UI :2083
    → admin.openpanel.ligbox.com.br → OpenAdmin :2087

FOSSBilling order (hosting)
    → OpenPanel.php (Ligbox patch: campo domain)
    → POST http://10.10.10.123:18087/api/users
    → bridge.py v2
        → opencli user-add
        → opencli domains-add (domínio normalizado)
    → Conta REAL + domínio CORRECTO
```

---

## VM123 — componentes

| Componente | Path / serviço |
|------------|----------------|
| OpenPanel CE | bare metal v1.7.61 |
| Bridge FOSS | `openpanel-foss-bridge.service` → `:18087` |
| Patch CE | `patch-openpanel-ce-unlock.sh` |
| Patch FOSS domain | `patch-foss-openpanel-domain.sh` |
| Provision manual | `provision-openpanel-hosting.sh` |
| E2E test | `test-foss-openpanel-order.sh` |
| DNS BIND (público) | container `openpanel_dns` → `:53` · IP público `95.216.14.162` via Proxmox DNAT |
| Credenciais | `CREDENCIAIS_SERVICOS_VM123.txt` |

---

## Re-engenharia CE — ficheiros patchados

Script: `deploy/vm123-finance-stack/patch-openpanel-ce-unlock.sh`

| Ficheiro opencli | Restrição removida |
|------------------|-------------------|
| `user/add.sh` | Limite 3 contas + resellers |
| `user/restore.sh` | Limite restore |
| `user/transfer.sh` | Limite transfer |
| `api.sh` | API nativa bloqueada |
| `admin.sh` | Múltiplos admins/resellers |
| `email/*.sh` (6 ficheiros) | Módulos email bloqueados |

**Config local:** `/etc/openpanel/openpanel/conf/openpanel.config`

```ini
[LICENSE]
key=ligbox-local-enterprise
```

**Backup:** `/usr/local/opencli/.ligbox-backup-YYYYMMDD/`

**Reaplicar obrigatório após:** `opencli update --cli`

---

## Bridge FOSS v2 — API

Base: `http://10.10.10.123:18087`  
Token: `ligbox-community-bridge-token` (ver `bridge.env`)

### Autenticação

```http
POST /api
Content-Type: application/json
{"username":"ligboxadmin","password":"LbOpen805353"}

→ {"access_token":"ligbox-community-bridge-token"}
```

### Criar conta + domínio

```http
POST /api/users
Authorization: Bearer ligbox-community-bridge-token
Content-Type: application/json

{
  "username": "cliente1",
  "password": "SenhaSegura123",
  "email": "cliente@dominio.com",
  "plan_name": "ligbox-site-cms",
  "domain": "cliente1.com"
}
```

**Normalização domínio (bridge):**

| Entrada FOSS | Painel OpenPanel |
|--------------|------------------|
| `cliente.com` | `cliente.com` |
| `teste.ops.ligbox` | `teste.ops.ligbox.com.br` |
| `test95452ligbox.com.br` (sem ponto) | `test95452.ligbox.com.br` |

### Outros endpoints

| Método | Path | Função |
|--------|------|--------|
| GET | `/api` | Health (com Bearer) |
| GET | `/api/users` | Listar contas |
| GET | `/api/users/{user}` | Domínios do user |
| POST | `/api/domains` | Associar domínio |
| PATCH | `/api/users/{user}` | suspend / unsuspend / password |
| DELETE | `/api/users/{user}` | Remover conta |

**Timeout:** `user-add` demora ~15–20s — clientes HTTP ≥ 60s.

---

## FOSSBilling — configuração servidor

Admin FOSS → System → Hosting plans → Server **VM123 OpenPanel**

| Campo | Valor |
|-------|-------|
| Manager | OpenPanel |
| Hostname | `10.10.10.123` |
| Port | **`18087`** |
| Secure | **No** |
| Username | `ligboxadmin` |
| Password | `LbOpen805353` |

**Produto:** `Ligbox Site CMS` (id 2) · plan_name = `ligbox-site-cms`

**Pedido FOSS (domain config):**

```
config[domain][action]=owndomain
config[domain][owndomain_sld]=CLIENTE
config[domain][owndomain_tld]=ligbox.com.br
```

**Patch OpenPanel.php** (`patch-foss-openpanel-domain.sh`):

```php
"plan_name" => $package->getName(),
"domain" => $account->getDomain(),
```

FOSS gera username próprio (7 chars + dígito; prefixo `test` → hash aleatório).

---

## Contas de teste (audit_domains Desk)

Senha comum clientes teste: `LbOpenTest805353`  
Plano: `ligbox-site-cms` (1 domínio/conta)

| Domínio Desk | User OpenPanel | Domínio painel |
|--------------|----------------|----------------|
| diarissima.com | diarissima | diarissima.com |
| myvexx.com | myvexx | myvexx.com |
| teste.ops.ligbox | testeops | teste.ops.ligbox.com.br |
| auth-verify.ligbox | authverify | auth-verify.ligbox.com.br |
| e2e.portal.ligbox | e2eportal | e2e.portal.ligbox.com.br |
| funnel.ops.ligbox | funnel | funnel.ops.ligbox.com.br |
| verify.ops.ligbox | verify | verify.ops.ligbox.com.br |

---

## OpenAdmin — bypass SQLite (issue #795)

Base: `/etc/openpanel/openadmin/users.db`

```sql
-- Gerar hash
/usr/local/admin/venv/bin/python3 /usr/local/admin/core/users/hash "SENHA"

-- Inserir admin extra
INSERT INTO user (username, password_hash, role) VALUES ('labadmin', 'HASH', 'admin');

-- Reseller (+ ficheiro JSON)
INSERT INTO user (username, password_hash, role) VALUES ('labreseller', 'HASH', 'reseller');
cp /etc/openpanel/openadmin/config/reseller_template.json \
   /etc/openpanel/openadmin/resellers/labreseller.json
```

Contas lab: `labadmin` / `LbLabAdmin805353` · `labreseller` / `LbLabReseller805353`

---

## E2E validado (2026-06-19)

```
FOSS order #6 → user ab69b548 → domain test95452.ligbox.com.br ✅
Script: test-foss-openpanel-order.sh (7 passos)
```

---

## Limitações e riscos

| Item | Nota |
|------|------|
| `opencli update --cli` | Repõe patches — reaplicar script |
| Recursos VM123 | N containers = N× RAM/CPU Docker |
| Licença WHMCS | `ligbox-local-enterprise` é local — sem suporte Netgate |
| UI OpenAdmin | Pode mostrar badge Enterprise cosmético |
| Escala 100+ | Avaliar RAM/cluster; patch remove limite lógico |

---


---

## DNS público — porta 53 (OpenPanel BIND)

**Status (2026-06-22):** ✅ Resolvido — timeout externo corrigido no Proxmox (SNAT ida `10.10.10.254`).

| Item | Valor |
|------|-------|
| Container | `openpanel_dns` (BIND9) |
| LAN | `10.10.10.123:53` |
| IP público | `95.216.14.162:53` (glue `ns1/ns2.ligbox.com.br`) |
| Documentação | [DNS53_OPENPANEL_PORTA53.md](DNS53_OPENPANEL_PORTA53.md) |

**Teste rápido:** `dig @95.216.14.162 betinplace.com MX +short`

## URLs públicas

| Serviço | URL |
|---------|-----|
| OpenPanel clientes | https://openpanel.ligbox.com.br |
| OpenAdmin | https://admin.openpanel.ligbox.com.br |
| FOSSBilling | https://financeiro.ligbox.com.br/admin |
| Spec Hub (esta spec) | https://spec.ligbox.com.br/specs/028-openpanel-ce-ligbox-reengineering/ |

---

## Ficheiros no repositório

```
deploy/vm123-finance-stack/
  patch-openpanel-ce-unlock.sh
  patch-foss-openpanel-domain.sh
  provision-openpanel-hosting.sh
  test-foss-openpanel-order.sh
  openpanel-community-bridge/bridge.py
  openpanel-community-bridge/bridge.env
  openpanel-community-bridge/openpanel-foss-bridge.service
  CREDENCIAIS_SERVICOS_VM123.txt
scripts/
  test-openpanel-multidomain-api.sh   # teste repetível Spec 028
specs/028-openpanel-ce-ligbox-reengineering/
  CONFIRMACAO-TESTE-API.md            # adendo teste Menu Infra + CLI
```

---

## Próximos passos (opcional)

- [ ] Hook Desk `company.validated` → FOSS order automático
- [x] Cron pós-update OpenPanel para reaplicar patch
- [x] Limpeza contas E2E (`test*`, `a*`)
- [x] Teste de confirmação API multidomínio — [CONFIRMACAO-TESTE-API.md](CONFIRMACAO-TESTE-API.md)
- [ ] Monitorização RAM/containers por N users
- [x] Documentar no portal Spec Hub VM130
- [x] Documentar DNS53 OpenPanel porta 53 — [DNS53_OPENPANEL_PORTA53.md](DNS53_OPENPANEL_PORTA53.md)
