Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d5540bf1d | ||
|
|
2d4b35c3ee | ||
|
|
f0fb00987a | ||
|
|
70a6d66e4d | ||
|
|
21c839b9b5 | ||
|
|
4f383490a3 | ||
|
|
a086c451c3 | ||
|
|
430431f2f6 | ||
|
|
0df175d9cb | ||
|
|
96eb0a6660 | ||
|
|
436b13ad3d | ||
|
|
a2645b5285 | ||
|
|
17b923ffdf | ||
|
|
50a3973662 | ||
|
|
a36ccbbd77 | ||
|
|
b9d3c10d01 | ||
|
|
00afd38a57 | ||
|
|
47b1ec0992 | ||
|
|
15406797a4 | ||
|
|
abe7afb9ab |
@@ -17,6 +17,8 @@ PROXMOX_TOKEN_VALUE=
|
||||
PROXMOX_ALLOW_ELEVATED=
|
||||
|
||||
# --- Cloudflare ---
|
||||
# Prefer CLOUDFLARE_API_TOKEN scoped to Zone:DNS:Edit on the zones you use (avoid global Account API key when possible).
|
||||
# Bulk DNS script: scripts/update-all-dns-to-public-ip.sh — use --dry-run and --zone-only=sankofa.nexus (etc.) before wide updates.
|
||||
CLOUDFLARE_API_TOKEN=
|
||||
CLOUDFLARE_EMAIL=
|
||||
CLOUDFLARE_API_KEY=
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,6 +16,9 @@ yarn.lock
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# NPMplus backups (backup-npmplus.sh — tarballs and extracted trees; may contain certs/DB)
|
||||
backups/npmplus/
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
36
AGENTS.md
Normal file
36
AGENTS.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Proxmox workspace — agent instructions
|
||||
|
||||
Single canonical copy for Cursor/Codex. (If your editor also loads `.cursor/rules`, treat those as overlays.)
|
||||
|
||||
## Scope
|
||||
|
||||
Orchestration for Proxmox VE, Chain 138 (`smom-dbis-138/`), explorers, NPMplus, and deployment runbooks.
|
||||
|
||||
## Quick pointers
|
||||
|
||||
| Need | Location |
|
||||
|------|-----------|
|
||||
| Doc index | `docs/MASTER_INDEX.md` |
|
||||
| cXAUC/cXAUT unit | 1 full token = 1 troy oz Au — `docs/11-references/EXPLORER_TOKEN_LIST_CROSSCHECK.md` (section 5.1) |
|
||||
| PMM mesh 6s tick | `smom-dbis-138/scripts/reserve/pmm-mesh-6s-automation.sh` — `docs/integration/ORACLE_AND_KEEPER_CHAIN138.md` (PMM mesh automation) |
|
||||
| VMID / IP / FQDN | `docs/04-configuration/ALL_VMIDS_ENDPOINTS.md` |
|
||||
| Ops template + JSON | `docs/03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md`, `config/proxmox-operational-template.json` |
|
||||
| Live vs template (read-only SSH) | `bash scripts/verify/audit-proxmox-operational-template.sh` |
|
||||
| Config validation | `bash scripts/validation/validate-config-files.sh` |
|
||||
| smom-dbis-138 `.env` in bash scripts | Prefer `source smom-dbis-138/scripts/lib/deployment/dotenv.sh` + `load_deployment_env --repo-root "$PROJECT_ROOT"` (trims RPC URL line endings). From an interactive shell: `source smom-dbis-138/scripts/load-env.sh`. Proxmox root scripts: `source scripts/lib/load-project-env.sh` (also trims common RPC vars). |
|
||||
| Sankofa portal → CT 7801 (build + restart) | `./scripts/deployment/sync-sankofa-portal-7801.sh` (`--dry-run` first); sets `NEXTAUTH_URL` on CT via `sankofa-portal-ensure-nextauth-on-ct.sh` |
|
||||
| CCIP relay (r630-01 host) | Unit: `config/systemd/ccip-relay.service` → `/etc/systemd/system/ccip-relay.service`; `systemctl enable --now ccip-relay` |
|
||||
| TsunamiSwap VM 5010 check | `./scripts/deployment/tsunamiswap-vm-5010-provision.sh` (inventory only until VM exists) |
|
||||
| The Order portal (`https://the-order.sankofa.nexus`) | OSJ management UI (secure auth); source repo **the_order** at `~/projects/the_order`. NPM upstream defaults to **order-haproxy** CT **10210** (`IP_ORDER_HAPROXY:80`); use `THE_ORDER_UPSTREAM_*` to point at the Sankofa portal if 10210 is down. Provision HAProxy: `scripts/deployment/provision-order-haproxy-10210.sh`. **`www.the-order.sankofa.nexus`** → **301** apex (same as www.sankofa / www.phoenix). |
|
||||
| Portal login + Keycloak systemd + `.env` (prints password once) | `./scripts/deployment/enable-sankofa-portal-login-7801.sh` (`--dry-run` first) |
|
||||
| Completable (no LAN) | `./scripts/run-completable-tasks-from-anywhere.sh` |
|
||||
| Operator (LAN + secrets) | `./scripts/run-all-operator-tasks-from-lan.sh` (use `--skip-backup` if `NPM_PASSWORD` unset) |
|
||||
| Cloudflare bulk DNS → `PUBLIC_IP` | `./scripts/update-all-dns-to-public-ip.sh` — use **`--dry-run`** and **`--zone-only=sankofa.nexus`** (or `d-bis.org` / `mim4u.org` / `defi-oracle.io`) to limit scope; see script header. Prefer scoped **`CLOUDFLARE_API_TOKEN`** (see `.env.master.example`). |
|
||||
|
||||
## Rules of engagement
|
||||
|
||||
- Review scripts before running; prefer `--dry-run` where supported.
|
||||
- Do not run the full operator flow when everything is healthy unless the user explicitly wants broad fixes (NPM/nginx/RPC churn).
|
||||
- Chain 138 deploy RPC: `http://192.168.11.211:8545` (Core). Read-only / non-deploy checks may use public RPC per project rules.
|
||||
|
||||
Full detail: see embedded workspace rules and `docs/00-meta/OPERATOR_READY_CHECKLIST.md`.
|
||||
Submodule ai-mcp-pmm-controller updated: b3eb9095fd...3e3f55fe79
Binary file not shown.
Binary file not shown.
27
config/haproxy/order-haproxy-10210.cfg.template
Normal file
27
config/haproxy/order-haproxy-10210.cfg.template
Normal file
@@ -0,0 +1,27 @@
|
||||
# HAProxy on VMID 10210 (order-haproxy @ 192.168.11.39).
|
||||
# NPMplus terminates TLS and forwards HTTP to :80 here; we proxy to the Sankofa/Order Next.js portal.
|
||||
# Deploy: scripts/deployment/provision-order-haproxy-10210.sh (substitutes __BACKEND_HOST__ / __BACKEND_PORT__).
|
||||
|
||||
global
|
||||
log stdout format raw local0
|
||||
maxconn 4096
|
||||
|
||||
defaults
|
||||
log global
|
||||
mode http
|
||||
option httplog
|
||||
option dontlognull
|
||||
option forwardfor
|
||||
timeout connect 10s
|
||||
timeout client 300s
|
||||
timeout server 300s
|
||||
timeout tunnel 3600s
|
||||
|
||||
frontend fe_http
|
||||
bind *:80
|
||||
# Client used HTTPS at NPM; help Next.js / auth callbacks
|
||||
http-request set-header X-Forwarded-Proto https if !{ hdr(X-Forwarded-Proto) -m found }
|
||||
default_backend be_portal
|
||||
|
||||
backend be_portal
|
||||
server portal __BACKEND_HOST__:__BACKEND_PORT__ check inter 10s fall 3 rise 2 maxconn 1000
|
||||
23
config/systemd/ccip-relay.service
Normal file
23
config/systemd/ccip-relay.service
Normal file
@@ -0,0 +1,23 @@
|
||||
# Install on Proxmox host (e.g. r630-01) where /opt/smom-dbis-138/services/relay exists:
|
||||
# sudo cp config/systemd/ccip-relay.service /etc/systemd/system/ccip-relay.service
|
||||
# sudo systemctl daemon-reload && sudo systemctl enable --now ccip-relay
|
||||
#
|
||||
# Uses start-relay.sh (loads parent .env and relay/.env.local).
|
||||
|
||||
[Unit]
|
||||
Description=CCIP relay service (Chain 138 to Mainnet)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/smom-dbis-138/services/relay
|
||||
ExecStart=/bin/bash /opt/smom-dbis-138/services/relay/start-relay.sh
|
||||
Restart=on-failure
|
||||
RestartSec=15
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Submodule cross-chain-pmm-lps updated: 9b511e5397...589ebaff86
Submodule dbis_core updated: e5d7a03236...1190476b0a
@@ -270,7 +270,7 @@
|
||||
| R18 | Ensure Blockscout (VMID 5000) is up and /api reachable | Health checks |
|
||||
| R19 | Run forge test before deploying; integration tests where available | Pre-deploy |
|
||||
| R20 | NatSpec on public contract functions | Code quality |
|
||||
| R21 | When The Order deployed: NPMplus proxy host; document in RPC_ENDPOINTS_MASTER | Sankofa/The Order go-live |
|
||||
| R21 | **Done 2026-03:** NPMplus Order via 10210; documented in RPC_ENDPOINTS_MASTER, ALL_VMIDS | Complete |
|
||||
| R22 | Document or configure blocks #2–#6 in NETWORK_ARCHITECTURE | When decided |
|
||||
| R23 | Scripts: progress indicators; --dry-run; config validation | Script updates |
|
||||
| R24 | Keep config/token-mapping.json as single source of truth for 138↔Mainnet | Adding tokens |
|
||||
@@ -299,8 +299,8 @@
|
||||
|
||||
| Item | Recommendation |
|
||||
|------|----------------|
|
||||
| the-order.sankofa.nexus | When The Order portal deployed: add NPMplus proxy host; document in RPC_ENDPOINTS_MASTER, ALL_VMIDS_ENDPOINTS |
|
||||
| Sankofa cutover plan | Replace <TARGET_IP>, <TARGET_PORT>, TBDs with actual IPs/ports when deployed |
|
||||
| the-order.sankofa.nexus | **Live:** NPM → `192.168.11.39:80` (10210 → portal :3000) |
|
||||
| Sankofa cutover plan | **Updated** v1.1 (2026-03-27); legacy API snippets may still use <TARGET_*> |
|
||||
| sankofa.nexus / phoenix routing | Ensure NPMplus proxy targets 192.168.11.51:3000 and 192.168.11.50:4000 per master docs; only explorer.d-bis.org → 192.168.11.140 |
|
||||
| Public blocks #2–#6 | Document in NETWORK_ARCHITECTURE / NETWORK_CONFIGURATION_MASTER when assigned or mark reserved |
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ Full operator actions: **[RECOMMENDATIONS_OPERATOR_CHECKLIST.md](RECOMMENDATIONS
|
||||
| R8–R11 | RPC_URL_138; GAS_PRICE on 138; phased deploy; nonce/tx stuck runbooks |
|
||||
| R12–R16 | Keep runbooks in sync; document addresses per chain; run verification after deploy; env per env |
|
||||
| R17–R20 | Monitor bridges; Blockscout up; forge test pre-deploy; NatSpec |
|
||||
| R21–R24 | The Order NPMplus; blocks #2–#6; script progress/dry-run/validation; token-mapping.json source of truth |
|
||||
| R21–R24 | **R21 done 2026-03** (Order NPM/10210); R22 blocks #2–#6; R23 script UX/validation; R24 token-mapping.json |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -96,9 +96,9 @@
|
||||
|
||||
| # | Action | When |
|
||||
|---|--------|------|
|
||||
| R21 | The Order / Sankofa NPMplus proxy host | When The Order portal deployed: add proxy; document in RPC_ENDPOINTS_MASTER, ALL_VMIDS_ENDPOINTS |
|
||||
| R21 | The Order / Sankofa NPMplus | **Done 2026-03** — Order → 10210 `.39:80`; see ALL_VMIDS, RPC_ENDPOINTS_MASTER |
|
||||
| R22 | Document or configure blocks #2–#6 in NETWORK_ARCHITECTURE | When decided |
|
||||
| Sankofa cutover | Replace <TARGET_IP>, <TARGET_PORT>, TBDs in SANKOFA_CUTOVER_PLAN | When deployed |
|
||||
| Sankofa cutover | **Done** — SANKOFA_CUTOVER_PLAN v1.1; fleet script `update-npmplus-proxy-hosts-api.sh` |
|
||||
| 75–81 | VLAN enablement, observability stack, CCIP fleet, sovereign tenants, missing containers | Per NEXT_STEPS_MASTER and deployment phases |
|
||||
|
||||
---
|
||||
|
||||
@@ -172,7 +172,7 @@ Dry-run deployments and cross-chain reconciliation.
|
||||
Source: NOT_CHANGED_BY_DESIGN.
|
||||
|
||||
**Configuration and DNS (R21–R22)**
|
||||
Sankofa alignment and configuration blocks 2–6.
|
||||
Sankofa zone NPM/docs **aligned (R21 done 2026-03)**; blocks #2–#6 still TBD.
|
||||
Source: ALL_REQUIREMENTS.
|
||||
|
||||
**Quick Wins (R23)**
|
||||
|
||||
@@ -119,7 +119,7 @@ flowchart TB
|
||||
Consolidated from [GAPS_AND_RECOMMENDATIONS_CONSOLIDATED.md](../GAPS_AND_RECOMMENDATIONS_CONSOLIDATED.md), [REQUIRED_FIXES_UPDATES_GAPS.md](../REQUIRED_FIXES_UPDATES_GAPS.md), [ALL_IMPROVEMENTS_AND_GAPS_INDEX.md](../ALL_IMPROVEMENTS_AND_GAPS_INDEX.md), and [NEXT_STEPS_MASTER.md](NEXT_STEPS_MASTER.md). Detailed tables stay in those docs; below are the resolution rules.
|
||||
|
||||
- **Secrets and API keys:** No real keys in `.env.example` (token-aggregation, root); use placeholders; document in [MASTER_SECRETS_INVENTORY.md](../04-configuration/MASTER_SECRETS_INVENTORY.md). Rotate any exposed keys.
|
||||
- **Config/DNS TBDs:** the-order.sankofa.nexus, Sankofa cutover plan `<TARGET_IP>`, RPC_ENDPOINTS_MASTER placeholders — **When The Order / Sankofa deployed, update NPMplus and docs; remove TBD.**
|
||||
- **Config/DNS (Sankofa zone):** **Done 2026-03** — the-order via **10210** `192.168.11.39:80`; cutover plan v1.1; RPC_ENDPOINTS_MASTER + ALL_VMIDS updated. Re-run `update-npmplus-proxy-hosts-api.sh` after infra changes. Legacy doc snippets may still show `<TARGET_IP>` in API examples.
|
||||
- **Network placeholders:** Public blocks #2–#6 in [NETWORK_ARCHITECTURE.md](../02-architecture/NETWORK_ARCHITECTURE.md) — **Document when assigned or mark reserved.**
|
||||
- **Code placeholders:** See Section 3.1 below (one-line resolution table).
|
||||
- **Documentation placeholders:** Emergency hotline and example URLs in dbis_core nostro-vostro — Done ("To be configured"). the-order REMAINING_TODOS.md — **Create or archive and fix links.**
|
||||
@@ -131,8 +131,8 @@ Consolidated from [GAPS_AND_RECOMMENDATIONS_CONSOLIDATED.md](../GAPS_AND_RECOMME
|
||||
| Item | Location | Resolution |
|
||||
|------|----------|------------|
|
||||
| API keys in .env.example | token-aggregation, root | Replace with placeholders; document in MASTER_SECRETS_INVENTORY; rotate if exposed. |
|
||||
| the-order.sankofa.nexus | RPC_ENDPOINTS_MASTER, ALL_VMIDS_ENDPOINTS | When The Order portal deployed: add NPMplus proxy host and document IP:port. |
|
||||
| Sankofa cutover plan TBDs | SANKOFA_CUTOVER_PLAN | Replace `<TARGET_IP>`, `<TARGET_PORT>` when Sankofa deployed. |
|
||||
| the-order.sankofa.nexus | RPC_ENDPOINTS_MASTER, ALL_VMIDS_ENDPOINTS | **Done:** NPM → 10210 `.39:80` → portal `:3000`. |
|
||||
| Sankofa cutover plan | SANKOFA_CUTOVER_PLAN | **Done v1.1** — live tables; substitute `<TARGET_*>` only if reusing old API curl templates. |
|
||||
| sankofa.nexus / phoenix routes | RPC_ENDPOINTS_MASTER | Keep in sync with NPMplus; remove "placeholder (routes to Blockscout)" when pointing to Sankofa/Phoenix. |
|
||||
| Public blocks #2–#6 | NETWORK_ARCHITECTURE, NETWORK_CONFIGURATION_MASTER | Document when assigned or mark reserved. |
|
||||
| AlltraAdapter fee | AlltraAdapter.sol | Implement configurable setBridgeFee; document in PLACEHOLDERS_AND_TBD. Update when ALL Mainnet fee known. |
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
| R18 | Explorer health: Blockscout VMID 5000, /api reachable | [ ] |
|
||||
| R19 | Test before deploy: forge test smom-dbis-138, alltra-lifi-settlement; integration tests | [x] |
|
||||
| R20 | NatSpec on public contract functions | [x] |
|
||||
| R21 | Sankofa/The Order: when deployed add NPMplus proxy; RPC_ENDPOINTS_MASTER, SANKOFA_CUTOVER_PLAN TBDs | [ ] |
|
||||
| R21 | Sankofa/The Order: NPMplus + docs (10210 HAProxy path) | [x] |
|
||||
| R22 | Network placeholders: blocks #2–#6 in NETWORK_ARCHITECTURE when assigned | [ ] |
|
||||
| R23 | Scripts: progress indicators; --dry-run where missing; extend config validation | [x] |
|
||||
|
||||
@@ -252,9 +252,9 @@
|
||||
|
||||
| Task | Status |
|
||||
|------|--------|
|
||||
| the-order.sankofa.nexus when portal deployed; NPMplus proxy + RPC_ENDPOINTS_MASTER | [ ] |
|
||||
| Sankofa cutover: replace TBDs in SANKOFA_CUTOVER_PLAN | [ ] |
|
||||
| NPMplus proxy: sankofa → 7801/.51:3000, phoenix → 7800/.50:4000; only explorer → .140 | [ ] |
|
||||
| the-order.sankofa.nexus; NPMplus + RPC_ENDPOINTS_MASTER | [x] |
|
||||
| Sankofa cutover: SANKOFA_CUTOVER_PLAN v1.1 | [x] |
|
||||
| NPMplus proxy: sankofa → .51:3000, phoenix → .50:4000, the-order → .39:80; only explorer → .140 | [x] |
|
||||
| Blocks #2–#6 in NETWORK_ARCHITECTURE when assigned | [ ] |
|
||||
|
||||
### smom-dbis-138 (GAPS §3)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
| Area | Deliverables |
|
||||
|------|--------------|
|
||||
| **Sankofa / The Order** | Checklist: replace <TARGET_IP>/<TARGET_PORT>; update ALL_VMIDS_ENDPOINTS, RPC_ENDPOINTS_MASTER; NPMplus proxy for the-order.sankofa.nexus; "where to update when done" (PLACEHOLDERS_AND_TBD, REMAINING_COMPONENTS). See [SANKOFA_THE_ORDER_CHECKLIST](../04-configuration/SANKOFA_THE_ORDER_CHECKLIST.md) or SANKOFA_CUTOVER_PLAN. |
|
||||
| **Sankofa / The Order** | **Routing done 2026-03** (NPM, ALL_VMIDS, RPC_ENDPOINTS_MASTER, SANKOFA_CUTOVER_PLAN v1.1, [SANKOFA_THE_ORDER_CHECKLIST](../04-configuration/SANKOFA_THE_ORDER_CHECKLIST.md)). This row retained for design-scope doc; implementation of app features (OMNIS SDK, legal vendors, etc.) remains separate. |
|
||||
| **OMNIS — Sankofa Phoenix SDK** | Integration spec: required SDK interface (getAuthUrl, validateToken, getUserInfo), env vars, fallback. See [OMNIS_SANKOFA_PHOENIX_SDK_INTEGRATION_SPEC](../04-configuration/OMNIS_SANKOFA_PHOENIX_SDK_INTEGRATION_SPEC.md). Dependency note in PLACEHOLDERS_AND_TBD / PLACEHOLDERS_AND_COMPLETION_MASTER_LIST: "Blocked on Sankofa Phoenix SDK availability." |
|
||||
| **the-order — legal-documents** | Vendor/implementation matrix (court-efiling, e-signature, document-security): Option, Prerequisites, Steps, "Where to update when done." See [LEGAL_DOCUMENTS_IMPLEMENTATION](LEGAL_DOCUMENTS_IMPLEMENTATION.md). Update GAPS_AND_RECOMMENDATIONS_CONSOLIDATED, PLACEHOLDERS_AND_COMPLETION_MASTER_LIST when done. |
|
||||
| **dbis_core** | Runbook or comment "When to implement": Prometheus when monitoring stack is up; Redis when caching needed. See [DBIS_CORE_WHEN_TO_IMPLEMENT](DBIS_CORE_WHEN_TO_IMPLEMENT.md). No new code; doc/checklist only. |
|
||||
|
||||
@@ -39,8 +39,8 @@ Use this checklist when you have operator or LAN access to complete the remainin
|
||||
|
||||
| # | Action | Notes |
|
||||
|---|--------|-------|
|
||||
| R21 | The Order / Sankofa NPMplus proxy host | When The Order portal deployed: add proxy in NPMplus; document in RPC_ENDPOINTS_MASTER, ALL_VMIDS_ENDPOINTS |
|
||||
| Sankofa cutover | Replace <TARGET_IP>, <TARGET_PORT>, TBDs in SANKOFA_CUTOVER_PLAN with actual values |
|
||||
| R21 | The Order / Sankofa NPMplus | **Done 2026-03** — see ALL_VMIDS, RPC_ENDPOINTS_MASTER, `update-npmplus-proxy-hosts-api.sh` |
|
||||
| Sankofa cutover | **Done** — SANKOFA_CUTOVER_PLAN v1.1 |
|
||||
| Blocks #2–#6 | Document in NETWORK_ARCHITECTURE / NETWORK_CONFIGURATION_MASTER when assigned or mark reserved |
|
||||
| 75–81 | VLAN enablement, observability stack, CCIP fleet, sovereign tenants, missing containers | Per NEXT_STEPS_MASTER and deployment phases |
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Operator Ready Checklist — Copy-Paste Commands
|
||||
|
||||
**Last Updated:** 2026-03-04
|
||||
**Last Updated:** 2026-03-27
|
||||
**Purpose:** Single page with exact commands to complete every pending todo. Run from **repo root** on a host with **LAN** access (and `smom-dbis-138/.env` with `PRIVATE_KEY`, `NPM_PASSWORD` where noted).
|
||||
|
||||
**Do you have all necessary creds?** See [OPERATOR_CREDENTIALS_CHECKLIST.md](OPERATOR_CREDENTIALS_CHECKLIST.md) — per-task list of LAN, PRIVATE_KEY, NPM_PASSWORD, RPC_URL_138, SSH, LINK, gas, token balance.
|
||||
@@ -15,6 +15,22 @@
|
||||
|
||||
---
|
||||
|
||||
## Completed in this session (2026-03-26)
|
||||
|
||||
| Item | Result |
|
||||
|------|--------|
|
||||
| NPMplus recovery | VMID `10233` was wedged on `192.168.11.167:81` (TCP connect, no HTTP). `pct reboot 10233` on `r630-01` restored the expected `301` response on port `81`. |
|
||||
| NPMplus API updater | `NPM_URL=https://192.168.11.167:81 bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh` completed with **39 hosts updated, 0 failed**. |
|
||||
| Sankofa / Order / Studio routing | **Superseded 2026-03-27:** Order hostnames default to **order-haproxy** `http://192.168.11.39:80` (10210 → `.51:3000`). Through 2026-03-26 NPM pointed Order directly at portal `:3000`. `studio.sankofa.nexus` → `http://192.168.11.72:8000`. |
|
||||
| Public E2E | Latest run `bash scripts/verify/verify-end-to-end-routing.sh --profile=public` exited `0` with **Failed: 0**, **DNS passed: 37**, **HTTPS passed: 22**. Sankofa, Phoenix, Studio, The Order, DBIS, Mifos, and MIM4U public endpoints passed. Evidence: `docs/04-configuration/verification-evidence/e2e-verification-20260326_115013/`. |
|
||||
| Private E2E | Latest run `bash scripts/verify/verify-end-to-end-routing.sh --profile=private` exited `0` with **Failed: 0** and **DNS passed: 4**. `rpc-http-prv.d-bis.org`, `rpc-fireblocks.d-bis.org`, `rpc-ws-prv.d-bis.org`, and `ws.rpc-fireblocks.d-bis.org` all passed. Evidence: `docs/04-configuration/verification-evidence/e2e-verification-20260326_120939/`. |
|
||||
| NPMplus backup | Fresh backup completed: `backups/npmplus/backup-20260326_115622.tar.gz`. API exports succeeded; direct SQLite file copy and certbot path copy were partial/warn-only, but the backup manifest and compressed bundle were created successfully. |
|
||||
| Blockscout verification run | `./scripts/verify/run-contract-verification-with-proxy.sh` completed; contracts were submitted or skipped if already verified. `WETH10` returned `The address is not a smart contract`; others like `Multicall`, `Aggregator`, `Proxy`, `CCIPSender`, `CCIPWETH10Bridge`, and `CCIPWETH9Bridge` submitted successfully. |
|
||||
| Private RPC redirect fix | `rpc-http-prv.d-bis.org` no longer returns HTTP `301` on JSON-RPC POST. Live NPMplus host `11` was updated to `ssl_forced=false` while preserving upstream `192.168.11.211:8545`. |
|
||||
| NPM creds loading | For NPM-only runs, prefer targeted `grep` of `NPM_EMAIL` / `NPM_PASSWORD` if full `.env` export triggers `Argument list too long`. |
|
||||
|
||||
---
|
||||
|
||||
## 1. High: Cronos closure + reachable CCIP funding
|
||||
|
||||
**Ref:** [CONFIG_READY_CHAINS_COMPLETION_RUNBOOK](../07-ccip/CONFIG_READY_CHAINS_COMPLETION_RUNBOOK.md)
|
||||
@@ -84,6 +100,8 @@ Single contract retry: `./scripts/verify/run-contract-verification-with-proxy.sh
|
||||
|
||||
**Runbook:** [502_DEEP_DIVE_ROOT_CAUSES_AND_FIXES.md](502_DEEP_DIVE_ROOT_CAUSES_AND_FIXES.md)
|
||||
|
||||
**Current status after 2026-03-26:** no public 502s reproduced in the latest public E2E run. Use this section only if those endpoints regress.
|
||||
|
||||
---
|
||||
|
||||
## 5. LAN: Run all operator tasks (backup + verify ± deploy ± create-vms)
|
||||
@@ -211,8 +229,14 @@ bash scripts/verify/backup-npmplus.sh
|
||||
|
||||
**NPMplus RPC fix (405):** From LAN: `bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`. Verify: `bash scripts/verify/verify-end-to-end-routing.sh`.
|
||||
|
||||
**Status (2026-03-26):** main NPMplus API update completed successfully with `39 hosts updated, 0 failed`; public E2E now passes for Sankofa root, Phoenix, Studio, and The Order. Re-run only when upstream targets or proxy definitions change.
|
||||
|
||||
**Latest backup evidence:** `backups/npmplus/backup-20260326_115622.tar.gz`
|
||||
|
||||
**NPMplus API unreachable (167/169):** Restart Docker inside NPMplus LXC: `./scripts/maintenance/fix-npmplus-services-via-proxmox-ssh.sh` (SSH to r630-01, restarts npmplus in 10233 and 10235).
|
||||
|
||||
**If port 81 accepts TCP but hangs at HTTP:** reboot CT `10233` with `pct reboot 10233` on `r630-01`, then retry the API updater.
|
||||
|
||||
**E2E from LAN (no public DNS):** If E2E fails at DNS (`Could not resolve host`), use [E2E_DNS_FROM_LAN_RUNBOOK.md](../04-configuration/E2E_DNS_FROM_LAN_RUNBOOK.md): append `config/e2e-hosts-append.txt` to `/etc/hosts`, then run `E2E_USE_SYSTEM_RESOLVER=1 ./scripts/verify/verify-end-to-end-routing.sh --profile=public`. Revert with `sudo ./scripts/verify/remove-e2e-hosts-from-etc-hosts.sh`.
|
||||
|
||||
**E2E profiles:** Use `--profile=public` for public endpoints (default) or `--profile=private` for private/admin RPC only. Run sequentially to avoid timestamp collision in evidence dirs. **Known E2E warnings** (502/404 and WS): [E2E_ENDPOINTS_LIST.md](../04-configuration/E2E_ENDPOINTS_LIST.md) § Known E2E warnings and Remediation. MIM4U web 502s and WS test-format warnings are **non-blocking** for contract/pool completion.
|
||||
@@ -221,6 +245,25 @@ bash scripts/verify/backup-npmplus.sh
|
||||
|
||||
---
|
||||
|
||||
## 8.5 PMM mesh (6s oracle / keeper / PMM–WETH poll)
|
||||
|
||||
**Ref:** `smom-dbis-138/docs/integration/ORACLE_AND_KEEPER_CHAIN138.md` (PMM mesh automation)
|
||||
|
||||
```bash
|
||||
cd smom-dbis-138
|
||||
# .env should include: PRIVATE_KEY, AGGREGATOR_ADDRESS, PRICE_FEED_KEEPER_ADDRESS (optional: KEEPER_PRIVATE_KEY if different from PRIVATE_KEY)
|
||||
./scripts/reserve/set-price-feed-keeper-interval.sh 6 # once per keeper deployment if interval was 30s
|
||||
./scripts/update-oracle-price.sh # verify transmitter + gas (Besu needs explicit gas limit in script)
|
||||
./scripts/reserve/sync-weth-mock-price.sh # if CHAIN138_WETH_MOCK_PRICE_FEED is set (keeper WETH path)
|
||||
mkdir -p logs
|
||||
nohup ./scripts/reserve/pmm-mesh-6s-automation.sh >> logs/pmm-mesh-automation.log 2>&1 &
|
||||
# journalctl equivalent: tail -f logs/pmm-mesh-automation.log
|
||||
```
|
||||
|
||||
**systemd:** `config/systemd/chain138-pmm-mesh-automation.service.example` — copy, set `User` and absolute paths, `enable --now`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Wemix token verification (Deferred)
|
||||
|
||||
This is intentionally deferred with the rest of the Wemix path. If the chain is brought back into scope later, open [scan.wemix.com/tokens](https://scan.wemix.com/tokens); confirm WETH, USDT, USDC addresses. If different, update `config/token-mapping-multichain.json` and [WEMIX_TOKEN_VERIFICATION.md](../07-ccip/WEMIX_TOKEN_VERIFICATION.md). Then:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Placeholders and What Needs to Be Completed — Master List
|
||||
|
||||
**Last Updated:** 2026-02-13
|
||||
**Last Updated:** 2026-03-27
|
||||
**Purpose:** Single list of every placeholder and what must be completed (code, config, docs, ops).
|
||||
|
||||
**Completion pass (2026-02-13):** OMNIS backend routes (POST/PUT budgets, POST documents/upload, PATCH profile) done; authController token blacklisting (in-memory + TOKEN_BLACKLIST_ENABLED); TezosRelayService Taquito skeleton + mock gated; Smart accounts .env.example + runbook; dbis_core Redis stub, Prometheus/risk comments, deal-execution tests skipped with ticket; CCIPLogger decision (omit unless monitoring); .bak listed and deprecated in BAK_FILES_DEPRECATION; deployment gaps (env table, TransactionMirror script, DEPLOYMENT_GAPS_COMPLETED); NPMplus HA and storage monitor already have ALERT_EMAIL/ALERT_WEBHOOK; deploy.sh TODO comments for migration/health; the-order legal-documents vendor integration README; root .gitignore (venv, __pycache__, .phase1).
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
| Placeholder | Location | What to complete |
|
||||
|-------------|----------|------------------|
|
||||
| **the-order.sankofa.nexus** | [ALL_VMIDS_ENDPOINTS](../04-configuration/ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER](../04-configuration/RPC_ENDPOINTS_MASTER.md) | When The Order portal is deployed: add NPMplus proxy host and document IP:port in RPC_ENDPOINTS_MASTER and ALL_VMIDS_ENDPOINTS. |
|
||||
| **Sankofa cutover plan** | [SANKOFA_CUTOVER_PLAN](../04-configuration/SANKOFA_CUTOVER_PLAN.md) | Replace `<TARGET_IP>`, `<TARGET_PORT>`, and table TBDs with actual Sankofa service IPs/ports when deployed. |
|
||||
| **the-order.sankofa.nexus** | [ALL_VMIDS_ENDPOINTS](../04-configuration/ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER](../04-configuration/RPC_ENDPOINTS_MASTER.md) | **Done 2026-03-27:** NPM → 10210 `192.168.11.39:80` (HAProxy → portal :3000). Keep docs in sync if routing changes. |
|
||||
| **Sankofa cutover plan** | [SANKOFA_CUTOVER_PLAN](../04-configuration/SANKOFA_CUTOVER_PLAN.md) | **Done 2026-03-27:** v1.1 lists live backends (incl. The Order via 10210). Legacy API examples may still contain `<TARGET_*>` placeholders—substitute real values if you reuse them. |
|
||||
| **sankofa.nexus / phoenix.sankofa.nexus** | [ALL_VMIDS_ENDPOINTS](../04-configuration/ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER](../04-configuration/RPC_ENDPOINTS_MASTER.md), [DNS_NPMPLUS_VM](../04-configuration/DNS_NPMPLUS_VM_COMPREHENSIVE_ARCHITECTURE.md) | **Doc fix done:** Correct targets: sankofa → 192.168.11.51:3000 (VMID 7801), phoenix → 192.168.11.50:4000 (VMID 7800). **Operator:** Ensure NPMplus proxy hosts use these, not 192.168.11.140. Only explorer.d-bis.org → .140. |
|
||||
| **Public blocks #2–#6** | [NETWORK_ARCHITECTURE](../02-architecture/NETWORK_ARCHITECTURE.md), [NETWORK_CONFIGURATION_MASTER](../11-references/NETWORK_CONFIGURATION_MASTER.md) | Document when blocks are assigned or mark as “reserved”. |
|
||||
| **PROXMOX_HOST / PROXMOX_TOKEN_SECRET** | smom-dbis-138-proxmox/README.md | Keep as `proxmox.example.com`, `your-token-secret`; document in deployment guide. |
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
| # | Action | When |
|
||||
|---|--------|------|
|
||||
| R21 | When The Order is deployed: NPMplus proxy host; document in RPC_ENDPOINTS_MASTER and ALL_VMIDS_ENDPOINTS; replace SANKOFA_CUTOVER_PLAN TBDs | Sankofa/The Order go-live |
|
||||
| R21 | **Done 2026-03:** NPMplus + ALL_VMIDS + RPC_ENDPOINTS_MASTER + SANKOFA_CUTOVER_PLAN v1.1 | Complete |
|
||||
| R22 | Document or configure blocks #2–#6 in NETWORK_ARCHITECTURE and NETWORK_CONFIGURATION_MASTER (or mark reserved); see NETWORK_PLACEHOLDERS_DECISION | When decided |
|
||||
|
||||
## Quick wins (R23)
|
||||
|
||||
@@ -166,7 +166,7 @@ See **Part 2** and [GAPS_AND_RECOMMENDATIONS_CONSOLIDATED](../GAPS_AND_RECOMMEND
|
||||
|
||||
| # | Recommendation | Action |
|
||||
|---|----------------|--------|
|
||||
| R21 | **Sankofa / The Order** | When The Order portal is deployed, add NPMplus proxy host and document in RPC_ENDPOINTS_MASTER and ALL_VMIDS_ENDPOINTS; replace SANKOFA_CUTOVER_PLAN TBDs with actual IPs/ports. |
|
||||
| R21 | **Sankofa / The Order** | **Done 2026-03:** NPMplus + docs (ALL_VMIDS, RPC_ENDPOINTS_MASTER, SANKOFA_CUTOVER_PLAN v1.1). HAProxy: `provision-order-haproxy-10210.sh`. |
|
||||
| R22 | **Network placeholders** | Document or configure blocks #2–#6 in NETWORK_ARCHITECTURE and NETWORK_CONFIGURATION_MASTER when assigned. |
|
||||
|
||||
### 2.9 Quick wins (code)
|
||||
|
||||
@@ -108,13 +108,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 2. Sankofa cutover (missing TBDs)
|
||||
## 2. Sankofa cutover (**documented — 2026-03**)
|
||||
|
||||
| | Detail |
|
||||
|---|--------|
|
||||
| **Needed** | For each Sankofa domain: target VMID, target IP, target port, service type. |
|
||||
| **Missing** | **the-order.sankofa.nexus:** VMID, IP, port, service type still **TBD** in [SANKOFA_CUTOVER_PLAN.md](../04-configuration/SANKOFA_CUTOVER_PLAN.md). Other four domains have values (e.g. 7801/192.168.11.51/3000 for sankofa.nexus). |
|
||||
| **Where to get** | Deploy The Order portal; assign VMID and IP; document in SANKOFA_CUTOVER_PLAN.md table; then run cutover steps (replace proxy backends in NPMplus). |
|
||||
| **Status** | Live backends in [SANKOFA_CUTOVER_PLAN.md](../04-configuration/SANKOFA_CUTOVER_PLAN.md) v1.1, [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER.md](../04-configuration/RPC_ENDPOINTS_MASTER.md). The Order: NPM → **10210** `192.168.11.39:80` → portal **192.168.11.51:3000**. |
|
||||
| **Ongoing** | If IPs/VMIDs change, run `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh` and update the master docs. |
|
||||
|
||||
---
|
||||
|
||||
@@ -227,8 +226,8 @@
|
||||
- Run `address-all-remaining-502s.sh --run-besu-fix --e2e` from LAN.
|
||||
- Run Blockscout verification script.
|
||||
|
||||
4. **Fill TBDs**
|
||||
- Sankofa: set the-order.sankofa.nexus target (VMID, IP, port) in SANKOFA_CUTOVER_PLAN.md.
|
||||
4. **Sankofa / Order**
|
||||
- **Done:** targets documented; refresh NPM with `update-npmplus-proxy-hosts-api.sh` after infra changes.
|
||||
- CCIP: collect per-chain addresses (CCIP directory) and fund deployer wallets for Gnosis/Celo/Wemix.
|
||||
|
||||
5. **dbis_core**
|
||||
|
||||
@@ -78,11 +78,11 @@
|
||||
|
||||
| Question | Answer |
|
||||
|----------|--------|
|
||||
| **What is it?** | Sankofa and The Order services deployed; DNS and NPMplus point to real IPs/ports; replace TBDs in docs. |
|
||||
| **Prerequisites** | Sankofa and The Order deployed; IPs and ports known (e.g. sankofa 192.168.11.51:3000 VMID 7801, phoenix 192.168.11.50:4000 VMID 7800 — already in docs). |
|
||||
| **Who** | Ops when services are live. |
|
||||
| **Steps to complete** | 1. Deploy Sankofa/The Order per your deployment process. 2. In [SANKOFA_CUTOVER_PLAN](../04-configuration/SANKOFA_CUTOVER_PLAN.md): replace `<TARGET_IP>`, `<TARGET_PORT>`, table TBDs with actual IPs/ports. 3. In NPMplus: ensure proxy hosts for sankofa.nexus and phoenix.sankofa.nexus point to 192.168.11.51:3000 and 192.168.11.50:4000 (not .140). 4. When The Order portal is deployed: add NPMplus proxy for the-order.sankofa.nexus; document in [RPC_ENDPOINTS_MASTER](../04-configuration/RPC_ENDPOINTS_MASTER.md) and [ALL_VMIDS_ENDPOINTS](../04-configuration/ALL_VMIDS_ENDPOINTS.md). |
|
||||
| **Where to update when done** | [PLACEHOLDERS](PLACEHOLDERS_AND_COMPLETION_MASTER_LIST.md) §2; [GAPS](../GAPS_AND_RECOMMENDATIONS_CONSOLIDATED.md) §2.1–2.2; [REMAINING](REMAINING_COMPONENTS_TASKS_AND_RECOMMENDATIONS.md) R21. |
|
||||
| **What is it?** | Sankofa zone on production backends; NPMplus and master docs aligned (incl. The Order via **10210** HAProxy). |
|
||||
| **Prerequisites** | LAN + `NPM_PASSWORD` for fleet updater; portal 7801 and Phoenix 7800 healthy. |
|
||||
| **Who** | Ops for NPM refresh after any VM/IP change. |
|
||||
| **Steps to complete** | **Done 2026-03:** See [SANKOFA_CUTOVER_PLAN](../04-configuration/SANKOFA_CUTOVER_PLAN.md) v1.1. Maintain with `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`. Bypass Order HAProxy if needed: `THE_ORDER_UPSTREAM_IP=192.168.11.51 THE_ORDER_UPSTREAM_PORT=3000`. |
|
||||
| **Where to update when done** | [PLACEHOLDERS](PLACEHOLDERS_AND_COMPLETION_MASTER_LIST.md) §2; [GAPS](../GAPS_AND_RECOMMENDATIONS_CONSOLIDATED.md) §2.1–2.2; R21 marked **done** in [REMAINING_COMPONENTS](REMAINING_COMPONENTS_TASKS_AND_RECOMMENDATIONS.md). |
|
||||
|
||||
---
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
| Trust official | Open PR to trustwallet/wallet-core with registry entry (coinId 10000138, chainId 138); run codegen/tests. |
|
||||
| CoinGecko/CMC | Submit chain + tokens via CoinGecko (and CMC) process; use COINGECKO_SUBMISSION_GUIDE and token docs. |
|
||||
| Consensys | Use CONSENSYS_OUTREACH_PACKAGE; contact Consensys for Swaps/Bridge support for 138. |
|
||||
| Sankofa cutover | When deployed: replace TBDs in SANKOFA_CUTOVER_PLAN; set NPMplus proxies to .51/.50; add the-order when live. |
|
||||
| Sankofa cutover | **Done:** v1.1 cutover plan + NPM; Order via .39:80 (10210). Re-run updater after changes. |
|
||||
| Blockscout verify | From LAN: `source smom-dbis-138/.env; ./scripts/verify/run-contract-verification-with-proxy.sh`. |
|
||||
| Multicall vs Oracle | Check explorer for 0x99b35...; document which contract it is in CONTRACT_ADDRESSES_REFERENCE. |
|
||||
| AlltraAdapter fee | After deploy: call `setBridgeFee(fee_wei)`; set ALLTRA_BRIDGE_FEE in .env; document in PLACEHOLDERS_AND_TBD. |
|
||||
|
||||
143
docs/03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md
Normal file
143
docs/03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Proxmox VE — Operational deployment template
|
||||
|
||||
**Last Updated:** 2026-03-25
|
||||
**Status:** Active — ties hypervisors, LAN/WAN, cluster peering, Chain 138 Besu tiers, NPMplus ingress, FQDNs, and deployment gates into one place.
|
||||
|
||||
**Machine-readable:** [`config/proxmox-operational-template.json`](../../config/proxmox-operational-template.json) (sync when you change VMIDs/IPs/FQDNs).
|
||||
|
||||
**Authoritative detail (do not drift):**
|
||||
|
||||
- VMID, port, status tables: [`docs/04-configuration/ALL_VMIDS_ENDPOINTS.md`](../04-configuration/ALL_VMIDS_ENDPOINTS.md)
|
||||
- Shell/env single source: [`config/ip-addresses.conf`](../../config/ip-addresses.conf)
|
||||
- Edge, port forwards, four NPMplus picture: [`docs/11-references/NETWORK_CONFIGURATION_MASTER.md`](../11-references/NETWORK_CONFIGURATION_MASTER.md)
|
||||
- Contract deploy order / gates: [`docs/03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md`](DEPLOYMENT_ORDER_OF_OPERATIONS.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Proxmox VE hosts (management)
|
||||
|
||||
| Hostname | MGMT IP | Proxmox UI | Cluster | Role (target) |
|
||||
|----------|---------|------------|---------|----------------|
|
||||
| ml110 | 192.168.11.10 | https://192.168.11.10:8006 | h (legacy) | Planned WAN aggregator (OPNsense/pfSense); **migrate CT/VM off before repurpose** |
|
||||
| r630-01 | 192.168.11.11 | https://192.168.11.11:8006 | h | Primary: Chain 138 RPC/CCIP-adjacent workloads, Sankofa Phoenix stack, much of DBIS |
|
||||
| r630-02 | 192.168.11.12 | https://192.168.11.12:8006 | h | Firefly, MIM4U, Mifos LXC, extra NPMplus instances, supporting infra |
|
||||
|
||||
**LAN:** 192.168.11.0/24, gateway **192.168.11.1** (UDM Pro), VLAN 11. Extended node IP plan (r630-03 …): `config/ip-addresses.conf` comments.
|
||||
|
||||
---
|
||||
|
||||
## 2. Cluster peering (Corosync / quorum)
|
||||
|
||||
| Item | Value / note |
|
||||
|------|----------------|
|
||||
| Cluster name | **h** (verify live: `pvecm status`) |
|
||||
| Ring | Typically same L2/L3 as MGMT — **192.168.11.0/24** |
|
||||
| UDP ports | **5405–5412** between all nodes (+ SSH 22, API **8006** TCP) |
|
||||
| Quorum | Odd node count preferred; during ml110 removal use 2-node awareness (risk window) or add qdevice |
|
||||
|
||||
Cluster and UDM: [`docs/04-configuration/UDM_PRO_PROXMOX_CLUSTER.md`](../04-configuration/UDM_PRO_PROXMOX_CLUSTER.md). **Live inventory:** [`docs/04-configuration/ALL_VMIDS_ENDPOINTS.md`](../04-configuration/ALL_VMIDS_ENDPOINTS.md), [`config/proxmox-operational-template.json`](../../config/proxmox-operational-template.json).
|
||||
|
||||
---
|
||||
|
||||
## 3. Chain 138 Besu — peering model (summary)
|
||||
|
||||
| Layer | VMID range (typical) | IPv4 pattern | P2P |
|
||||
|--------|----------------------|--------------|-----|
|
||||
| Validators | 1000–1004 | 192.168.11.100–104 | 30303 — **to sentries**, not raw public |
|
||||
| Sentries | 1500–1506 | .150–.154, .213–.214 | Boundary / fan-out |
|
||||
| Core RPC (deploy) | 2101 | **192.168.11.211** | 8545/8546 + 30303 |
|
||||
| Core RPC (Nathan core-2) | 2102 | **192.168.11.212** | NPMplus **10235** / tunnel |
|
||||
| Public RPC | 2201 | **192.168.11.221** | Frontends / bridge / read-mostly |
|
||||
| Named RPC | 2303–2308 | .233–.238 | Partner-dedicated |
|
||||
| ThirdWeb stack | 2400–2403 | .240–.243 | Includes translator/nginx on 2400 |
|
||||
|
||||
Canonical roles and adjacency rules: [`docs/02-architecture/CHAIN138_CANONICAL_NETWORK_ROLES_VALIDATORS_SENTRY_AND_RPC.md`](../02-architecture/CHAIN138_CANONICAL_NETWORK_ROLES_VALIDATORS_SENTRY_AND_RPC.md).
|
||||
|
||||
---
|
||||
|
||||
## 4. NPMplus and public ingress
|
||||
|
||||
| VMID | Internal IP(s) | Public IP (typical) | Purpose |
|
||||
|------|----------------|---------------------|---------|
|
||||
| 10233 | 192.168.11.166 / **.167** | 76.53.10.36 | Main d-bis.org, explorer, Option B RPC, MIM4U |
|
||||
| 10234 | 192.168.11.168 | 76.53.10.37 | Secondary HA (confirm running) |
|
||||
| 10235 | 192.168.11.169 | 76.53.10.38 (alt **76.53.10.42**) | rpc-core-2, Alltra, HYBX |
|
||||
| 10236 | 192.168.11.170 | 76.53.10.40 | Dev / Codespaces tunnel, Gitea, Proxmox admin |
|
||||
| 10237 | 192.168.11.171 | (tunnel/Mifos) | mifos.d-bis.org → VMID 5800 |
|
||||
|
||||
UDM Pro forwards **80 / 443** (and **81** where documented) to the matching internal IP. Detail: [`docs/04-configuration/NPMPLUS_FOUR_INSTANCES_MASTER.md`](../04-configuration/NPMPLUS_FOUR_INSTANCES_MASTER.md).
|
||||
|
||||
---
|
||||
|
||||
## 5. FQDN → backend (high level)
|
||||
|
||||
Use the full table in **ALL_VMIDS_ENDPOINTS** (“NPMplus Endpoint Configuration Reference”). Critical correctness checks:
|
||||
|
||||
- **explorer.d-bis.org** → VMID **5000**, **192.168.11.140** (not Sankofa IPs).
|
||||
- **sankofa.nexus** / **phoenix.sankofa.nexus** → VMID **7801** / **7800** at **.51:3000** / **.50:4000**.
|
||||
- **rpc-http-prv / rpc-ws-prv** → **2101** (.211); **rpc-http-pub / rpc-ws-pub** → **2201** (.221).
|
||||
- **rpc.public-0138.defi-oracle.io** → **2400** **192.168.11.240:443** (update NPM if still pointing at decommissioned IPs).
|
||||
|
||||
**the-order.sankofa.nexus:** NPMplus → order HAProxy **10210** @ **192.168.11.39:80** (proxies to Sankofa portal **192.168.11.51:3000**). See `scripts/deployment/provision-order-haproxy-10210.sh`.
|
||||
|
||||
### 5.1 Order stack (live VMIDs, r630-01 unless noted)
|
||||
|
||||
| VMID | Hostname | IP | Role (short) |
|
||||
|------|----------|-----|----------------|
|
||||
| 10030 | order-identity | 192.168.11.40 | Identity |
|
||||
| 10040 | order-intake | 192.168.11.41 | Intake |
|
||||
| 10050 | order-finance | 192.168.11.49 | Finance |
|
||||
| 10060 | order-dataroom | 192.168.11.42 | Dataroom |
|
||||
| 10070 | order-legal | **192.168.11.87** | Legal — **moved off .54 2026-03-25** (`IP_ORDER_LEGAL`); .54 is **only** VMID 7804 gov-portals |
|
||||
| 10080 | order-eresidency | 192.168.11.43 | eResidency |
|
||||
| 10090 | order-portal-public | 192.168.11.36 | Public portal |
|
||||
| 10091 | order-portal-internal | 192.168.11.35 | Internal portal |
|
||||
| 10092 | order-mcp-legal | 192.168.11.37 | MCP legal |
|
||||
| 10200 | order-prometheus | 192.168.11.46 | Metrics |
|
||||
| 10201 | order-grafana | 192.168.11.47 | Dashboards |
|
||||
| 10202 | order-opensearch | 192.168.11.48 | Search |
|
||||
| 10210 | order-haproxy | 192.168.11.39 | Edge / HAProxy |
|
||||
|
||||
**Redis:** `ORDER_REDIS_IP` = 192.168.11.38 in `ip-addresses.conf` — bind to live VMID via `pct list` / audit script.
|
||||
|
||||
---
|
||||
|
||||
## 6. Deployment requirements (cross-domain)
|
||||
|
||||
### 6.1 Platform (Proxmox / network)
|
||||
|
||||
- [ ] All cluster nodes **quorate**; storage sufficient for CT/VM disks (local-lvm / future Ceph per master plan).
|
||||
- [ ] **vmbr0** VLAN-aware; each workload IP **unique** on 192.168.11.0/24 (see ALL_VMIDS conflict section).
|
||||
- [ ] UDM Pro routes and port-forwards match **NETWORK_CONFIGURATION_MASTER**.
|
||||
- [ ] NPMplus proxy host rows match **ALL_VMIDS** (no Blockscout IP on Sankofa hostnames).
|
||||
|
||||
### 6.2 Chain 138 (contracts / ops)
|
||||
|
||||
- [ ] **Core RPC** 2101 reachable: `http://192.168.11.211:8545` for **deploy only** (not public RPC).
|
||||
- [ ] `smom-dbis-138/.env`: `PRIVATE_KEY`, `RPC_URL_138`, nonce discipline — **DEPLOYMENT_ORDER_OF_OPERATIONS** Phase 0.
|
||||
- [ ] Optional: `./scripts/deployment/preflight-chain138-deploy.sh` before any broadcast.
|
||||
|
||||
### 6.3 Application / operator
|
||||
|
||||
- [ ] Repo **`.env`** + **`smom-dbis-138/.env`** for operator scripts (`scripts/lib/load-project-env.sh`).
|
||||
- [ ] Blockscout / verify / NPM backup scripts per **OPERATOR_READY_CHECKLIST** when doing release ops.
|
||||
|
||||
---
|
||||
|
||||
## 7. Maintaining this template
|
||||
|
||||
1. Change **ALL_VMIDS_ENDPOINTS** and/or **ip-addresses.conf** first (operator truth).
|
||||
2. Update **`config/proxmox-operational-template.json`** so automation (future CMDB, checks) stays aligned.
|
||||
3. Run **`./scripts/validation/validate-config-files.sh`** (includes JSON shape check for the template).
|
||||
4. **Live diff (read-only, SSH):** from repo root on a host with SSH to Proxmox nodes: **`bash scripts/verify/audit-proxmox-operational-template.sh`**. Compares template VMIDs to `pct`/`qm` lists on ML110 + R630s (override **`PROXMOX_HOSTS`** if needed).
|
||||
|
||||
---
|
||||
|
||||
## 8. Related runbooks
|
||||
|
||||
| Topic | Doc |
|
||||
|-------|-----|
|
||||
| Operational runbooks index | [`OPERATIONAL_RUNBOOKS.md`](OPERATIONAL_RUNBOOKS.md) |
|
||||
| Phoenix / Sankofa deploy | [`PHOENIX_DEPLOYMENT_RUNBOOK.md`](PHOENIX_DEPLOYMENT_RUNBOOK.md) |
|
||||
| NPMplus health | [`docs/04-configuration/NPMPLUS_QUICK_REF.md`](../04-configuration/NPMPLUS_QUICK_REF.md) |
|
||||
| 13-node / HA roadmap | [`docs/02-architecture/R630_13_NODE_DOD_HA_MASTER_PLAN.md`](../02-architecture/R630_13_NODE_DOD_HA_MASTER_PLAN.md) |
|
||||
117
docs/03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md
Normal file
117
docs/03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Public sector live deployment checklist (Complete Credential, SMOA, Phoenix)
|
||||
|
||||
**Last updated:** 2026-03-23
|
||||
**Related:** [PUBLIC_SECTOR_TENANCY_MARKETPLACE_AND_DEPLOYMENT_BASELINE.md](../02-architecture/PUBLIC_SECTOR_TENANCY_MARKETPLACE_AND_DEPLOYMENT_BASELINE.md), [COMPLETE_CREDENTIAL_EIDAS_PROGRAM_REPOS.md](../11-references/COMPLETE_CREDENTIAL_EIDAS_PROGRAM_REPOS.md), [DEPLOY_CONFIRM_AND_FULL_E2E_RUNBOOK.md](../00-meta/DEPLOY_CONFIRM_AND_FULL_E2E_RUNBOOK.md), [`config/public-sector-program-manifest.json`](../../config/public-sector-program-manifest.json)
|
||||
|
||||
This checklist tracks **proxmox-repo automation** and **sibling repos** (`../complete-credential`, `../smoa`). Rows marked **Done (session)** were executed from an operator host with LAN access unless noted.
|
||||
|
||||
---
|
||||
|
||||
## Execution log (2026-03-23)
|
||||
|
||||
| Action | Result |
|
||||
|--------|--------|
|
||||
| Sankofa `api` + `portal` (workstation) | API: `websocket.ts` imports `logger`; GraphQL/schema fixes under `api/src`. Portal: Apollo + dashboard GraphQL, UI primitives, **`root: true`** `.eslintrc.json` with **`@typescript-eslint` + strict `no-explicit-any` / `no-console` / a11y / `import/order`** (optional hardening: lib clients typed with `unknown`, form `htmlFor`/`id`, escaped entities). **`pnpm exec tsc --noEmit`** + **`pnpm build`** clean. **Deploy:** sync `portal/` (+ lockfile) to CT **7801**, `pnpm install && pnpm build`, restart `sankofa-portal`; sync **7800** API if needed |
|
||||
|
||||
## Execution log (2026-03-26)
|
||||
|
||||
| Action | Result |
|
||||
|--------|--------|
|
||||
| `./scripts/run-all-operator-tasks-from-lan.sh` (live, no `--dry-run`) | Exit 0 (~36 min); W0-1 NPMplus RPC/proxy host updates; W0-3 live NPMplus backup; Blockscout verification step ran |
|
||||
| NPMplus update script | Some hosts logged duplicate-create then PUT recovery; `rpc.tw-core.d-bis.org` and `*.tw-core.d-bis.org` showed repeated failures — **review those rows in NPM UI** if traffic depends on them |
|
||||
| `scripts/maintenance/diagnose-vm-health-via-proxmox-ssh.sh` | Completed: Phoenix CTs **7800–7803** running on r630-01; NPMplus **10233** up; port 81 check OK |
|
||||
| `scripts/maintenance/npmplus-verify-port81.sh` | **Restored** in repo; loopback :81 returns HTTP 301 (redirect) — treated as reachable |
|
||||
| `pct exec 7800` / `7801`: `ss -tlnp` | **As of 2026-03-26 session:** no listeners. **As of 2026-03-23 follow-up:** **7800** API can reach `active` + `/health` on **:4000** when `sankofa-api` is deployed; **7801** portal needs **current** portal tree + successful **`pnpm build`** on the CT (see 2026-03-23 log row above) |
|
||||
| `pct exec 7802` Keycloak | `http://127.0.0.1:8080/` → **200**; `/health/ready` → 404 (version may use different health path) |
|
||||
| `./scripts/run-completable-tasks-from-anywhere.sh` | Exit 0 |
|
||||
| `E2E_ACCEPT_502_INTERNAL=1 ./scripts/verify/verify-end-to-end-routing.sh` | 0 failed; report `docs/04-configuration/verification-evidence/e2e-verification-20260325_182512/` |
|
||||
| `./scripts/verify/run-contract-verification-with-proxy.sh` | Exit 0 |
|
||||
| `complete-credential` Phase 1 compose + `run-phase1-synthetic.sh` | OK (operator console 8087 = 200) |
|
||||
| `../smoa`: `./gradlew :app:assembleDebug` | BUILD SUCCESSFUL; APK: `smoa/app/build/outputs/apk/debug/app-debug.apk` |
|
||||
|
||||
---
|
||||
|
||||
## Execution log (2026-03-25)
|
||||
|
||||
| Action | Result |
|
||||
|--------|--------|
|
||||
| RPC `192.168.11.221:8545` / `192.168.11.211:8545` | HTTP 201 |
|
||||
| SSH `root@192.168.11.10` / `.11` | OK (BatchMode) |
|
||||
| `./scripts/run-completable-tasks-from-anywhere.sh` | Exit 0 |
|
||||
| `./scripts/verify/check-contracts-on-chain-138.sh` | 59/59 present |
|
||||
| `E2E_ACCEPT_502_INTERNAL=1 ./scripts/verify/verify-end-to-end-routing.sh` | 37 domains, 0 failed; report under `docs/04-configuration/verification-evidence/e2e-verification-20260325_165153/` |
|
||||
| `https://phoenix.sankofa.nexus/`, `https://sankofa.nexus/` | HTTP 200 |
|
||||
| `http://192.168.11.50:4000/health`, `:51:3000`, `:52:8080/health/ready` | No HTTP response from operator host (hosts ping; services may be down, firewalled, or not bound) — **re-check on Proxmox / in-container** |
|
||||
| `./scripts/verify/backup-npmplus.sh --dry-run` | OK |
|
||||
| `./scripts/verify/run-contract-verification-with-proxy.sh` | Exit 0 |
|
||||
| `./scripts/run-all-operator-tasks-from-lan.sh --dry-run` | Printed wave0 + verify sequence |
|
||||
| `cd smom-dbis-138 && forge test --match-path 'test/e2e/*.sol'` | Exit 0 |
|
||||
| `cd ../smoa && ./gradlew smoaVerify --no-daemon` | Exit 0 |
|
||||
| `complete-credential`: `git submodule status` | Submodules present on commits |
|
||||
| `docker compose -f integration/docker-compose.phase1.yml config` | Valid |
|
||||
| `docker compose -f integration/docker-compose.phase1.yml up -d` | All Phase 1 containers up |
|
||||
| Rebuild + recreate `cc-operator-console`; `./integration/run-phase1-synthetic.sh` | OK |
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
| ID | Task | Status |
|
||||
|----|------|--------|
|
||||
| A1 | LAN / VPN; Proxmox SSH | Done (session) |
|
||||
| A2 | Root `.env` + `smom-dbis-138/.env` for operator | Operator to confirm secrets present |
|
||||
| A3 | `config/public-sector-program-manifest.json` valid | Done (completable) |
|
||||
| B1 | NPMplus proxy + TLS for public FQDNs | **Done (2026-03-26)** — `run-wave0-from-lan.sh` / update script applied; spot-check `rpc.tw-core` / `*.tw-core` in NPM if needed |
|
||||
| B2 | `scripts/verify/backup-npmplus.sh` (live) | **Done (2026-03-26)** — W0-3 as part of `run-all-operator-tasks-from-lan.sh` |
|
||||
| B3 | `scripts/maintenance/npmplus-verify-port81.sh` | **Done** — script restored; SSH `pct exec 10233` loopback :81 |
|
||||
| C1 | Phoenix stack VMIDs 7800–7803 per `SERVICE_DESCRIPTIONS.md` | **7802 Keycloak:** HTTP 200 on `/` inside CT. **7800 API:** deploy/restart `sankofa-api` — expect listener **:4000**. **7801 portal:** deploy latest portal artifact (see 2026-03-23 log) — expect **:3000** |
|
||||
| C2 | Keycloak realms: admin / tenant / org-unit RBAC | Product + IdP work — not automated here |
|
||||
| C3 | Phoenix API + portal wired; GraphQL `/graphql`, `/health` | **API:** curl `http://192.168.11.50:4000/health` (and `/graphql` as needed). **Portal:** after **7801** build, curl `http://192.168.11.51:3000/` |
|
||||
| C4 | Service catalog SKUs + entitlements (billing optional) | Product — see tenancy baseline G2 |
|
||||
| D1 | SMOA LXC per `smoa/backend/docs/LXC-PROXMOX-CONTAINERS.md` | Deploy on Proxmox |
|
||||
| D2 | SMOA API behind NPM | After D1 |
|
||||
| D3 | Release APK + download URL or MDM | **Debug APK built (2026-03-26):** `../smoa/app/build/outputs/apk/debug/app-debug.apk` — publish via CI signed release + NPM/static URL or MDM |
|
||||
| D4 | Device E2E against prod API | After D2–D3 |
|
||||
| E1 | `complete-credential` submodules initialized | Done (session) |
|
||||
| E2 | Phase 1 Docker stack local/CI | Done (session) — not yet Proxmox production |
|
||||
| E3 | `./integration/run-phase1-synthetic.sh` after console rebuild | Done (session) |
|
||||
| E4 | Production slice / dedicated LXC for `cc-*` | Architecture choice (profile A/B/C) |
|
||||
| F1 | Chain 138 on-chain contract check | Done (session) |
|
||||
| F2 | Blockscout verification | Done (session) |
|
||||
| F3 | Public E2E routing | Done (session, 502-tolerant flag) |
|
||||
| G1 | Logs, metrics, DB backups for Phoenix + SMOA + CC DBs | Operational runbooks |
|
||||
| G2 | Incident ownership per stack | Process |
|
||||
|
||||
---
|
||||
|
||||
## Quick commands (repo root unless noted)
|
||||
|
||||
```bash
|
||||
./scripts/run-completable-tasks-from-anywhere.sh
|
||||
source scripts/lib/load-project-env.sh && ./scripts/verify/check-contracts-on-chain-138.sh
|
||||
E2E_ACCEPT_502_INTERNAL=1 ./scripts/verify/verify-end-to-end-routing.sh
|
||||
./scripts/verify/run-contract-verification-with-proxy.sh
|
||||
./scripts/verify/backup-npmplus.sh --dry-run # then run without --dry-run
|
||||
```
|
||||
|
||||
**Complete Credential (sibling clone):**
|
||||
|
||||
```bash
|
||||
cd ../complete-credential
|
||||
docker compose -f integration/docker-compose.phase1.yml up -d --build
|
||||
./integration/run-phase1-synthetic.sh
|
||||
```
|
||||
|
||||
**SMOA:**
|
||||
|
||||
```bash
|
||||
cd ../smoa && ./gradlew smoaVerify --no-daemon
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Follow-ups
|
||||
|
||||
1. **Phoenix LAN services:** From a host on the same L2 as `192.168.11.50–53`, curl `/health` and portal port **3000**; if down, start CTs/VMs on Proxmox and confirm process listeners.
|
||||
2. **Operator full wave:** `./scripts/run-all-operator-tasks-from-lan.sh` only when NPM RPC fix + backup + verify are intentionally desired (mutates NPM).
|
||||
3. **Production Complete Credential:** Move from laptop Docker to **dedicated LXC** and NPM routes per deployment profile.
|
||||
@@ -1,9 +1,11 @@
|
||||
# Complete VMID and Endpoints Reference
|
||||
|
||||
**Last Updated:** 2026-02-12
|
||||
**Last Updated:** 2026-03-26
|
||||
**Document Version:** 1.2
|
||||
**Status:** Active Documentation — **Master (source of truth)** for VMID, IP, port, and domain mapping. See [MASTER_DOCUMENTATION_INDEX.md](../00-meta/MASTER_DOCUMENTATION_INDEX.md).
|
||||
|
||||
**Operational template (hosts, peering, deployment gates, JSON):** [../03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md](../03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md) · [`config/proxmox-operational-template.json`](../../config/proxmox-operational-template.json)
|
||||
|
||||
---
|
||||
|
||||
**Date**: 2026-01-20
|
||||
@@ -46,6 +48,8 @@
|
||||
|
||||
**Note**: NPMplus primary is on VLAN 11 (192.168.11.167). Secondary NPMplus instance on r630-02 for HA configuration.
|
||||
|
||||
**Operational note (2026-03-26):** if `192.168.11.167:81` accepts TCP but hangs without returning HTTP, CT `10233` may be wedged even when networking looks healthy. Rebooting it from `r630-01` with `pct reboot 10233` restored the expected `301` on port `81` and unblocked the API updater.
|
||||
|
||||
---
|
||||
|
||||
## RPC Translator Supporting Services
|
||||
@@ -198,7 +202,7 @@ The following VMIDs have been permanently removed:
|
||||
|------|------------|----------|--------|-----------|---------|
|
||||
| 10100 | 192.168.11.105 | dbis-postgres-primary | ✅ Running | PostgreSQL: 5432 | Primary database |
|
||||
| 10101 | 192.168.11.106 | dbis-postgres-replica-1 | ✅ Running | PostgreSQL: 5432 | Database replica |
|
||||
| 10120 | 192.168.11.120 | dbis-redis | ✅ Running | Redis: 6379 | Cache layer |
|
||||
| 10120 | 192.168.11.125 | dbis-redis | ✅ Running | Redis: 6379 | Cache layer |
|
||||
| 10130 | 192.168.11.130 | dbis-frontend | ✅ Running | Web: 80, 443 | Frontend admin console |
|
||||
| 10150 | 192.168.11.155 | dbis-api-primary | ✅ Running | API: 3000 | Primary API server |
|
||||
| 10151 | 192.168.11.156 | dbis-api-secondary | ✅ Running | API: 3000 | Secondary API server |
|
||||
@@ -245,12 +249,14 @@ The following VMIDs have been permanently removed:
|
||||
|
||||
**Public Domains** (NPMplus routing):
|
||||
- `sankofa.nexus` → Routes to `http://192.168.11.51:3000` (Sankofa Portal/VMID 7801) ✅
|
||||
- `www.sankofa.nexus` → Routes to `http://192.168.11.51:3000` (Sankofa Portal/VMID 7801) ✅
|
||||
- `www.sankofa.nexus` → Same upstream as apex; NPM **`advanced_config`** issues **301** to **`https://sankofa.nexus`** (preserve path/query via `$request_uri`). ✅
|
||||
- `phoenix.sankofa.nexus` → Routes to `http://192.168.11.50:4000` (Phoenix API/VMID 7800) ✅
|
||||
- `www.phoenix.sankofa.nexus` → Routes to `http://192.168.11.50:4000` (Phoenix API/VMID 7800) ✅
|
||||
- `the-order.sankofa.nexus` → ⚠️ **TBD** (not yet configured)
|
||||
- `www.phoenix.sankofa.nexus` → Same upstream; **301** to **`https://phoenix.sankofa.nexus`**. ✅
|
||||
- `the-order.sankofa.nexus` / `www.the-order.sankofa.nexus` → OSJ management portal (secure auth). App source: **the_order** at `~/projects/the_order`. NPMplus default upstream: **order-haproxy** `http://192.168.11.39:80` (VMID **10210**), which proxies to Sankofa portal `http://192.168.11.51:3000` (7801). Fallback: set `THE_ORDER_UPSTREAM_IP` / `THE_ORDER_UPSTREAM_PORT` to `.51` / `3000` if HAProxy is offline. **`www.the-order.sankofa.nexus`** → **301** **`https://the-order.sankofa.nexus`** (same as `www.sankofa` / `www.phoenix`).
|
||||
- `studio.sankofa.nexus` → Routes to `http://192.168.11.72:8000` (Sankofa Studio / VMID 7805)
|
||||
|
||||
**Public verification evidence (2026-03-26):** `bash scripts/verify/verify-end-to-end-routing.sh --profile=public` passed with `Failed: 0`; Sankofa root, Phoenix, Studio, and The Order returned `200`. See [verification_report.md](verification-evidence/e2e-verification-20260326_100057/verification_report.md).
|
||||
|
||||
**Service Details:**
|
||||
- **Host:** r630-01 (192.168.11.11)
|
||||
- **Network:** VLAN 11 (192.168.11.0/24)
|
||||
@@ -261,6 +267,28 @@ The following VMIDs have been permanently removed:
|
||||
|
||||
---
|
||||
|
||||
### The Order — microservices (r630-01)
|
||||
|
||||
| VMID | IP Address | Hostname | Status | Endpoints | Purpose |
|
||||
|------|------------|----------|--------|-----------|---------|
|
||||
| 10030 | 192.168.11.40 | order-identity | ✅ Running | API | Identity |
|
||||
| 10040 | 192.168.11.41 | order-intake | ✅ Running | API | Intake |
|
||||
| 10050 | 192.168.11.49 | order-finance | ✅ Running | API | Finance |
|
||||
| 10060 | 192.168.11.42 | order-dataroom | ✅ Running | Web: 80 | Dataroom |
|
||||
| 10070 | **192.168.11.87** | order-legal | ✅ Running | API | Legal — **use `IP_ORDER_LEGAL` (.87); not .54** |
|
||||
| 10080 | 192.168.11.43 | order-eresidency | ✅ Running | API | eResidency |
|
||||
| 10090 | 192.168.11.36 | order-portal-public | ✅ Running | Web | Public portal |
|
||||
| 10091 | 192.168.11.35 | order-portal-internal | ✅ Running | Web | Internal portal |
|
||||
| 10092 | 192.168.11.37 | order-mcp-legal | ✅ Running | API | MCP legal |
|
||||
| 10200 | 192.168.11.46 | order-prometheus | ✅ Running | 9090 | Metrics (`IP_ORDER_PROMETHEUS`; not Order Redis) |
|
||||
| 10201 | 192.168.11.47 | order-grafana | ✅ Running | 3000 | Dashboards |
|
||||
| 10202 | 192.168.11.48 | order-opensearch | ✅ Running | 9200 | Search |
|
||||
| 10210 | 192.168.11.39 | order-haproxy | ✅ Running | 80 (HAProxy → portal :3000) | Edge for **the-order.sankofa.nexus**; HAProxy config via `config/haproxy/order-haproxy-10210.cfg.template` + `scripts/deployment/provision-order-haproxy-10210.sh` |
|
||||
|
||||
**Gov portals vs Order:** VMID **7804** alone uses **192.168.11.54** (`IP_GOV_PORTALS_DEV`). Order-legal must not use .54.
|
||||
|
||||
---
|
||||
|
||||
### Phoenix Vault Cluster (8640-8642)
|
||||
|
||||
| VMID | IP Address | Hostname | Status | Endpoints | Purpose |
|
||||
@@ -368,7 +396,7 @@ Direct to RPC Nodes:
|
||||
|
||||
1. **192.168.11.50**: ✅ **RESOLVED**
|
||||
- VMID 7800 (sankofa-api-1): 192.168.11.50 ✅ **UNIQUE**
|
||||
- VMID 10070 (order-legal): Reassigned to 192.168.11.54 ✅
|
||||
- VMID 10070 (order-legal): **192.168.11.87** (`IP_ORDER_LEGAL`) — moved off .54 2026-03-25 (ARP conflict with VMID 7804 gov-portals) ✅
|
||||
|
||||
2. **192.168.11.51**: ✅ **RESOLVED**
|
||||
- VMID 7801 (sankofa-portal-1): 192.168.11.51 ✅ **UNIQUE**
|
||||
@@ -384,7 +412,7 @@ Direct to RPC Nodes:
|
||||
|
||||
**Verification:** ✅ All IPs verified unique, all services operational
|
||||
|
||||
**Documentation:** See `docs/archive/root-status-reports/IP_CONFLICT_RESOLUTION_COMPLETE.md` for historical details.
|
||||
**IP conflicts (canonical):** [reports/status/IP_CONFLICTS_RESOLUTION_COMPLETE.md](../../reports/status/IP_CONFLICTS_RESOLUTION_COMPLETE.md); CCIP range move: [reports/status/IP_CONFLICTS_CCIP_RANGE_RESOLVED_20260201.md](../../reports/status/IP_CONFLICTS_CCIP_RANGE_RESOLVED_20260201.md). **Script:** `scripts/resolve-ip-conflicts.sh` (uses `config/ip-addresses.conf`).
|
||||
|
||||
---
|
||||
|
||||
@@ -481,7 +509,7 @@ This section lists all endpoints that should be configured in NPMplus, extracted
|
||||
| `www.sankofa.nexus` | `192.168.11.51` | `http` | `3000` | ❌ No | Sankofa Portal (VMID 7801) ✅ **Deployed** |
|
||||
| `phoenix.sankofa.nexus` | `192.168.11.50` | `http` | `4000` | ❌ No | Phoenix API - Cloud Platform Portal (VMID 7800) ✅ **Deployed** |
|
||||
| `www.phoenix.sankofa.nexus` | `192.168.11.50` | `http` | `4000` | ❌ No | Phoenix API (VMID 7800) ✅ **Deployed** |
|
||||
| `the-order.sankofa.nexus` | ⚠️ **TBD** | `http` | `TBD` | ❌ No | The Order Portal - ⚠️ **Not yet configured** |
|
||||
| `the-order.sankofa.nexus`, `www.the-order.sankofa.nexus` | `192.168.11.39` (10210 HAProxy; default) or `192.168.11.51` (direct portal if env override) | `http` | `80` or `3000` | ❌ No | NPM → **.39:80** by default; HAProxy → **.51:3000** |
|
||||
| `studio.sankofa.nexus` | `192.168.11.72` | `http` | `8000` | ❌ No | Sankofa Studio (FusionAI Creator) — VMID 7805 |
|
||||
|
||||
### Path-Based Routing Notes
|
||||
@@ -509,7 +537,7 @@ Some domains use path-based routing in NPM configs:
|
||||
| `explorer.d-bis.org` | 5000, 192.168.11.140:80 (web), :4000 (API) | — |
|
||||
| `sankofa.nexus`, `www.sankofa.nexus` | 7801, 192.168.11.51:3000 | 192.168.11.140 (Blockscout) |
|
||||
| `phoenix.sankofa.nexus`, `www.phoenix.sankofa.nexus` | 7800, 192.168.11.50:4000 | 192.168.11.140 (Blockscout) |
|
||||
| `the-order.sankofa.nexus` | TBD (when The Order portal is deployed) | 192.168.11.140 (Blockscout) |
|
||||
| `the-order.sankofa.nexus`, `www.the-order.sankofa.nexus` | 10210, 192.168.11.39:80 | 192.168.11.140 (Blockscout) |
|
||||
| `studio.sankofa.nexus` | 7805, 192.168.11.72:8000 | — |
|
||||
|
||||
If NPMplus proxy hosts for sankofa.nexus or phoenix.sankofa.nexus currently point to 192.168.11.140, update them to the correct IP:port above. See [RPC_ENDPOINTS_MASTER.md](RPC_ENDPOINTS_MASTER.md) and table "Sankofa Phoenix Services" in this document.
|
||||
@@ -518,7 +546,7 @@ If NPMplus proxy hosts for sankofa.nexus or phoenix.sankofa.nexus currently poin
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-01-18
|
||||
**Last Updated**: 2026-03-27
|
||||
**Maintained By**: Infrastructure Team
|
||||
|
||||
---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# DNS → NPMplus → VM Comprehensive Architecture Table
|
||||
|
||||
**Last Updated:** 2026-01-31
|
||||
**Document Version:** 1.0
|
||||
**Last Updated:** 2026-03-27
|
||||
**Document Version:** 1.1
|
||||
**Status:** Active Documentation
|
||||
|
||||
---
|
||||
@@ -62,7 +62,7 @@ Backend VMs (Various IPs) - Services with/without Nginx
|
||||
| `www.sankofa.nexus` | A | 76.53.10.36 | DNS Only | 64 | 22 | `192.168.11.51:3000` | 7801 | 192.168.11.51 | sankofa-portal-1 | r630-01 | Sankofa Portal | ❌ No | 3000 | HTTP → 3000 |
|
||||
| `phoenix.sankofa.nexus` | A | 76.53.10.36 | DNS Only | 51 | 23 | `192.168.11.50:4000` | 7800 | 192.168.11.50 | sankofa-api-1 | r630-01 | Phoenix API | ❌ No | 4000 | HTTP → 4000 |
|
||||
| `www.phoenix.sankofa.nexus` | A | 76.53.10.36 | DNS Only | 63 | 24 | `192.168.11.50:4000` | 7800 | 192.168.11.50 | sankofa-api-1 | r630-01 | Phoenix API | ❌ No | 4000 | HTTP → 4000 |
|
||||
| `the-order.sankofa.nexus` | A | 76.53.10.36 | DNS Only | 60 | 25 | ⚠️ TBD | TBD | TBD | — | — | The Order Portal | — | — | ⚠️ Configure when deployed |
|
||||
| `the-order.sankofa.nexus` | A | 76.53.10.36 | DNS Only | 60 | 25 | `192.168.11.39:80` | 10210 | 192.168.11.39 | order-haproxy | r630-01 | The Order (HAProxy→portal) | ❌ No | 80 | HTTP → 80 → `.51:3000` |
|
||||
| **defi-oracle.io Zone** |
|
||||
| `rpc.public-0138.defi-oracle.io` | A | 76.53.10.36 | DNS Only | 56 | 26 | `192.168.11.240:443` | 2400 | 192.168.11.240 | thirdweb-rpc-1 | ml110 | ThirdWeb RPC | ✅ Yes | 443 | HTTPS → 443 |
|
||||
|
||||
@@ -291,7 +291,7 @@ nginx on VMID 2400 (192.168.11.240:443):
|
||||
|--------|------------------|---------------------|
|
||||
| `sankofa.nexus`, `www.sankofa.nexus` | 192.168.11.51:3000 (VMID 7801) | 192.168.11.140 |
|
||||
| `phoenix.sankofa.nexus`, `www.phoenix.sankofa.nexus` | 192.168.11.50:4000 (VMID 7800) | 192.168.11.140 |
|
||||
| `the-order.sankofa.nexus` | TBD when The Order portal is deployed | 192.168.11.140 |
|
||||
| `the-order.sankofa.nexus`, `www.the-order.sankofa.nexus` | 192.168.11.39:80 (10210 HAProxy → .51:3000); www → 301 apex | 192.168.11.140 |
|
||||
|
||||
**Action:** If any Sankofa/Phoenix proxy host in NPMplus points to 192.168.11.140 (Blockscout), update it to the correct IP:port above. Only `explorer.d-bis.org` should point to 192.168.11.140.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# DNS → NPMplus → VM Streamlined Architecture Table
|
||||
|
||||
**Last Updated:** 2026-01-31
|
||||
**Document Version:** 1.0
|
||||
**Last Updated:** 2026-03-27
|
||||
**Document Version:** 1.1
|
||||
**Status:** Active Documentation
|
||||
|
||||
---
|
||||
@@ -59,17 +59,17 @@ Backend VMs (Various IPs) - Services with/without Nginx
|
||||
| `secure.mim4u.org` | 59 | 19 | 7810 (mim-web-1) | 192.168.11.37 | 80 | ✅ Yes | MIM4U Secure Portal |
|
||||
| `training.mim4u.org` | 61 | 20 | 7810 (mim-web-1) | 192.168.11.37 | 80 | ✅ Yes | MIM4U Training Portal |
|
||||
|
||||
### sankofa.nexus Zone (5 Domains) ⚠️
|
||||
### sankofa.nexus zone (live backends)
|
||||
|
||||
| Domain | SSL Cert | NPMplus Proxy | Backend VM | IP | Port | Has Nginx | Service Type | Status |
|
||||
|--------|----------|---------------|------------|----|----|-----------|--------------|--------|
|
||||
| `sankofa.nexus` | 57 | 21 | ⚠️ TBD | 192.168.11.140 ⚠️ | 80 ⚠️ | ⚠️ TBD | Sankofa Main Portal | ⚠️ Not Deployed |
|
||||
| `www.sankofa.nexus` | 64 | 22 | ⚠️ TBD | 192.168.11.140 ⚠️ | 80 ⚠️ | ⚠️ TBD | Sankofa Main Portal | ⚠️ Not Deployed |
|
||||
| `phoenix.sankofa.nexus` | 51 | 23 | ⚠️ TBD | 192.168.11.140 ⚠️ | 80 ⚠️ | ⚠️ TBD | Phoenix Site | ⚠️ Not Deployed |
|
||||
| `www.phoenix.sankofa.nexus` | 63 | 24 | ⚠️ TBD | 192.168.11.140 ⚠️ | 80 ⚠️ | ⚠️ TBD | Phoenix Site | ⚠️ Not Deployed |
|
||||
| `the-order.sankofa.nexus` | 60 | 25 | ⚠️ TBD | 192.168.11.140 ⚠️ | 80 ⚠️ | ⚠️ TBD | The Order Portal | ⚠️ Not Deployed |
|
||||
| Domain | SSL Cert (ex.) | NPMplus Proxy (ex.) | Backend VM | IP | Port | Has Nginx | Service type | Status |
|
||||
|--------|------------------|---------------------|------------|----|------|-----------|--------------|--------|
|
||||
| `sankofa.nexus` | 57 | 21 | 7801 | 192.168.11.51 | 3000 | ❌ No | Sankofa portal | ✅ Live |
|
||||
| `www.sankofa.nexus` | 64 | 22 | 7801 | 192.168.11.51 | 3000 | ❌ No | Sankofa portal (301 apex) | ✅ Live |
|
||||
| `phoenix.sankofa.nexus` | 51 | 23 | 7800 | 192.168.11.50 | 4000 | ❌ No | Phoenix API | ✅ Live |
|
||||
| `www.phoenix.sankofa.nexus` | 63 | 24 | 7800 | 192.168.11.50 | 4000 | ❌ No | Phoenix API (301 apex) | ✅ Live |
|
||||
| `the-order.sankofa.nexus` | 60 | 25 | 10210 | 192.168.11.39 | 80 | ❌ No | Order via HAProxy→portal | ✅ Live |
|
||||
|
||||
**⚠️ Note**: All Sankofa domains currently route to Blockscout (192.168.11.140) but services are NOT deployed. This is incorrect routing and needs to be fixed once services are deployed.
|
||||
**Note:** SSL cert and NPM proxy **IDs** differ per installation—verify in NPM UI. **IPs/ports** are authoritative vs Blockscout (`.140` is only for `explorer.d-bis.org`). See [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md).
|
||||
|
||||
### defi-oracle.io Zone (3 Domains)
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
**Run E2E (public profile recommended):** `./scripts/verify/verify-end-to-end-routing.sh --profile=public` (from LAN with DNS or use `E2E_USE_SYSTEM_RESOLVER=1` and `/etc/hosts` per [E2E_DNS_FROM_LAN_RUNBOOK.md](E2E_DNS_FROM_LAN_RUNBOOK.md)).
|
||||
**Run E2E (private/admin):** `./scripts/verify/verify-end-to-end-routing.sh --profile=private`.
|
||||
|
||||
**Latest verified public pass:** `2026-03-27` via `bash scripts/verify/verify-end-to-end-routing.sh --profile=public` with report at [verification_report.md](verification-evidence/e2e-verification-20260327_134032/verification_report.md). Result: exit `0`, `DNS passed: 38`, `Failed: 0`, `HTTPS passed: 19`, `Skipped / optional: 1` (after `run-all-operator-tasks-from-lan.sh` NPM sync; `rpc.defi-oracle.io` may log HTTP 405 on the verifier probe but stays non-failing for the profile).
|
||||
**Latest verified private/admin pass:** `2026-03-27` via `bash scripts/verify/verify-end-to-end-routing.sh --profile=private` with report at [verification_report.md](verification-evidence/e2e-verification-20260327_134137/verification_report.md). Result: exit `0`, `DNS passed: 4`, `Failed: 0`.
|
||||
|
||||
**Evidence folders:** Each run creates `verification-evidence/e2e-verification-YYYYMMDD_HHMMSS/`. Commit the runs you want on record; older dirs can be removed locally to reduce noise (`scripts/maintenance/prune-e2e-verification-evidence.sh --dry-run` lists candidates). Routing truth is **not** inferred from old reports—use [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md).
|
||||
|
||||
## Verification profiles
|
||||
|
||||
- **Public profile (default for routine E2E):** web, api, public RPC endpoints.
|
||||
@@ -25,10 +30,11 @@
|
||||
| secure.mim4u.org | web | https://secure.mim4u.org | MIM4U secure portal. |
|
||||
| training.mim4u.org | web | https://training.mim4u.org | MIM4U training site. |
|
||||
| sankofa.nexus | web | https://sankofa.nexus | Sankofa Nexus root / web. |
|
||||
| www.sankofa.nexus | web | https://www.sankofa.nexus | Sankofa Nexus www. |
|
||||
| phoenix.sankofa.nexus | web | https://phoenix.sankofa.nexus | Phoenix (Sankofa) web app. |
|
||||
| www.phoenix.sankofa.nexus | web | https://www.phoenix.sankofa.nexus | Phoenix www. |
|
||||
| the-order.sankofa.nexus | web | https://the-order.sankofa.nexus | Hosted client on the Sankofa Phoenix cloud services platform. |
|
||||
| www.sankofa.nexus | web | https://www.sankofa.nexus | **301** to `https://sankofa.nexus` (canonical apex; NPM `advanced_config`). |
|
||||
| phoenix.sankofa.nexus | web | https://phoenix.sankofa.nexus | Phoenix API (7800); E2E uses `/health` for HTTPS check. |
|
||||
| www.phoenix.sankofa.nexus | web | https://www.phoenix.sankofa.nexus | **301** to `https://phoenix.sankofa.nexus` (canonical apex; NPM `advanced_config`). |
|
||||
| the-order.sankofa.nexus | web | https://the-order.sankofa.nexus | OSJ management portal (secure auth); app **the_order** at `~/projects/the_order`. NPM upstream default: **order-haproxy** VMID **10210** `http://192.168.11.39:80` → portal **192.168.11.51:3000** (`provision-order-haproxy-10210.sh`). Override with `THE_ORDER_UPSTREAM_*` for direct portal if 10210 is down. |
|
||||
| www.the-order.sankofa.nexus | web | https://www.the-order.sankofa.nexus | **301** to `https://the-order.sankofa.nexus` (canonical apex; NPM `advanced_config`). |
|
||||
| studio.sankofa.nexus | web | https://studio.sankofa.nexus | Sankofa Studio (FusionAI Creator) at VMID 7805. |
|
||||
| cacti-alltra.d-bis.org | web | https://cacti-alltra.d-bis.org | Cacti monitoring UI for Alltra. |
|
||||
| cacti-hybx.d-bis.org | web | https://cacti-hybx.d-bis.org | Cacti monitoring UI for HYBX. |
|
||||
@@ -75,6 +81,7 @@
|
||||
| phoenix.sankofa.nexus | https://phoenix.sankofa.nexus |
|
||||
| www.phoenix.sankofa.nexus | https://www.phoenix.sankofa.nexus |
|
||||
| the-order.sankofa.nexus | https://the-order.sankofa.nexus |
|
||||
| www.the-order.sankofa.nexus | https://www.the-order.sankofa.nexus |
|
||||
| studio.sankofa.nexus | https://studio.sankofa.nexus |
|
||||
| cacti-alltra.d-bis.org | https://cacti-alltra.d-bis.org |
|
||||
| cacti-hybx.d-bis.org | https://cacti-hybx.d-bis.org |
|
||||
@@ -148,6 +155,8 @@ When running from outside LAN or when backends are down, the following endpoints
|
||||
|
||||
**These known items do not block contract or pool completion.** Fix when convenient; E2E still passes when they are in `E2E_OPTIONAL_WHEN_FAIL`.
|
||||
|
||||
**2026-03-26 note:** after recovering NPMplus CT `10233` and re-running `update-npmplus-proxy-hosts-api.sh`, the latest public profile passed for all currently tested public domains, including Sankofa, Phoenix, Studio, The Order, DBIS, Mifos, and MIM4U.
|
||||
|
||||
| Endpoint | Typical cause |
|
||||
|----------|----------------|
|
||||
| dbis-admin.d-bis.org | 502 — backend (VMID 10130) unreachable from public |
|
||||
@@ -155,9 +164,17 @@ When running from outside LAN or when backends are down, the following endpoints
|
||||
| secure.d-bis.org | 502 — secure portal backend unreachable |
|
||||
| mifos.d-bis.org | 502 — Mifos (VMID 5800) unreachable from public |
|
||||
| mim4u.org, www.mim4u.org, secure.mim4u.org, training.mim4u.org | 502 — MIM4U web backends (192.168.11.37:80); non-blocking for contract/pool |
|
||||
| studio.sankofa.nexus | 404 — FusionAI Creator (VMID 7805) path or proxy config |
|
||||
| studio.sankofa.nexus | Historically 404 when the proxy misses `/studio/` or backend `192.168.11.72:8000`; verifier checks `/studio/`. Passed on 2026-03-26 after the NPMplus host update |
|
||||
| phoenix.sankofa.nexus, www.phoenix.sankofa.nexus | (Resolved in verifier) Phoenix API (7800) is API-first; `verify-end-to-end-routing.sh` checks `https://…/health` (200), not `/`. A separate **marketing** site on the apex hostname (if desired) needs another upstream or app routes—NPM still points `phoenix.sankofa.nexus` at the Fastify API today. |
|
||||
| the-order.sankofa.nexus | 502 if **10210** HAProxy or backend portal is down. NPM defaults upstream to **192.168.11.39:80** (order-haproxy). Fallback: `THE_ORDER_UPSTREAM_IP` / `THE_ORDER_UPSTREAM_PORT` = portal **192.168.11.51:3000** |
|
||||
|
||||
**WebSocket test-format warnings:** RPC WS tests may show "connection established but RPC test failed" when `wscat` is used: the upgrade succeeds but the script’s check for `"result"` in `wscat` output may miss due to output format or timing. Non-blocking for contract/pool. The script now also accepts Chain 138 chainId `0x8a` in output; WS connectivity is still confirmed by the upgrade (101).
|
||||
**Verifier behavior (2026-03):** `openssl s_client` is wrapped with `timeout` (`E2E_OPENSSL_TIMEOUT` default 15s, `E2E_OPENSSL_X509_TIMEOUT` default 5s) so `--profile=private` / `--profile=all` cannot hang. **`--profile=all`** merges private and public `E2E_OPTIONAL_WHEN_FAIL` lists for temporary regressions. Install **`wscat`** (`npm install -g wscat`) for full WSS JSON-RPC checks; the script uses `wscat -n` to match `curl -k`, and now treats a clean `wscat` exit as a successful full WebSocket check even when the tool prints no JSON output.
|
||||
|
||||
**Canonical www redirects (2026-03):** For `www.sankofa.nexus`, `www.phoenix.sankofa.nexus`, and `www.the-order.sankofa.nexus`, HTTP **301**/**308** must include a **`Location`** whose host matches the expected apex (`E2E_WWW_CANONICAL_BASE` in `verify-end-to-end-routing.sh`). Wrong apex → HTTPS **fail**. Missing `Location` → **warn**.
|
||||
|
||||
**Cloudflare bulk DNS:** `scripts/update-all-dns-to-public-ip.sh` supports **`--dry-run`** (no API calls) and **`--zone-only=sankofa.nexus`** (or `d-bis.org` | `mim4u.org` | `defi-oracle.io`) to limit blast radius. Env: `CLOUDFLARE_DNS_DRY_RUN=1`, `DNS_ZONE_ONLY=…`.
|
||||
|
||||
**WebSocket test-format warnings:** Older runs may show "connection established but RPC test failed" when `wscat` is used: the upgrade succeeded but the verifier expected printable `"result"` output. The script now accepts either explicit JSON output or a clean `wscat` exit, so current runs treat those WS checks as pass when the connection completes successfully. The script also accepts Chain 138 chainId `0x8a` in output.
|
||||
|
||||
### Remediation (when you want these to pass from public)
|
||||
|
||||
@@ -165,3 +182,4 @@ When running from outside LAN or when backends are down, the following endpoints
|
||||
|------|--------|
|
||||
| **502s (dbis-admin, dbis-api, secure, mifos)** | From LAN: `./scripts/maintenance/address-all-remaining-502s.sh [--run-besu-fix] [--e2e]` or `./scripts/maintenance/run-all-maintenance-via-proxmox-ssh.sh --e2e`. If NPMplus API is unreachable: `./scripts/maintenance/fix-npmplus-services-via-proxmox-ssh.sh`. Runbook: [502_DEEP_DIVE_ROOT_CAUSES_AND_FIXES.md](../00-meta/502_DEEP_DIVE_ROOT_CAUSES_AND_FIXES.md). |
|
||||
| **404 studio.sankofa.nexus** | Ensure backend (VMID 7805, 192.168.11.72:8000) is up and NPMplus proxy for `studio.sankofa.nexus` points to it. See [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md), [SANKOFA_STUDIO_E2E_FLOW.md](../03-deployment/SANKOFA_STUDIO_E2E_FLOW.md), [SANKOFA_STUDIO_DEPLOYMENT.md](../03-deployment/SANKOFA_STUDIO_DEPLOYMENT.md). |
|
||||
| **the-order 502** | Check **10210** HAProxy (`curl http://192.168.11.39:80/` with `Host: the-order.sankofa.nexus`) and portal **192.168.11.51:3000**. Re-provision: `bash scripts/deployment/provision-order-haproxy-10210.sh`. NPM refresh: `bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`. Direct portal bypass: `THE_ORDER_UPSTREAM_IP=192.168.11.51 THE_ORDER_UPSTREAM_PORT=3000` for that run. |
|
||||
|
||||
@@ -135,7 +135,7 @@ See [DBIS_CORE_API_REFERENCE.md](../11-references/DBIS_CORE_API_REFERENCE.md).
|
||||
|
||||
### Sankofa Services (sankofa.nexus)
|
||||
|
||||
**Config TBD:** When The Order portal is deployed or Sankofa cutover is completed, update this table and [SANKOFA_CUTOVER_PLAN.md](SANKOFA_CUTOVER_PLAN.md) with actual IP:port and NPMplus proxy backends.
|
||||
**NPMplus backends:** See [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md). The Order uses **10210** (HAProxy) in front of the portal.
|
||||
|
||||
| Domain | Protocol | Target VMID | Target IP | Target Port | WebSocket | Notes |
|
||||
|--------|----------|-------------|-----------|-------------|-----------|-------|
|
||||
@@ -143,7 +143,8 @@ See [DBIS_CORE_API_REFERENCE.md](../11-references/DBIS_CORE_API_REFERENCE.md).
|
||||
| `www.sankofa.nexus` | Redirect | - | - | - | ❌ No | Redirects to sankofa.nexus |
|
||||
| `phoenix.sankofa.nexus` | HTTP | 7800 | 192.168.11.50 | 4000 | ❌ No | Phoenix API |
|
||||
| `www.phoenix.sankofa.nexus` | Redirect | - | - | - | ❌ No | Redirects to phoenix.sankofa.nexus |
|
||||
| `the-order.sankofa.nexus` | HTTP | TBD | TBD | TBD | ❌ No | ⚠️ Placeholder — not yet configured; add when The Order portal is deployed |
|
||||
| `the-order.sankofa.nexus` | HTTP | 10210 | 192.168.11.39 | 80 | ❌ No | HAProxy → portal 7801 (192.168.11.51:3000); provision: `scripts/deployment/provision-order-haproxy-10210.sh` |
|
||||
| `www.the-order.sankofa.nexus` | Redirect | - | - | - | ❌ No | 301 → `https://the-order.sankofa.nexus` (NPM advanced_config) |
|
||||
|
||||
---
|
||||
|
||||
@@ -183,7 +184,8 @@ secure.mim4u.org → http://192.168.11.37:80
|
||||
training.mim4u.org → http://192.168.11.37:80
|
||||
sankofa.nexus → http://192.168.11.51:3000
|
||||
phoenix.sankofa.nexus → http://192.168.11.50:4000
|
||||
the-order.sankofa.nexus → (TBD — add when The Order portal is deployed)
|
||||
the-order.sankofa.nexus → http://192.168.11.39:80 (10210 HAProxy → 192.168.11.51:3000)
|
||||
www.the-order.sankofa.nexus → 301 apex (NPM)
|
||||
```
|
||||
|
||||
### Redirect Hosts
|
||||
@@ -192,6 +194,7 @@ the-order.sankofa.nexus → (TBD — add when The Order portal is deployed)
|
||||
www.mim4u.org → mim4u.org
|
||||
www.sankofa.nexus → sankofa.nexus
|
||||
www.phoenix.sankofa.nexus → phoenix.sankofa.nexus
|
||||
www.the-order.sankofa.nexus → the-order.sankofa.nexus
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Sankofa Cutover Plan
|
||||
|
||||
**Last Updated:** 2026-01-31
|
||||
**Document Version:** 1.0
|
||||
**Status:** Active Documentation
|
||||
**Last Updated:** 2026-03-27
|
||||
**Document Version:** 1.1
|
||||
**Status:** Active Documentation (historical procedure + live targets)
|
||||
|
||||
**Live NPM routing (2026-03-27):** Sankofa / Phoenix / The Order / Studio are on production backends. Canonical: [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER.md](RPC_ENDPOINTS_MASTER.md). **The Order:** NPM → **192.168.11.39:80** (VMID **10210** HAProxy) → **192.168.11.51:3000** (portal 7801). Fleet updater: `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`. NPM proxy host numeric IDs below may differ from your DB—verify in NPM UI.
|
||||
|
||||
---
|
||||
|
||||
@@ -12,23 +14,22 @@
|
||||
|
||||
---
|
||||
|
||||
## Current State
|
||||
## Current state (post-cutover)
|
||||
|
||||
### Sankofa Domains (5 Total)
|
||||
### Sankofa zone domains (authoritative backends)
|
||||
|
||||
| Domain | SSL Cert ID | NPMplus Proxy Host ID | Current Backend | Status |
|
||||
|--------|-------------|----------------------|-----------------|--------|
|
||||
| `sankofa.nexus` | 57 | 21 | 192.168.11.140:80 (Blockscout) | ⚠️ Temporary |
|
||||
| `www.sankofa.nexus` | 64 | 22 | 192.168.11.140:80 (Blockscout) | ⚠️ Temporary |
|
||||
| `phoenix.sankofa.nexus` | 51 | 23 | 192.168.11.140:80 (Blockscout) | ⚠️ Temporary |
|
||||
| `www.phoenix.sankofa.nexus` | 63 | 24 | 192.168.11.140:80 (Blockscout) | ⚠️ Temporary |
|
||||
| `the-order.sankofa.nexus` | 60 | 25 | 192.168.11.140:80 (Blockscout) | ⚠️ Temporary |
|
||||
| Domain | NPMplus forwards to (HTTP) | Origin stack | Notes |
|
||||
|--------|----------------------------|--------------|--------|
|
||||
| `sankofa.nexus`, `www.sankofa.nexus` | `192.168.11.51:3000` | VMID 7801 portal | `www` → 301 apex in NPM |
|
||||
| `phoenix.sankofa.nexus`, `www.phoenix.sankofa.nexus` | `192.168.11.50:4000` | VMID 7800 API | `www` → 301 apex |
|
||||
| `the-order.sankofa.nexus`, `www.the-order.sankofa.nexus` | `192.168.11.39:80` | VMID 10210 → `.51:3000` | `www` → 301 apex; HAProxy: `provision-order-haproxy-10210.sh` |
|
||||
| `studio.sankofa.nexus` | `192.168.11.72:8000` | VMID 7805 | — |
|
||||
|
||||
**Current Issue**: All 5 Sankofa domains route to Blockscout (VMID 5000) but Sankofa services are NOT deployed.
|
||||
**SSL:** Terminated at NPMplus (Let’s Encrypt). **Do not** point these hostnames at Blockscout (`192.168.11.140`) except for explorer domains.
|
||||
|
||||
**SSL Certificates**: All certificates exist and are valid until 2026-04-16.
|
||||
### Historical note (pre-2026 cutover)
|
||||
|
||||
**NPMplus Proxy Hosts**: All proxy hosts exist and are configured, but point to wrong backend.
|
||||
Previously these hostnames temporarily targeted Blockscout. The step-by-step below documents that migration; IDs (SSL cert / proxy host #) were examples—confirm in your NPMplus instance.
|
||||
|
||||
---
|
||||
|
||||
@@ -67,9 +68,9 @@ done
|
||||
| `www.sankofa.nexus` | 7801 | 192.168.11.51 | 3000 | Portal | Sankofa Portal (Microsoft Website) |
|
||||
| `phoenix.sankofa.nexus` | 7800 | 192.168.11.50 | 4000 | API | Phoenix API (Azure-like Portal) |
|
||||
| `www.phoenix.sankofa.nexus` | 7800 | 192.168.11.50 | 4000 | API | Phoenix API (Azure-like Portal) |
|
||||
| `the-order.sankofa.nexus` | ⚠️ TBD | ⚠️ TBD | ⚠️ TBD | ⚠️ TBD | To be determined |
|
||||
| `the-order.sankofa.nexus` | 10210 | 192.168.11.39 | 80 | HAProxy edge | Proxies to portal 7801 `:3000`; app **the_order** |
|
||||
|
||||
**Note**: Replace ⚠️ TBD with actual values once Sankofa services are deployed.
|
||||
**Note:** `www.the-order.sankofa.nexus` uses the same NPM upstream as apex; NPM `advanced_config` 301 → `https://the-order.sankofa.nexus`.
|
||||
|
||||
### 3. Health Endpoints Verified
|
||||
|
||||
@@ -143,10 +144,9 @@ curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \
|
||||
jq '.[] | select(.domain_names[] == "sankofa.nexus")'
|
||||
```
|
||||
|
||||
3. **Document Current State**:
|
||||
- All 5 Sankofa domains currently route to `192.168.11.140:80` (Blockscout)
|
||||
- SSL certificates exist (IDs: 51, 57, 60, 63, 64)
|
||||
- Proxy hosts exist (IDs: 21-25)
|
||||
3. **Document state (historical pre-cutover)**:
|
||||
- Before cutover, these domains pointed at `192.168.11.140:80` (Blockscout)
|
||||
- SSL certificates existed (example IDs: 51, 57, 60, 63, 64); proxy hosts (example 21–25)—**confirm in your NPM DB**
|
||||
|
||||
---
|
||||
|
||||
@@ -167,9 +167,7 @@ for vmid in <SANKOFA_VMIDS>; do
|
||||
done
|
||||
```
|
||||
|
||||
3. **Document Actual IPs/Ports**:
|
||||
- Update the TBD table above with actual values
|
||||
- Record VMIDs, IPs, ports, and service types
|
||||
3. **Document actual IPs/ports** (✅ filled in **Current state** section and [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md))
|
||||
|
||||
---
|
||||
|
||||
@@ -224,9 +222,9 @@ curl -s -k -X PUT "$NPM_URL/api/nginx/proxy-hosts/$HOST_ID" \
|
||||
| `www.sankofa.nexus` | 22 | 192.168.11.140:80 | 192.168.11.51:3000 |
|
||||
| `phoenix.sankofa.nexus` | 23 | 192.168.11.140:80 | 192.168.11.50:4000 |
|
||||
| `www.phoenix.sankofa.nexus` | 24 | 192.168.11.140:80 | 192.168.11.50:4000 |
|
||||
| `the-order.sankofa.nexus` | 25 | 192.168.11.140:80 | ⚠️ TBD (to be determined) |
|
||||
| `the-order.sankofa.nexus` | 25 (example) | 192.168.11.140:80 (old) | `192.168.11.39:80` (10210 HAProxy) |
|
||||
|
||||
**Note**: `the-order.sankofa.nexus` target service needs to be determined.
|
||||
**Note:** Use `update-npmplus-proxy-hosts-api.sh` for domain-based updates; proxy host IDs vary.
|
||||
|
||||
---
|
||||
|
||||
@@ -319,19 +317,9 @@ cat docs/04-configuration/INGRESS_SOURCE_OF_TRUTH.json | jq '.backend_vms[] | se
|
||||
|
||||
---
|
||||
|
||||
### Step 7: Update Baseline Documentation
|
||||
### Step 7: Update baseline documentation
|
||||
|
||||
**Update reference docs with actual values**:
|
||||
|
||||
1. **Update Comprehensive Architecture Doc**:
|
||||
- File: `docs/04-configuration/DNS_NPMPLUS_VM_COMPREHENSIVE_ARCHITECTURE.md`
|
||||
- Replace TBD values with actual Sankofa VM details
|
||||
- Update status from ⚠️ to ✅
|
||||
|
||||
2. **Update Streamlined Table Doc**:
|
||||
- File: `docs/04-configuration/DNS_NPMPLUS_VM_STREAMLINED_TABLE.md`
|
||||
- Replace TBD values with actual Sankofa VM details
|
||||
- Update status from ⚠️ Not Deployed to ✅ Active
|
||||
**Status 2026-03-27:** Comprehensive and streamlined DNS/NPM tables, RPC_ENDPOINTS_MASTER, and ALL_VMIDS_ENDPOINTS list live backends (including The Order via 10210). Re-open this step only if VMIDs or IPs change.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
# Sankofa and The Order deployment checklist
|
||||
# Sankofa and The Order — routing checklist
|
||||
|
||||
Replace TBDs with real IPs and ports when deployed. Update ALL_VMIDS_ENDPOINTS, RPC_ENDPOINTS_MASTER. Add NPMplus proxy for the-order.sankofa.nexus when The Order is live. When done update PLACEHOLDERS_AND_TBD and REMAINING_COMPONENTS_TASKS_AND_RECOMMENDATIONS. See NOT_IMPLEMENTED_FULL_SCOPE in docs/00-meta.
|
||||
**Canonical:** [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md) (NPM targets), [RPC_ENDPOINTS_MASTER.md](RPC_ENDPOINTS_MASTER.md) (Sankofa table).
|
||||
|
||||
## Done (production)
|
||||
|
||||
- [x] NPMplus **the-order.sankofa.nexus** / **www.the-order.sankofa.nexus** → **192.168.11.39:80** (VMID **10210** order-haproxy), HAProxy → **192.168.11.51:3000** (portal 7801).
|
||||
- [x] **www.the-order** → **301** `https://the-order.sankofa.nexus` (NPM `advanced_config`).
|
||||
- [x] HAProxy on 10210: `config/haproxy/order-haproxy-10210.cfg.template`, deploy `scripts/deployment/provision-order-haproxy-10210.sh`.
|
||||
|
||||
## If 10210 is down (bypass)
|
||||
|
||||
```bash
|
||||
THE_ORDER_UPSTREAM_IP=192.168.11.51 THE_ORDER_UPSTREAM_PORT=3000 \
|
||||
bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh
|
||||
```
|
||||
|
||||
## Ongoing
|
||||
|
||||
- [ ] Keep **the_order** app and portal 7801 healthy (HAProxy only forwards).
|
||||
- [ ] Re-run E2E: `scripts/verify/verify-end-to-end-routing.sh --profile=public`.
|
||||
|
||||
Related: [SANKOFA_CUTOVER_PLAN.md](SANKOFA_CUTOVER_PLAN.md) (history + same targets).
|
||||
|
||||
@@ -0,0 +1,928 @@
|
||||
[
|
||||
{
|
||||
"domain": "dbis-admin.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:32-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "dbis-admin.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 15 06:47:43 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.048185,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-alltra-3.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:33-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "mifos.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:33-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.129259,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-hybx-2.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:34-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "104.21.86.131",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "cacti-hybx.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:34-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "104.21.86.131",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.122747,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:35-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "sankofa.nexus",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 16 06:48:37 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.088318,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-alltra.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:35-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-http-pub.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:36-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc-http-pub.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 16 06:48:10 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc.public-0138.defi-oracle.io",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:36-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc.public-0138.defi-oracle.io",
|
||||
"issuer": "E8",
|
||||
"expires": "Apr 16 20:58:05 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "studio.sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:36-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.141.209",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "sankofa.nexus",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 6 03:30:54 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.158212,
|
||||
"has_hsts": false,
|
||||
"has_csp": false,
|
||||
"has_xfo": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "dbis-api.d-bis.org",
|
||||
"domain_type": "api",
|
||||
"timestamp": "2026-03-27T13:40:37-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "dbis-api.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 16 06:47:45 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.052015,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-hybx-3.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:37-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:38-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Apr 30 13:35:45 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "dapp.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:38-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 301,
|
||||
"response_time_seconds": 0.134693,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "www.sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:39-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "www.sankofa.nexus",
|
||||
"issuer": "E7",
|
||||
"expires": "Apr 16 20:59:41 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 301,
|
||||
"response_time_seconds": 0.047036,
|
||||
"canonical_redirect": true,
|
||||
"location_header": "location: https://sankofa.nexus/"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "www.the-order.sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:39-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "www.the-order.sankofa.nexus",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 25 04:52:05 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 301,
|
||||
"response_time_seconds": 0.043245,
|
||||
"canonical_redirect": true,
|
||||
"location_header": "location: https://the-order.sankofa.nexus/"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "mim4u.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:39-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "mim4u.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 16 06:47:53 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "warn",
|
||||
"http_code": 502,
|
||||
"response_time_seconds": 0.089702
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "ws.rpc.d-bis.org",
|
||||
"domain_type": "rpc-ws",
|
||||
"timestamp": "2026-03-27T13:40:40-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "ws.rpc.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Apr 30 03:43:05 2026 GMT"
|
||||
},
|
||||
"websocket": {
|
||||
"status": "pass",
|
||||
"http_code": "400",
|
||||
"full_test": true,
|
||||
"full_test_output": "result"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "phoenix.sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:46-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "phoenix.sankofa.nexus",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 16 06:47:58 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.047239,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "www.mim4u.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:46-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "www.mim4u.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 15 06:47:54 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "warn",
|
||||
"http_code": 502,
|
||||
"response_time_seconds": 0.055618
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "wss.defi-oracle.io",
|
||||
"domain_type": "rpc-ws",
|
||||
"timestamp": "2026-03-27T13:40:46-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "wss.defi-oracle.io",
|
||||
"issuer": "E8",
|
||||
"expires": "Apr 30 03:44:57 2026 GMT"
|
||||
},
|
||||
"websocket": {
|
||||
"status": "pass",
|
||||
"http_code": "400",
|
||||
"full_test": true,
|
||||
"full_test_output": "result"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "the-order.sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:52-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "the-order.sankofa.nexus",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 16 06:48:53 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.065987,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc2.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:52-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc2.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Apr 30 03:40:50 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-ws-pub.d-bis.org",
|
||||
"domain_type": "rpc-ws",
|
||||
"timestamp": "2026-03-27T13:40:53-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc-ws-pub.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 16 06:48:27 2026 GMT"
|
||||
},
|
||||
"websocket": {
|
||||
"status": "pass",
|
||||
"http_code": "400",
|
||||
"full_test": true,
|
||||
"full_test_output": "result"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "dev.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:58-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "104.21.86.131",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.137467,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-alltra-2.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:40:59-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "www.phoenix.sankofa.nexus",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:59-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "www.phoenix.sankofa.nexus",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 15 06:48:02 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 301,
|
||||
"response_time_seconds": 0.071859,
|
||||
"canonical_redirect": true,
|
||||
"location_header": "location: https://phoenix.sankofa.nexus/health"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "gitea.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:40:59-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "104.21.86.131",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.113480,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "secure.mim4u.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:41:00-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "secure.mim4u.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Jun 16 06:48:46 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "warn",
|
||||
"http_code": 502,
|
||||
"response_time_seconds": 0.039578
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "explorer.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:41:00-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "explorer.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "May 7 23:15:36 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.039903,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
},
|
||||
"blockscout_api": {
|
||||
"status": "pass",
|
||||
"http_code": 200
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "training.mim4u.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:41:01-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "training.mim4u.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 16 06:49:02 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "warn",
|
||||
"http_code": 502,
|
||||
"response_time_seconds": 0.037443
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "dbis-api-2.d-bis.org",
|
||||
"domain_type": "api",
|
||||
"timestamp": "2026-03-27T13:41:01-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "dbis-api-2.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "Apr 16 20:56:22 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.036568,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "secure.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:41:01-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "secure.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Apr 16 20:58:28 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.044836,
|
||||
"has_hsts": true,
|
||||
"has_csp": true,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-hybx.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:41:01-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "104.21.86.131",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "codespaces.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:41:02-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "172.67.220.49",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.102393,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc.defi-oracle.io",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:41:02-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "*",
|
||||
"issuer": "*",
|
||||
"expires": "May 19 19:15:03 3025 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "skip",
|
||||
"http_code": "405",
|
||||
"error": "<html>\r\n<head><title>405 Not Allowed</title></head>\r\n<body>\r\n<center><h1>405 Not Allowed</h1></center>\r\n</body>\r\n</html>"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "ws.rpc2.d-bis.org",
|
||||
"domain_type": "rpc-ws",
|
||||
"timestamp": "2026-03-27T13:41:03-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "ws.rpc2.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Apr 30 03:43:58 2026 GMT"
|
||||
},
|
||||
"websocket": {
|
||||
"status": "pass",
|
||||
"http_code": "400",
|
||||
"full_test": true,
|
||||
"full_test_output": "result"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "cacti-alltra.d-bis.org",
|
||||
"domain_type": "web",
|
||||
"timestamp": "2026-03-27T13:41:08-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "104.21.86.131",
|
||||
"expected_ip": "any"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "d-bis.org",
|
||||
"issuer": "WE1",
|
||||
"expires": "May 27 07:40:56 2026 GMT"
|
||||
},
|
||||
"https": {
|
||||
"status": "pass",
|
||||
"http_code": 200,
|
||||
"response_time_seconds": 0.133026,
|
||||
"has_hsts": true,
|
||||
"has_csp": false,
|
||||
"has_xfo": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:41:09 GMT
|
||||
content-type: text/html
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
last-modified: Tue, 10 Mar 2026 14:38:11 GMT
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
vary: Accept-Encoding
|
||||
x-content-type-options: nosniff
|
||||
x-dns-prefetch-control: off
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-permitted-cross-domain-policies: none
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=f8NeZozda4HsovLIQL01oQj63nadMyYeqRDkiXAHVVtis4Io4fq6f5ClcyYkmhpL9CV%2FAUzvrqi5E6Rql%2Ft3Qa4YcM4WUjQP2gcVRnoTkTeJ2l5pQahvcWI5x5NtC1KocjV3p5BKlhQq"}]}
|
||||
server: cloudflare
|
||||
cf-ray: 9e3136d70f1727ec-LAX
|
||||
|
||||
|
||||
0.133026
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:35 GMT
|
||||
content-type: text/html
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
last-modified: Tue, 10 Mar 2026 14:38:22 GMT
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
vary: Accept-Encoding
|
||||
x-content-type-options: nosniff
|
||||
x-dns-prefetch-control: off
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-permitted-cross-domain-policies: none
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=dWhmwhiBuOkBb4Zhh8n9L6nFgmZe3f8ajvfCrunlO1KNEanDxYaeT6e8c0Emd3%2FHzmdtEntKPMvGGzw3diaNrOWeNU3xchSFv5qBWDJ3fqZPTlYo0B872OcuyY9qXQNZ6cpk6dTxAA%3D%3D"}]}
|
||||
server: cloudflare
|
||||
cf-ray: 9e313602cda4c961-LAX
|
||||
|
||||
|
||||
0.122747
|
||||
@@ -0,0 +1,17 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:41:02 GMT
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
x-content-type-options: nosniff
|
||||
x-dns-prefetch-control: off
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-permitted-cross-domain-policies: none
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=cmll2l6EthHdX14gJDNzEheLY%2FY3pxyXR1y4YXOJJBh5n%2FoCd2eTf%2F7bCVykHvaIeVNv2Qy5spUQWO1tFMr2VjTHrzD6X0Rioskcb%2F9GQM%2Bg0KXsCqvHrVo7dTBB%2BSrxNK3nrJM%2FKg%3D%3D"}]}
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
server: cloudflare
|
||||
cf-ray: 9e3136b01b1b2b77-LAX
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
|
||||
0.102393
|
||||
@@ -0,0 +1,15 @@
|
||||
HTTP/2 301
|
||||
date: Fri, 27 Mar 2026 20:40:38 GMT
|
||||
content-type: text/html
|
||||
location: https://dapp.d-bis.org/
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
x-content-type-options: nosniff
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=cCinyCyPjx0pMhMVnxKaVzYP9WOUQH%2FmCcWha0MGYJfl6PQTI9l3Qq3cDXhErs9AgF0SzNdi2MvYScUg0JI6auoO5yteaMvEtrYnWpf0lF7rCDjI27y3tmCwfaNdXHNNdw%3D%3D"}]}
|
||||
server: cloudflare
|
||||
cf-ray: 9e31361adf372efc-LAX
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
|
||||
0.134693
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:33 GMT
|
||||
content-type: text/html
|
||||
content-length: 31
|
||||
vary: Accept-Encoding
|
||||
last-modified: Tue, 10 Mar 2026 14:34:29 GMT
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.048185
|
||||
@@ -0,0 +1,19 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:41:01 GMT
|
||||
content-type: text/html; charset=utf-8
|
||||
content-length: 344
|
||||
vary: Accept-Encoding
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.036568
|
||||
@@ -0,0 +1,19 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:37 GMT
|
||||
content-type: text/html; charset=utf-8
|
||||
content-length: 344
|
||||
vary: Accept-Encoding
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.052015
|
||||
@@ -0,0 +1,17 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:59 GMT
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
x-content-type-options: nosniff
|
||||
x-dns-prefetch-control: off
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-permitted-cross-domain-policies: none
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=qmt%2BbVFJ2EwVGI0OLmGJL8Lkx%2BERxAEqJsPQuMWo1d4t3AYUZrwU%2BdIR5cmwtOQAqOsAZN7wOelPdw4h%2FZVFHpW7oct8yg40Aze3%2BhVjifrgWiDtGRAU8Z%2FIQ1jV%2BaKM"}]}
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
server: cloudflare
|
||||
cf-ray: 9e313698ab19490e-LAX
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
|
||||
0.137467
|
||||
@@ -0,0 +1 @@
|
||||
{"average_block_time":2.0e3,"coin_image":"https://coin-images.coingecko.com/coins/images/39140/small/ETH.png?1720706783","coin_price":"1975.13","coin_price_change_percentage":-8.93,"gas_price_updated_at":"2026-03-27T20:40:55.112693Z","gas_prices":{"slow":2.0,"average":2.0,"fast":2.0},"gas_prices_update_in":25339,"gas_used_today":"421762900","market_cap":"0.000","network_utilization_percentage":0.0491656,"secondary_coin_image":null,"secondary_coin_price":null,"static_gas_price":null,"total_addresses":"441","total_blocks":"3352124","total_gas_used":"0","total_transactions":"28499","transactions_today":"6704","tvl":null}
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:41:00 GMT
|
||||
content-type: text/html
|
||||
content-length: 79248
|
||||
vary: Accept-Encoding
|
||||
last-modified: Fri, 27 Mar 2026 20:39:14 GMT
|
||||
etag: "69c6eaf2-13590"
|
||||
cache-control: no-store, no-cache, must-revalidate
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://unpkg.com https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; img-src 'self' data: https:; font-src 'self' https://cdnjs.cloudflare.com; connect-src 'self' https://explorer.d-bis.org wss://explorer.d-bis.org https://rpc-http-pub.d-bis.org wss://rpc-ws-pub.d-bis.org http://192.168.11.221:8545 ws://192.168.11.221:8546;
|
||||
accept-ranges: bytes
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
@@ -0,0 +1,17 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:41:00 GMT
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
x-content-type-options: nosniff
|
||||
x-dns-prefetch-control: off
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-permitted-cross-domain-policies: none
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=wY6qWCOjIlaaMg11zTMNBcKFuDsOIbZbbrXVu%2FRNkNMMsjETgQGbufbZo3Ow7YVZlAEYAt%2BFTRJ5mEeQgo8%2FQNy5JdOdzaP8VdFRy%2FfhnGk%2FzNAKZO8cjKCcfBu%2FQyHS0%2Bc%3D"}]}
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
server: cloudflare
|
||||
cf-ray: 9e3136a0cd32d7ab-LAX
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
|
||||
0.113480
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:34 GMT
|
||||
content-type: text/html
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=Lg4tY0tUDoH9QvsPHHjl61IXVrGNonfx5jn4IiNf4HGj4VBE8QTez4vHyWTk%2FGh3DZcwXRbHprUcCuwmkzVuT7iMlHfEhViCaRXP49i98n1vXfkgzP8bA4FDoDCLlUfpB68%3D"}]}
|
||||
last-modified: Mon, 31 Mar 2025 07:37:06 GMT
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
vary: Accept-Encoding
|
||||
x-content-type-options: nosniff
|
||||
x-dns-prefetch-control: off
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-permitted-cross-domain-policies: none
|
||||
cf-cache-status: DYNAMIC
|
||||
strict-transport-security: max-age=31536000; includeSubDomains
|
||||
server: cloudflare
|
||||
cf-ray: 9e3135fd0c332b62-LAX
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
|
||||
0.129259
|
||||
@@ -0,0 +1,18 @@
|
||||
HTTP/2 502
|
||||
date: Fri, 27 Mar 2026 20:40:40 GMT
|
||||
content-type: text/html
|
||||
content-length: 122
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.089702
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:46 GMT
|
||||
content-type: application/json; charset=utf-8
|
||||
content-length: 54
|
||||
vary: Accept-Encoding
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 0
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'nonce-f7oZ79fkmHF5pFaZFuVUNw=='; style-src 'self' 'nonce-f7oZ79fkmHF5pFaZFuVUNw=='; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
permissions-policy: geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()
|
||||
x-permitted-cross-domain-policies: none
|
||||
cross-origin-embedder-policy: require-corp
|
||||
cross-origin-opener-policy: same-origin
|
||||
cross-origin-resource-policy: same-origin
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head><title>405 Not Allowed</title></head>
|
||||
<body>
|
||||
<center><h1>405 Not Allowed</h1></center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","result":"0x8a","id":1}
|
||||
@@ -0,0 +1,19 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:35 GMT
|
||||
content-type: text/html; charset=utf-8
|
||||
content-length: 5165
|
||||
vary: Accept-Encoding
|
||||
x-dns-prefetch-control: on
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-content-type-options: nosniff
|
||||
x-xss-protection: 0
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
permissions-policy: camera=(), microphone=(), geolocation=()
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:
|
||||
vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Accept-Encoding
|
||||
cache-control: s-maxage=31536000, stale-while-revalidate
|
||||
etag: "yc5tqwrxjc3zb"
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:41:01 GMT
|
||||
content-type: text/html
|
||||
content-length: 31
|
||||
vary: Accept-Encoding
|
||||
last-modified: Tue, 10 Mar 2026 14:34:29 GMT
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.044836
|
||||
@@ -0,0 +1,18 @@
|
||||
HTTP/2 502
|
||||
date: Fri, 27 Mar 2026 20:41:00 GMT
|
||||
content-type: text/html
|
||||
content-length: 122
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.039578
|
||||
@@ -0,0 +1,14 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:37 GMT
|
||||
content-type: text/html; charset=utf-8
|
||||
vary: Accept-Encoding
|
||||
last-modified: Sat, 28 Feb 2026 16:54:14 GMT
|
||||
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=APaBHQl3T2EffLK36x8sJc%2BO%2B68g7N88s1dlgFoPrOE0gYbpvsYqQ9HpZDwxv2W6NjikzornPFlO4tUw1QXBFdwKyM8vQ4W%2BCqo%2BgKJE6Dvfy7ZPr%2BzmVSXfQsV03Lb%2BRXoSpJZbTA%3D%3D"}]}
|
||||
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
|
||||
cf-cache-status: DYNAMIC
|
||||
server: cloudflare
|
||||
cf-ray: 9e3136102ee1b860-LAX
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
|
||||
|
||||
0.158212
|
||||
@@ -0,0 +1,20 @@
|
||||
HTTP/2 200
|
||||
date: Fri, 27 Mar 2026 20:40:52 GMT
|
||||
content-type: text/html; charset=utf-8
|
||||
content-length: 5165
|
||||
vary: Accept-Encoding
|
||||
x-dns-prefetch-control: on
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-content-type-options: nosniff
|
||||
x-xss-protection: 0
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
permissions-policy: camera=(), microphone=(), geolocation=()
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:
|
||||
vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Accept-Encoding
|
||||
cache-control: s-maxage=31536000, stale-while-revalidate
|
||||
etag: "yc5tqwrxjc3zb"
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
@@ -0,0 +1,18 @@
|
||||
HTTP/2 502
|
||||
date: Fri, 27 Mar 2026 20:41:01 GMT
|
||||
content-type: text/html
|
||||
content-length: 122
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.037443
|
||||
@@ -0,0 +1,390 @@
|
||||
# End-to-End Routing Verification Report
|
||||
|
||||
**Date**: 2026-03-27T13:41:09-07:00
|
||||
**Public IP**: 76.53.10.36
|
||||
**Profile**: public
|
||||
**Verifier**: intlc
|
||||
|
||||
## All endpoints (38)
|
||||
|
||||
| Domain | Type | URL |
|
||||
|--------|------|-----|
|
||||
| cacti-alltra.d-bis.org | web | https://cacti-alltra.d-bis.org |
|
||||
| cacti-hybx.d-bis.org | web | https://cacti-hybx.d-bis.org |
|
||||
| codespaces.d-bis.org | web | https://codespaces.d-bis.org |
|
||||
| dapp.d-bis.org | web | https://dapp.d-bis.org |
|
||||
| dbis-admin.d-bis.org | web | https://dbis-admin.d-bis.org |
|
||||
| dbis-api-2.d-bis.org | api | https://dbis-api-2.d-bis.org |
|
||||
| dbis-api.d-bis.org | api | https://dbis-api.d-bis.org |
|
||||
| dev.d-bis.org | web | https://dev.d-bis.org |
|
||||
| explorer.d-bis.org | web | https://explorer.d-bis.org |
|
||||
| gitea.d-bis.org | web | https://gitea.d-bis.org |
|
||||
| mifos.d-bis.org | web | https://mifos.d-bis.org |
|
||||
| mim4u.org | web | https://mim4u.org |
|
||||
| phoenix.sankofa.nexus | web | https://phoenix.sankofa.nexus |
|
||||
| rpc-alltra-2.d-bis.org | rpc-http | https://rpc-alltra-2.d-bis.org |
|
||||
| rpc-alltra-3.d-bis.org | rpc-http | https://rpc-alltra-3.d-bis.org |
|
||||
| rpc-alltra.d-bis.org | rpc-http | https://rpc-alltra.d-bis.org |
|
||||
| rpc-http-pub.d-bis.org | rpc-http | https://rpc-http-pub.d-bis.org |
|
||||
| rpc-hybx-2.d-bis.org | rpc-http | https://rpc-hybx-2.d-bis.org |
|
||||
| rpc-hybx-3.d-bis.org | rpc-http | https://rpc-hybx-3.d-bis.org |
|
||||
| rpc-hybx.d-bis.org | rpc-http | https://rpc-hybx.d-bis.org |
|
||||
| rpc-ws-pub.d-bis.org | rpc-ws | https://rpc-ws-pub.d-bis.org |
|
||||
| rpc.d-bis.org | rpc-http | https://rpc.d-bis.org |
|
||||
| rpc.defi-oracle.io | rpc-http | https://rpc.defi-oracle.io |
|
||||
| rpc.public-0138.defi-oracle.io | rpc-http | https://rpc.public-0138.defi-oracle.io |
|
||||
| rpc2.d-bis.org | rpc-http | https://rpc2.d-bis.org |
|
||||
| sankofa.nexus | web | https://sankofa.nexus |
|
||||
| secure.d-bis.org | web | https://secure.d-bis.org |
|
||||
| secure.mim4u.org | web | https://secure.mim4u.org |
|
||||
| studio.sankofa.nexus | web | https://studio.sankofa.nexus |
|
||||
| the-order.sankofa.nexus | web | https://the-order.sankofa.nexus |
|
||||
| training.mim4u.org | web | https://training.mim4u.org |
|
||||
| ws.rpc.d-bis.org | rpc-ws | https://ws.rpc.d-bis.org |
|
||||
| ws.rpc2.d-bis.org | rpc-ws | https://ws.rpc2.d-bis.org |
|
||||
| wss.defi-oracle.io | rpc-ws | https://wss.defi-oracle.io |
|
||||
| www.mim4u.org | web | https://www.mim4u.org |
|
||||
| www.phoenix.sankofa.nexus | web | https://www.phoenix.sankofa.nexus |
|
||||
| www.sankofa.nexus | web | https://www.sankofa.nexus |
|
||||
| www.the-order.sankofa.nexus | web | https://www.the-order.sankofa.nexus |
|
||||
|
||||
## Summary
|
||||
|
||||
- **Total domains tested**: 38
|
||||
- **DNS tests passed**: 38
|
||||
- **HTTPS tests passed**: 19
|
||||
- **Failed tests**: 0
|
||||
- **Skipped / optional (not configured or unreachable)**: 1
|
||||
- **Average response time**: 0.07994821739130435s
|
||||
|
||||
## Results overview
|
||||
|
||||
| Domain | Type | DNS | SSL | HTTPS | RPC |
|
||||
|--------|------|-----|-----|-------|-----|
|
||||
| dbis-admin.d-bis.org | web | pass | pass | pass | - |
|
||||
| rpc-alltra-3.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| mifos.d-bis.org | web | pass | pass | pass | - |
|
||||
| rpc-hybx-2.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| cacti-hybx.d-bis.org | web | pass | pass | pass | - |
|
||||
| sankofa.nexus | web | pass | pass | pass | - |
|
||||
| rpc-alltra.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| rpc-http-pub.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| rpc.public-0138.defi-oracle.io | rpc-http | pass | pass | - | pass |
|
||||
| studio.sankofa.nexus | web | pass | pass | pass | - |
|
||||
| dbis-api.d-bis.org | api | pass | pass | pass | - |
|
||||
| rpc-hybx-3.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| rpc.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| dapp.d-bis.org | web | pass | pass | pass | - |
|
||||
| www.sankofa.nexus | web | pass | pass | pass | - |
|
||||
| www.the-order.sankofa.nexus | web | pass | pass | pass | - |
|
||||
| mim4u.org | web | pass | pass | warn | - |
|
||||
| ws.rpc.d-bis.org | rpc-ws | pass | pass | - | - |
|
||||
| phoenix.sankofa.nexus | web | pass | pass | pass | - |
|
||||
| www.mim4u.org | web | pass | pass | warn | - |
|
||||
| wss.defi-oracle.io | rpc-ws | pass | pass | - | - |
|
||||
| the-order.sankofa.nexus | web | pass | pass | pass | - |
|
||||
| rpc2.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| rpc-ws-pub.d-bis.org | rpc-ws | pass | pass | - | - |
|
||||
| dev.d-bis.org | web | pass | pass | pass | - |
|
||||
| rpc-alltra-2.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| www.phoenix.sankofa.nexus | web | pass | pass | pass | - |
|
||||
| gitea.d-bis.org | web | pass | pass | pass | - |
|
||||
| secure.mim4u.org | web | pass | pass | warn | - |
|
||||
| explorer.d-bis.org | web | pass | pass | pass | - |
|
||||
| training.mim4u.org | web | pass | pass | warn | - |
|
||||
| dbis-api-2.d-bis.org | api | pass | pass | pass | - |
|
||||
| secure.d-bis.org | web | pass | pass | pass | - |
|
||||
| rpc-hybx.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| codespaces.d-bis.org | web | pass | pass | pass | - |
|
||||
| rpc.defi-oracle.io | rpc-http | pass | pass | - | skip |
|
||||
| ws.rpc2.d-bis.org | rpc-ws | pass | pass | - | - |
|
||||
| cacti-alltra.d-bis.org | web | pass | pass | pass | - |
|
||||
|
||||
## Test Results by Domain (detail)
|
||||
|
||||
|
||||
### dbis-admin.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-alltra-3.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### mifos.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-hybx-2.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### cacti-hybx.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-alltra.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-http-pub.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc.public-0138.defi-oracle.io
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### studio.sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### dbis-api.d-bis.org
|
||||
- Type: api
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-hybx-3.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### dapp.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### www.sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### www.the-order.sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### mim4u.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: warn
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### ws.rpc.d-bis.org
|
||||
- Type: rpc-ws
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### phoenix.sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### www.mim4u.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: warn
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### wss.defi-oracle.io
|
||||
- Type: rpc-ws
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### the-order.sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc2.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-ws-pub.d-bis.org
|
||||
- Type: rpc-ws
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### dev.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-alltra-2.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### www.phoenix.sankofa.nexus
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### gitea.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### secure.mim4u.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: warn
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### explorer.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Blockscout API: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### training.mim4u.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: warn
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### dbis-api-2.d-bis.org
|
||||
- Type: api
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### secure.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-hybx.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### codespaces.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc.defi-oracle.io
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: skip
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### ws.rpc2.d-bis.org
|
||||
- Type: rpc-ws
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### cacti-alltra.d-bis.org
|
||||
- Type: web
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- HTTPS: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
## Files Generated
|
||||
|
||||
- `all_e2e_results.json` - Complete E2E test results
|
||||
- `*_https_headers.txt` - HTTP response headers per domain
|
||||
- `*_rpc_response.txt` - RPC response per domain
|
||||
- `verification_report.md` - This report
|
||||
|
||||
## Notes
|
||||
|
||||
- **Optional domains:** Domains in `E2E_OPTIONAL_WHEN_FAIL` (default: many d-bis.org/sankofa/mim4u/rpc) have any fail treated as skip so the run passes when off-LAN or services unreachable. Set `E2E_OPTIONAL_WHEN_FAIL=` (empty) for strict mode.
|
||||
- WebSocket tests require `wscat` tool: `npm install -g wscat`
|
||||
- OpenSSL fetch uses `timeout` (`E2E_OPENSSL_TIMEOUT` / `E2E_OPENSSL_X509_TIMEOUT`, defaults 15s / 5s) so `openssl s_client` cannot hang indefinitely
|
||||
- Internal connectivity tests require access to NPMplus container
|
||||
- Explorer (explorer.d-bis.org): optional Blockscout API check; use `SKIP_BLOCKSCOUT_API=1` to skip when backend is unreachable (e.g. off-LAN). Fix runbook: docs/03-deployment/BLOCKSCOUT_FIX_RUNBOOK.md
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review test results for each domain
|
||||
2. Investigate any failed tests
|
||||
3. Test WebSocket connections for RPC WS domains (if wscat available)
|
||||
4. Test internal connectivity from NPMplus container
|
||||
5. Update source-of-truth JSON after verification
|
||||
@@ -0,0 +1,18 @@
|
||||
HTTP/2 502
|
||||
date: Fri, 27 Mar 2026 20:40:46 GMT
|
||||
content-type: text/html
|
||||
content-length: 122
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
x-xss-protection: 1; mode=block
|
||||
referrer-policy: strict-origin-when-cross-origin
|
||||
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests
|
||||
|
||||
|
||||
0.055618
|
||||
@@ -0,0 +1,14 @@
|
||||
HTTP/2 301
|
||||
date: Fri, 27 Mar 2026 20:40:59 GMT
|
||||
content-type: text/html
|
||||
content-length: 134
|
||||
location: https://phoenix.sankofa.nexus/health
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
|
||||
|
||||
0.071859
|
||||
@@ -0,0 +1,14 @@
|
||||
HTTP/2 301
|
||||
date: Fri, 27 Mar 2026 20:40:39 GMT
|
||||
content-type: text/html
|
||||
content-length: 134
|
||||
location: https://sankofa.nexus/
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
x-xss-protection: 0
|
||||
x-content-type-options: nosniff
|
||||
x-frame-options: SAMEORIGIN
|
||||
content-security-policy: upgrade-insecure-requests
|
||||
strict-transport-security: max-age=63072000; includeSubDomains; preload
|
||||
|
||||
|
||||
0.047036
|
||||
@@ -0,0 +1,8 @@
|
||||
HTTP/2 301
|
||||
date: Fri, 27 Mar 2026 20:40:39 GMT
|
||||
content-type: text/html
|
||||
content-length: 134
|
||||
location: https://the-order.sankofa.nexus/
|
||||
|
||||
|
||||
0.043245
|
||||
@@ -0,0 +1,94 @@
|
||||
[
|
||||
{
|
||||
"domain": "ws.rpc-fireblocks.d-bis.org",
|
||||
"domain_type": "rpc-ws",
|
||||
"timestamp": "2026-03-27T13:41:37-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "ws.rpc-fireblocks.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "May 22 21:48:21 2026 GMT"
|
||||
},
|
||||
"websocket": {
|
||||
"status": "pass",
|
||||
"http_code": "400",
|
||||
"full_test": true,
|
||||
"full_test_output": "result"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-http-prv.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:41:43-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc-http-prv.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 25 16:00:12 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-fireblocks.d-bis.org",
|
||||
"domain_type": "rpc-http",
|
||||
"timestamp": "2026-03-27T13:41:43-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc-fireblocks.d-bis.org",
|
||||
"issuer": "E8",
|
||||
"expires": "May 22 21:47:15 2026 GMT"
|
||||
},
|
||||
"rpc_http": {
|
||||
"status": "pass",
|
||||
"chain_id": "0x8a"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "rpc-ws-prv.d-bis.org",
|
||||
"domain_type": "rpc-ws",
|
||||
"timestamp": "2026-03-27T13:41:44-07:00",
|
||||
"tests": {
|
||||
"dns": {
|
||||
"status": "pass",
|
||||
"resolved_ip": "76.53.10.36",
|
||||
"expected_ip": "76.53.10.36"
|
||||
},
|
||||
"ssl": {
|
||||
"status": "pass",
|
||||
"cn": "rpc-ws-prv.d-bis.org",
|
||||
"issuer": "E7",
|
||||
"expires": "Jun 16 06:48:19 2026 GMT"
|
||||
},
|
||||
"websocket": {
|
||||
"status": "pass",
|
||||
"http_code": "400",
|
||||
"full_test": true,
|
||||
"full_test_output": "result"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":"0x8a"}
|
||||
@@ -0,0 +1,85 @@
|
||||
# End-to-End Routing Verification Report
|
||||
|
||||
**Date**: 2026-03-27T13:41:49-07:00
|
||||
**Public IP**: 76.53.10.36
|
||||
**Profile**: private
|
||||
**Verifier**: intlc
|
||||
|
||||
## All endpoints (4)
|
||||
|
||||
| Domain | Type | URL |
|
||||
|--------|------|-----|
|
||||
| rpc-fireblocks.d-bis.org | rpc-http | https://rpc-fireblocks.d-bis.org |
|
||||
| rpc-http-prv.d-bis.org | rpc-http | https://rpc-http-prv.d-bis.org |
|
||||
| rpc-ws-prv.d-bis.org | rpc-ws | https://rpc-ws-prv.d-bis.org |
|
||||
| ws.rpc-fireblocks.d-bis.org | rpc-ws | https://ws.rpc-fireblocks.d-bis.org |
|
||||
|
||||
## Summary
|
||||
|
||||
- **Total domains tested**: 4
|
||||
- **DNS tests passed**: 4
|
||||
- **HTTPS tests passed**: 0
|
||||
- **Failed tests**: 0
|
||||
- **Skipped / optional (not configured or unreachable)**: 0
|
||||
- **Average response time**: 0s
|
||||
|
||||
## Results overview
|
||||
|
||||
| Domain | Type | DNS | SSL | HTTPS | RPC |
|
||||
|--------|------|-----|-----|-------|-----|
|
||||
| ws.rpc-fireblocks.d-bis.org | rpc-ws | pass | pass | - | - |
|
||||
| rpc-http-prv.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| rpc-fireblocks.d-bis.org | rpc-http | pass | pass | - | pass |
|
||||
| rpc-ws-prv.d-bis.org | rpc-ws | pass | pass | - | - |
|
||||
|
||||
## Test Results by Domain (detail)
|
||||
|
||||
|
||||
### ws.rpc-fireblocks.d-bis.org
|
||||
- Type: rpc-ws
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-http-prv.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-fireblocks.d-bis.org
|
||||
- Type: rpc-http
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- RPC: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
### rpc-ws-prv.d-bis.org
|
||||
- Type: rpc-ws
|
||||
- DNS: pass
|
||||
- SSL: pass
|
||||
- Details: See `all_e2e_results.json`
|
||||
|
||||
## Files Generated
|
||||
|
||||
- `all_e2e_results.json` - Complete E2E test results
|
||||
- `*_https_headers.txt` - HTTP response headers per domain
|
||||
- `*_rpc_response.txt` - RPC response per domain
|
||||
- `verification_report.md` - This report
|
||||
|
||||
## Notes
|
||||
|
||||
- **Optional domains:** Domains in `E2E_OPTIONAL_WHEN_FAIL` (default: many d-bis.org/sankofa/mim4u/rpc) have any fail treated as skip so the run passes when off-LAN or services unreachable. Set `E2E_OPTIONAL_WHEN_FAIL=` (empty) for strict mode.
|
||||
- WebSocket tests require `wscat` tool: `npm install -g wscat`
|
||||
- OpenSSL fetch uses `timeout` (`E2E_OPENSSL_TIMEOUT` / `E2E_OPENSSL_X509_TIMEOUT`, defaults 15s / 5s) so `openssl s_client` cannot hang indefinitely
|
||||
- Internal connectivity tests require access to NPMplus container
|
||||
- Explorer (explorer.d-bis.org): optional Blockscout API check; use `SKIP_BLOCKSCOUT_API=1` to skip when backend is unreachable (e.g. off-LAN). Fix runbook: docs/03-deployment/BLOCKSCOUT_FIX_RUNBOOK.md
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review test results for each domain
|
||||
2. Investigate any failed tests
|
||||
3. Test WebSocket connections for RPC WS domains (if wscat available)
|
||||
4. Test internal connectivity from NPMplus container
|
||||
5. Update source-of-truth JSON after verification
|
||||
@@ -1,6 +1,6 @@
|
||||
# E2E Success Runbook: Cloudflare Domains
|
||||
|
||||
**Last Updated:** 2026-02-05
|
||||
**Last Updated:** 2026-03-27
|
||||
**Status:** Active
|
||||
**Purpose:** Achieve and verify complete end-to-end success for all public endpoints reachable via Cloudflare DNS (and optionally Fastly). All domains must pass DNS, SSL, and HTTP/RPC/WebSocket tests.
|
||||
|
||||
@@ -38,7 +38,7 @@ The verification script covers all public domains that require access from Cloud
|
||||
| mim4u.org, www, secure, training | web | 192.168.11.37:80 |
|
||||
| sankofa.nexus, www | web | 192.168.11.51:3000 |
|
||||
| phoenix.sankofa.nexus, www | web | 192.168.11.50:4000 |
|
||||
| the-order.sankofa.nexus | web | TBD |
|
||||
| the-order.sankofa.nexus, www.the-order.sankofa.nexus | web | NPM → `192.168.11.39:80` (10210 HAProxy → `192.168.11.51:3000`); www → 301 apex |
|
||||
| studio.sankofa.nexus | web | 192.168.11.72:8000 |
|
||||
| rpc.public-0138.defi-oracle.io | rpc-http | 192.168.11.240:443 |
|
||||
| rpc.defi-oracle.io | rpc-http | 192.168.11.221:8545 |
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Gaps, Placeholders, and Recommendations — Consolidated
|
||||
|
||||
**Last Updated:** 2026-03-02
|
||||
**Last Updated:** 2026-03-27
|
||||
**Purpose:** Single reference for all identified gaps, placeholders, and actionable recommendations across the repository.
|
||||
|
||||
**Related:** [REQUIRED_FIXES_UPDATES_GAPS.md](REQUIRED_FIXES_UPDATES_GAPS.md) | [00-meta/GAPS_STATUS.md](00-meta/GAPS_STATUS.md) | [PLACEHOLDERS_AND_TBD.md](PLACEHOLDERS_AND_TBD.md) | [NOT_IMPLEMENTED_FULL_SCOPE](00-meta/NOT_IMPLEMENTED_FULL_SCOPE.md) | [ALL_RECOMMENDATIONS_AND_IMPROVEMENTS_LIST.md](00-meta/ALL_RECOMMENDATIONS_AND_IMPROVEMENTS_LIST.md) | [04-configuration/VERIFICATION_GAPS_AND_TODOS.md](04-configuration/VERIFICATION_GAPS_AND_TODOS.md). **Where to update when completed:** [00-meta/BLITZKRIEG_SOURCE_DOCUMENT_INDEX.md](00-meta/BLITZKRIEG_SOURCE_DOCUMENT_INDEX.md).
|
||||
|
||||
**Updates (2026-03-27):** Sankofa / The Order NPM routing documented as **live** (NPM → 10210 `192.168.11.39:80` → portal `:3000`). See [ALL_VMIDS_ENDPOINTS.md](04-configuration/ALL_VMIDS_ENDPOINTS.md), [SANKOFA_CUTOVER_PLAN.md](04-configuration/SANKOFA_CUTOVER_PLAN.md) v1.1. Section 2.1 below updated accordingly.
|
||||
|
||||
**Updates (2026-03-02):** All in-repo actionable gaps from REQUIRED_FIXES (§§1–6), DETAILED_GAPS, and VERIFICATION_GAPS addressed or documented. See [00-meta/GAPS_STATUS.md](00-meta/GAPS_STATUS.md). Fixes: verify-all-systems Explorer/Wallet timeout 25s; nginx order documented; runbook .env production note added.
|
||||
|
||||
**Updates (2026-02-05):** API keys in token-aggregation and root `.env.example` replaced with placeholders. `docs/TODO.md` and `smom-dbis-138/docs/TODO.md` created; smom-dbis-138 status-report links to `../tasks/TODO.md` fixed. RPC_ENDPOINTS_MASTER Sankofa section updated (sankofa.nexus → 7801/.51:3000, phoenix → 7800/.50:4000; the-order TBD). dbis_core nostro-vostro emergency hotline and example URLs set to "To be configured".
|
||||
@@ -29,12 +31,12 @@
|
||||
|
||||
## 2. Configuration and DNS placeholders
|
||||
|
||||
### 2.1 Sankofa / The Order (TBD)
|
||||
### 2.1 Sankofa / The Order (routing — **done 2026-03**)
|
||||
|
||||
| Item | Location | Recommendation |
|
||||
|------|----------|----------------|
|
||||
| `the-order.sankofa.nexus` | [ALL_VMIDS_ENDPOINTS.md](04-configuration/ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER.md](04-configuration/RPC_ENDPOINTS_MASTER.md) | Marked TBD / not yet configured. Once The Order portal is deployed, add NPMplus proxy host and document IP:port in RPC_ENDPOINTS_MASTER and ALL_VMIDS_ENDPOINTS. |
|
||||
| Sankofa cutover plan | [SANKOFA_CUTOVER_PLAN.md](04-configuration/SANKOFA_CUTOVER_PLAN.md) | Replace `<TARGET_IP>`, `<TARGET_PORT>`, and table TBDs with actual Sankofa service IPs/ports when deployed. |
|
||||
| Item | Location | Status / recommendation |
|
||||
|------|----------|-------------------------|
|
||||
| `the-order.sankofa.nexus` (+ `www`) | [ALL_VMIDS_ENDPOINTS.md](04-configuration/ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER.md](04-configuration/RPC_ENDPOINTS_MASTER.md) | **Live:** NPM → `192.168.11.39:80` (VMID 10210 HAProxy) → `192.168.11.51:3000`. Provision: `scripts/deployment/provision-order-haproxy-10210.sh`. |
|
||||
| Sankofa cutover plan | [SANKOFA_CUTOVER_PLAN.md](04-configuration/SANKOFA_CUTOVER_PLAN.md) | **Updated v1.1 (2026-03-27):** live backend tables + historical procedure. Replace any remaining `<TARGET_*>` in copy-paste API examples if you reuse them for new hosts. |
|
||||
|
||||
### 2.2 sankofa.nexus / phoenix.sankofa.nexus routing (authoritative)
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ Documents are archived when:
|
||||
- **05-network-superseded/** — CLOUDFLARE_TUNNEL_ROUTING_ARCHITECTURE, CENTRAL_NGINX_ROUTING_SETUP (use CLOUDFLARE_ROUTING_MASTER and RPC_ENDPOINTS_MASTER instead).
|
||||
- **00-meta-pruned/** — 27 one-off status/completion/planning/script-audit docs (batch 1: 10; batch 2: 17). Use NEXT_STEPS_OPERATOR, REMAINING_WORK_DETAILED_STEPS, OPERATIONAL_RUNBOOKS.
|
||||
- **verification-evidence-old/** — Pruned 2026-02-08: verification run folders before 2026-02-06 (72 folders). Current runs remain in docs/04-configuration/verification-evidence/.
|
||||
- **deployment-reports/** — Deployment/cutover snapshots (e.g. 2026-01). **Obsolete for routing:** see [deployment-reports/README.md](deployment-reports/README.md) and live docs above.
|
||||
|
||||
## Accessing Archived Documents
|
||||
|
||||
@@ -75,5 +76,5 @@ If an archived document needs to be restored, move it back to the main `docs/` d
|
||||
|
||||
**2026-02-20:** Batch 4 — 12 one-off/dated 00-meta docs → 00-meta-pruned. Batch 5 — CONTINUE_AND_COMPLETE, FULL_PARALLEL_RUN_LOG → 00-meta-pruned. ALL_TASKS_COMPLETE → root-status-reports. **Root cleanup:** 40+ status/temp/screenshot files from project root → [root-cleanup-20260220/](root-cleanup-20260220/README.md).
|
||||
|
||||
**Last Updated:** 2026-02-20
|
||||
**Last Updated:** 2026-03-27
|
||||
|
||||
|
||||
21
docs/archive/deployment-reports/README.md
Normal file
21
docs/archive/deployment-reports/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Archived deployment reports (historical)
|
||||
|
||||
Markdown files in this folder are **time-stamped snapshots** (mostly **2026-01**). They may still describe:
|
||||
|
||||
- `the-order.sankofa.nexus` as **TBD** or pointing at **192.168.11.140** (Blockscout)
|
||||
- Sankofa/Phoenix as “not deployed” or on temporary backends
|
||||
|
||||
**Do not use these tables for operations.**
|
||||
|
||||
**Current source of truth**
|
||||
|
||||
- [ALL_VMIDS_ENDPOINTS.md](../../04-configuration/ALL_VMIDS_ENDPOINTS.md)
|
||||
- [RPC_ENDPOINTS_MASTER.md](../../04-configuration/RPC_ENDPOINTS_MASTER.md)
|
||||
- [SANKOFA_CUTOVER_PLAN.md](../../04-configuration/SANKOFA_CUTOVER_PLAN.md) (v1.1+)
|
||||
- NPM fleet script: `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`
|
||||
|
||||
**The Order (summary):** NPM → `192.168.11.39:80` (VMID **10210** HAProxy) → portal `192.168.11.51:3000`.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2026-03-27
|
||||
Submodule explorer-monorepo updated: d02ee71cf6...06e2c7a29e
2
gru-docs
2
gru-docs
Submodule gru-docs updated: 188218ec10...c3a61dd5dd
Submodule metamask-integration updated: 25c96e210a...522ce98806
@@ -91,7 +91,7 @@ This document lists all tasks that were mentioned or identified during the conta
|
||||
- [ ] Set up dashboards and alerts
|
||||
|
||||
#### Infrastructure Services (4 containers)
|
||||
- **CT 10210** (order-haproxy) - HAProxy needs installation
|
||||
- **CT 10210** (order-haproxy) — **HAProxy installed 2026-03-27** (`config/haproxy/order-haproxy-10210.cfg.template`, `scripts/deployment/provision-order-haproxy-10210.sh`; unprivileged CT may need one-time host `chown -R 100000:100000` on mounted rootfs if apt fails)
|
||||
- **CT 10230** (order-vault) - Vault needs installation
|
||||
- **CT 5200** (cacti-1) - Cacti needs installation
|
||||
- **CT 6000** (fabric-1) - Hyperledger Fabric needs installation
|
||||
@@ -174,7 +174,7 @@ This document lists all tasks that were mentioned or identified during the conta
|
||||
|
||||
**Tasks:**
|
||||
- [ ] Configure Order services to connect to PostgreSQL (192.168.11.44) and Redis (192.168.11.38)
|
||||
- [ ] Configure DBIS services to connect to PostgreSQL (192.168.11.105) and Redis (192.168.11.120)
|
||||
- [ ] Configure DBIS services to connect to PostgreSQL (192.168.11.105) and Redis (192.168.11.125)
|
||||
- [ ] Configure frontend services to connect to API services
|
||||
- [ ] Configure monitoring services to scrape targets
|
||||
- [ ] Configure HAProxy backends
|
||||
|
||||
@@ -121,7 +121,7 @@ echo "$ACTIVE_CERTS" | while IFS='|' read -r cert_id domain_names; do
|
||||
done
|
||||
|
||||
# Check for duplicates in sankofa.nexus domains
|
||||
SANKOFA_DOMAINS="sankofa.nexus,www.sankofa.nexus,phoenix.sankofa.nexus,www.phoenix.sankofa.nexus,the-order.sankofa.nexus"
|
||||
SANKOFA_DOMAINS="sankofa.nexus,www.sankofa.nexus,phoenix.sankofa.nexus,www.phoenix.sankofa.nexus,the-order.sankofa.nexus,www.the-order.sankofa.nexus"
|
||||
SANKOFA_CERTS=$(echo "$CERT_JSON" | jq -r ".[] | select(.is_deleted == 0) | select(.domain_names | tostring | test(\"sankofa.nexus\")) | .id" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$SANKOFA_CERTS" ]; then
|
||||
|
||||
78
scripts/deployment/provision-order-haproxy-10210.sh
Executable file
78
scripts/deployment/provision-order-haproxy-10210.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install HAProxy in LXC 10210 (order-haproxy) and proxy :80 → Sankofa/Order portal (Next.js).
|
||||
# Requires SSH to Proxmox host that runs CT 10210 (default: r630-01). See config/ip-addresses.conf.
|
||||
# Usage: ./scripts/deployment/provision-order-haproxy-10210.sh [--dry-run]
|
||||
#
|
||||
# One-time repair (unprivileged CT with host uid 0 on disk → "nobody" inside, apt broken): on Proxmox host,
|
||||
# pct stop 10210 && pct mount 10210 && chown -R 100000:100000 /var/lib/lxc/10210/rootfs && pct unmount 10210 && pct start 10210
|
||||
# (Default Proxmox idmap: container root = 100000 on host.)
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "$PROJECT_ROOT/config/ip-addresses.conf"
|
||||
|
||||
DRY_RUN=false
|
||||
for a in "$@"; do [[ "$a" == "--dry-run" ]] && DRY_RUN=true; done
|
||||
|
||||
PROXMOX="${PROXMOX_ORDER_HAPROXY_NODE:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${ORDER_HAPROXY_VMID:-10210}"
|
||||
BACKEND_HOST="${ORDER_HAPROXY_BACKEND_HOST:-${IP_SANKOFA_PORTAL:-192.168.11.51}}"
|
||||
BACKEND_PORT="${ORDER_HAPROXY_BACKEND_PORT:-${SANKOFA_PORTAL_PORT:-3000}}"
|
||||
TEMPLATE="$PROJECT_ROOT/config/haproxy/order-haproxy-10210.cfg.template"
|
||||
|
||||
if [[ ! -r "$TEMPLATE" ]]; then
|
||||
echo "❌ Missing template: $TEMPLATE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CFG=$(sed -e "s/__BACKEND_HOST__/${BACKEND_HOST}/g" -e "s/__BACKEND_PORT__/${BACKEND_PORT}/g" "$TEMPLATE")
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Provision order-haproxy (CT $VMID on $PROXMOX)"
|
||||
echo " Backend: http://${BACKEND_HOST}:${BACKEND_PORT}"
|
||||
echo " Dry-run: $DRY_RUN"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
echo "$CFG"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
remote_run() {
|
||||
ssh -o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new \
|
||||
"${PROXMOX_SSH_USER:-root}@$PROXMOX" "$@"
|
||||
}
|
||||
|
||||
if ! remote_run "pct status $VMID" 2>/dev/null | grep -q running; then
|
||||
echo "❌ CT $VMID is not running on $PROXMOX"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
remote_run "pct exec $VMID -- bash -c '
|
||||
set -e
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
if ! dpkg -s haproxy >/dev/null 2>&1; then
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq haproxy
|
||||
fi
|
||||
'"
|
||||
|
||||
echo "$CFG" | remote_run "pct exec $VMID -- bash -c 'cat > /etc/haproxy/haproxy.cfg'"
|
||||
|
||||
remote_run "pct exec $VMID -- bash -c '
|
||||
set -e
|
||||
haproxy -c -f /etc/haproxy/haproxy.cfg
|
||||
systemctl enable haproxy
|
||||
systemctl restart haproxy
|
||||
sleep 1
|
||||
systemctl is-active --quiet haproxy
|
||||
echo OK: haproxy active
|
||||
command -v ss >/dev/null && ss -lntp | grep -E \":80|:443\" || true
|
||||
'"
|
||||
|
||||
IP_ORDER="${IP_ORDER_HAPROXY:-192.168.11.39}"
|
||||
echo ""
|
||||
echo "✅ Done. From LAN: curl -sS -o /dev/null -w '%{http_code}\\n' http://${IP_ORDER}:80/"
|
||||
echo " Then NPM: THE_ORDER_UPSTREAM_IP=${IP_ORDER} THE_ORDER_UPSTREAM_PORT=80 bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh"
|
||||
46
scripts/deployment/sankofa-portal-ensure-nextauth-on-ct.sh
Executable file
46
scripts/deployment/sankofa-portal-ensure-nextauth-on-ct.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
# Ensure CT 7801 (or VMID) has NEXTAUTH_URL (public NPM host) and NEXTAUTH_SECRET.
|
||||
# Does not print secret values. Safe to run after every portal sync.
|
||||
#
|
||||
# Env: PROXMOX_HOST, SANKOFA_PORTAL_VMID, SANKOFA_PORTAL_CT_DIR, SANKOFA_PORTAL_NEXTAUTH_URL
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${SANKOFA_PORTAL_VMID:-7801}"
|
||||
CT_APP_DIR="${SANKOFA_PORTAL_CT_DIR:-/opt/sankofa-portal}"
|
||||
SERVICE_NAME="${SANKOFA_PORTAL_SERVICE:-sankofa-portal}"
|
||||
NEXTAUTH_PUBLIC_URL="${SANKOFA_PORTAL_NEXTAUTH_URL:-https://sankofa.nexus}"
|
||||
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
||||
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- bash -s" <<EOF
|
||||
set -euo pipefail
|
||||
mkdir -p "${CT_APP_DIR}"
|
||||
cd "${CT_APP_DIR}"
|
||||
|
||||
# .env.local (preferred for secrets / overrides)
|
||||
ENV_LOCAL=".env.local"
|
||||
touch "\$ENV_LOCAL"
|
||||
if grep -q '^NEXTAUTH_URL=' "\$ENV_LOCAL" 2>/dev/null; then
|
||||
sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=${NEXTAUTH_PUBLIC_URL}|" "\$ENV_LOCAL"
|
||||
else
|
||||
printf '%s\n' "NEXTAUTH_URL=${NEXTAUTH_PUBLIC_URL}" >> "\$ENV_LOCAL"
|
||||
fi
|
||||
if ! grep -q '^NEXTAUTH_SECRET=' "\$ENV_LOCAL" 2>/dev/null; then
|
||||
printf '%s\n' "NEXTAUTH_SECRET=\$(openssl rand -hex 32)" >> "\$ENV_LOCAL"
|
||||
fi
|
||||
|
||||
# .env on CT often ships with LAN NEXTAUTH_URL; Next merges both — align to public URL.
|
||||
if [[ -f .env ]] && grep -q '^NEXTAUTH_URL=' .env 2>/dev/null; then
|
||||
sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=${NEXTAUTH_PUBLIC_URL}|" .env
|
||||
fi
|
||||
EOF
|
||||
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- systemctl restart ${SERVICE_NAME}"
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- systemctl is-active ${SERVICE_NAME}"
|
||||
|
||||
echo "NextAuth env ensured on CT ${VMID} (NEXTAUTH_URL=${NEXTAUTH_PUBLIC_URL}; secret added only if missing). Service restarted."
|
||||
110
scripts/deployment/sync-sankofa-portal-7801.sh
Executable file
110
scripts/deployment/sync-sankofa-portal-7801.sh
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
# Sync Sankofa Next.js portal source to LXC 7801, install deps, production build, restart systemd.
|
||||
# Prerequisites: SSH root@PROXMOX_HOST; portal tree at SANKOFA_PORTAL_SRC (default: sibling ../Sankofa/portal).
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/deployment/sync-sankofa-portal-7801.sh [--dry-run]
|
||||
# Env:
|
||||
# PROXMOX_HOST (default 192.168.11.11), SANKOFA_PORTAL_VMID (7801), SANKOFA_PORTAL_SRC, IP_SANKOFA_PORTAL (for post-check only)
|
||||
# SANKOFA_PORTAL_NEXTAUTH_URL (default https://sankofa.nexus) — applied on CT after build
|
||||
#
|
||||
# See: docs/03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md (Phoenix CT 7801)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${SANKOFA_PORTAL_VMID:-7801}"
|
||||
CT_APP_DIR="${SANKOFA_PORTAL_CT_DIR:-/opt/sankofa-portal}"
|
||||
SERVICE_NAME="${SANKOFA_PORTAL_SERVICE:-sankofa-portal}"
|
||||
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
||||
|
||||
DEFAULT_SRC="${PROJECT_ROOT}/../Sankofa/portal"
|
||||
if [[ -d "$DEFAULT_SRC" ]]; then
|
||||
SANKOFA_PORTAL_SRC="${SANKOFA_PORTAL_SRC:-$DEFAULT_SRC}"
|
||||
else
|
||||
SANKOFA_PORTAL_SRC="${SANKOFA_PORTAL_SRC:-}"
|
||||
fi
|
||||
|
||||
DRY_RUN=false
|
||||
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
echo "=== Sync Sankofa portal → CT ${VMID} (${CT_APP_DIR}) ==="
|
||||
echo "Proxmox: ${PROXMOX_HOST}"
|
||||
echo "Source: ${SANKOFA_PORTAL_SRC:-<unset>}"
|
||||
echo ""
|
||||
|
||||
if [[ -z "$SANKOFA_PORTAL_SRC" || ! -d "$SANKOFA_PORTAL_SRC" ]]; then
|
||||
echo "ERROR: Set SANKOFA_PORTAL_SRC to the portal directory (clone of Sankofa/portal)."
|
||||
echo "Example: SANKOFA_PORTAL_SRC=/path/to/Sankofa/portal $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v tar >/dev/null; then
|
||||
echo "ERROR: tar required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP_TGZ="${TMPDIR:-/tmp}/sankofa-portal-sync-$$.tgz"
|
||||
REMOTE_TGZ="/tmp/sankofa-portal-sync-$$.tgz"
|
||||
CT_TGZ="/tmp/sankofa-portal-sync.tgz"
|
||||
|
||||
cleanup() { rm -f "$TMP_TGZ"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[DRY-RUN] tar (exclude node_modules,.next,.git) → $TMP_TGZ"
|
||||
echo "[DRY-RUN] scp → root@${PROXMOX_HOST}:${REMOTE_TGZ}"
|
||||
echo "[DRY-RUN] ssh pct push ${VMID} … && pct exec ${VMID} systemctl stop ${SERVICE_NAME}"
|
||||
echo "[DRY-RUN] pct exec: tar xf into ${CT_APP_DIR}; pnpm install; pnpm build; systemctl start ${SERVICE_NAME}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📦 Archiving portal (excluding node_modules, .next, .git, .env / .env.local)…"
|
||||
tar czf "$TMP_TGZ" \
|
||||
--exclude=node_modules \
|
||||
--exclude=.next \
|
||||
--exclude=.git \
|
||||
--exclude=.env.local \
|
||||
--exclude=.env \
|
||||
-C "$SANKOFA_PORTAL_SRC" .
|
||||
|
||||
echo "📤 Copy to Proxmox host…"
|
||||
scp $SSH_OPTS "$TMP_TGZ" "root@${PROXMOX_HOST}:${REMOTE_TGZ}"
|
||||
|
||||
echo "📥 Push into CT ${VMID} and build…"
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" bash -s <<REMOTE_EOF
|
||||
set -euo pipefail
|
||||
pct push ${VMID} ${REMOTE_TGZ} ${CT_TGZ}
|
||||
rm -f ${REMOTE_TGZ}
|
||||
pct exec ${VMID} -- systemctl stop ${SERVICE_NAME} || true
|
||||
pct exec ${VMID} -- bash -lc 'set -euo pipefail
|
||||
mkdir -p ${CT_APP_DIR}
|
||||
cd ${CT_APP_DIR}
|
||||
tar xzf ${CT_TGZ}
|
||||
rm -f ${CT_TGZ}
|
||||
command -v pnpm >/dev/null || { echo "ERROR: pnpm missing in CT"; exit 1; }
|
||||
pnpm install
|
||||
pnpm build
|
||||
'
|
||||
pct exec ${VMID} -- systemctl start ${SERVICE_NAME}
|
||||
pct exec ${VMID} -- systemctl is-active ${SERVICE_NAME}
|
||||
REMOTE_EOF
|
||||
|
||||
echo ""
|
||||
echo "🔐 Ensuring NextAuth URL/secret on CT (see sankofa-portal-ensure-nextauth-on-ct.sh)…"
|
||||
SANKOFA_PORTAL_NEXTAUTH_URL="${SANKOFA_PORTAL_NEXTAUTH_URL:-https://sankofa.nexus}"
|
||||
export SANKOFA_PORTAL_VMID SANKOFA_PORTAL_CT_DIR SANKOFA_PORTAL_SERVICE SANKOFA_PORTAL_NEXTAUTH_URL PROXMOX_HOST
|
||||
bash "${SCRIPT_DIR}/sankofa-portal-ensure-nextauth-on-ct.sh"
|
||||
|
||||
echo ""
|
||||
echo "✅ Done. Verify:"
|
||||
echo " curl -sS http://${IP_SANKOFA_PORTAL:-192.168.11.51}:3000/ | head -c 120"
|
||||
echo " curl -sSI https://sankofa.nexus/api/auth/signin | head -n 15"
|
||||
echo " https://sankofa.nexus/ (via NPM)"
|
||||
echo ""
|
||||
echo "Override public auth URL: SANKOFA_PORTAL_NEXTAUTH_URL=https://portal.sankofa.nexus $0"
|
||||
28
scripts/deployment/tsunamiswap-vm-5010-provision.sh
Executable file
28
scripts/deployment/tsunamiswap-vm-5010-provision.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
# TsunamiSwap VM 5010 — inventory check + example qm lines (always informational).
|
||||
# Ref: docs/00-meta/OPERATOR_READY_CHECKLIST.md section 5c.
|
||||
#
|
||||
# Usage: ./scripts/deployment/tsunamiswap-vm-5010-provision.sh
|
||||
# Env: PROXMOX_HOST (default 192.168.11.11), TSUNAMI_VMID (5010)
|
||||
#
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${TSUNAMI_VMID:-5010}"
|
||||
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
||||
|
||||
echo "=== TsunamiSwap VM ${VMID} on ${PROXMOX_HOST} ==="
|
||||
if ssh $SSH_OPTS "root@${PROXMOX_HOST}" "qm status ${VMID} 2>/dev/null" | grep -q .; then
|
||||
echo "Status: VMID ${VMID} exists."
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "qm status ${VMID}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Status: VMID ${VMID} not found (still to provision)."
|
||||
echo "Checklist target: r630-01, 8 vCPU, 16 GB RAM, ~160 GB, IP e.g. 192.168.11.91."
|
||||
echo "Create with your Proxmox template/ISO, then run setup/deploy scripts if available."
|
||||
exit 0
|
||||
62
scripts/maintenance/prune-e2e-verification-evidence.sh
Executable file
62
scripts/maintenance/prune-e2e-verification-evidence.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
# List or remove old E2E report dirs under docs/04-configuration/verification-evidence/e2e-verification-*
|
||||
# Default: dry-run only. Deletes dirs older than KEEP_DAYS (default 45). Never deletes the two latest by mtime.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
EVIDENCE="$PROJECT_ROOT/docs/04-configuration/verification-evidence"
|
||||
|
||||
DRY_RUN=true
|
||||
for a in "$@"; do
|
||||
[[ "$a" == "--apply" ]] && DRY_RUN=false
|
||||
done
|
||||
|
||||
KEEP_DAYS="${KEEP_DAYS:-45}"
|
||||
MIN_KEEP="${MIN_KEEP:-2}"
|
||||
|
||||
if [[ ! -d "$EVIDENCE" ]]; then
|
||||
echo "No directory: $EVIDENCE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mapfile -t ALL < <(find "$EVIDENCE" -maxdepth 1 -type d -name 'e2e-verification-*' -printf '%T@ %p\n' 2>/dev/null | sort -n | awk '{print $2}')
|
||||
if [[ ${#ALL[@]} -eq 0 ]]; then
|
||||
echo "No e2e-verification-* directories under $EVIDENCE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Newest MIN_KEEP paths (never prune)
|
||||
declare -A PROTECT
|
||||
for ((i = ${#ALL[@]} - MIN_KEEP; i < ${#ALL[@]}; i++)); do
|
||||
[[ $i -ge 0 ]] || continue
|
||||
PROTECT["${ALL[$i]}"]=1
|
||||
done
|
||||
|
||||
now=$(date +%s)
|
||||
cutoff=$((now - KEEP_DAYS * 86400))
|
||||
removed=0
|
||||
checked=0
|
||||
|
||||
for dir in "${ALL[@]}"; do
|
||||
[[ -n "${PROTECT[$dir]:-}" ]] && continue
|
||||
mt=$(stat -c %Y "$dir" 2>/dev/null || echo 0)
|
||||
(( checked++ )) || true
|
||||
if (( mt < cutoff )); then
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
echo "Would remove (older than ${KEEP_DAYS}d): $dir"
|
||||
else
|
||||
rm -rf "$dir"
|
||||
echo "Removed: $dir"
|
||||
fi
|
||||
(( removed++ )) || true
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
echo ""
|
||||
echo "Dry-run. Protected newest $MIN_KEEP dir(s). Set KEEP_DAYS=$KEEP_DAYS."
|
||||
echo "To delete: KEEP_DAYS=$KEEP_DAYS bash $0 --apply"
|
||||
else
|
||||
echo "Done. Removed $removed director(y/ies); checked $checked (excluding protected)."
|
||||
fi
|
||||
@@ -69,9 +69,8 @@ const DOMAINS = [
|
||||
|
||||
// www.* domains that redirect to parent domains
|
||||
const REDIRECT_DOMAINS = [
|
||||
// REMOVED: Sankofa redirects - services not deployed
|
||||
// { domain: 'www.sankofa.nexus', redirectTo: 'sankofa.nexus' },
|
||||
// { domain: 'www.phoenix.sankofa.nexus', redirectTo: 'phoenix.sankofa.nexus' },
|
||||
// Sankofa www → apex: use scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh (301 via proxy host advanced_config).
|
||||
// Do not add duplicate NPM "Redirection Host" rows for www.sankofa / www.phoenix here while those names are proxy hosts with LE certs.
|
||||
{ domain: 'www.mim4u.org', redirectTo: 'mim4u.org' },
|
||||
];
|
||||
|
||||
|
||||
@@ -3,21 +3,17 @@
|
||||
# Auth failures: only a short error message is printed by default. For a redacted JSON snippet set NPM_DEBUG_AUTH=1.
|
||||
set -euo pipefail
|
||||
|
||||
# Load IP configuration
|
||||
# Repo root (…/proxmox) — same as second block below; load IPs once from the right path
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
|
||||
# Update existing NPMplus proxy hosts via API with correct VMIDs and IPs
|
||||
# This script updates existing proxy hosts, not creates new ones.
|
||||
# PUT payload includes only forward_* / websocket / block_exploits — existing certificate_id and ssl_forced are preserved by NPMplus.
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
# Preserve NPM credentials from environment so "export NPM_PASSWORD=...; ./script" works
|
||||
_orig_npm_url="${NPM_URL:-}"
|
||||
_orig_npm_email="${NPM_EMAIL:-}"
|
||||
@@ -58,11 +54,12 @@ echo ""
|
||||
|
||||
# NPMplus API can stall indefinitely without --max-time (override e.g. NPM_CURL_MAX_TIME=300)
|
||||
NPM_CURL_MAX_TIME="${NPM_CURL_MAX_TIME:-120}"
|
||||
curl_npm() { curl -s -k --connect-timeout 10 --max-time "$NPM_CURL_MAX_TIME" "$@"; }
|
||||
# -L: port 81 often 301s HTTP→HTTPS; POST /api/tokens without -L returns 400 "Payload is undefined"
|
||||
curl_npm() { curl -s -k -L --connect-timeout 10 --max-time "$NPM_CURL_MAX_TIME" "$@"; }
|
||||
|
||||
# Connection check (NPMplus is on LAN 192.168.11.x). Try HTTP if HTTPS fails; try alternate IP .166/.167 if unreachable.
|
||||
echo "🔐 Authenticating to NPMplus..."
|
||||
try_connect() { curl -s -k -o /dev/null --connect-timeout 5 --max-time 15 "$1" 2>/dev/null; }
|
||||
try_connect() { curl -s -k -L -o /dev/null --connect-timeout 5 --max-time 15 "$1" 2>/dev/null; }
|
||||
if ! try_connect "$NPM_URL/"; then
|
||||
# Try HTTP instead of HTTPS (NPM admin often listens on HTTP only on port 81)
|
||||
http_url="${NPM_URL/https:/http:}"
|
||||
@@ -73,7 +70,7 @@ if ! try_connect "$NPM_URL/"; then
|
||||
alt_url=""
|
||||
if [[ "$NPM_URL" == *"${IP_NPMPLUS_ETH0}"* ]]; then
|
||||
alt_url="https://${IP_NPMPLUS}:81"
|
||||
elif [[ "$NPM_URL" == *"${IP_NPMPLUS}"* ]] || [[ "$NPM_URL" == *"${IP_NPMPLUS_ETH1}"* ]]; then
|
||||
elif [[ "$NPM_URL" == *"${IP_NPMPLUS}"* ]] || [[ -n "${IP_NPMPLUS_ETH1:-}" && "$NPM_URL" == *"${IP_NPMPLUS_ETH1}"* ]]; then
|
||||
alt_url="https://${IP_NPMPLUS_ETH0}:81"
|
||||
fi
|
||||
connected=""
|
||||
@@ -134,13 +131,46 @@ resolve_proxy_host_id() {
|
||||
.id' 2>/dev/null | head -n1
|
||||
}
|
||||
|
||||
# www → apex redirect: only https://hostname[:port] (no path/query); rejects characters that could break nginx advanced_config.
|
||||
validate_canonical_https_redirect() {
|
||||
local url="$1"
|
||||
local ctx="${2:-canonical_https}"
|
||||
if [[ "$url" != https://* ]]; then
|
||||
echo " ❌ $ctx: canonical_https must start with https:// (got: $url)"
|
||||
return 1
|
||||
fi
|
||||
if [[ "$url" == *$'\n'* || "$url" == *$'\r'* || "$url" == *' '* || "$url" == *';'* || "$url" == *'$'* || "$url" == *'`'* ]]; then
|
||||
echo " ❌ $ctx: canonical_https contains forbidden characters (no spaces, semicolons, dollar, backticks)"
|
||||
return 1
|
||||
fi
|
||||
local rest="${url#https://}"
|
||||
if [[ "$rest" == */* ]]; then
|
||||
echo " ❌ $ctx: canonical_https must not include a path (got: $url)"
|
||||
return 1
|
||||
fi
|
||||
if ! [[ "$rest" =~ ^[a-zA-Z0-9._-]+(:[0-9]{1,5})?$ ]]; then
|
||||
echo " ❌ $ctx: canonical_https must be https://hostname or https://hostname:port (got: $url)"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to add proxy host (POST) when domain does not exist
|
||||
# Optional 6th arg: canonical HTTPS apex for www-style hosts (sets advanced_config 301 → apex$request_uri)
|
||||
add_proxy_host() {
|
||||
local domain=$1
|
||||
local forward_host=$2
|
||||
local forward_port=$3
|
||||
local websocket=$4
|
||||
local block_exploits=${5:-false}
|
||||
local canonical_https="${6:-}"
|
||||
local adv_line=""
|
||||
if [ -n "$canonical_https" ] && ! validate_canonical_https_redirect "$canonical_https" "add_proxy_host($domain)"; then
|
||||
return 1
|
||||
fi
|
||||
if [ -n "$canonical_https" ]; then
|
||||
adv_line="return 301 ${canonical_https}\$request_uri;"
|
||||
fi
|
||||
local payload
|
||||
payload=$(jq -n \
|
||||
--arg domain "$domain" \
|
||||
@@ -148,6 +178,7 @@ add_proxy_host() {
|
||||
--argjson port "$forward_port" \
|
||||
--argjson ws "$websocket" \
|
||||
--argjson block_exploits "$([ "$block_exploits" = "true" ] && echo true || echo false)" \
|
||||
--arg adv "$adv_line" \
|
||||
'{
|
||||
domain_names: [$domain],
|
||||
forward_scheme: "http",
|
||||
@@ -157,7 +188,7 @@ add_proxy_host() {
|
||||
block_exploits: $block_exploits,
|
||||
certificate_id: null,
|
||||
ssl_forced: false
|
||||
}' 2>/dev/null)
|
||||
} + (if $adv != "" then {advanced_config: $adv} else {} end)' 2>/dev/null)
|
||||
if [ -z "$payload" ]; then
|
||||
echo " ❌ Failed to build payload for $domain"
|
||||
return 1
|
||||
@@ -170,7 +201,11 @@ add_proxy_host() {
|
||||
local id
|
||||
id=$(echo "$resp" | jq -r '.id // empty' 2>/dev/null)
|
||||
if [ -n "$id" ] && [ "$id" != "null" ]; then
|
||||
echo " ✅ Added: $domain -> http://${forward_host}:${forward_port} (WebSocket: $websocket)"
|
||||
if [ -n "$canonical_https" ]; then
|
||||
echo " ✅ Added: $domain -> http://${forward_host}:${forward_port} (WebSocket: $websocket) + 301 → ${canonical_https}\$request_uri"
|
||||
else
|
||||
echo " ✅ Added: $domain -> http://${forward_host}:${forward_port} (WebSocket: $websocket)"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
local err
|
||||
@@ -180,7 +215,7 @@ add_proxy_host() {
|
||||
echo " ↪ Host likely exists; refreshing list and attempting PUT update..."
|
||||
PROXY_HOSTS_JSON=$(curl_npm -X GET "$NPM_URL/api/nginx/proxy-hosts" \
|
||||
-H "Authorization: Bearer $TOKEN")
|
||||
if update_proxy_host "$domain" "http://${forward_host}:${forward_port}" "$websocket" "$block_exploits"; then
|
||||
if update_proxy_host "$domain" "http://${forward_host}:${forward_port}" "$websocket" "$block_exploits" "$canonical_https"; then
|
||||
echo " ✅ Updated after duplicate-create error: $domain"
|
||||
return 0
|
||||
fi
|
||||
@@ -191,12 +226,17 @@ add_proxy_host() {
|
||||
|
||||
# Function to update proxy host
|
||||
# block_exploits: set false for RPC hosts (JSON-RPC uses POST to /; block_exploits can cause 405)
|
||||
# Optional 5th arg: canonical HTTPS URL (no path) — sets advanced_config to 301 redirect (www → apex)
|
||||
update_proxy_host() {
|
||||
local domain=$1
|
||||
local target=$2
|
||||
local websocket=$3
|
||||
local block_exploits=${4:-true}
|
||||
|
||||
local canonical_https="${5:-}"
|
||||
if [ -n "$canonical_https" ] && ! validate_canonical_https_redirect "$canonical_https" "update_proxy_host($domain)"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Parse target URL
|
||||
local scheme=$(echo "$target" | sed -E 's|^([^:]+):.*|\1|')
|
||||
local hostname=$(echo "$target" | sed -E 's|^[^/]+//([^:]+):.*|\1|')
|
||||
@@ -208,6 +248,17 @@ update_proxy_host() {
|
||||
hostname=$(echo "$target" | sed -E 's|^https://([^:]+):.*|\1|')
|
||||
port=$(echo "$target" | sed -E 's|^https://[^:]+:([0-9]+).*|\1|' || echo "443")
|
||||
fi
|
||||
|
||||
# Reject bad parses (e.g. https://:443 when forward IP env is empty) — NPM returns errors without .id and jq message is empty.
|
||||
if [[ -z "$hostname" || "$hostname" == *"://"* || "$hostname" == *"/"* ]]; then
|
||||
echo " ❌ Invalid forward target for $domain (check env / ip-addresses.conf): $target → host=[$hostname]"
|
||||
return 1
|
||||
fi
|
||||
port="${port//[^0-9]/}"
|
||||
if [[ -z "$port" || "$port" -lt 1 || "$port" -gt 65535 ]]; then
|
||||
echo " ❌ Invalid forward port for $domain: $target (parsed port=$port)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get host ID (case-insensitive); refresh once if missing (stale list / race with other writers)
|
||||
HOST_ID=$(resolve_proxy_host_id "$domain" "$PROXY_HOSTS_JSON")
|
||||
@@ -228,19 +279,24 @@ update_proxy_host() {
|
||||
# block_exploits must be false for RPC so POST to / is allowed (JSON-RPC); explicit false fixes 405
|
||||
local be_json="false"
|
||||
[ "$block_exploits" = "true" ] && be_json="true"
|
||||
local adv_line=""
|
||||
if [ -n "$canonical_https" ]; then
|
||||
adv_line="return 301 ${canonical_https}\$request_uri;"
|
||||
fi
|
||||
UPDATE_PAYLOAD=$(jq -n \
|
||||
--arg scheme "$scheme" \
|
||||
--arg hostname "$hostname" \
|
||||
--argjson port "$(echo "$port" | sed 's/[^0-9]//g' || echo "80")" \
|
||||
--argjson websocket "$websocket" \
|
||||
--argjson block_exploits "$be_json" \
|
||||
--arg adv "$adv_line" \
|
||||
'{
|
||||
forward_scheme: $scheme,
|
||||
forward_host: $hostname,
|
||||
forward_port: $port,
|
||||
allow_websocket_upgrade: $websocket,
|
||||
block_exploits: $block_exploits
|
||||
}' 2>/dev/null || echo "")
|
||||
} + (if $adv != "" then {advanced_config: $adv} else {} end)' 2>/dev/null || echo "")
|
||||
|
||||
UPDATE_RESPONSE=$(curl_npm -X PUT "$NPM_URL/api/nginx/proxy-hosts/$HOST_ID" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
@@ -250,10 +306,16 @@ update_proxy_host() {
|
||||
UPDATE_ID=$(echo "$UPDATE_RESPONSE" | jq -r '.id // empty' 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$UPDATE_ID" ] && [ "$UPDATE_ID" != "null" ]; then
|
||||
echo " ✅ Updated: $scheme://$hostname:$port (WebSocket: $websocket)"
|
||||
if [ -n "$canonical_https" ]; then
|
||||
echo " ✅ Updated: $scheme://$hostname:$port (WebSocket: $websocket) + 301 → ${canonical_https}\$request_uri"
|
||||
else
|
||||
echo " ✅ Updated: $scheme://$hostname:$port (WebSocket: $websocket)"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
ERROR=$(echo "$UPDATE_RESPONSE" | jq -r '.error.message // .error // "Unknown error"' 2>/dev/null || echo "$UPDATE_RESPONSE")
|
||||
ERROR=$(echo "$UPDATE_RESPONSE" | jq -r '.error.message // .message // .error // empty' 2>/dev/null || echo "")
|
||||
[ -z "$ERROR" ] && ERROR=$(echo "$UPDATE_RESPONSE" | head -c 400 | tr -d '\r\n')
|
||||
[ -z "$ERROR" ] && ERROR="(empty API response — timeout or connection error; try NPM_CURL_MAX_TIME=300)"
|
||||
echo " ❌ Failed: $ERROR"
|
||||
return 1
|
||||
fi
|
||||
@@ -280,7 +342,9 @@ update_proxy_host "wss.tw-core.d-bis.org" "http://${RPC_THIRDWEB_ADMIN_CORE}:854
|
||||
# Catch-all for foo.tw-core.d-bis.org → Besu HTTP JSON-RPC :8545 (exact rpc./wss. hosts above take precedence for nginx server_name)
|
||||
update_proxy_host '*.tw-core.d-bis.org' "http://${RPC_THIRDWEB_ADMIN_CORE}:8545" true false && updated_count=$((updated_count + 1)) || { add_proxy_host '*.tw-core.d-bis.org' "${RPC_THIRDWEB_ADMIN_CORE}" 8545 true false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# RPC Core-2 (Nathan) is on the THIRD NPMplus (192.168.11.169) — use add-rpc-core-2-npmplus-proxy.sh and update-npmplus-alltra-hybx-proxy-hosts.sh
|
||||
update_proxy_host "rpc.public-0138.defi-oracle.io" "https://${RPC_THIRDWEB_PRIMARY}:443" true false && updated_count=$((updated_count + 1)) || failed_count=$((failed_count + 1))
|
||||
# ThirdWeb / public-0138 edge (VMID 2400 nginx HTTPS) — default IP must match ALL_VMIDS_ENDPOINTS if env is unset
|
||||
RPC_THIRDWEB_PRIMARY="${RPC_THIRDWEB_PRIMARY:-192.168.11.240}"
|
||||
update_proxy_host "rpc.public-0138.defi-oracle.io" "https://${RPC_THIRDWEB_PRIMARY}:443" true false && updated_count=$((updated_count + 1)) || { sleep 2; echo " ↪ Retry rpc.public-0138.defi-oracle.io after transient NPM/API error..."; update_proxy_host "rpc.public-0138.defi-oracle.io" "https://${RPC_THIRDWEB_PRIMARY}:443" true false && updated_count=$((updated_count + 1)) || failed_count=$((failed_count + 1)); }
|
||||
# rpc.defi-oracle.io / wss.defi-oracle.io → same backend as rpc-http-pub / rpc-ws-pub (VMID 2201)
|
||||
update_proxy_host "rpc.defi-oracle.io" "http://${RPC_PUBLIC_1}:8545" true false && updated_count=$((updated_count + 1)) || { add_proxy_host "rpc.defi-oracle.io" "${RPC_PUBLIC_1}" 8545 true false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "wss.defi-oracle.io" "http://${RPC_PUBLIC_1}:8546" true false && updated_count=$((updated_count + 1)) || { add_proxy_host "wss.defi-oracle.io" "${RPC_PUBLIC_1}" 8546 true false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
@@ -309,6 +373,36 @@ update_proxy_host "dbis.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_
|
||||
update_proxy_host "iccc.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_DEV}:3002" false && updated_count=$((updated_count + 1)) || { add_proxy_host "iccc.xom-dev.phoenix.sankofa.nexus" "${IP_GOV_PORTALS_DEV}" 3002 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "omnl.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_DEV}:3003" false && updated_count=$((updated_count + 1)) || { add_proxy_host "omnl.xom-dev.phoenix.sankofa.nexus" "${IP_GOV_PORTALS_DEV}" 3003 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "xom.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_DEV}:3004" false && updated_count=$((updated_count + 1)) || { add_proxy_host "xom.xom-dev.phoenix.sankofa.nexus" "${IP_GOV_PORTALS_DEV}" 3004 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Sankofa portal (Next.js CT 7801) and Phoenix API (Fastify CT 7800) — not Blockscout / SolaceScanScout (that is explorer.d-bis.org / IP_BLOCKSCOUT:80)
|
||||
# Public URL policy: https://sankofa.nexus = sovereign technology utility (portal); https://phoenix.sankofa.nexus = Phoenix division (API host; marketing site may share hostname later).
|
||||
# www.sankofa.nexus → 301 https://sankofa.nexus$request_uri; www.phoenix → phoenix; www.the-order → the-order (NPM advanced_config).
|
||||
IP_SANKOFA_PORTAL="${IP_SANKOFA_PORTAL:-${IP_SERVICE_51:-192.168.11.51}}"
|
||||
IP_SANKOFA_PHOENIX_API="${IP_SANKOFA_PHOENIX_API:-${IP_SERVICE_50:-192.168.11.50}}"
|
||||
SANKOFA_PORTAL_PORT="${SANKOFA_PORTAL_PORT:-3000}"
|
||||
SANKOFA_PHOENIX_API_PORT="${SANKOFA_PHOENIX_API_PORT:-4000}"
|
||||
update_proxy_host "sankofa.nexus" "http://${IP_SANKOFA_PORTAL}:${SANKOFA_PORTAL_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "sankofa.nexus" "${IP_SANKOFA_PORTAL}" "${SANKOFA_PORTAL_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "www.sankofa.nexus" "http://${IP_SANKOFA_PORTAL}:${SANKOFA_PORTAL_PORT}" false false "https://sankofa.nexus" && updated_count=$((updated_count + 1)) || { add_proxy_host "www.sankofa.nexus" "${IP_SANKOFA_PORTAL}" "${SANKOFA_PORTAL_PORT}" false false "https://sankofa.nexus" && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "phoenix.sankofa.nexus" "http://${IP_SANKOFA_PHOENIX_API}:${SANKOFA_PHOENIX_API_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "phoenix.sankofa.nexus" "${IP_SANKOFA_PHOENIX_API}" "${SANKOFA_PHOENIX_API_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "www.phoenix.sankofa.nexus" "http://${IP_SANKOFA_PHOENIX_API}:${SANKOFA_PHOENIX_API_PORT}" false false "https://phoenix.sankofa.nexus" && updated_count=$((updated_count + 1)) || { add_proxy_host "www.phoenix.sankofa.nexus" "${IP_SANKOFA_PHOENIX_API}" "${SANKOFA_PHOENIX_API_PORT}" false false "https://phoenix.sankofa.nexus" && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Keycloak (CT 7802) — portal SSO; NPM must forward X-Forwarded-* (Keycloak KC_PROXY_HEADERS=xforwarded on upstream)
|
||||
IP_KEYCLOAK="${IP_KEYCLOAK:-192.168.11.52}"
|
||||
update_proxy_host "keycloak.sankofa.nexus" "http://${IP_KEYCLOAK}:8080" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "keycloak.sankofa.nexus" "${IP_KEYCLOAK}" 8080 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# the-order.sankofa.nexus — public hostname for the Sovereign Military Order of Malta (OSJ) management portal (secure auth).
|
||||
# Application source (operator workstation): repo the_order at ~/projects/the_order (e.g. /home/intlc/projects/the_order).
|
||||
# Default upstream: VMID 10210 order-haproxy @ IP_ORDER_HAPROXY:80 (provision: scripts/deployment/provision-order-haproxy-10210.sh).
|
||||
# If 10210 is down: THE_ORDER_UPSTREAM_IP=${IP_SANKOFA_PORTAL} THE_ORDER_UPSTREAM_PORT=${SANKOFA_PORTAL_PORT} (direct portal 7801).
|
||||
# www.the-order.sankofa.nexus → 301 https://the-order.sankofa.nexus$request_uri (same pattern as www.sankofa / www.phoenix).
|
||||
IP_ORDER_HAPROXY="${IP_ORDER_HAPROXY:-192.168.11.39}"
|
||||
THE_ORDER_UPSTREAM_IP="${THE_ORDER_UPSTREAM_IP:-${IP_ORDER_HAPROXY}}"
|
||||
THE_ORDER_UPSTREAM_PORT="${THE_ORDER_UPSTREAM_PORT:-80}"
|
||||
# block_exploits false — same policy as sankofa.nexus portal (Next/API-friendly; avoid 405 on some POST paths)
|
||||
update_proxy_host "the-order.sankofa.nexus" "http://${THE_ORDER_UPSTREAM_IP}:${THE_ORDER_UPSTREAM_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "the-order.sankofa.nexus" "${THE_ORDER_UPSTREAM_IP}" "${THE_ORDER_UPSTREAM_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "www.the-order.sankofa.nexus" "http://${THE_ORDER_UPSTREAM_IP}:${THE_ORDER_UPSTREAM_PORT}" false false "https://the-order.sankofa.nexus" && updated_count=$((updated_count + 1)) || { add_proxy_host "www.the-order.sankofa.nexus" "${THE_ORDER_UPSTREAM_IP}" "${THE_ORDER_UPSTREAM_PORT}" false false "https://the-order.sankofa.nexus" && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Sankofa Studio (FusionAI) — VMID 7805; UI at /studio/ on same origin (port 8000). Prefer IP_SANKOFA_STUDIO from ip-addresses.conf / .env
|
||||
IP_SANKOFA_STUDIO="${IP_SANKOFA_STUDIO:-192.168.11.72}"
|
||||
SANKOFA_STUDIO_PORT="${SANKOFA_STUDIO_PORT:-8000}"
|
||||
# block_exploits false — studio UI/API may POST; align with portal policy (avoid spurious 405 from NPM WAF)
|
||||
update_proxy_host "studio.sankofa.nexus" "http://${IP_SANKOFA_STUDIO}:${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "studio.sankofa.nexus" "${IP_SANKOFA_STUDIO}" "${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
# Sets all records to DNS only mode (gray cloud) for direct NAT routing
|
||||
# Supports multiple zones: sankofa.nexus, d-bis.org, mim4u.org, defi-oracle.io
|
||||
# UDM Pro port forwarding: 76.53.10.36:80/443 → ${IP_NPMPLUS:-${IP_NPMPLUS:-192.168.11.167}}:80/443 (NPMplus)
|
||||
#
|
||||
# WARNING: For each hostname, existing CNAME records are deleted before an A record is created.
|
||||
# By default all configured zones are processed. Use --zone-only to limit scope.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/update-all-dns-to-public-ip.sh
|
||||
# ./scripts/update-all-dns-to-public-ip.sh --dry-run
|
||||
# ./scripts/update-all-dns-to-public-ip.sh --zone-only=sankofa.nexus
|
||||
# ./scripts/update-all-dns-to-public-ip.sh --dry-run --zone-only=d-bis.org
|
||||
# Env (optional): CLOUDFLARE_DNS_DRY_RUN=1, DNS_ZONE_ONLY=sankofa.nexus (same as flags)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -11,6 +21,22 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
# --help before .env (so operators can read usage without credentials)
|
||||
for _arg in "$@"; do
|
||||
if [[ "$_arg" == "--help" || "$_arg" == "-h" ]]; then
|
||||
cat <<'EOF'
|
||||
Cloudflare DNS → PUBLIC_IP (A records, DNS-only / gray cloud).
|
||||
|
||||
Options:
|
||||
--dry-run Log intended changes only; no Cloudflare API calls.
|
||||
--zone-only=ZONE ZONE one of: sankofa.nexus | d-bis.org | mim4u.org | defi-oracle.io
|
||||
-h, --help This message.
|
||||
|
||||
Requires repo .env with Cloudflare auth and zone IDs (see script header).
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
@@ -63,6 +89,23 @@ ZONE_D_BIS_ORG="${CLOUDFLARE_ZONE_ID_D_BIS_ORG:-${CLOUDFLARE_ZONE_ID:-}}"
|
||||
ZONE_MIM4U_ORG="${CLOUDFLARE_ZONE_ID_MIM4U_ORG:-}"
|
||||
ZONE_DEFI_ORACLE_IO="${CLOUDFLARE_ZONE_ID_DEFI_ORACLE_IO:-}"
|
||||
|
||||
# CLI / env: dry-run and single-zone scope
|
||||
CLOUDFLARE_DNS_DRY_RUN="${CLOUDFLARE_DNS_DRY_RUN:-0}"
|
||||
DNS_ZONE_ONLY="${DNS_ZONE_ONLY:-}"
|
||||
parse_dns_update_cli_args() {
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) CLOUDFLARE_DNS_DRY_RUN=1 ;;
|
||||
--zone-only=*) DNS_ZONE_ONLY="${arg#*=}" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
parse_dns_update_cli_args "$@"
|
||||
|
||||
if [ "$CLOUDFLARE_DNS_DRY_RUN" = "1" ]; then
|
||||
log_warn "DRY-RUN: no Cloudflare list/create/update/delete API calls will be made."
|
||||
fi
|
||||
|
||||
# Function to make Cloudflare API request
|
||||
cf_api_request() {
|
||||
local method="$1"
|
||||
@@ -152,6 +195,11 @@ create_or_update_dns_record() {
|
||||
fi
|
||||
|
||||
log_info "Processing: $full_name → $ip (proxied: $proxied)"
|
||||
|
||||
if [ "$CLOUDFLARE_DNS_DRY_RUN" = "1" ]; then
|
||||
log_success "[dry-run] Would remove CNAME(s) on $full_name if any, then upsert A → $ip (proxied=$proxied)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check for existing CNAME records (must delete before creating A record)
|
||||
local all_records=$(get_all_dns_records "$zone_id" "$full_name")
|
||||
@@ -256,28 +304,46 @@ main() {
|
||||
echo ""
|
||||
log_info "Public IP: $PUBLIC_IP"
|
||||
log_info "Proxy Mode: DNS Only (gray cloud)"
|
||||
if [ -n "$DNS_ZONE_ONLY" ]; then
|
||||
log_info "Zone filter: only $DNS_ZONE_ONLY"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
local total_failures=0
|
||||
local run_sankofa=1 run_dbis=1 run_mim4u=1 run_defi=1
|
||||
if [ -n "$DNS_ZONE_ONLY" ]; then
|
||||
run_sankofa=0 run_dbis=0 run_mim4u=0 run_defi=0
|
||||
case "$DNS_ZONE_ONLY" in
|
||||
sankofa.nexus) run_sankofa=1 ;;
|
||||
d-bis.org) run_dbis=1 ;;
|
||||
mim4u.org) run_mim4u=1 ;;
|
||||
defi-oracle.io) run_defi=1 ;;
|
||||
*)
|
||||
log_error "Unknown --zone-only=$DNS_ZONE_ONLY (expected: sankofa.nexus | d-bis.org | mim4u.org | defi-oracle.io)"
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# sankofa.nexus domain records
|
||||
if [ -n "$ZONE_SANKOFA_NEXUS" ]; then
|
||||
if [ "$run_sankofa" = 1 ] && [ -n "$ZONE_SANKOFA_NEXUS" ]; then
|
||||
SANKOFA_RECORDS=(
|
||||
"@" # sankofa.nexus
|
||||
"www" # www.sankofa.nexus
|
||||
"phoenix" # phoenix.sankofa.nexus
|
||||
"www.phoenix" # www.phoenix.sankofa.nexus
|
||||
"the-order" # the-order.sankofa.nexus
|
||||
"www.the-order" # www.the-order.sankofa.nexus
|
||||
)
|
||||
if ! process_zone "$ZONE_SANKOFA_NEXUS" "sankofa.nexus" "${SANKOFA_RECORDS[@]}"; then
|
||||
((total_failures++))
|
||||
fi
|
||||
else
|
||||
elif [ "$run_sankofa" = 1 ]; then
|
||||
log_warn "Skipping sankofa.nexus (no zone ID configured)"
|
||||
fi
|
||||
|
||||
# d-bis.org domain records
|
||||
if [ -n "$ZONE_D_BIS_ORG" ]; then
|
||||
if [ "$run_dbis" = 1 ] && [ -n "$ZONE_D_BIS_ORG" ]; then
|
||||
DBIS_RECORDS=(
|
||||
"rpc-http-pub" # rpc-http-pub.d-bis.org
|
||||
"rpc-ws-pub" # rpc-ws-pub.d-bis.org
|
||||
@@ -296,12 +362,12 @@ main() {
|
||||
if ! process_zone "$ZONE_D_BIS_ORG" "d-bis.org" "${DBIS_RECORDS[@]}"; then
|
||||
((total_failures++))
|
||||
fi
|
||||
else
|
||||
elif [ "$run_dbis" = 1 ]; then
|
||||
log_warn "Skipping d-bis.org (no zone ID configured)"
|
||||
fi
|
||||
|
||||
# mim4u.org domain records
|
||||
if [ -n "$ZONE_MIM4U_ORG" ]; then
|
||||
if [ "$run_mim4u" = 1 ] && [ -n "$ZONE_MIM4U_ORG" ]; then
|
||||
MIM4U_RECORDS=(
|
||||
"@" # mim4u.org
|
||||
"www" # www.mim4u.org
|
||||
@@ -311,12 +377,12 @@ main() {
|
||||
if ! process_zone "$ZONE_MIM4U_ORG" "mim4u.org" "${MIM4U_RECORDS[@]}"; then
|
||||
((total_failures++))
|
||||
fi
|
||||
else
|
||||
elif [ "$run_mim4u" = 1 ]; then
|
||||
log_warn "Skipping mim4u.org (no zone ID configured)"
|
||||
fi
|
||||
|
||||
# defi-oracle.io domain records
|
||||
if [ -n "$ZONE_DEFI_ORACLE_IO" ]; then
|
||||
if [ "$run_defi" = 1 ] && [ -n "$ZONE_DEFI_ORACLE_IO" ]; then
|
||||
DEFI_ORACLE_RECORDS=(
|
||||
"explorer" # explorer.defi-oracle.io (Blockscout - same as explorer.d-bis.org)
|
||||
"rpc.public-0138" # rpc.public-0138.defi-oracle.io
|
||||
@@ -326,7 +392,7 @@ main() {
|
||||
if ! process_zone "$ZONE_DEFI_ORACLE_IO" "defi-oracle.io" "${DEFI_ORACLE_RECORDS[@]}"; then
|
||||
((total_failures++))
|
||||
fi
|
||||
else
|
||||
elif [ "$run_defi" = 1 ]; then
|
||||
log_warn "Skipping defi-oracle.io (no zone ID configured)"
|
||||
fi
|
||||
|
||||
@@ -353,5 +419,5 @@ main() {
|
||||
return $total_failures
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
# Run (CLI already parsed above)
|
||||
main
|
||||
|
||||
@@ -1,34 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Load IP configuration
|
||||
# Update Sankofa NPMplus proxy hosts (portal + Phoenix API + the-order) via API by numeric host ID.
|
||||
# Prefer for production: scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh (domain-based, full fleet).
|
||||
# NPM proxy host IDs below match backup backup-20260325_183932 (3–6, 7, 59); override with SANKOFA_NPM_ID_* if your DB differs.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
|
||||
# Update Sankofa NPMplus proxy hosts via API
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
# Load environment variables
|
||||
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||
export $(cat "$PROJECT_ROOT/.env" | grep -v '^#' | xargs)
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
source "$PROJECT_ROOT/.env"
|
||||
set +a
|
||||
fi
|
||||
|
||||
NPM_URL="${NPM_URL:-https://${IP_NPMPLUS}:81}"
|
||||
NPM_EMAIL="${NPM_EMAIL:-nsatoshi2007@hotmail.com}"
|
||||
NPM_PASSWORD="${NPM_PASSWORD:-}"
|
||||
NPM_CURL_MAX_TIME="${NPM_CURL_MAX_TIME:-180}"
|
||||
|
||||
# Sankofa proxy host mappings
|
||||
IP_SANKOFA_PORTAL="${IP_SANKOFA_PORTAL:-${IP_SERVICE_51:-192.168.11.51}}"
|
||||
IP_SANKOFA_PHOENIX_API="${IP_SANKOFA_PHOENIX_API:-${IP_SERVICE_50:-192.168.11.50}}"
|
||||
SANKOFA_PORTAL_PORT="${SANKOFA_PORTAL_PORT:-3000}"
|
||||
SANKOFA_PHOENIX_API_PORT="${SANKOFA_PHOENIX_API_PORT:-4000}"
|
||||
IP_ORDER_HAPROXY="${IP_ORDER_HAPROXY:-192.168.11.39}"
|
||||
THE_ORDER_UPSTREAM_IP="${THE_ORDER_UPSTREAM_IP:-${IP_ORDER_HAPROXY}}"
|
||||
THE_ORDER_UPSTREAM_PORT="${THE_ORDER_UPSTREAM_PORT:-80}"
|
||||
|
||||
# NPM proxy host IDs: sankofa=3, www.sankofa=4, phoenix=5, www.phoenix=6; the-order=7, www.the-order=59 (typical; verify in NPM UI)
|
||||
SANKOFA_NPM_ID_ROOT="${SANKOFA_NPM_ID_ROOT:-3}"
|
||||
SANKOFA_NPM_ID_WWW="${SANKOFA_NPM_ID_WWW:-4}"
|
||||
SANKOFA_NPM_ID_PHOENIX="${SANKOFA_NPM_ID_PHOENIX:-5}"
|
||||
SANKOFA_NPM_ID_WWW_PHOENIX="${SANKOFA_NPM_ID_WWW_PHOENIX:-6}"
|
||||
SANKOFA_NPM_ID_THE_ORDER="${SANKOFA_NPM_ID_THE_ORDER:-7}"
|
||||
SANKOFA_NPM_ID_WWW_THE_ORDER="${SANKOFA_NPM_ID_WWW_THE_ORDER:-59}"
|
||||
|
||||
# Optional 4th field: canonical HTTPS apex — NPM advanced_config 301 (www → apex). Matches update-npmplus-proxy-hosts-api.sh.
|
||||
declare -A PROXY_HOSTS=(
|
||||
["21"]="sankofa.nexus|${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-192.168.11.51}}}}}}|3000"
|
||||
["22"]="www.sankofa.nexus|${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-${IP_SERVICE_51:-192.168.11.51}}}}}}|3000"
|
||||
["23"]="phoenix.sankofa.nexus|${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-192.168.11.50}}}}}}|4000"
|
||||
["24"]="www.phoenix.sankofa.nexus|${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-${IP_SERVICE_50:-192.168.11.50}}}}}}|4000"
|
||||
["$SANKOFA_NPM_ID_ROOT"]="sankofa.nexus|${IP_SANKOFA_PORTAL}|${SANKOFA_PORTAL_PORT}|"
|
||||
["$SANKOFA_NPM_ID_WWW"]="www.sankofa.nexus|${IP_SANKOFA_PORTAL}|${SANKOFA_PORTAL_PORT}|https://sankofa.nexus"
|
||||
["$SANKOFA_NPM_ID_PHOENIX"]="phoenix.sankofa.nexus|${IP_SANKOFA_PHOENIX_API}|${SANKOFA_PHOENIX_API_PORT}|"
|
||||
["$SANKOFA_NPM_ID_WWW_PHOENIX"]="www.phoenix.sankofa.nexus|${IP_SANKOFA_PHOENIX_API}|${SANKOFA_PHOENIX_API_PORT}|https://phoenix.sankofa.nexus"
|
||||
["$SANKOFA_NPM_ID_THE_ORDER"]="the-order.sankofa.nexus|${THE_ORDER_UPSTREAM_IP}|${THE_ORDER_UPSTREAM_PORT}|"
|
||||
["$SANKOFA_NPM_ID_WWW_THE_ORDER"]="www.the-order.sankofa.nexus|${THE_ORDER_UPSTREAM_IP}|${THE_ORDER_UPSTREAM_PORT}|https://the-order.sankofa.nexus"
|
||||
)
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -38,7 +56,7 @@ echo ""
|
||||
|
||||
# Authenticate
|
||||
echo "🔐 Authenticating to NPMplus..."
|
||||
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
|
||||
TOKEN_RESPONSE=$(curl -s -k --connect-timeout 15 --max-time "$NPM_CURL_MAX_TIME" -X POST "$NPM_URL/api/tokens" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}")
|
||||
|
||||
@@ -58,11 +76,12 @@ update_proxy_host() {
|
||||
local domain=$2
|
||||
local target_ip=$3
|
||||
local target_port=$4
|
||||
local canonical_https="${5:-}"
|
||||
|
||||
echo "📝 Updating Proxy Host $host_id: $domain → $target_ip:$target_port"
|
||||
|
||||
# Get current proxy host
|
||||
CURRENT_HOST=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts/$host_id" \
|
||||
CURRENT_HOST=$(curl -s -k --connect-timeout 15 --max-time "$NPM_CURL_MAX_TIME" -X GET "$NPM_URL/api/nginx/proxy-hosts/$host_id" \
|
||||
-H "Authorization: Bearer $TOKEN" 2>/dev/null || echo "{}")
|
||||
|
||||
if [ "$(echo "$CURRENT_HOST" | jq -r '.id // empty')" = "" ]; then
|
||||
@@ -70,11 +89,28 @@ update_proxy_host() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Update proxy host
|
||||
UPDATE_PAYLOAD=$(echo "$CURRENT_HOST" | jq --arg ip "$target_ip" --arg port "$target_port" \
|
||||
'.forward_host = $ip | .forward_port = ($port | tonumber)')
|
||||
# NPMplus rejects full-document PUT (e.g. locations: null) — send only allowed forward fields.
|
||||
local scheme="http"
|
||||
local adv_line=""
|
||||
if [ -n "$canonical_https" ]; then
|
||||
adv_line="return 301 ${canonical_https}\$request_uri;"
|
||||
fi
|
||||
UPDATE_PAYLOAD=$(jq -n \
|
||||
--arg scheme "$scheme" \
|
||||
--arg hostname "$target_ip" \
|
||||
--argjson port "$(echo "$target_port" | sed 's/[^0-9]//g')" \
|
||||
--argjson websocket false \
|
||||
--argjson block_exploits false \
|
||||
--arg adv "$adv_line" \
|
||||
'{
|
||||
forward_scheme: $scheme,
|
||||
forward_host: $hostname,
|
||||
forward_port: $port,
|
||||
allow_websocket_upgrade: $websocket,
|
||||
block_exploits: $block_exploits
|
||||
} + (if $adv != "" then {advanced_config: $adv} else {} end)')
|
||||
|
||||
RESPONSE=$(curl -s -k -X PUT "$NPM_URL/api/nginx/proxy-hosts/$host_id" \
|
||||
RESPONSE=$(curl -s -k --connect-timeout 15 --max-time "${NPM_CURL_MAX_TIME:-120}" -X PUT "$NPM_URL/api/nginx/proxy-hosts/$host_id" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$UPDATE_PAYLOAD")
|
||||
@@ -87,6 +123,9 @@ update_proxy_host() {
|
||||
else
|
||||
echo "❌ Failed to update proxy host $host_id"
|
||||
echo "$RESPONSE" | jq '.' 2>/dev/null || echo "$RESPONSE"
|
||||
if echo "$RESPONSE" | jq -e '.error.code == 403' >/dev/null 2>&1; then
|
||||
echo " (403 often means NPM user lacks permission to mutate proxy hosts; check UI role or use an admin identity.)"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -96,9 +135,9 @@ SUCCESS=0
|
||||
FAILED=0
|
||||
|
||||
for host_id in "${!PROXY_HOSTS[@]}"; do
|
||||
IFS='|' read -r domain target_ip target_port <<< "${PROXY_HOSTS[$host_id]}"
|
||||
IFS='|' read -r domain target_ip target_port canonical_https _ <<< "${PROXY_HOSTS[$host_id]}"
|
||||
|
||||
if update_proxy_host "$host_id" "$domain" "$target_ip" "$target_port"; then
|
||||
if update_proxy_host "$host_id" "$domain" "$target_ip" "$target_port" "$canonical_https"; then
|
||||
((SUCCESS++))
|
||||
else
|
||||
((FAILED++))
|
||||
|
||||
@@ -55,6 +55,7 @@ declare -A DOMAIN_ZONES=(
|
||||
["phoenix.sankofa.nexus"]="sankofa.nexus"
|
||||
["www.phoenix.sankofa.nexus"]="sankofa.nexus"
|
||||
["the-order.sankofa.nexus"]="sankofa.nexus"
|
||||
["www.the-order.sankofa.nexus"]="sankofa.nexus"
|
||||
["studio.sankofa.nexus"]="sankofa.nexus"
|
||||
["rpc.public-0138.defi-oracle.io"]="defi-oracle.io"
|
||||
)
|
||||
|
||||
@@ -34,6 +34,9 @@ PUBLIC_IP_FOURTH="${PUBLIC_IP_FOURTH:-76.53.10.40}"
|
||||
ACCEPT_ANY_DNS="${ACCEPT_ANY_DNS:-0}"
|
||||
# Use system resolver (e.g. /etc/hosts) instead of dig @8.8.8.8 — set when running from LAN with generate-e2e-hosts.sh entries
|
||||
E2E_USE_SYSTEM_RESOLVER="${E2E_USE_SYSTEM_RESOLVER:-0}"
|
||||
# openssl s_client has no built-in connect timeout; wrap to avoid hangs (private/wss hosts).
|
||||
E2E_OPENSSL_TIMEOUT="${E2E_OPENSSL_TIMEOUT:-15}"
|
||||
E2E_OPENSSL_X509_TIMEOUT="${E2E_OPENSSL_X509_TIMEOUT:-5}"
|
||||
if [ "$E2E_USE_SYSTEM_RESOLVER" = "1" ]; then
|
||||
ACCEPT_ANY_DNS=1
|
||||
log_info "E2E_USE_SYSTEM_RESOLVER=1: using getent (respects /etc/hosts); ACCEPT_ANY_DNS=1"
|
||||
@@ -77,7 +80,8 @@ declare -A DOMAIN_TYPES_ALL=(
|
||||
["www.sankofa.nexus"]="web"
|
||||
["phoenix.sankofa.nexus"]="web"
|
||||
["www.phoenix.sankofa.nexus"]="web"
|
||||
["the-order.sankofa.nexus"]="web"
|
||||
["the-order.sankofa.nexus"]="web" # OSJ portal (secure auth); app: ~/projects/the_order
|
||||
["www.the-order.sankofa.nexus"]="web" # 301 → https://the-order.sankofa.nexus
|
||||
["studio.sankofa.nexus"]="web"
|
||||
["rpc.public-0138.defi-oracle.io"]="rpc-http"
|
||||
["rpc.defi-oracle.io"]="rpc-http"
|
||||
@@ -162,11 +166,15 @@ else
|
||||
fi
|
||||
|
||||
# Domains that are optional when any test fails (off-LAN, 502, unreachable); fail → skip so run passes.
|
||||
_PUB_OPTIONAL_WHEN_FAIL="dapp.d-bis.org mifos.d-bis.org explorer.d-bis.org dbis-admin.d-bis.org dbis-api.d-bis.org dbis-api-2.d-bis.org secure.d-bis.org sankofa.nexus www.sankofa.nexus phoenix.sankofa.nexus www.phoenix.sankofa.nexus the-order.sankofa.nexus www.the-order.sankofa.nexus studio.sankofa.nexus mim4u.org www.mim4u.org secure.mim4u.org training.mim4u.org rpc-http-pub.d-bis.org rpc.d-bis.org rpc2.d-bis.org rpc.public-0138.defi-oracle.io rpc.defi-oracle.io ws.rpc.d-bis.org ws.rpc2.d-bis.org"
|
||||
_PRIV_OPTIONAL_WHEN_FAIL="rpc-http-prv.d-bis.org rpc-ws-prv.d-bis.org rpc-fireblocks.d-bis.org ws.rpc-fireblocks.d-bis.org"
|
||||
if [[ -z "${E2E_OPTIONAL_WHEN_FAIL:-}" ]]; then
|
||||
if [[ "$PROFILE" == "private" ]]; then
|
||||
E2E_OPTIONAL_WHEN_FAIL="rpc-http-prv.d-bis.org rpc-ws-prv.d-bis.org rpc-fireblocks.d-bis.org ws.rpc-fireblocks.d-bis.org"
|
||||
E2E_OPTIONAL_WHEN_FAIL="$_PRIV_OPTIONAL_WHEN_FAIL"
|
||||
elif [[ "$PROFILE" == "all" ]]; then
|
||||
E2E_OPTIONAL_WHEN_FAIL="$_PRIV_OPTIONAL_WHEN_FAIL $_PUB_OPTIONAL_WHEN_FAIL"
|
||||
else
|
||||
E2E_OPTIONAL_WHEN_FAIL="dapp.d-bis.org mifos.d-bis.org explorer.d-bis.org dbis-admin.d-bis.org dbis-api.d-bis.org dbis-api-2.d-bis.org secure.d-bis.org sankofa.nexus www.sankofa.nexus phoenix.sankofa.nexus www.phoenix.sankofa.nexus the-order.sankofa.nexus studio.sankofa.nexus mim4u.org www.mim4u.org secure.mim4u.org training.mim4u.org rpc-http-pub.d-bis.org rpc.d-bis.org rpc2.d-bis.org rpc.public-0138.defi-oracle.io rpc.defi-oracle.io ws.rpc.d-bis.org ws.rpc2.d-bis.org"
|
||||
E2E_OPTIONAL_WHEN_FAIL="$_PUB_OPTIONAL_WHEN_FAIL"
|
||||
fi
|
||||
else
|
||||
E2E_OPTIONAL_WHEN_FAIL="${E2E_OPTIONAL_WHEN_FAIL}"
|
||||
@@ -178,6 +186,36 @@ declare -A EXPECTED_IP=(
|
||||
["dev.d-bis.org"]="$PUBLIC_IP_FOURTH"
|
||||
["codespaces.d-bis.org"]="$PUBLIC_IP_FOURTH"
|
||||
)
|
||||
# HTTPS check path (default "/"). API-first hosts may 404 on /; see docs/02-architecture/EXPECTED_WEB_CONTENT.md
|
||||
declare -A E2E_HTTPS_PATH=(
|
||||
["phoenix.sankofa.nexus"]="/health"
|
||||
["www.phoenix.sankofa.nexus"]="/health"
|
||||
["studio.sankofa.nexus"]="/studio/"
|
||||
)
|
||||
|
||||
# Expected apex URL for NPM www → canonical 301/308 (Location must use this host; path from E2E_HTTPS_PATH must appear when set)
|
||||
declare -A E2E_WWW_CANONICAL_BASE=(
|
||||
["www.sankofa.nexus"]="https://sankofa.nexus"
|
||||
["www.phoenix.sankofa.nexus"]="https://phoenix.sankofa.nexus"
|
||||
["www.the-order.sankofa.nexus"]="https://the-order.sankofa.nexus"
|
||||
)
|
||||
|
||||
# Returns 0 if Location URL matches expected canonical apex (and HTTPS path suffix when non-empty).
|
||||
e2e_www_redirect_location_ok() {
|
||||
local loc_val="$1" base="$2" path="${3:-}"
|
||||
local loc_lc base_lc
|
||||
loc_lc=$(printf '%s' "$loc_val" | tr '[:upper:]' '[:lower:]')
|
||||
base_lc=$(printf '%s' "$base" | tr '[:upper:]' '[:lower:]')
|
||||
if [[ "$loc_lc" != "$base_lc" && "$loc_lc" != "$base_lc/"* ]]; then
|
||||
return 1
|
||||
fi
|
||||
if [ -n "$path" ] && [ "$path" != "/" ]; then
|
||||
local p_lc
|
||||
p_lc=$(printf '%s' "$path" | tr '[:upper:]' '[:lower:]')
|
||||
[[ "$loc_lc" == *"$p_lc"* ]] || return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# --list-endpoints: print selected profile endpoints and exit (no tests)
|
||||
if [[ "$LIST_ENDPOINTS" == "1" ]]; then
|
||||
@@ -257,7 +295,7 @@ test_domain() {
|
||||
if [ "$domain_type" != "unknown" ]; then
|
||||
log_info "Test 2: SSL Certificate"
|
||||
|
||||
cert_info=$(echo | openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName 2>/dev/null || echo "")
|
||||
cert_info=$( (echo | timeout "$E2E_OPENSSL_TIMEOUT" openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null) | timeout "$E2E_OPENSSL_X509_TIMEOUT" openssl x509 -noout -subject -issuer -dates -ext subjectAltName 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$cert_info" ]; then
|
||||
cert_cn=$(echo "$cert_info" | grep "subject=" | sed -E 's/.*CN\s*=\s*([^,]*).*/\1/' | sed 's/^ *//;s/ *$//' || echo "")
|
||||
@@ -301,10 +339,12 @@ test_domain() {
|
||||
|
||||
# Test 3: HTTPS Request
|
||||
if [ "$domain_type" = "web" ] || [ "$domain_type" = "api" ]; then
|
||||
log_info "Test 3: HTTPS Request"
|
||||
https_path="${E2E_HTTPS_PATH[$domain]:-}"
|
||||
https_url="https://${domain}${https_path}"
|
||||
log_info "Test 3: HTTPS Request (${https_url})"
|
||||
|
||||
START_TIME=$(date +%s.%N)
|
||||
http_response=$(curl -s -I -k --connect-timeout 10 -w "\n%{time_total}" "https://$domain" 2>&1 || echo "")
|
||||
http_response=$(curl -s -I -k --connect-timeout 10 -w "\n%{time_total}" "$https_url" 2>&1 || echo "")
|
||||
END_TIME=$(date +%s.%N)
|
||||
RESPONSE_TIME=$(echo "$END_TIME - $START_TIME" | bc 2>/dev/null || echo "0")
|
||||
|
||||
@@ -315,8 +355,39 @@ test_domain() {
|
||||
echo "$headers" > "$OUTPUT_DIR/${domain//./_}_https_headers.txt"
|
||||
|
||||
if [ -n "$http_code" ]; then
|
||||
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 400 ]; then
|
||||
log_success "HTTPS: $domain returned HTTP $http_code (Time: ${time_total}s)"
|
||||
# NPM canonical www → apex (advanced_config return 301/308)
|
||||
local _e2e_canonical_www_redirect=""
|
||||
local location_hdr=""
|
||||
case "$domain" in
|
||||
www.sankofa.nexus|www.phoenix.sankofa.nexus|www.the-order.sankofa.nexus)
|
||||
if [ "$http_code" = "301" ] || [ "$http_code" = "308" ]; then
|
||||
_e2e_canonical_www_redirect=1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ -n "$_e2e_canonical_www_redirect" ]; then
|
||||
location_hdr=$(echo "$headers" | grep -iE '^[Ll]ocation:' | head -1 | tr -d '\r' || echo "")
|
||||
loc_val=$(printf '%s' "$location_hdr" | sed -E 's/^[Ll][Oo][Cc][Aa][Tt][Ii][Oo][Nn]:[[:space:]]*//' | sed 's/[[:space:]]*$//')
|
||||
expected_base="${E2E_WWW_CANONICAL_BASE[$domain]:-}"
|
||||
if [ -z "$loc_val" ]; then
|
||||
log_warn "HTTPS: $domain returned HTTP $http_code but no Location header${https_path:+ (${https_url})}"
|
||||
result=$(echo "$result" | jq --arg code "$http_code" --arg time "$time_total" \
|
||||
'.tests.https = {"status": "warn", "http_code": ($code | tonumber), "response_time_seconds": ($time | tonumber), "note": "missing Location on redirect"}')
|
||||
elif [ -z "$expected_base" ]; then
|
||||
log_warn "HTTPS: $domain redirect pass (no E2E_WWW_CANONICAL_BASE entry)"
|
||||
result=$(echo "$result" | jq --arg code "$http_code" --arg time "$time_total" --arg loc "$location_hdr" \
|
||||
'.tests.https = {"status": "pass", "http_code": ($code | tonumber), "response_time_seconds": ($time | tonumber), "canonical_redirect": true, "location_header": $loc}')
|
||||
elif ! e2e_www_redirect_location_ok "$loc_val" "$expected_base" "$https_path"; then
|
||||
log_error "HTTPS: $domain Location mismatch (got \"$loc_val\", expected prefix \"$expected_base\" with path \"${https_path:-/}\")"
|
||||
result=$(echo "$result" | jq --arg code "$http_code" --arg time "$time_total" --arg loc "$loc_val" --arg exp "$expected_base" --arg pth "${https_path:-}" \
|
||||
'.tests.https = {"status": "fail", "http_code": ($code | tonumber), "response_time_seconds": ($time | tonumber), "reason": "location_mismatch", "location": $loc, "expected_prefix": $exp, "expected_path_suffix": $pth}')
|
||||
else
|
||||
log_success "HTTPS: $domain returned HTTP $http_code (canonical redirect → $loc_val)${https_path:+ at ${https_url}}"
|
||||
result=$(echo "$result" | jq --arg code "$http_code" --arg time "$time_total" --arg loc "$location_hdr" \
|
||||
'.tests.https = {"status": "pass", "http_code": ($code | tonumber), "response_time_seconds": ($time | tonumber), "canonical_redirect": true, "location_header": $loc}')
|
||||
fi
|
||||
elif [ "$http_code" -ge 200 ] && [ "$http_code" -lt 400 ]; then
|
||||
log_success "HTTPS: $domain returned HTTP $http_code (Time: ${time_total}s)${https_path:+ at ${https_path}}"
|
||||
|
||||
# Check security headers
|
||||
hsts=$(echo "$headers" | grep -i "strict-transport-security" || echo "")
|
||||
@@ -330,12 +401,12 @@ test_domain() {
|
||||
--argjson hsts "$HAS_HSTS" --argjson csp "$HAS_CSP" --argjson xfo "$HAS_XFO" \
|
||||
'.tests.https = {"status": "pass", "http_code": ($code | tonumber), "response_time_seconds": ($time | tonumber), "has_hsts": $hsts, "has_csp": $csp, "has_xfo": $xfo}')
|
||||
else
|
||||
log_warn "HTTPS: $domain returned HTTP $http_code (Time: ${time_total}s)"
|
||||
log_warn "HTTPS: $domain returned HTTP $http_code (Time: ${time_total}s)${https_path:+ (${https_url})}"
|
||||
result=$(echo "$result" | jq --arg code "$http_code" --arg time "$time_total" \
|
||||
'.tests.https = {"status": "warn", "http_code": ($code | tonumber), "response_time_seconds": ($time | tonumber)}')
|
||||
fi
|
||||
else
|
||||
log_error "HTTPS: Failed to connect to $domain"
|
||||
log_error "HTTPS: Failed to connect to ${https_url}"
|
||||
result=$(echo "$result" | jq --arg time "$time_total" '.tests.https = {"status": "fail", "response_time_seconds": ($time | tonumber)}')
|
||||
fi
|
||||
# Optional: Blockscout API check for explorer.d-bis.org (does not affect E2E pass/fail)
|
||||
@@ -401,13 +472,21 @@ test_domain() {
|
||||
# Check if wscat is available for full test
|
||||
if command -v wscat >/dev/null 2>&1; then
|
||||
log_info " Attempting full WebSocket test with wscat..."
|
||||
WS_FULL_TEST=$(timeout 3 wscat -c "wss://$domain" -x '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' 2>&1 || echo "")
|
||||
# -n: no TLS verify (aligns with curl -k); -w: seconds to wait for JSON-RPC response
|
||||
WS_FULL_TEST=""
|
||||
WS_FULL_EXIT=0
|
||||
if ! WS_FULL_TEST=$(timeout 15 wscat -n -c "wss://$domain" -x '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' -w 5 2>&1); then
|
||||
WS_FULL_EXIT=$?
|
||||
fi
|
||||
if echo "$WS_FULL_TEST" | grep -q "result"; then
|
||||
log_success "WebSocket: Full test passed"
|
||||
result=$(echo "$result" | jq --arg code "$WS_RESULT" '.tests.websocket = {"status": "pass", "http_code": $code, "full_test": true}')
|
||||
result=$(echo "$result" | jq --arg code "$WS_RESULT" '.tests.websocket = {"status": "pass", "http_code": $code, "full_test": true, "full_test_output": "result"}')
|
||||
elif [ "$WS_FULL_EXIT" -eq 0 ]; then
|
||||
log_success "WebSocket: Full test connected cleanly"
|
||||
result=$(echo "$result" | jq --arg code "$WS_RESULT" '.tests.websocket = {"status": "pass", "http_code": $code, "full_test": true, "note": "wscat exited successfully without printable RPC output"}')
|
||||
else
|
||||
log_warn "WebSocket: Connection established but RPC test failed"
|
||||
result=$(echo "$result" | jq --arg code "$WS_RESULT" '.tests.websocket = {"status": "warning", "http_code": $code, "full_test": false}')
|
||||
result=$(echo "$result" | jq --arg code "$WS_RESULT" --arg exit_code "$WS_FULL_EXIT" '.tests.websocket = {"status": "warning", "http_code": $code, "full_test": false, "exit_code": $exit_code}')
|
||||
fi
|
||||
else
|
||||
log_warn "WebSocket: Basic test (Code: $WS_RESULT) - Install wscat for full test: npm install -g wscat"
|
||||
@@ -558,6 +637,7 @@ cat >> "$REPORT_FILE" <<EOF
|
||||
|
||||
- **Optional domains:** Domains in \`E2E_OPTIONAL_WHEN_FAIL\` (default: many d-bis.org/sankofa/mim4u/rpc) have any fail treated as skip so the run passes when off-LAN or services unreachable. Set \`E2E_OPTIONAL_WHEN_FAIL=\` (empty) for strict mode.
|
||||
- WebSocket tests require \`wscat\` tool: \`npm install -g wscat\`
|
||||
- OpenSSL fetch uses \`timeout\` (\`E2E_OPENSSL_TIMEOUT\` / \`E2E_OPENSSL_X509_TIMEOUT\`, defaults 15s / 5s) so \`openssl s_client\` cannot hang indefinitely
|
||||
- Internal connectivity tests require access to NPMplus container
|
||||
- Explorer (explorer.d-bis.org): optional Blockscout API check; use \`SKIP_BLOCKSCOUT_API=1\` to skip when backend is unreachable (e.g. off-LAN). Fix runbook: docs/03-deployment/BLOCKSCOUT_FIX_RUNBOOK.md
|
||||
|
||||
|
||||
Submodule smom-dbis-138 updated: a780eff7c5...721cdeb92f
Reference in New Issue
Block a user