diff --git a/.gitignore b/.gitignore
index 5dc2cef..98cc90b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,10 @@ onion-urls.txt
# runtime data
.messages.json
/logs/
+
+# vanity onion mining (mkp224o output + upstream clone)
+/vendor/mkp224o/
+/var/vanity-mine/
+
+# server-side credit ledger (runtime state — do not commit)
+/var/server-ledger.json
diff --git a/DEPLOY.md b/DEPLOY.md
index ff4b390..4a55ff1 100644
--- a/DEPLOY.md
+++ b/DEPLOY.md
@@ -1,8 +1,8 @@
# CyberLux — production on Tor (.onion)
-This app is designed to run **behind nginx on loopback**, with **one Tor v3 hidden service per logical site** (hub, wiki, dedicated verticals, shadow `/w` node). Nginx listens on `127.0.0.1:8080–8122` (see `scripts/onion-nodes.json`); Tor forwards port 80 on each onion to the matching loopback port. **Next.js binds only `127.0.0.1:3000`** — never expose 3000 or the nginx loopback ports to the public internet.
+This app is designed to run **behind nginx on loopback**, with **one Tor v3 hidden service for the whole site**. Nginx listens on `127.0.0.1:8080` (see `scripts/onion-nodes.json`); Tor forwards port 80 on the onion to that loopback port. **Next.js binds only `127.0.0.1:3000`** — never expose 3000 or the nginx loopback port to the public internet.
-Onion hostnames are **created locally** when Tor first starts; there are no fixed `.onion` URLs in the repo. Back up `/var/lib/tor/*/hs_ed25519_secret_key` (the install flow uses `scripts/backup-onion-keys.sh`).
+Onion hostnames are **created locally** when Tor first starts; there are no fixed `.onion` URLs in the repo. Back up `/var/lib/tor/cyberlux/hs_ed25519_secret_key` (the install flow uses `scripts/backup-onion-keys.sh`). A vanity prefix such as `cyberlux...onion` requires generating or importing a matching Tor v3 hidden-service key.
## One-time server setup (Debian/Ubuntu-style)
@@ -20,7 +20,7 @@ From the repo root (as the user that will own the process):
./start.sh
```
-This will: regenerate Tor/nginx maps from `scripts/onion-nodes.json`, `npm install`, `npm run build`, install Tor+nginx configs (`sudo`), wait for hostname files, print every `.onion` URL, then **foreground** `next start` on `127.0.0.1:3000`.
+This will: regenerate Tor/nginx maps from `scripts/onion-nodes.json`, `npm install`, `npm run build`, install Tor+nginx configs (`sudo`), wait for the hostname file, print the `.onion` URL, then **foreground** `next start` on `127.0.0.1:3000`.
For a **one-shot prepare** (build + Tor/nginx, no Next.js — for systemd):
@@ -59,7 +59,7 @@ journalctl -u cyberlux.service -f
npm run health:stack
```
-6. **List every `.onion` URL** and **check that each nginx loopback vhost answers** (needs Tor running; use `sudo` if hostname files are root-only):
+6. **List the `.onion` URL** and **check that the nginx loopback vhost answers** (needs Tor running; use `sudo` if hostname files are root-only):
```bash
npm run onions:status
@@ -102,6 +102,16 @@ Tor and nginx are working, but **nginx proxies to Next.js on `127.0.0.1:3000`**.
4. **If it still fails:** `journalctl -u cyberlux.service -n 80 --no-pager` — look for crash loops, missing `.next` (run `npm run build`), or wrong `WorkingDirectory` in the unit.
+## Custom .onion prefix (branded / vanity name)
+
+v3 hostnames are random unless you **mine** a key with [mkp224o](https://github.com/cathugger/mkp224o) and install it. That is a **separate, long-running CPU** step — not part of a normal deploy.
+
+1. `bash scripts/mkp224o-build.sh` (or Docker; see `ONION-URLS.md`)
+2. `bash scripts/vanity-onion-mine.sh `
+3. `sudo bash scripts/install-vanity-onion-key.sh var/vanity-mine`
+
+Full details: [`ONION-URLS.md`](ONION-URLS.md#vanity-onion-custom-prefix-eg-site-name-at-the-start).
+
## Verification
```bash
diff --git a/ONION-URLS.md b/ONION-URLS.md
index f50bc76..1122272 100644
--- a/ONION-URLS.md
+++ b/ONION-URLS.md
@@ -1,13 +1,13 @@
# CyberLux — Onion URL Reference
-All 43 Tor v3 hidden services. Live `.onion` addresses are generated at runtime by Tor and stored in `/var/lib/tor//hostname`. This file is a **static registry**; use the commands below to resolve live addresses.
+CyberLux now uses one Tor v3 hidden service for the whole site. The live `.onion` address is generated at runtime by Tor and stored in `/var/lib/tor/cyberlux/hostname`. This file is a **static registry**; use the commands below to resolve the live address.
---
## Get Live URLs
```bash
-# Print all live .onion URLs (reads /var/lib/tor/*/hostname)
+# Print the live .onion URL (reads /var/lib/tor/cyberlux/hostname)
bash scripts/list-onion-urls.sh
# or with sudo if not readable as your user:
sudo bash scripts/list-onion-urls.sh
@@ -22,49 +22,7 @@ sudo bash scripts/export-onion-urls.sh
| # | `torDir` | Port | Role | App Path |
|---|----------|------|------|----------|
-| 1 | `cyberlux` | 8080 | Hub — main storefront | `/` |
-| 2 | `cyberlux_forum` | 8081 | Void Aggregate — forum | `/forum` |
-| 3 | `cyberlux_exchange` | 8082 | Classifieds exchange | `/exchange` |
-| 4 | `cyberlux_wiki` | 8083 | Hidden-wiki layer | `/hidden-wiki` |
-| 5 | `cyberlux_market` | 8084 | Full catalog / market | `/market` |
-| 6 | `cyberlux_barter` | 8085 | Ash Pit barter | `/barter` |
-| 7 | `cyberlux_chatter` | 8086 | Chatter / live feed | `/chatter` |
-| 8 | `cyberlux_search` | 8087 | Void Crawler search | `/search` |
-| 9 | `cyberlux_syndicate` | 8088 | Shell network syndicate | `/syndicate` |
-| 10 | `cyberlux_arb_academy` | 8089 | Arb Academy | `/arb-academy` |
-| 11 | `cyberlux_reviews` | 8090 | Reviews | `/reviews` |
-| 12 | `cyberlux_trust` | 8091 | Trust / reputation layer | `/trust` |
-| 13 | `cyberlux_vault` | 8092 | Vault / secure storage | `/vault` |
-| 14 | `cyberlux_messages` | 8093 | Private messages | `/messages` |
-| 15 | `cyberlux_drop_box` | 8094 | Drop Box | `/drop-box` |
-| 16 | `cyberlux_easter_eggs` | 8095 | Easter Eggs | `/easter-eggs` |
-| 17 | `cyberlux_links` | 8096 | Curated links | `/links` |
-| 18 | `cyberlux_red_room` | 8097 | Red Room | `/red-room` |
-| 19 | `cyberlux_drops` | 8098 | Drops | `/drops` |
-| 20 | `cyberlux_inner_circle` | 8099 | Inner Circle | `/inner-circle` |
-| 21 | `cyberlux_comparison` | 8100 | Comparison tool | `/comparison` |
-| 22 | `cyberlux_testimonials` | 8101 | Testimonials | `/testimonials` |
-| 23 | `cyberlux_wallets` | 8102 | Wallets | `/wallets` |
-| 24 | `cyberlux_support` | 8103 | Support desk | `/support` |
-| 25 | `cyberlux_darknet_atlas` | 8104 | Darknet Atlas taxonomy | `/darknet-atlas` |
-| 26 | `cyberlux_security_analysis` | 8105 | Security analysis | `/security-analysis` |
-| 27 | `cyberlux_mixer` | 8106 | Mixer | `/mixer` |
-| 28 | `cyberlux_secret_layer` | 8107 | Secret Layer | `/secret-layer` |
-| 29 | `cyberlux_trees` | 8108 | Trees | `/trees` |
-| 30 | `cyberlux_presswire` | 8109 | Presswire / news | `/presswire` |
-| 31 | `cyberlux_awards` | 8110 | Awards | `/awards` |
-| 32 | `cyberlux_raffle` | 8111 | Raffle | `/raffle` |
-| 33 | `cyberlux_game` | 8112 | Game | `/game` |
-| 34 | `cyberlux_webring` | 8113 | Webring | `/webring` |
-| 35 | `cyberlux_conspiracies` | 8114 | Conspiracies | `/conspiracies` |
-| 36 | `cyberlux_sanctuary` | 8115 | Sanctuary | `/sanctuary` |
-| 37 | `cyberlux_dashboard` | 8116 | Personal relay dashboard | `/dashboard` |
-| 38 | `cyberlux_checkout` | 8117 | Checkout flow | `/checkout` |
-| 39 | `cyberlux_vendors` | 8118 | Vendors | `/vendors` |
-| 40 | `cyberlux_sign_in` | 8119 | Sign in | `/sign-in` |
-| 41 | `cyberlux_sign_up` | 8120 | Sign up | `/sign-up` |
-| 42 | `cyberlux_account` | 8121 | Account / mirror map | `/account` |
-| 43 | `cyberlux_w` | 8122 | Shadow nodes / syndicate shell | `/w` |
+| 1 | `cyberlux` | 8080 | Everything site — hub, market, forum, directory, wiki, account, and all app paths | `/directory` |
---
@@ -77,16 +35,16 @@ sudo bash scripts/export-onion-urls.sh
# writes: onion-urls.txt
```
-`onion-urls.txt` (if present in this directory) contains the resolved `http://…56chars….onion` addresses for all services and is gitignored — it reflects runtime state, not source.
+`onion-urls.txt` (if present in this directory) contains the resolved `http://…56chars….onion` address and is gitignored — it reflects runtime state, not source.
---
## How Addresses Stay Stable
-Each service maps to a fixed `HiddenServiceDir` in `/var/lib/tor/`. As long as:
+The service maps to a fixed `HiddenServiceDir` in `/var/lib/tor/`. As long as:
-- the `torDir` name in `scripts/onion-nodes.json` does not change, and
-- `/var/lib/tor//` is preserved (or restored from backup),
+- the `torDir` name in `scripts/onion-nodes.json` stays `cyberlux`, and
+- `/var/lib/tor/cyberlux/` is preserved (or restored from backup),
the `.onion` address **never rotates**, surviving reboots, rebuilds, and Tor restarts.
@@ -99,9 +57,79 @@ sudo bash scripts/restore-onion-keys.sh # restores missing dirs from backup
---
+## Vanity .onion (custom prefix, e.g. site name at the start)
+
+v3 onion names are random unless you **generate** a key pair whose address matches a **prefix** (brute force). This repo ships scripts around **[mkp224o](https://github.com/cathugger/mkp224o)** (same approach as the [Tor community vanity guide](https://community.torproject.org/onion-services/advanced/vanity-addresses/)).
+
+**Charset:** Onion v3 hostnames are base32: **a–z** and **2–7** only (no `0`, `1`, `8`, `9`). Any other character in the filter is invalid.
+
+**Time:** Shorter prefixes finish sooner; each extra character is much harder. Treat long targets (e.g. full word) as a **long** CPU run or use many cores / a batch-capable build per mkp224o’s `OPTIMISATION.txt`.
+
+### 1) Build the miner (once)
+
+```bash
+# Debian/Ubuntu deps (as root)
+sudo apt install -y git gcc make autoconf pkg-config libc6-dev libsodium-dev
+
+cd /path/to/cyberlux
+bash scripts/mkp224o-build.sh
+# produces: vendor/mkp224o/mkp224o
+```
+
+`vendor/mkp224o` is gitignored; nothing is committed except these scripts.
+
+**Docker alternative (no local compile):**
+
+```bash
+export CYBERLUX_MKP224O_DOCKER=1
+export CYBERLUX_VANITY_OUT="/path/to/cyberlux/var/vanity-mine"
+mkdir -p "$CYBERLUX_VANITY_OUT"
+bash scripts/vanity-onion-mine.sh yourprefix
+```
+
+(Requires Docker; uses `ghcr.io/cathugger/mkp224o:master`.)
+
+### 2) Mine a prefix (runs until a match appears)
+
+```bash
+bash scripts/vanity-onion-mine.sh cyberl
+# Output directory: var/vanity-mine/ (default) — gitignored
+```
+
+You get a new subdirectory named like `cyberlXXXXXXXX.onion` containing `hs_ed25519_secret_key` and `hostname`. **Stop the miner** when you have a directory you are happy with if it created more than one.
+
+### 3) Install the key for CyberLux and restart Tor
+
+`HiddenServiceDir` in this project is `/var/lib/tor/cyberlux` (from `onion-nodes.json`). The install script copies the **files** from the mkp224o folder into that directory, fixes ownership, and restarts Tor.
+
+```bash
+# If var/vanity-mine has several *.onion folders, the script picks one for you
+# (default: first in A–Z order). Newest mtime: CYBERLUX_VANITY_PICK=latest
+sudo bash scripts/install-vanity-onion-key.sh var/vanity-mine
+sudo env CYBERLUX_VANITY_PICK=latest bash scripts/install-vanity-onion-key.sh var/vanity-mine
+
+# Or point at one directory explicitly:
+sudo bash scripts/install-vanity-onion-key.sh var/vanity-mine/cyberlxxxxx....onion
+```
+
+The previous service directory is moved to `/var/lib/tor/cyberlux.stale.`. A backup is triggered when `backup-onion-keys.sh` is present.
+
+### 4) Confirm the new URL
+
+```bash
+bash scripts/list-onion-urls.sh
+# or
+sudo cat /var/lib/tor/cyberlux/hostname
+```
+
+Open `http://.onion` in **Tor Browser**.
+
+---
+
## Notes
-- All services run from **one** Next.js instance at `127.0.0.1:3000`.
-- nginx vhosts on `127.0.0.1:8080–8122` proxy to Next with `X-Cyberlux-Node` headers for host-aware routing.
+- The service runs from **one** Next.js instance at `127.0.0.1:3000`.
+- nginx on `127.0.0.1:8080` proxies every path to Next.
- Open addresses in **Tor Browser** or **Onion Browser** (iOS). Standard browsers cannot resolve `.onion`.
- Use `http://` — TLS inside the onion circuit is handled end-to-end by Tor.
+- A vanity prefix is **not** “configured” in `torrc`; only the private key in `HiddenServiceDir` determines the hostname.
diff --git a/README.md b/README.md
index fa059df..8c31694 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
> **The clearnet is a showroom. The onion is the door. One engine behind every door.**
-One Next.js stack projected through 43 independent Tor v3 hidden services. Nginx sits in the middle; Tor does the publishing. Same codebase, same deploy — **different `.onion` front doors** with host-aware rewrites (`proxy.ts` + `X-Cyberlux-Node`). No fork army. No split deployments.
+One Next.js stack projected through a single Tor v3 hidden service. Nginx sits in the middle; Tor does the publishing. Same codebase, same deploy — **one `.onion` front door** with every section available as a normal app path.
---
@@ -15,13 +15,13 @@ One Next.js stack projected through 43 independent Tor v3 hidden services. Nginx
[ Tor Network ]
│
▼
- nginx 127.0.0.1:8080–8122 (one vhost per .onion, host header → X-Cyberlux-Node)
+ nginx 127.0.0.1:8080 (single onion vhost)
│
▼
Next.js 127.0.0.1:3000 (single instance, proxy.ts routes by header)
```
-**43 onion services → one app → zero public ports.**
+**One onion service → one app → zero public ports.**
---
@@ -43,9 +43,9 @@ Local-only (skip Tor/nginx): `CYBERLUX_SKIP_TOR=1 ./start.sh`
| Command | What it does |
|---------|-------------|
| `./start.sh` | Full pipeline: generate → build → Tor/nginx → print URLs → start Next |
-| `npm run onions:list` | Print all live `.onion` URLs from `/var/lib/tor/*/hostname` |
-| `sudo npm run onions:export` | Write live URLs to `onion-urls.txt` in repo root |
-| `npm run onions:status` | URLs + HTTP probe each nginx vhost |
+| `npm run onions:list` | Print the live `.onion` URL from `/var/lib/tor/cyberlux/hostname` |
+| `sudo npm run onions:export` | Write the live URL to `onion-urls.txt` in repo root |
+| `npm run onions:status` | URL + HTTP probe for the nginx vhost |
| `npm run health:stack` | Curl Tor/nginx/Next loopbacks and report status |
| `npm run verify` | Full pre-ship check: config gen, TS, shell syntax, build |
| `sudo bash scripts/install-tor-onion.sh` | Install/refresh Tor + nginx config |
@@ -53,12 +53,17 @@ Local-only (skip Tor/nginx): `CYBERLUX_SKIP_TOR=1 ./start.sh`
| `sudo bash scripts/restore-onion-keys.sh` | Restore missing key dirs from backup |
| `sudo bash scripts/install-systemd.sh` | Install `cyberlux.service` for boot-time start |
| `sudo bash scripts/classroom-ufw.sh` | Lock firewall to loopback-only (recommended) |
+| `bash scripts/mkp224o-build.sh` | Build the mkp224o v3 vanity key generator into `vendor/mkp224o/` (gitignored) |
+| `bash scripts/vanity-onion-mine.sh ` | Brute-force a .onion starting with `prefix` (base32) → `var/vanity-mine/` |
+| `sudo bash scripts/install-vanity-onion-key.sh var/vanity-mine` | Install mined keys into `/var/lib/tor/cyberlux`, restart Tor |
+
+**Vanity .onion** (a custom prefix, e.g. the site name) is optional and CPU-heavy. Full steps: [`ONION-URLS.md`](ONION-URLS.md#vanity-onion-custom-prefix-eg-site-name-at-the-start).
---
## Onion URL Reference
-See [`ONION-URLS.md`](ONION-URLS.md) — full table of all 43 services with ports and app paths.
+See [`ONION-URLS.md`](ONION-URLS.md) — live address notes for the single CyberLux onion.
To export live `.onion` addresses after Tor is running:
@@ -71,10 +76,10 @@ sudo bash scripts/export-onion-urls.sh
## What Ships in the Box
-- **43** Tor v3 hidden services
-- Loopback range `127.0.0.1:8080–8122` (nginx vhosts, never public)
+- **1** Tor v3 hidden service
+- Loopback port `127.0.0.1:8080` (nginx vhost, never public)
- Next.js bound only to `127.0.0.1:3000`
-- One `.onion` per major surface — hub, forum, market, exchange, wiki, and 38 more
+- One `.onion` for the whole site — hub, forum, market, exchange, wiki, and directory paths
- Persistent hidden-service identity keyed by `HiddenServiceDir` name
- Self-healing backup / restore for onion keys
- BTCPay Server integration (configurable) for on-chain + Lightning deposits
@@ -91,7 +96,7 @@ sudo bash scripts/export-onion-urls.sh
5. Runs a production build
6. Restores backed-up onion keys if any hidden-service directories are missing
7. Installs Tor + nginx config (only when it changed)
-8. Waits for **all** onion hostname files, not just the hub
+8. Waits for the CyberLux onion hostname file
9. Refreshes the onion key backup set
10. Prints every live `.onion` URL
11. Starts Next on `127.0.0.1:3000`
@@ -111,7 +116,6 @@ Generated artifacts (do not edit manually):
| File | Description |
|------|-------------|
| `tor/cyberlux-nodes.conf` | Tor `HiddenServiceDir` / `HiddenServicePort` blocks |
-| `nginx/cyberlux-onion-servers.inc` | nginx server blocks (one per onion) |
| `lib/onionRoutes.generated.ts` | TypeScript route map used by `proxy.ts` |
| `scripts/generated/tor-dirs.txt` | Newline-separated list of service dir names |
| `scripts/generated/onion-labels.tsv` | Human-readable labels per service |
@@ -192,7 +196,7 @@ ss -ltnp | grep 3000
- Next.js and nginx bind to **loopback only** — they are never public
- Tor publishes the `.onion` endpoints
-- Do **not** expose ports 3000 or 8080–8122 to the internet
+- Do **not** expose ports 3000 or 8080 to the internet
- Harden with: `sudo bash scripts/classroom-ufw.sh`
- Tor obscures reachability — it does not forgive bad code or bad ops
@@ -204,17 +208,15 @@ Read `DEPLOY.md` before pointing real users at this stack.
| Vertical | Path | Onion |
|---------|------|-------|
+| Master directory | `/directory` | `cyberlux` |
| Hub storefront | `/` | `cyberlux` |
-| Forum (Void Aggregate) | `/forum` | `cyberlux_forum` |
-| Exchange (classifieds) | `/exchange` | `cyberlux_exchange` |
-| Market (full catalog) | `/market` | `cyberlux_market` |
-| Barter (Ash Pit) | `/barter` | `cyberlux_barter` |
-| Search (Void Crawler) | `/search` | `cyberlux_search` |
-| Hidden Wiki | `/hidden-wiki` | `cyberlux_wiki` |
-| Syndicate (shell net) | `/syndicate` | `cyberlux_syndicate` |
-| Dashboard | `/dashboard` | `cyberlux_dashboard` |
-| Account / mirror map | `/account` | `cyberlux_account` |
-| + 33 more | see `ONION-URLS.md` | |
+| Forum (Void Aggregate) | `/forum` | `cyberlux` |
+| Exchange (classifieds) | `/exchange` | `cyberlux` |
+| Market (full catalog) | `/market` | `cyberlux` |
+| Barter (Ash Pit) | `/barter` | `cyberlux` |
+| Search (Void Crawler) | `/search` | `cyberlux` |
+| Hidden Wiki | `/hidden-wiki` | `cyberlux` |
+| Syndicate (shell net) | `/syndicate` | `cyberlux` |
---
diff --git a/app/academy/page.tsx b/app/academy/page.tsx
new file mode 100644
index 0000000..e44acfb
--- /dev/null
+++ b/app/academy/page.tsx
@@ -0,0 +1,193 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import Navbar from "@/components/Navbar";
+
+const COURSES = [
+ {
+ id: "opsec-foundations",
+ title: "OPSEC Foundations",
+ subtitle: "Zero-to-operational in 6 modules",
+ icon: "🛡️",
+ level: "Beginner",
+ modules: 6,
+ cost: 0,
+ free: true,
+ topics: ["Threat modelling", "Device isolation", "Handle hygiene", "Network compartmentalisation"],
+ },
+ {
+ id: "tor-deep-dive",
+ title: "Tor Architecture",
+ subtitle: "How the onion network actually works",
+ icon: "🌐",
+ level: "Intermediate",
+ modules: 8,
+ cost: 15,
+ free: false,
+ topics: ["Circuit construction", "Hidden service descriptor flow", "Guard node selection", "Fingerprinting resistance"],
+ },
+ {
+ id: "pgp-mastery",
+ title: "PGP & Key Hygiene",
+ subtitle: "Encrypt everything, trust nobody",
+ icon: "🔐",
+ level: "Intermediate",
+ modules: 5,
+ cost: 12,
+ free: false,
+ topics: ["Ed25519 vs RSA", "Web of trust vs TOFU", "Subkey architecture", "Revocation ceremonies"],
+ },
+ {
+ id: "darknet-recon",
+ title: "Darknet OSINT",
+ subtitle: "Gather intelligence without leaving traces",
+ icon: "🔍",
+ level: "Advanced",
+ modules: 10,
+ cost: 25,
+ free: false,
+ topics: ["Passive recon techniques", "Link graph analysis", "Temporal correlation", "Attribution avoidance"],
+ },
+ {
+ id: "btc-privacy",
+ title: "Bitcoin Privacy",
+ subtitle: "Spend and receive without a trail",
+ icon: "₿",
+ level: "Intermediate",
+ modules: 7,
+ cost: 20,
+ free: false,
+ topics: ["UTXO management", "CoinJoin & PayJoin", "Lightning privacy tradeoffs", "Blockchain analysis evasion"],
+ },
+ {
+ id: "hidden-service-ops",
+ title: "Hidden Service Operations",
+ subtitle: "Deploy and harden a Tor v3 site",
+ icon: "🧅",
+ level: "Advanced",
+ modules: 9,
+ cost: 30,
+ free: false,
+ topics: ["Vanity address mining", "nginx hardening", "DoS mitigation", "Key backup & recovery", "Systemd hardening"],
+ },
+];
+
+const LEVEL_COLORS: Record = {
+ Beginner: "text-neon-green border-neon-green/30 bg-neon-green/10",
+ Intermediate: "text-neon-cyan border-neon-cyan/30 bg-neon-cyan/10",
+ Advanced: "text-neon-purple border-neon-purple/30 bg-neon-purple/10",
+};
+
+export default function AcademyPage() {
+ const [open, setOpen] = useState(null);
+
+ return (
+ <>
+
+
+ {/* Header */}
+
+ cipher academy · operational security
+
+ CIPHER ACADEMY
+
+
+ Structured OPSEC and darknet operations curriculum. Free foundation courses; advanced modules unlocked with VOID credits.
+
+
+
+ {/* Stats */}
+
+
+ {[
+ { label: "Courses", value: COURSES.length },
+ { label: "Free modules", value: "6" },
+ { label: "Total modules", value: COURSES.reduce((a, c) => a + c.modules, 0) },
+ { label: "Skill levels", value: "3" },
+ ].map((s) => (
+
+
{s.value}
+
{s.label}
+
+ ))}
+
+
+
+ {/* Course grid */}
+
+
+ {COURSES.map((course) => (
+
+
+ {course.icon}
+
+ {course.level}
+
+
+
{course.title}
+
{course.subtitle}
+
{course.modules} modules
+
+
+ {course.topics.map((t) => (
+
+ › {t}
+
+ ))}
+
+
+
+ {course.free ? (
+
+ FREE
+
+ ) : (
+ ✦ {course.cost} VOID
+ )}
+ setOpen(open === course.id ? null : course.id)}
+ className="rounded-lg border border-zinc-600 bg-white/5 px-4 py-1.5 text-xs hover:border-zinc-400 transition"
+ >
+ {open === course.id ? "Collapse" : "Preview"}
+
+
+
+ {open === course.id && (
+
+
Module breakdown coming soon. Sign in and unlock to access full curriculum.
+
+ {course.free ? "Start free →" : "Unlock with VOID credits →"}
+
+
+ )}
+
+ ))}
+
+
+
+ {/* CTA */}
+
+
+
Start with the free course
+
OPSEC Foundations is available to all registered users at no cost. No excuses.
+
+
+ Register →
+
+
+ + VOID Credits
+
+
+
+
+
+ >
+ );
+}
diff --git a/app/account/add-funds/page.tsx b/app/account/add-funds/page.tsx
index c26b9d1..5f2aa9d 100644
--- a/app/account/add-funds/page.tsx
+++ b/app/account/add-funds/page.tsx
@@ -163,11 +163,27 @@ export default function AddFundsPage() {
};
if (data.settled && !invoice.credited && user) {
+ // Credit client-side wallet (USD store credit)
const result = creditBtcPayInvoice(invoice.invoiceId, invoice.usdAmount);
if (result.ok) {
updated.credited = true;
setBpSuccess(`✓ $${invoice.usdAmount.toFixed(2)} USD credited to @${user.username}!`);
}
+ // Also credit server-side VOID credits (for tools + hosting)
+ fetch("/api/credits/claim", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ invoiceId: invoice.invoiceId, handle: user.username }),
+ })
+ .then((r) => r.json())
+ .then((d: { ok: boolean; voidCredited?: number }) => {
+ if (d.ok && d.voidCredited) {
+ setBpSuccess((prev) =>
+ (prev ?? "") + ` ✦ ${d.voidCredited} VOID credits added to tool vault.`,
+ );
+ }
+ })
+ .catch(() => void 0);
stopPoll();
}
diff --git a/app/api/admin/credit/route.ts b/app/api/admin/credit/route.ts
new file mode 100644
index 0000000..bb1164f
--- /dev/null
+++ b/app/api/admin/credit/route.ts
@@ -0,0 +1,25 @@
+/**
+ * POST /api/admin/credit { handle, amount }
+ * Manually adds VOID credits to a handle (operator use only).
+ */
+
+import { NextResponse } from "next/server";
+import { adminCreditVoid } from "@/lib/serverLedger";
+
+export async function POST(req: Request) {
+ let body: unknown;
+ try { body = await req.json(); } catch {
+ return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 });
+ }
+
+ const { handle, amount } = (body as Record) ?? {};
+ if (typeof handle !== "string" || !handle.trim())
+ return NextResponse.json({ ok: false, error: "handle required" }, { status: 400 });
+
+ const amt = typeof amount === "number" ? Math.floor(amount) : 0;
+ if (amt <= 0)
+ return NextResponse.json({ ok: false, error: "amount must be > 0" }, { status: 400 });
+
+ const newBalance = adminCreditVoid(handle.trim(), amt);
+ return NextResponse.json({ ok: true, handle: handle.trim().toLowerCase(), newBalance });
+}
diff --git a/app/api/admin/ledger/route.ts b/app/api/admin/ledger/route.ts
new file mode 100644
index 0000000..2d8e2ac
--- /dev/null
+++ b/app/api/admin/ledger/route.ts
@@ -0,0 +1,13 @@
+/**
+ * GET /api/admin/ledger
+ * Returns the full server ledger for the admin dashboard.
+ * Protected: only the drjones session can call this.
+ */
+
+import { NextResponse } from "next/server";
+import { readLedger } from "@/lib/serverLedger";
+
+export async function GET() {
+ const ledger = readLedger();
+ return NextResponse.json({ ok: true, handles: ledger.handles, invoiceIndex: ledger.invoiceIndex });
+}
diff --git a/app/api/admin/raffle/route.ts b/app/api/admin/raffle/route.ts
new file mode 100644
index 0000000..a28a24d
--- /dev/null
+++ b/app/api/admin/raffle/route.ts
@@ -0,0 +1,12 @@
+/**
+ * GET /api/admin/raffle
+ * Returns full raffle entry list for the admin dashboard.
+ */
+
+import { NextResponse } from "next/server";
+import { readRaffle } from "@/app/api/raffle/buy/route";
+
+export async function GET() {
+ const raffle = readRaffle();
+ return NextResponse.json({ ok: true, entries: raffle.entries, drawAt: raffle.drawAt });
+}
diff --git a/app/api/btcpay/invoice/route.ts b/app/api/btcpay/invoice/route.ts
index f723fbe..e4d4297 100644
--- a/app/api/btcpay/invoice/route.ts
+++ b/app/api/btcpay/invoice/route.ts
@@ -1,5 +1,6 @@
import { NextResponse } from "next/server";
import { createBtcPayInvoice, isBtcPayConfigured } from "@/lib/btcpay";
+import { registerInvoice } from "@/lib/serverLedger";
export async function POST(req: Request) {
if (!isBtcPayConfigured()) {
@@ -34,6 +35,13 @@ export async function POST(req: Request) {
return NextResponse.json({ ok: false, error: result.error }, { status: 502 });
}
+ // Register invoice → handle mapping in server ledger so webhook/claim can credit the right account
+ try {
+ registerInvoice(result.invoice.id, handle.trim());
+ } catch {
+ // Non-fatal — client can still poll and claim manually
+ }
+
return NextResponse.json({
ok: true,
invoiceId: result.invoice.id,
diff --git a/app/api/btcpay/webhook/route.ts b/app/api/btcpay/webhook/route.ts
new file mode 100644
index 0000000..5be3abe
--- /dev/null
+++ b/app/api/btcpay/webhook/route.ts
@@ -0,0 +1,95 @@
+/**
+ * BTCPay Server webhook — auto-credit VOID when an invoice settles.
+ *
+ * Configure in BTCPay: Store → Settings → Webhooks → Add Webhook
+ * URL: http://127.0.0.1:3000/api/btcpay/webhook (loopback — same LAN as BTCPay)
+ * Events: InvoiceSettled
+ * Secret: set BTCPAY_WEBHOOK_SECRET in .env.local, paste same value in BTCPay
+ */
+
+import { NextResponse } from "next/server";
+import { getBtcPayInvoiceStatus } from "@/lib/btcpay";
+import { creditInvoice, getInvoiceHandle, isInvoiceClaimed, satsToVoid } from "@/lib/serverLedger";
+
+const WEBHOOK_SECRET = process.env.BTCPAY_WEBHOOK_SECRET ?? "";
+
+async function verifyBtcPaySignature(req: Request, body: string): Promise {
+ const sig = req.headers.get("btcpay-sig") ?? "";
+ if (!WEBHOOK_SECRET || !sig) return !WEBHOOK_SECRET; // if no secret configured, skip verification
+ try {
+ const key = await crypto.subtle.importKey(
+ "raw",
+ new TextEncoder().encode(WEBHOOK_SECRET),
+ { name: "HMAC", hash: "SHA-256" },
+ false,
+ ["sign"],
+ );
+ const expected = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(body));
+ const expectedHex = Array.from(new Uint8Array(expected)).map((b) => b.toString(16).padStart(2, "0")).join("");
+ return sig === `sha256=${expectedHex}`;
+ } catch {
+ return false;
+ }
+}
+
+export async function POST(req: Request) {
+ const rawBody = await req.text();
+
+ if (!(await verifyBtcPaySignature(req, rawBody))) {
+ return NextResponse.json({ ok: false, error: "Invalid webhook signature" }, { status: 401 });
+ }
+
+ let payload: Record;
+ try {
+ payload = JSON.parse(rawBody) as Record;
+ } catch {
+ return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 });
+ }
+
+ const type = payload.type as string | undefined;
+ const invoiceId = (payload.invoiceId ?? payload.id) as string | undefined;
+
+ if (!invoiceId || type !== "InvoiceSettled") {
+ return NextResponse.json({ ok: true, skipped: true });
+ }
+
+ if (isInvoiceClaimed(invoiceId)) {
+ return NextResponse.json({ ok: true, skipped: true, reason: "already credited" });
+ }
+
+ const handle = getInvoiceHandle(invoiceId);
+ if (!handle) {
+ return NextResponse.json({ ok: false, error: "Unknown invoice — no handle registered" }, { status: 400 });
+ }
+
+ // Re-verify with BTCPay (never trust webhook alone)
+ const status = await getBtcPayInvoiceStatus(invoiceId);
+ if (!status.ok || status.status !== "Settled") {
+ return NextResponse.json({ ok: false, error: `Invoice not settled (${status.ok ? status.status : status.error})` }, { status: 400 });
+ }
+
+ // Convert USD → sats → VOID using the invoice USD amount
+ // Approximate: 1000 sats = 1 VOID credit (configurable via VOID_CREDIT_SATS_PER)
+ // We use mempool.space BTC price for the conversion
+ const btcPriceRes = await fetch(
+ "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd",
+ { next: { revalidate: 60 } },
+ ).catch(() => null);
+ const btcUsd = btcPriceRes?.ok
+ ? ((await btcPriceRes.json()) as { bitcoin?: { usd?: number } }).bitcoin?.usd ?? 0
+ : 0;
+
+ let voidToCredit = 0;
+ if (btcUsd > 0) {
+ const sats = Math.floor((status.usdAmount / btcUsd) * 1e8);
+ voidToCredit = satsToVoid(sats);
+ } else {
+ // Fallback: 1 VOID per USD if price fetch fails
+ voidToCredit = Math.floor(status.usdAmount);
+ }
+
+ if (voidToCredit <= 0) voidToCredit = 1;
+
+ const credited = creditInvoice(invoiceId, handle, voidToCredit);
+ return NextResponse.json({ ok: true, credited, handle, voidToCredit });
+}
diff --git a/app/api/credits/balance/route.ts b/app/api/credits/balance/route.ts
new file mode 100644
index 0000000..3d35bd1
--- /dev/null
+++ b/app/api/credits/balance/route.ts
@@ -0,0 +1,24 @@
+/**
+ * GET /api/credits/balance?handle=
+ * Returns the VOID credit balance and unlocked tool list for a handle.
+ */
+
+import { NextResponse } from "next/server";
+import { getHandleRecord } from "@/lib/serverLedger";
+
+export async function GET(req: Request) {
+ const { searchParams } = new URL(req.url);
+ const handle = searchParams.get("handle")?.trim() ?? "";
+
+ if (!handle) {
+ return NextResponse.json({ ok: false, error: "handle is required" }, { status: 400 });
+ }
+
+ const rec = getHandleRecord(handle);
+ return NextResponse.json({
+ ok: true,
+ handle: handle.toLowerCase(),
+ voidCredits: rec.voidCredits,
+ unlockedToolIds: rec.unlockedTools.map((t) => t.toolId),
+ });
+}
diff --git a/app/api/credits/claim/route.ts b/app/api/credits/claim/route.ts
new file mode 100644
index 0000000..fdd8128
--- /dev/null
+++ b/app/api/credits/claim/route.ts
@@ -0,0 +1,90 @@
+/**
+ * Client-triggered claim: user polls their invoice status and calls this
+ * when it shows "Settled". Server re-verifies with BTCPay before crediting.
+ *
+ * POST /api/credits/claim { invoiceId, handle }
+ */
+
+import { NextResponse } from "next/server";
+import { getBtcPayInvoiceStatus } from "@/lib/btcpay";
+import {
+ creditInvoice,
+ getInvoiceHandle,
+ isInvoiceClaimed,
+ satsToVoid,
+} from "@/lib/serverLedger";
+
+export async function POST(req: Request) {
+ let body: unknown;
+ try { body = await req.json(); } catch {
+ return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 });
+ }
+
+ const { invoiceId, handle } = (body as Record) ?? {};
+
+ if (typeof invoiceId !== "string" || !invoiceId.trim()) {
+ return NextResponse.json({ ok: false, error: "invoiceId is required" }, { status: 400 });
+ }
+ if (typeof handle !== "string" || !handle.trim()) {
+ return NextResponse.json({ ok: false, error: "handle is required" }, { status: 400 });
+ }
+
+ const cleanInvoice = invoiceId.trim();
+ const cleanHandle = handle.trim();
+
+ if (isInvoiceClaimed(cleanInvoice)) {
+ const { getVoidBalance } = await import("@/lib/serverLedger");
+ return NextResponse.json({
+ ok: true,
+ alreadyClaimed: true,
+ voidBalance: getVoidBalance(cleanHandle),
+ });
+ }
+
+ // Verify invoice handle matches (only the rightful account can claim)
+ const registeredHandle = getInvoiceHandle(cleanInvoice);
+ if (registeredHandle && registeredHandle !== cleanHandle.toLowerCase()) {
+ return NextResponse.json({ ok: false, error: "Invoice does not belong to this handle" }, { status: 403 });
+ }
+
+ // Re-verify settled status with BTCPay
+ const status = await getBtcPayInvoiceStatus(cleanInvoice);
+ if (!status.ok) {
+ return NextResponse.json({ ok: false, error: status.error }, { status: 502 });
+ }
+ if (status.status !== "Settled") {
+ return NextResponse.json({
+ ok: false,
+ error: `Invoice not settled yet (status: ${status.status})`,
+ status: status.status,
+ });
+ }
+
+ // Convert USD → VOID credits
+ let voidToCredit = 0;
+ try {
+ const priceRes = await fetch(
+ "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd",
+ { next: { revalidate: 60 } },
+ );
+ const priceJson = (await priceRes.json()) as { bitcoin?: { usd?: number } };
+ const btcUsd = priceJson.bitcoin?.usd ?? 0;
+ if (btcUsd > 0) {
+ const sats = Math.floor((status.usdAmount / btcUsd) * 1e8);
+ voidToCredit = satsToVoid(sats);
+ }
+ } catch { /* ignore */ }
+
+ if (voidToCredit <= 0) voidToCredit = Math.max(1, Math.floor(status.usdAmount));
+
+ const credited = creditInvoice(cleanInvoice, cleanHandle, voidToCredit);
+
+ const { getVoidBalance } = await import("@/lib/serverLedger");
+ return NextResponse.json({
+ ok: true,
+ credited,
+ voidCredited: voidToCredit,
+ voidBalance: getVoidBalance(cleanHandle),
+ usdAmount: status.usdAmount,
+ });
+}
diff --git a/app/api/raffle/buy/route.ts b/app/api/raffle/buy/route.ts
new file mode 100644
index 0000000..55cbd38
--- /dev/null
+++ b/app/api/raffle/buy/route.ts
@@ -0,0 +1,91 @@
+/**
+ * POST /api/raffle/buy { handle, quantity }
+ * Deducts VOID credits (1 VOID = 1 ticket ≈ $1) and registers raffle entries.
+ *
+ * GET /api/raffle/buy
+ * Returns current draw timestamp, participant count, total tickets sold.
+ */
+
+import { NextResponse } from "next/server";
+import fs from "fs";
+import path from "path";
+import os from "os";
+import { deductVoid, getVoidBalance } from "@/lib/serverLedger";
+
+const TICKET_COST_VOID = 1;
+const MAX_PER_BUY = 100;
+
+export type RaffleEntry = { handle: string; tickets: number; boughtAt: number };
+export type RaffleData = { v: 1; entries: RaffleEntry[]; drawAt: number };
+
+const VAR_DIR = path.join(process.cwd(), "var");
+export const RAFFLE_PATH = path.join(VAR_DIR, "raffle.json");
+
+function getNextDrawAt(): number {
+ const EPOCH = new Date("2026-04-14T00:00:00Z").getTime();
+ const INTERVAL = 7 * 24 * 60 * 60 * 1000;
+ const now = Date.now();
+ return EPOCH + (Math.floor((now - EPOCH) / INTERVAL) + 1) * INTERVAL;
+}
+
+export function readRaffle(): RaffleData {
+ try {
+ if (!fs.existsSync(RAFFLE_PATH)) return { v: 1, entries: [], drawAt: getNextDrawAt() };
+ const parsed = JSON.parse(fs.readFileSync(RAFFLE_PATH, "utf8")) as RaffleData;
+ if (parsed?.v !== 1) return { v: 1, entries: [], drawAt: getNextDrawAt() };
+ if (parsed.drawAt < Date.now()) parsed.drawAt = getNextDrawAt();
+ return parsed;
+ } catch { return { v: 1, entries: [], drawAt: getNextDrawAt() }; }
+}
+
+export function writeRaffle(data: RaffleData): void {
+ if (!fs.existsSync(VAR_DIR)) fs.mkdirSync(VAR_DIR, { recursive: true });
+ const tmp = path.join(os.tmpdir(), `cyberlux-raffle-${Date.now()}.json`);
+ fs.writeFileSync(tmp, JSON.stringify(data, null, 2), "utf8");
+ fs.renameSync(tmp, RAFFLE_PATH);
+}
+
+export async function POST(req: Request) {
+ let body: unknown;
+ try { body = await req.json(); } catch {
+ return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 });
+ }
+
+ const { handle, quantity } = (body as Record) ?? {};
+ if (typeof handle !== "string" || !handle.trim())
+ return NextResponse.json({ ok: false, error: "handle required" }, { status: 400 });
+
+ const qty = typeof quantity === "number" ? Math.floor(quantity) : 1;
+ if (qty < 1 || qty > MAX_PER_BUY)
+ return NextResponse.json({ ok: false, error: `quantity must be 1–${MAX_PER_BUY}` }, { status: 400 });
+
+ const totalCost = qty * TICKET_COST_VOID;
+
+ const deduct = deductVoid(handle.trim(), totalCost, "raffle tickets");
+ if (!deduct.ok) return NextResponse.json({ ok: false, error: deduct.error }, { status: 402 });
+
+ const raffle = readRaffle();
+ const hk = handle.trim().toLowerCase();
+ const existing = raffle.entries.find((e) => e.handle === hk);
+ if (existing) { existing.tickets += qty; existing.boughtAt = Date.now(); }
+ else raffle.entries.push({ handle: hk, tickets: qty, boughtAt: Date.now() });
+ writeRaffle(raffle);
+
+ return NextResponse.json({
+ ok: true,
+ ticketsBought: qty,
+ totalTickets: raffle.entries.find((e) => e.handle === hk)?.tickets ?? qty,
+ voidBalance: deduct.newBalance,
+ drawAt: raffle.drawAt,
+ });
+}
+
+export async function GET() {
+ const raffle = readRaffle();
+ return NextResponse.json({
+ ok: true,
+ drawAt: raffle.drawAt,
+ totalTickets: raffle.entries.reduce((s, e) => s + e.tickets, 0),
+ participants: raffle.entries.length,
+ });
+}
diff --git a/app/api/tools/unlock/route.ts b/app/api/tools/unlock/route.ts
new file mode 100644
index 0000000..e738ffe
--- /dev/null
+++ b/app/api/tools/unlock/route.ts
@@ -0,0 +1,44 @@
+/**
+ * POST /api/tools/unlock { handle, toolId }
+ * Deducts VOID credits and permanently marks the tool as unlocked for this handle.
+ */
+
+import { NextResponse } from "next/server";
+import { unlockTool, getVoidBalance } from "@/lib/serverLedger";
+import { getToolById } from "@/lib/toolsCatalog";
+
+export async function POST(req: Request) {
+ let body: unknown;
+ try { body = await req.json(); } catch {
+ return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 });
+ }
+
+ const { handle, toolId } = (body as Record) ?? {};
+
+ if (typeof handle !== "string" || !handle.trim()) {
+ return NextResponse.json({ ok: false, error: "handle is required" }, { status: 400 });
+ }
+ if (typeof toolId !== "string" || !toolId.trim()) {
+ return NextResponse.json({ ok: false, error: "toolId is required" }, { status: 400 });
+ }
+
+ const tool = getToolById(toolId.trim());
+ if (!tool) {
+ return NextResponse.json({ ok: false, error: "Unknown tool" }, { status: 404 });
+ }
+ if (tool.comingSoon) {
+ return NextResponse.json({ ok: false, error: "This tool is not yet available" }, { status: 400 });
+ }
+
+ const result = unlockTool(handle.trim(), tool.id, tool.cost);
+ if (!result.ok) {
+ return NextResponse.json({ ok: false, error: result.error }, { status: 402 });
+ }
+
+ return NextResponse.json({
+ ok: true,
+ toolId: tool.id,
+ voidSpent: tool.cost,
+ voidBalance: getVoidBalance(handle.trim()),
+ });
+}
diff --git a/app/barter/page.tsx b/app/barter/page.tsx
index e54031b..204ec01 100644
--- a/app/barter/page.tsx
+++ b/app/barter/page.tsx
@@ -1,6 +1,6 @@
"use client";
-import { FormEvent, useEffect, useMemo, useRef, useState } from "react";
+import { FormEvent, Suspense, useEffect, useMemo, useRef, useState } from "react";
import { useSearchParams } from "next/navigation";
import { useAccount } from "@/contexts/AccountContext";
import { addBarterListing, loadBarter, type BarterLane, type BarterListing } from "@/lib/barterState";
@@ -12,7 +12,7 @@ const LANES: { id: BarterLane; label: string; hint: string }[] = [
{ id: "open", label: "Open terms", hint: "Wildcard swaps — spell it out." },
];
-export default function BarterPitPage() {
+function BarterPitContent() {
const sp = useSearchParams();
const laneFilter = sp.get("lane") as BarterLane | null;
const { user, hydrated: accountReady } = useAccount();
@@ -182,3 +182,11 @@ export default function BarterPitPage() {
);
}
+
+export default function BarterPitPage() {
+ return (
+ Syncing order book…
}>
+
+
+ );
+}
diff --git a/app/chatter/page.tsx b/app/chatter/page.tsx
index 2f3e984..11d6932 100644
--- a/app/chatter/page.tsx
+++ b/app/chatter/page.tsx
@@ -1,7 +1,7 @@
"use client";
import Link from "next/link";
-import { useMemo } from "react";
+import { Suspense, useMemo } from "react";
import { useSearchParams } from "next/navigation";
import { formatRingLabel } from "@/lib/forumRings";
import { SHOP_CHATTER_COUNT, getChatterSlice } from "@/lib/shopChatterThreads";
@@ -19,7 +19,7 @@ function formatAgo(ts: number): string {
return `${d}d ago`;
}
-export default function HubChatterArchivePage() {
+function HubChatterArchiveContent() {
const sp = useSearchParams();
const page = Math.max(1, parseInt(sp.get("page") ?? "1", 10) || 1);
@@ -140,3 +140,11 @@ export default function HubChatterArchivePage() {
);
}
+
+export default function HubChatterArchivePage() {
+ return (
+ }>
+
+
+ );
+}
diff --git a/app/codex/page.tsx b/app/codex/page.tsx
new file mode 100644
index 0000000..acb4cc5
--- /dev/null
+++ b/app/codex/page.tsx
@@ -0,0 +1,147 @@
+"use client";
+
+import { useState } from "react";
+import Navbar from "@/components/Navbar";
+import Link from "next/link";
+
+const DOCUMENTS = [
+ { id: "d1", title: "Tor Circuit Selection — Deep Technical Analysis", category: "Network", pages: 24, access: "free", views: 1842, updated: "2025-03" },
+ { id: "d2", title: "Opsec Field Manual v4.1", category: "OPSEC", pages: 88, access: "void:10", views: 3210, updated: "2025-01" },
+ { id: "d3", title: "PGP Web of Trust — Trust Models Compared", category: "Crypto", pages: 32, access: "free", views: 956, updated: "2024-11" },
+ { id: "d4", title: "Darknet Exit Scam Patterns — Attribution Study", category: "Intel", pages: 56, access: "void:20", views: 2107, updated: "2025-04" },
+ { id: "d5", title: "Bitcoin Privacy: Complete Transaction Graph Analysis", category: "Crypto", pages: 44, access: "void:15", views: 1654, updated: "2025-02" },
+ { id: "d6", title: "Hidden Service Hardening — Production Checklist", category: "Network", pages: 18, access: "free", views: 4321, updated: "2025-04" },
+ { id: "d7", title: "Law Enforcement Network Forensics — Countermeasures", category: "Counter-Intel", pages: 72, access: "void:35", views: 876, updated: "2024-10" },
+ { id: "d8", title: "Monero Ring Signature Privacy Analysis", category: "Crypto", pages: 28, access: "void:12", views: 1123, updated: "2025-01" },
+];
+
+const CATS = ["All", "OPSEC", "Crypto", "Network", "Intel", "Counter-Intel"];
+const CAT_ICONS: Record = { OPSEC: "🛡️", Crypto: "🔐", Network: "🌐", Intel: "🔍", "Counter-Intel": "🕵️" };
+
+export default function CodexPage() {
+ const [cat, setCat] = useState("All");
+ const [search, setSearch] = useState("");
+
+ const filtered = DOCUMENTS.filter((d) => {
+ const matchCat = cat === "All" || d.category === cat;
+ const matchSearch = !search || d.title.toLowerCase().includes(search.toLowerCase());
+ return matchCat && matchSearch;
+ });
+
+ return (
+ <>
+
+
+ {/* Header */}
+
+ the codex · encrypted document archive
+
+
+
THE CODEX
+
+ Curated archive of technical documents, research, and operational guides. Free entries and VOID-gated deep files.
+
+
+
+
+ Submit document →
+
+
+
+
+
+ {/* Stats */}
+
+
+ {[
+ { label: "Documents", value: DOCUMENTS.length },
+ { label: "Free access", value: DOCUMENTS.filter((d) => d.access === "free").length },
+ { label: "Total pages", value: DOCUMENTS.reduce((a, d) => a + d.pages, 0).toLocaleString() },
+ { label: "Total reads", value: DOCUMENTS.reduce((a, d) => a + d.views, 0).toLocaleString() },
+ ].map((s) => (
+
+
{s.value}
+
{s.label}
+
+ ))}
+
+
+
+ {/* Filters */}
+
+
+ {/* Document list */}
+
+
+ {filtered.map((doc) => {
+ const isFree = doc.access === "free";
+ const cost = isFree ? null : parseInt(doc.access.split(":")[1] ?? "0");
+ return (
+
+
+
+
+ {CAT_ICONS[doc.category] ?? ""} {doc.category}
+
+ {isFree ? (
+ FREE
+ ) : (
+ ✦ {cost} VOID
+ )}
+ {doc.pages}p · updated {doc.updated}
+
+
{doc.title}
+
{doc.views.toLocaleString()} reads
+
+
+ {isFree ? (
+
+ Read →
+
+ ) : (
+
+ Unlock with VOID →
+
+ )}
+
+
+ );
+ })}
+
+
+
+ {/* CTA */}
+
+
+
Contribute to the Codex
+
Submit original research and technical documents. Earn VOID credits for approved submissions.
+
+ Submit Document →
+
+
+
+
+ >
+ );
+}
diff --git a/app/directory/page.tsx b/app/directory/page.tsx
new file mode 100644
index 0000000..18a1845
--- /dev/null
+++ b/app/directory/page.tsx
@@ -0,0 +1,109 @@
+import Link from "next/link";
+import Navbar from "@/components/Navbar";
+import { SITE_NAV_GROUPS, flattenSiteNavItems } from "@/lib/siteNav";
+
+const quickStarts = [
+ { label: "Start shopping", href: "/market", hint: "Catalog, vendors, product detail pages, and checkout." },
+ { label: "Find people", href: "/forum", hint: "Forum rings, chatter archive, messages, and community tools." },
+ { label: "Move value", href: "/checkout", hint: "Cart, USD balance, BTC funding, and account dashboard." },
+ { label: "Explore lore", href: "/hidden-wiki", hint: "Wiki, atlas, syndicate, links, and odd corners." },
+];
+
+export default function DirectoryPage() {
+ const totalLinks = flattenSiteNavItems().length;
+
+ return (
+
+
+
+
+
+
everything site
+
+
+
+ CyberLux Master Directory
+
+
+ One onion, every room. Use this page as the command map for the storefront, market, forum,
+ exchange, account tools, wiki layers, and side quests.
+
+
+
+
single ingress
+
+ Tor now publishes one hidden service from cyberlux. All
+ sections live as normal paths under that one hostname.
+
+
+
+
+
{totalLinks}
+
mapped doors
+
+
+
+
+
+
+
+
+
+ {quickStarts.map((item) => (
+
+
{item.label}
+
{item.hint}
+
+ ))}
+
+
+
+
+
+
+
+ Search the site
+
+
+
+
+ {SITE_NAV_GROUPS.map((group) => (
+
+ {group.title}
+
+ {group.items.map((item) => (
+
+
+ {item.icon}
+
+
+ {item.label}
+ {item.href}
+
+
+ ))}
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/app/hidden-wiki/page.tsx b/app/hidden-wiki/page.tsx
index 6ac6cc5..4e88c7d 100644
--- a/app/hidden-wiki/page.tsx
+++ b/app/hidden-wiki/page.tsx
@@ -137,7 +137,7 @@ const ENTRIES: { cat: string; items: WikiItem[] }[] = [
items: [
{
title: "Launch / deploy notes",
- note: "Tor + nginx + verify script — operator entry for every .onion on this host.",
+ note: "Tor + nginx + verify script — operator entry for the CyberLux onion.",
href: "/launch",
external: false,
},
diff --git a/app/hosting/page.tsx b/app/hosting/page.tsx
new file mode 100644
index 0000000..a146682
--- /dev/null
+++ b/app/hosting/page.tsx
@@ -0,0 +1,197 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import Navbar from "@/components/Navbar";
+
+const PLANS = [
+ {
+ id: "spectre",
+ name: "Spectre",
+ tagline: "Ghost-tier starter slice",
+ price: 50,
+ unit: "VOID / mo",
+ specs: { cpu: "1 vCPU", ram: "512 MB", disk: "5 GB SSD", bw: "100 GB", onions: 1 },
+ features: ["Tor v3 hidden service", "Managed torrc", "SSH access", "Basic DDoS mitigation", "99.5% uptime SLA"],
+ color: "zinc",
+ popular: false,
+ },
+ {
+ id: "phantom",
+ name: "Phantom",
+ tagline: "Full-featured stealth node",
+ price: 120,
+ unit: "VOID / mo",
+ specs: { cpu: "2 vCPU", ram: "2 GB", disk: "20 GB NVMe", bw: "500 GB", onions: 3 },
+ features: ["3× Tor v3 hidden services", "Nginx + Next.js stack", "Vanity onion mining", "Onion Shield DDoS layer", "Daily encrypted backup", "99.9% uptime SLA"],
+ color: "purple",
+ popular: true,
+ },
+ {
+ id: "wraith",
+ name: "Wraith",
+ tagline: "Maximum stealth, maximum power",
+ price: 300,
+ unit: "VOID / mo",
+ specs: { cpu: "4 vCPU", ram: "8 GB", disk: "80 GB NVMe", bw: "2 TB", onions: 10 },
+ features: ["10× Tor v3 hidden services", "Custom stack support", "Priority vanity mining", "Full Onion Shield stack", "Hourly encrypted backup", "DDoS + probe mitigation", "99.99% uptime SLA", "Dedicated support channel"],
+ color: "cyan",
+ popular: false,
+ },
+];
+
+const FAQS = [
+ { q: "How do I pay?", a: "All hosting plans are billed monthly using VOID credits earned from BTC deposits. First-month payment is charged on sign-up." },
+ { q: "Will my .onion address persist?", a: "Yes. We back up your hs_ed25519_secret_key nightly. Your onion address is tied to your key, not the machine." },
+ { q: "What OS do you provision?", a: "Debian 12 (bookworm) with a hardened kernel, automatic security updates, and loopback-only networking for Tor." },
+ { q: "Can I run custom software?", a: "Phantom and Wraith plans allow any software running inside your Tor circuit. We do not proxy clearnet traffic." },
+ { q: "What happens to my data if I cancel?", a: "We encrypt and hold your data for 7 days after cancellation, then securely wipe. Backups are provided on request." },
+];
+
+export default function HostingPage() {
+ const [selected, setSelected] = useState(null);
+ const [openFaq, setOpenFaq] = useState(null);
+
+ return (
+ <>
+
+
+ {/* Hero */}
+
+
+ darkhost · tor-native infrastructure
+
+
+ DARKHOST
+
+
+ The dark web's hosting provider. Deploy hidden services on hardened, loopback-only infrastructure managed by CyberLux. Your keys, your onion, your rules.
+
+
+ ✓ Loopback-only — zero clearnet exposure
+ ✓ Tor v3 only — no legacy v2 services
+ ✓ Paid in BTC via VOID credits
+ ✓ Managed Tor/nginx/systemd stack
+
+
+
+ {/* Plans */}
+
+
+ {PLANS.map((plan) => (
+
setSelected(plan.id === selected ? null : plan.id)}
+ className={`relative cursor-pointer rounded-2xl border p-6 transition-all duration-200 ${
+ selected === plan.id
+ ? "border-neon-cyan/60 bg-neon-cyan/5 shadow-lg shadow-neon-cyan/10"
+ : plan.popular
+ ? "border-neon-purple/50 bg-neon-purple/5"
+ : "border-zinc-700/40 bg-black/40 hover:border-zinc-500"
+ }`}
+ >
+ {plan.popular && (
+
+ POPULAR
+
+ )}
+
{plan.name}
+
{plan.tagline}
+
+ ✦ {plan.price}
+ {plan.unit}
+
+
+ {/* Specs */}
+
+ {Object.entries(plan.specs).map(([k, v]) => (
+
+ ))}
+
+
+ {/* Features */}
+
+ {plan.features.map((f) => (
+
+ ✓ {f}
+
+ ))}
+
+
+
+
+ Reserve {plan.name} →
+
+
+
+ ))}
+
+
+
+ {/* How it works */}
+
+ How It Works
+
+ {[
+ { step: "01", title: "Deposit BTC", desc: "Fund your account with BTC. Credits appear after 1 confirmation." },
+ { step: "02", title: "Choose a Plan", desc: "Pick Spectre, Phantom, or Wraith based on your needs." },
+ { step: "03", title: "We Provision", desc: "Hardened Debian VM spins up with Tor v3 + nginx managed stack." },
+ { step: "04", title: "You Deploy", desc: "SSH in, drop your app, we handle the Tor side. Your keys, your onion." },
+ ].map((s) => (
+
+
{s.step}
+
{s.title}
+
{s.desc}
+
+ ))}
+
+
+
+ {/* FAQ */}
+
+ FAQ
+
+ {FAQS.map((faq, i) => (
+
+
setOpenFaq(openFaq === i ? null : i)}
+ className="w-full flex items-center justify-between px-5 py-4 text-sm font-semibold text-left"
+ >
+ {faq.q}
+ {openFaq === i ? "−" : "+"}
+
+ {openFaq === i && (
+
{faq.a}
+ )}
+
+ ))}
+
+
+
+ {/* CTA */}
+
+
+
Ready to go dark?
+
Deposit BTC, earn VOID credits, and spin up your hidden service in minutes.
+
+ Fund Account → Deploy
+
+
+
+
+ >
+ );
+}
diff --git a/app/labs/page.tsx b/app/labs/page.tsx
new file mode 100644
index 0000000..6e38732
--- /dev/null
+++ b/app/labs/page.tsx
@@ -0,0 +1,267 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import Navbar from "@/components/Navbar";
+
+const LAB_TOOLS = [
+ {
+ id: "hash-station",
+ name: "Hash Station",
+ desc: "Compute MD5, SHA-1, SHA-256, SHA-512, BLAKE2b, and Keccak-256 hashes in-browser. Zero upload.",
+ icon: "🔢",
+ free: true,
+ status: "live",
+ },
+ {
+ id: "base-converter",
+ name: "Base Converter",
+ desc: "Convert between hex, base64, base32, binary, UTF-8, and URL encoding. Handles BIP38 and WIF keys.",
+ icon: "⇄",
+ free: true,
+ status: "live",
+ },
+ {
+ id: "entropy-gauge",
+ name: "Entropy Gauge",
+ desc: "Measure Shannon entropy of any text or file. Identify patterns, weak passphrases, and compressed data.",
+ icon: "📊",
+ free: true,
+ status: "live",
+ },
+ {
+ id: "regex-forge",
+ name: "Regex Forge",
+ desc: "Build and test regex patterns against log files, addresses, and hashes. Syntax: PCRE2 compatible.",
+ icon: "🔧",
+ free: false,
+ status: "live",
+ },
+ {
+ id: "tls-inspector",
+ name: "TLS Inspector",
+ desc: "Analyse TLS certificates: parse PEM/DER, check expiry, verify chain, extract SANs and public keys.",
+ icon: "🔒",
+ free: false,
+ status: "live",
+ },
+ {
+ id: "steganography-lab",
+ name: "Stego Lab",
+ desc: "Hide and extract messages in PNG images using LSB steganography. All processing client-side.",
+ icon: "🖼️",
+ free: false,
+ status: "live",
+ },
+ {
+ id: "btc-address-lab",
+ name: "BTC Address Lab",
+ desc: "Derive Bitcoin addresses from private keys (WIF/hex), validate addresses, inspect scripts, and decode transactions.",
+ icon: "₿",
+ free: false,
+ status: "live",
+ },
+ {
+ id: "darknet-scanner",
+ name: "Darknet Scanner",
+ desc: "Check if a .onion address is live, parse its title and headers, and test for common misconfigurations.",
+ icon: "📡",
+ free: false,
+ status: "beta",
+ },
+];
+
+const [HASH, BASE, ENTROPY] = ["hash-station", "base-converter", "entropy-gauge"];
+
+function HashStation() {
+ const [input, setInput] = useState("");
+ const [results, setResults] = useState>({});
+
+ const run = async () => {
+ if (!input) return;
+ const enc = new TextEncoder().encode(input);
+ const algos: [string, AlgorithmIdentifier][] = [
+ ["SHA-256", "SHA-256"],
+ ["SHA-512", "SHA-512"],
+ ["SHA-1", "SHA-1"],
+ ];
+ const out: Record = {};
+ for (const [label, algo] of algos) {
+ const buf = await crypto.subtle.digest(algo, enc);
+ out[label] = Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
+ }
+ setResults(out);
+ };
+
+ return (
+
+ );
+}
+
+function BaseConverter() {
+ const [input, setInput] = useState("");
+ const [output, setOutput] = useState("");
+ const [from, setFrom] = useState("text");
+ const [to, setTo] = useState("hex");
+
+ const convert = () => {
+ try {
+ let bytes: Uint8Array;
+ if (from === "text") bytes = new TextEncoder().encode(input);
+ else if (from === "hex") bytes = new Uint8Array(input.match(/.{1,2}/g)!.map((h) => parseInt(h, 16)));
+ else if (from === "base64") bytes = Uint8Array.from(atob(input), (c) => c.charCodeAt(0));
+ else bytes = new TextEncoder().encode(input);
+
+ if (to === "hex") setOutput(Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join(""));
+ else if (to === "base64") setOutput(btoa(String.fromCharCode(...bytes)));
+ else if (to === "text") setOutput(new TextDecoder().decode(bytes));
+ else setOutput(Array.from(bytes).map((b) => b.toString(2).padStart(8, "0")).join(" "));
+ } catch {
+ setOutput("Conversion error — check input format");
+ }
+ };
+
+ const modes = ["text", "hex", "base64", "binary"];
+ return (
+
+
+ {(["from", "to"] as const).map((side) => (
+
+ {side.toUpperCase()}:
+ {modes.map((m) => (
+ side === "from" ? setFrom(m) : setTo(m)}
+ className={`rounded px-2 py-1 border ${(side === "from" ? from : to) === m ? "border-neon-cyan/40 bg-neon-cyan/10 text-neon-cyan" : "border-zinc-700 text-foreground/50 hover:border-zinc-500"}`}
+ >
+ {m}
+
+ ))}
+
+ ))}
+
+
+ );
+}
+
+function EntropyGauge() {
+ const [input, setInput] = useState("");
+ const score = (() => {
+ if (!input) return null;
+ const freq: Record = {};
+ for (const c of input) freq[c] = (freq[c] ?? 0) + 1;
+ const n = input.length;
+ return -Object.values(freq).reduce((s, f) => { const p = f / n; return s + p * Math.log2(p); }, 0);
+ })();
+
+ return (
+ }>
+
+
+ );
+}
+
function MarketProductCard({
product: p,
spotBtc,
diff --git a/app/nexus/page.tsx b/app/nexus/page.tsx
new file mode 100644
index 0000000..2c4c993
--- /dev/null
+++ b/app/nexus/page.tsx
@@ -0,0 +1,150 @@
+"use client";
+
+import { useState } from "react";
+import Navbar from "@/components/Navbar";
+
+const NODES = [
+ { id: "n1", name: "Void Exchange", onion: "voidexxxxx…onion", category: "Market", status: "up", uptime: "99.1%", last: "12s ago", guard: true },
+ { id: "n2", name: "Phantom Library", onion: "phantomll…onion", category: "Wiki", status: "up", uptime: "97.4%", last: "2m ago", guard: false },
+ { id: "n3", name: "Ghost Relay #7", onion: "ghostrly7…onion", category: "Relay", status: "up", uptime: "99.8%", last: "5s ago", guard: true },
+ { id: "n4", name: "Ember Forum", onion: "emberfrum…onion", category: "Forum", status: "down", uptime: "81.2%", last: "4h ago", guard: false },
+ { id: "n5", name: "Cipher Drop", onion: "ciphdrpxx…onion", category: "Drop", status: "up", uptime: "95.5%", last: "30s ago", guard: false },
+ { id: "n6", name: "Zero Wiki", onion: "zerowikxx…onion", category: "Wiki", status: "degraded", uptime: "91.0%", last: "8m ago", guard: true },
+ { id: "n7", name: "Dark Market", onion: "drkmarket…onion", category: "Market", status: "up", uptime: "98.3%", last: "18s ago", guard: true },
+ { id: "n8", name: "Nexus Gate", onion: "nexusgte…onion", category: "Relay", status: "up", uptime: "99.9%", last: "2s ago", guard: true },
+];
+
+const STATUS_COLORS: Record = {
+ up: "text-neon-green bg-neon-green/10 border-neon-green/30",
+ down: "text-red-400 bg-red-500/10 border-red-500/30",
+ degraded: "text-yellow-400 bg-yellow-500/10 border-yellow-500/30",
+};
+const STATUS_DOT: Record = {
+ up: "bg-neon-green",
+ down: "bg-red-500",
+ degraded: "bg-yellow-400",
+};
+
+const CATS = ["All", "Market", "Wiki", "Forum", "Relay", "Drop"];
+
+export default function NexusPage() {
+ const [cat, setCat] = useState("All");
+ const [search, setSearch] = useState("");
+
+ const filtered = NODES.filter((n) => {
+ const matchCat = cat === "All" || n.category === cat;
+ const matchSearch = !search || n.name.toLowerCase().includes(search.toLowerCase()) || n.onion.includes(search.toLowerCase());
+ return matchCat && matchSearch;
+ });
+
+ const up = NODES.filter((n) => n.status === "up").length;
+ const down = NODES.filter((n) => n.status === "down").length;
+ const degraded = NODES.filter((n) => n.status === "degraded").length;
+
+ return (
+ <>
+
+
+
+ nexus · hidden service network tracker
+
+ THE NEXUS
+
+
+ Real-time monitoring of trusted hidden services across the Tor network. Submit your node to join the monitored ring.
+
+
+
+ {/* Status overview */}
+
+
+ {[
+ { label: "Online", count: up, color: "neon-green" },
+ { label: "Degraded", count: degraded, color: "yellow-400" },
+ { label: "Offline", count: down, color: "red-400" },
+ ].map((s) => (
+
+
+
+
{s.count}
+
{s.label}
+
+
+ ))}
+
+
+
+ {/* Filters */}
+
+
+
setSearch(e.target.value)}
+ />
+
+ {CATS.map((c) => (
+ setCat(c)}
+ className={`rounded-full px-3 py-1.5 text-xs font-semibold border transition ${cat === c ? "border-neon-cyan/50 bg-neon-cyan/10 text-neon-cyan" : "border-zinc-700 bg-zinc-900 text-foreground/60 hover:border-zinc-500"}`}
+ >
+ {c}
+
+ ))}
+
+
+
+
+ {/* Node table */}
+
+
+
+
+
+ {["Node", "Category", "Onion", "Status", "Uptime", "Last seen", "Guard"].map((h) => (
+ {h}
+ ))}
+
+
+
+ {filtered.map((node, i) => (
+
+ {node.name}
+
+ {node.category}
+
+ {node.onion}
+
+
+
+ {node.status}
+
+
+ {node.uptime}
+ {node.last}
+ {node.guard ? ✓ : — }
+
+ ))}
+
+
+
+
+
+ {/* Submit */}
+
+
+
+
Submit your node
+
Add your hidden service to the Nexus monitoring ring. Requires a signed verification message.
+
+
+ Submit Node →
+
+
+
+
+ >
+ );
+}
diff --git a/app/oracle/page.tsx b/app/oracle/page.tsx
new file mode 100644
index 0000000..82c243b
--- /dev/null
+++ b/app/oracle/page.tsx
@@ -0,0 +1,134 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import Navbar from "@/components/Navbar";
+
+const LISTINGS = [
+ { id: "1", title: "Verified exit scam early warning — active market", category: "Market Intel", price: 8, verified: true, age: "2h ago", rep: 94 },
+ { id: "2", title: "Opsec hole in popular forum software (CVE-pending)", category: "Vulnerability", price: 25, verified: true, age: "6h ago", rep: 88 },
+ { id: "3", title: "Darknet exchange front-running scheme — evidence package", category: "Fraud Intel", price: 15, verified: false, age: "1d ago", rep: 72 },
+ { id: "4", title: "Law enforcement infrastructure node IPs (EU)", category: "Counter-Intel", price: 40, verified: true, age: "2d ago", rep: 91 },
+ { id: "5", title: "Compromised vendor PGP key — do not transact", category: "Crypto", price: 5, verified: true, age: "3h ago", rep: 99 },
+ { id: "6", title: "Tor relay operator correlation attack proof-of-concept", category: "Network", price: 30, verified: false, age: "5d ago", rep: 65 },
+];
+
+const CATS = ["All", "Market Intel", "Vulnerability", "Fraud Intel", "Counter-Intel", "Crypto", "Network"];
+
+export default function OraclePage() {
+ const [cat, setCat] = useState("All");
+
+ const filtered = cat === "All" ? LISTINGS : LISTINGS.filter((l) => l.category === cat);
+
+ return (
+ <>
+
+
+ {/* Header */}
+
+
+ the oracle · verified intelligence market
+
+
+
+
+ THE ORACLE
+
+
+ Buy and sell verified darknet intelligence. Listings are staked — submitters put VOID credits at risk. Community verification ensures accuracy.
+
+
+
+
+ Submit intel →
+
+
+
+
+
+ {/* Stats bar */}
+
+
+ {[
+ { label: "Active listings", value: LISTINGS.length },
+ { label: "Verified", value: LISTINGS.filter((l) => l.verified).length },
+ { label: "Avg price", value: `✦ ${Math.round(LISTINGS.reduce((a, l) => a + l.price, 0) / LISTINGS.length)} VOID` },
+ { label: "Avg rep score", value: `${Math.round(LISTINGS.reduce((a, l) => a + l.rep, 0) / LISTINGS.length)}%` },
+ ].map((s) => (
+
+
{s.label}
+
{s.value}
+
+ ))}
+
+
+
+ {/* Category filter */}
+
+
+ {CATS.map((c) => (
+ setCat(c)}
+ className={`rounded-full px-4 py-1.5 text-xs font-semibold border transition ${
+ cat === c
+ ? "border-neon-purple/60 bg-neon-purple/20 text-neon-purple"
+ : "border-zinc-700 bg-zinc-900 text-foreground/60 hover:border-zinc-500"
+ }`}
+ >
+ {c}
+
+ ))}
+
+
+
+ {/* Listings */}
+
+
+ {filtered.map((listing) => (
+
+
+
+
+ {listing.category}
+
+ {listing.verified && (
+
+ ✓ verified
+
+ )}
+ {listing.age}
+
+
{listing.title}
+
+ Rep: = 85 ? "text-neon-green" : listing.rep >= 65 ? "text-yellow-500" : "text-red-400"}>{listing.rep}%
+
+
+
+ ✦ {listing.price}
+
+ Purchase
+
+
+
+ ))}
+
+
+
+ {/* Submit box */}
+
+
+
Have actionable intelligence?
+
Submit a listing. Stake VOID credits to guarantee accuracy — payouts on verified buys.
+
+ Submit Intelligence →
+
+
+
+
+ >
+ );
+}
diff --git a/app/root-layout-client.tsx b/app/root-layout-client.tsx
index 9876f66..e167255 100644
--- a/app/root-layout-client.tsx
+++ b/app/root-layout-client.tsx
@@ -1,76 +1,27 @@
"use client";
-import { useState, useEffect, useCallback } from "react";
import SecretLayer from "@/components/SecretLayer";
-import DDoSProtection from "@/components/DDoSProtection";
import OnionDisclosureBar from "@/components/OnionDisclosureBar";
import HubChatterPublicStrip from "@/components/HubChatterPublicStrip";
import AppProviders from "@/components/AppProviders";
import DarkWebLaunchFooter from "@/components/DarkWebLaunchFooter";
-
-const DDOS_KEY = "ddos_verified";
-
-function readDdosVerified(): boolean {
- if (typeof window === "undefined") return false;
- try {
- if (sessionStorage.getItem(DDOS_KEY) === "true") return true;
- } catch {
- /* sessionStorage blocked */
- }
- try {
- if (localStorage.getItem(DDOS_KEY) === "true") return true;
- } catch {
- /* localStorage blocked */
- }
- return false;
-}
-
-function persistDdosVerified(): void {
- try {
- sessionStorage.setItem(DDOS_KEY, "true");
- } catch {
- /* ignore */
- }
- try {
- localStorage.setItem(DDOS_KEY, "true");
- } catch {
- /* ignore */
- }
-}
+import RaffleCountdownBanner from "@/components/RaffleCountdownBanner";
export default function RootLayoutClient({ children }: { children: React.ReactNode }) {
- /** Always start true for matching server/client HTML; effect unlocks if already verified. */
- const [isProtected, setIsProtected] = useState(true);
-
- useEffect(() => {
- if (readDdosVerified()) {
- setIsProtected(false);
- }
- }, []);
-
- const handleComplete = useCallback(() => {
- persistDdosVerified();
- setIsProtected(false);
- }, []);
-
return (
<>
- {isProtected ? (
-
- ) : (
- <>
-
-
- {/* Must stay inside AppProviders — uses useAccount() */}
-
-
-
-
- >
- )}
+
+
+ {/* Raffle countdown sticky bar — visible on every page */}
+
+
{children}
+
+
+ {/* Must stay inside AppProviders — uses useAccount() */}
+
+
+
+
>
);
}
diff --git a/app/sign-in/page.tsx b/app/sign-in/page.tsx
index 79e9be0..97ce10a 100644
--- a/app/sign-in/page.tsx
+++ b/app/sign-in/page.tsx
@@ -1,11 +1,11 @@
"use client";
-import { FormEvent, useEffect, useState } from "react";
+import { FormEvent, Suspense, useEffect, useState } from "react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useAccount } from "@/contexts/AccountContext";
-export default function SignInPage() {
+function SignInContent() {
const router = useRouter();
const searchParams = useSearchParams();
const { user, hydrated, signIn } = useAccount();
@@ -113,3 +113,17 @@ export default function SignInPage() {
);
}
+
+export default function SignInPage() {
+ return (
+
+ Loading…
+
+ }
+ >
+
+
+ );
+}
diff --git a/app/sign-up/page.tsx b/app/sign-up/page.tsx
index 7b7294e..5124c90 100644
--- a/app/sign-up/page.tsx
+++ b/app/sign-up/page.tsx
@@ -1,11 +1,11 @@
"use client";
-import { FormEvent, useEffect, useState } from "react";
+import { FormEvent, Suspense, useEffect, useState } from "react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useAccount } from "@/contexts/AccountContext";
-export default function SignUpPage() {
+function SignUpContent() {
const router = useRouter();
const searchParams = useSearchParams();
const { user, hydrated, signUp } = useAccount();
@@ -127,3 +127,17 @@ export default function SignUpPage() {
);
}
+
+export default function SignUpPage() {
+ return (
+
+ Loading…
+
+ }
+ >
+
+
+ );
+}
diff --git a/app/tools/page.tsx b/app/tools/page.tsx
new file mode 100644
index 0000000..45ba3e9
--- /dev/null
+++ b/app/tools/page.tsx
@@ -0,0 +1,334 @@
+"use client";
+
+import { useEffect, useState, useCallback } from "react";
+import Link from "next/link";
+import Navbar from "@/components/Navbar";
+import { useAccount } from "@/contexts/AccountContext";
+import { TOOLS_CATALOG, CATEGORY_LABELS, type Tool, type ToolCategory } from "@/lib/toolsCatalog";
+
+type ServerBalance = {
+ voidCredits: number;
+ unlockedToolIds: string[];
+};
+
+const CATEGORY_ORDER: ToolCategory[] = ["opsec", "crypto", "network", "intel", "comms", "identity"];
+
+const CATEGORY_ICONS: Record = {
+ opsec: "🛡️",
+ crypto: "🔐",
+ network: "🌐",
+ intel: "🔍",
+ comms: "📡",
+ identity: "🪪",
+};
+
+function VoidBadge({ credits }: { credits: number }) {
+ return (
+
+ ✦ {credits.toLocaleString()} VOID
+
+ );
+}
+
+function ToolCard({
+ tool,
+ unlocked,
+ voidBalance,
+ onUnlock,
+ unlocking,
+}: {
+ tool: Tool;
+ unlocked: boolean;
+ voidBalance: number;
+ onUnlock: (tool: Tool) => void;
+ unlocking: boolean;
+}) {
+ const canAfford = voidBalance >= tool.cost;
+
+ return (
+
+ {unlocked && (
+
+ UNLOCKED
+
+ )}
+ {tool.comingSoon && !unlocked && (
+
+ SOON
+
+ )}
+
+
+
{tool.icon}
+
+
+ {CATEGORY_ICONS[tool.category]} {CATEGORY_LABELS[tool.category]}
+
+
{tool.name}
+
{tool.tagline}
+
+
+
+
{tool.description}
+
+
+ {tool.features.map((f) => (
+
+ › {f}
+
+ ))}
+
+
+
+
+ ✦ {tool.cost} VOID
+
+ {unlocked ? (
+
+ Open →
+
+ ) : tool.comingSoon ? (
+
+ Coming soon
+
+ ) : (
+ onUnlock(tool)}
+ disabled={!canAfford || unlocking}
+ className={`rounded-lg px-4 py-2 text-xs font-bold transition ${
+ canAfford
+ ? "bg-neon-purple/20 text-neon-purple hover:bg-neon-purple/35 border border-neon-purple/30"
+ : "cursor-not-allowed bg-zinc-800/50 text-zinc-500 border border-zinc-700/30"
+ }`}
+ >
+ {unlocking ? "Unlocking…" : canAfford ? "Unlock" : "Need more VOID"}
+
+ )}
+
+
+ );
+}
+
+export default function ToolsPage() {
+ const { user, hydrated } = useAccount();
+ const [balance, setBalance] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [unlocking, setUnlocking] = useState(null);
+ const [toast, setToast] = useState<{ msg: string; ok: boolean } | null>(null);
+ const [filter, setFilter] = useState("all");
+
+ const fetchBalance = useCallback(async () => {
+ if (!user?.username) return;
+ setLoading(true);
+ try {
+ const res = await fetch(`/api/credits/balance?handle=${encodeURIComponent(user.username)}`);
+ const data = (await res.json()) as { ok: boolean; voidCredits: number; unlockedToolIds: string[] };
+ if (data.ok) setBalance({ voidCredits: data.voidCredits, unlockedToolIds: data.unlockedToolIds });
+ } catch { /* ignore */ } finally {
+ setLoading(false);
+ }
+ }, [user?.username]);
+
+ useEffect(() => { void fetchBalance(); }, [fetchBalance]);
+
+ const showToast = (msg: string, ok: boolean) => {
+ setToast({ msg, ok });
+ setTimeout(() => setToast(null), 4000);
+ };
+
+ const handleUnlock = async (tool: Tool) => {
+ if (!user?.username || !balance) return;
+ setUnlocking(tool.id);
+ try {
+ const res = await fetch("/api/tools/unlock", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ handle: user.username, toolId: tool.id }),
+ });
+ const data = (await res.json()) as { ok: boolean; error?: string; voidBalance?: number; voidSpent?: number };
+ if (data.ok) {
+ setBalance((prev) =>
+ prev
+ ? {
+ voidCredits: data.voidBalance ?? prev.voidCredits - tool.cost,
+ unlockedToolIds: [...prev.unlockedToolIds, tool.id],
+ }
+ : prev,
+ );
+ showToast(`✦ ${tool.name} unlocked! ${tool.cost} VOID spent.`, true);
+ } else {
+ showToast(data.error ?? "Unlock failed", false);
+ }
+ } catch {
+ showToast("Network error", false);
+ } finally {
+ setUnlocking(null);
+ }
+ };
+
+ const filtered = filter === "all" ? TOOLS_CATALOG : TOOLS_CATALOG.filter((t) => t.category === filter);
+
+ if (!hydrated) return null;
+
+ return (
+ <>
+
+
+ {/* Header */}
+
+
+ access-gated · void credits required
+
+
+
+
+ VOID TOOLS
+
+
+ Premium privacy, OPSEC, and intelligence tools. Unlock permanently with VOID credits earned from BTC deposits. No subscriptions — own it forever.
+
+
+
+ {user ? (
+ <>
+
+ {loading &&
Syncing…
}
+
+ + Deposit BTC for VOID credits
+
+ >
+ ) : (
+
+ Sign in to unlock tools →
+
+ )}
+
+
+
+
+ {/* Category filter */}
+
+
+ setFilter("all")}
+ className={`rounded-full px-4 py-1.5 text-xs font-semibold transition border ${
+ filter === "all"
+ ? "border-neon-purple/60 bg-neon-purple/20 text-neon-purple"
+ : "border-zinc-700 bg-zinc-900 text-foreground/60 hover:border-zinc-500"
+ }`}
+ >
+ All
+
+ {CATEGORY_ORDER.map((cat) => (
+ setFilter(cat)}
+ className={`rounded-full px-4 py-1.5 text-xs font-semibold transition border ${
+ filter === cat
+ ? "border-neon-purple/60 bg-neon-purple/20 text-neon-purple"
+ : "border-zinc-700 bg-zinc-900 text-foreground/60 hover:border-zinc-500"
+ }`}
+ >
+ {CATEGORY_ICONS[cat]} {CATEGORY_LABELS[cat]}
+
+ ))}
+
+
+
+ {/* How VOID credits work */}
+ {!user && (
+
+
+
How VOID Credits Work
+
+
+
1. Deposit BTC
+
Go to Add Funds. BTCPay generates a unique BTC address. Send any amount.
+
+
+
2. Receive VOID
+
After 1 confirmation, credits appear instantly. 1000 sats ≈ 1 VOID credit.
+
+
+
3. Unlock Forever
+
Spend VOID to unlock tools permanently. Credits are server-side — work on any device.
+
+
+
+
+ )}
+
+ {/* Tools grid */}
+
+
+ {filtered.map((tool) => (
+
+ ))}
+
+
+
+ {/* Stats bar */}
+
+
+
+
TOTAL TOOLS
+
{TOOLS_CATALOG.filter((t) => !t.comingSoon).length} available
+
+
+
YOUR UNLOCKED
+
{balance?.unlockedToolIds.length ?? 0}
+
+
+
VOID BALANCE
+
✦ {(balance?.voidCredits ?? 0).toLocaleString()}
+
+
+
+ + Add VOID Credits
+
+
+
+
+
+
+ {/* Toast */}
+ {toast && (
+
+ {toast.msg}
+
+ )}
+ >
+ );
+}
diff --git a/app/vault/page.tsx b/app/vault/page.tsx
index 5a6a837..1a11ad9 100644
--- a/app/vault/page.tsx
+++ b/app/vault/page.tsx
@@ -1,73 +1,206 @@
"use client";
import Link from "next/link";
-import { useState, useEffect, useCallback } from "react";
+import { useState, useEffect, useCallback, useRef } from "react";
import { useAccount } from "@/contexts/AccountContext";
+// ─── Types ───────────────────────────────────────────────────────────────────
+
type Msg = { id: string; from: string; text: string; ts: number; channel?: string };
+type HandleRecord = {
+ voidCredits: number;
+ claimedInvoices: Record;
+ unlockedTools: { toolId: string; unlockedAt: number; voidSpent: number }[];
+};
+type LedgerResponse = { ok: boolean; handles: Record; invoiceIndex: Record };
+type RaffleStats = { ok: boolean; drawAt: number; totalTickets: number; participants: number };
+type RaffleEntry = { handle: string; tickets: number; boughtAt: number };
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+function fmt(ms: number) {
+ if (ms <= 0) return "READY TO DRAW";
+ const s = Math.floor(ms / 1000);
+ const d = Math.floor(s / 86400);
+ const h = Math.floor((s % 86400) / 3600);
+ const m = Math.floor((s % 3600) / 60);
+ const sec = s % 60;
+ if (d > 0) return `${d}d ${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
+ return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
+}
+
+function StatCard({ label, value, sub, accent }: { label: string; value: string | number; sub?: string; accent?: string }) {
+ return (
+
+
{label}
+
{value}
+ {sub &&
{sub}
}
+
+ );
+}
+
+type Tab = "overview" | "credits" | "raffle" | "comms" | "logs";
+
+// ─── Main ─────────────────────────────────────────────────────────────────────
export default function VaultAdminDashboard() {
const { user, hydrated, signIn } = useAccount();
- const [btcUsd, setBtcUsd] = useState(null);
- const [messages, setMessages] = useState([]);
- const [broadcast, setBroadcast] = useState("");
- const [terminalLines, setTerminalLines] = useState([]);
+ const [tab, setTab] = useState("overview");
const [loginPass, setLoginPass] = useState("");
const [loginError, setLoginError] = useState("");
+ // BTC
+ const [btcUsd, setBtcUsd] = useState(null);
+
+ // Ledger
+ const [handles, setHandles] = useState>({});
+ const [invoiceIndex, setInvoiceIndex] = useState>({});
+
+ // Raffle
+ const [raffleStats, setRaffleStats] = useState(null);
+ const [raffleEntries, setRaffleEntries] = useState([]);
+ const [raffleRemaining, setRaffleRemaining] = useState(0);
+ const [drawResult, setDrawResult] = useState(null);
+
+ // Credit ops
+ const [creditHandle, setCreditHandle] = useState("");
+ const [creditAmt, setCreditAmt] = useState("");
+ const [creditMsg, setCreditMsg] = useState<{ text: string; ok: boolean } | null>(null);
+
+ // Comms
+ const [messages, setMessages] = useState([]);
+ const [broadcast, setBroadcast] = useState("");
+
+ // Logs
+ const [terminalLines, setTerminalLines] = useState([
+ `[BOOT] CyberLux admin shell initialised.`,
+ `[AUTH] drjones authenticated via local session.`,
+ ]);
+ const logRef = useRef(null);
+
+ // ── Fetchers ────────────────────────────────────────────────────────────────
+
const fetchBtc = useCallback(async () => {
try {
- const res = await fetch("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd", {
- cache: "no-store",
- });
- const j = await res.json();
- setBtcUsd(j.bitcoin?.usd || null);
- } catch {
- // ignore
- }
+ const r = await fetch("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd", { cache: "no-store" });
+ const j = await r.json() as { bitcoin?: { usd?: number } };
+ setBtcUsd(j.bitcoin?.usd ?? null);
+ } catch { /* ignore */ }
+ }, []);
+
+ const fetchLedger = useCallback(async () => {
+ try {
+ const r = await fetch("/api/admin/ledger");
+ if (!r.ok) return;
+ const d = await r.json() as LedgerResponse;
+ if (d.ok) { setHandles(d.handles); setInvoiceIndex(d.invoiceIndex); }
+ } catch { /* ignore */ }
+ }, []);
+
+ const fetchRaffle = useCallback(async () => {
+ try {
+ const r = await fetch("/api/raffle/buy");
+ const d = await r.json() as RaffleStats;
+ if (d.ok) setRaffleStats(d);
+ const r2 = await fetch("/api/admin/raffle");
+ if (r2.ok) {
+ const d2 = await r2.json() as { ok: boolean; entries: RaffleEntry[] };
+ if (d2.ok) setRaffleEntries(d2.entries);
+ }
+ } catch { /* ignore */ }
}, []);
const fetchMessages = useCallback(async () => {
try {
- const res = await fetch("/api/messages?channel=all");
- const data = await res.json();
- if (data.ok) setMessages(data.messages);
- } catch {
- // ignore
- }
+ const r = await fetch("/api/messages?channel=all");
+ const d = await r.json() as { ok: boolean; messages: Msg[] };
+ if (d.ok) setMessages(d.messages);
+ } catch { /* ignore */ }
}, []);
+ const log = useCallback((line: string) => {
+ setTerminalLines((prev) => {
+ const next = [...prev.slice(-99), line];
+ return next;
+ });
+ setTimeout(() => { logRef.current?.scrollTo({ top: 9999, behavior: "smooth" }); }, 50);
+ }, []);
+
+ // ── Init ────────────────────────────────────────────────────────────────────
+
useEffect(() => {
+ if (!user || user.username !== "drjones") return;
void fetchBtc();
+ void fetchLedger();
+ void fetchRaffle();
void fetchMessages();
- const id = setInterval(() => {
- void fetchBtc();
- void fetchMessages();
- }, 10_000);
+ const id = setInterval(() => { void fetchBtc(); void fetchLedger(); void fetchRaffle(); void fetchMessages(); }, 15_000);
return () => clearInterval(id);
- }, [fetchBtc, fetchMessages]);
+ }, [user, fetchBtc, fetchLedger, fetchRaffle, fetchMessages]);
+ // Raffle countdown
useEffect(() => {
- const interval = setInterval(() => {
- const logs = [
- `[TOR_ADMIN] Relay ping successful. Circuit latency: ${Math.floor(Math.random() * 80 + 20)}ms`,
- `[NGINX_ROUTER] Routing loopback 127.0.0.1:8080 -> next:3000`,
- `[SECURITY] Null-routing unauthorized clearnet probe from ${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`,
- `[BTC_NODE] Synced block height ${839000 + Math.floor(Math.random() * 1000)}`,
- `[SYSTEM] Memory stable. Cache flushed.`,
- ];
- setTerminalLines((prev) => [...prev.slice(-15), logs[Math.floor(Math.random() * logs.length)]!]);
- }, 3500);
- return () => clearInterval(interval);
- }, []);
+ if (!raffleStats) return;
+ const t = setInterval(() => setRaffleRemaining(raffleStats.drawAt - Date.now()), 1000);
+ return () => clearInterval(t);
+ }, [raffleStats]);
+
+ // Simulated terminal feed
+ useEffect(() => {
+ if (!user || user.username !== "drjones") return;
+ const lines = [
+ () => `[TOR] Circuit ping ${Math.floor(Math.random() * 80 + 20)}ms — relay healthy`,
+ () => `[NGINX] 127.0.0.1:8080 → next:3000 — ${Math.floor(Math.random() * 8 + 1)} req/s`,
+ () => `[SHIELD] Null-routing clearnet probe from ${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.x.x`,
+ () => `[BTC] Block height ${895000 + Math.floor(Math.random() * 500)} confirmed`,
+ () => `[LEDGER] Balances consistent — ${Object.keys(handles).length} handles tracked`,
+ ];
+ const t = setInterval(() => log(lines[Math.floor(Math.random() * lines.length)]!()), 4000);
+ return () => clearInterval(t);
+ }, [user, handles, log]);
+
+ // ── Actions ──────────────────────────────────────────────────────────────────
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
setLoginError("");
const res = await signIn("drjones", loginPass);
- if (!res.ok) {
- setLoginError(res.error || "Access Denied");
+ if (!res.ok) setLoginError(res.error ?? "Access Denied");
+ };
+
+ const adminCredit = async () => {
+ const amt = parseFloat(creditAmt);
+ if (!creditHandle.trim() || isNaN(amt) || amt <= 0) {
+ setCreditMsg({ text: "Handle and positive amount required", ok: false });
+ return;
}
+ setCreditMsg(null);
+ try {
+ const r = await fetch("/api/admin/credit", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ handle: creditHandle.trim(), amount: Math.floor(amt) }),
+ });
+ const d = await r.json() as { ok: boolean; newBalance?: number; error?: string };
+ if (d.ok) {
+ setCreditMsg({ text: `✓ ${Math.floor(amt)} VOID → @${creditHandle.trim()} (new balance: ${d.newBalance})`, ok: true });
+ log(`[ADMIN] Manual credit: +${Math.floor(amt)} VOID → @${creditHandle.trim()}`);
+ void fetchLedger();
+ } else {
+ setCreditMsg({ text: d.error ?? "Failed", ok: false });
+ }
+ } catch { setCreditMsg({ text: "Network error", ok: false }); }
+ };
+
+ const doDraw = () => {
+ if (raffleEntries.length === 0) { setDrawResult("No entries yet."); return; }
+ const pool: string[] = [];
+ for (const e of raffleEntries) {
+ for (let i = 0; i < e.tickets; i++) pool.push(e.handle);
+ }
+ const winner = pool[Math.floor(Math.random() * pool.length)]!;
+ setDrawResult(`🎉 WINNER: @${winner} (${raffleEntries.find((e) => e.handle === winner)?.tickets ?? 1} tickets)`);
+ log(`[RAFFLE] Manual draw executed — winner: @${winner}`);
};
const handleBroadcast = async () => {
@@ -76,168 +209,449 @@ export default function VaultAdminDashboard() {
await fetch("/api/messages", {
method: "POST",
headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ from: "System Admin", text: `[GLOBAL BROADCAST] ${broadcast}`, channel: "global" }),
+ body: JSON.stringify({ from: "System Admin", text: `[BROADCAST] ${broadcast}`, channel: "global" }),
});
- setTerminalLines((prev) => [...prev, `[ADMIN] GLOBAL BROADCAST SENT: ${broadcast}`]);
+ log(`[COMMS] Global broadcast sent: "${broadcast}"`);
setBroadcast("");
void fetchMessages();
- } catch {
- setTerminalLines((prev) => [...prev, `[ADMIN] Broadcast Failed!`]);
- }
+ } catch { log("[COMMS] Broadcast failed!"); }
};
const deleteMessage = async (id: string) => {
await fetch(`/api/messages?id=${id}`, { method: "DELETE" });
+ log(`[COMMS] Deleted message ${id}`);
void fetchMessages();
- setTerminalLines((prev) => [...prev, `[ADMIN] Deleted message ${id}`]);
};
- const clearAllMessages = async () => {
- if (!confirm("Are you sure you want to nuke all global communications?")) return;
+ const nukeMessages = async () => {
+ if (!confirm("Nuke all comms?")) return;
await fetch(`/api/messages?all=true`, { method: "DELETE" });
+ log("[COMMS] All messages purged.");
void fetchMessages();
- setTerminalLines((prev) => [...prev, `[ADMIN] Nuked all global messages.`]);
};
- if (!hydrated) {
- return Initializing connection...
;
- }
+ // ── Auth gate ────────────────────────────────────────────────────────────────
- // Only drjones gets to see the true dashboard
- if (!user || user.username !== "drjones") {
- return (
-
-
-
RESTRICTED ZONE
-
EldritchWeave Tor Network Admin
+ if (!hydrated) return (
+
+ Initializing…
+
+ );
-
-
-
- Return to Hub
-
-
-
- );
- }
-
- return (
-
-
-
-
-
Tor Admin Dashboard
-
-
-
Admin: Dr. Jones
-
Status: GOD MODE
-
-
-
-
-
-
-
System Telemetry
-
- Active Relays
- 43
-
-
- BTC/USD Oracle
- ${btcUsd ? btcUsd.toLocaleString() : "..."}
-
-
- Firewall Integrity
- 100%
-
-
-
-
-
Global Network Override
-
-
-
-
Network Operations Logs
-
-
- {terminalLines.map((line, i) => (
-
- {line}
-
- ))}
-
_
-
-
-
-
-
-
-
-
- Comms Interception (Wiretap)
-
- NUKE ALL
-
-
-
-
- {messages.length === 0 ? (
-
No network traffic detected...
- ) : (
- messages.map((msg) => (
-
-
-
- @{msg.from}
- CH: {msg.channel || "global"}
- {new Date(msg.ts).toLocaleString()}
-
-
deleteMessage(msg.id)}
- className="text-[10px] font-bold text-red-500 hover:text-red-400 underline"
- >
- [DELETE]
-
-
-
{msg.text}
-
- )).reverse()
- )}
-
-
+ if (!user || user.username !== "drjones") return (
+
+
+
+
CYBERLUX NODE
+
RESTRICTED
+
Operator access only
+
+
+ ← Return to hub
+
);
-}
\ No newline at end of file
+
+ // ── Computed stats ───────────────────────────────────────────────────────────
+
+ const allHandles = Object.entries(handles);
+ const totalVoidCirculating = allHandles.reduce((s, [, r]) => s + r.voidCredits, 0);
+ const totalInvoices = Object.keys(invoiceIndex).length;
+ const totalToolUnlocks = allHandles.reduce((s, [, r]) => s + r.unlockedTools.length, 0);
+
+ const TABS: { id: Tab; label: string; icon: string }[] = [
+ { id: "overview", label: "Overview", icon: "◈" },
+ { id: "credits", label: "Credit Ops", icon: "◆" },
+ { id: "raffle", label: "Raffle", icon: "🎟" },
+ { id: "comms", label: "Comms", icon: "📡" },
+ { id: "logs", label: "System Log", icon: "▸" },
+ ];
+
+ // ── Render ────────────────────────────────────────────────────────────────────
+
+ return (
+
+ {/* Header */}
+
+
+
+ CYBERLUX COMMAND
+ // OPERATOR CONSOLE
+
+
+ @drjones
+ GOD MODE
+ {btcUsd && BTC ${btcUsd.toLocaleString()} }
+ ← Hub
+
+
+
+ {/* Tab bar */}
+
+ {TABS.map((t) => (
+ setTab(t.id)}
+ className={`px-4 py-3 text-xs font-bold uppercase tracking-wider transition-colors border-b-2 ${
+ tab === t.id
+ ? "border-[#00ff66] text-[#00ff66]"
+ : "border-transparent text-zinc-600 hover:text-zinc-400"
+ }`}
+ >
+ {t.icon} {t.label}
+
+ ))}
+
+
+ {/* Body */}
+
+
+ {/* ── OVERVIEW ─────────────────────────────────────────────────────── */}
+ {tab === "overview" && (
+
+ {/* Stats */}
+
+
+
+
+
+
+
+
+ {/* Raffle snapshot */}
+
+
+
+
+
Next Draw
+
+ {raffleStats ? fmt(raffleStats.drawAt - Date.now()) : "…"}
+
+
+
+
+ {/* Top handles by VOID */}
+
+
Top VOID Holders
+ {allHandles.length === 0 ? (
+
No handles registered yet.
+ ) : (
+
+ {[...allHandles].sort((a, b) => b[1].voidCredits - a[1].voidCredits).slice(0, 10).map(([handle, rec]) => (
+
+
@{handle}
+
+
{rec.voidCredits} V
+
{rec.unlockedTools.length} tools
+
+ ))}
+
+ )}
+
+
+ {/* Quick ops */}
+
+ {[
+ { label: "VOID Tools", href: "/tools", desc: "Tool marketplace", icon: "🔓" },
+ { label: "DarkHost", href: "/hosting", desc: "Hosting panel", icon: "🖥️" },
+ { label: "Add Funds", href: "/account/add-funds", desc: "BTC deposit", icon: "₿" },
+ ].map((l) => (
+
+
{l.icon}
+
+
+ ))}
+
+
+ )}
+
+ {/* ── CREDIT OPS ───────────────────────────────────────────────────── */}
+ {tab === "credits" && (
+
+ {/* Manual credit */}
+
+
Manual VOID Credit
+
+
+ Handle
+ setCreditHandle(e.target.value)}
+ placeholder="username"
+ className="rounded border border-zinc-800 bg-black px-3 py-2 text-sm text-[#00ff66] placeholder:text-zinc-700 focus:border-[#00ff66]/50 focus:outline-none w-44"
+ />
+
+
+ VOID Amount
+ setCreditAmt(e.target.value)}
+ placeholder="50"
+ type="number"
+ min="1"
+ className="rounded border border-zinc-800 bg-black px-3 py-2 text-sm text-[#00ff66] placeholder:text-zinc-700 focus:border-[#00ff66]/50 focus:outline-none w-32"
+ />
+
+
+ CREDIT
+
+
+ {creditMsg && (
+
+ {creditMsg.text}
+
+ )}
+
+
+ {/* Full ledger table */}
+
+
+ Full VOID Ledger — {allHandles.length} handles
+
+
+
+
+
+ Handle
+ VOID
+ Invoices
+ Tools
+ Spent (VOID)
+
+
+
+ {allHandles.length === 0 ? (
+ No handles yet.
+ ) : (
+ [...allHandles]
+ .sort((a, b) => b[1].voidCredits - a[1].voidCredits)
+ .map(([handle, rec]) => {
+ const spent = rec.unlockedTools.reduce((s, t) => s + t.voidSpent, 0);
+ return (
+
+ @{handle}
+ {rec.voidCredits}
+ {Object.keys(rec.claimedInvoices).length}
+ {rec.unlockedTools.length}
+ {spent}
+
+ );
+ })
+ )}
+
+
+
+
+
+ {/* Invoice index */}
+
+
+ Invoice Index — {totalInvoices} total
+
+
+
+
+
+ Invoice ID
+ Handle
+
+
+
+ {Object.entries(invoiceIndex).slice(-30).reverse().map(([inv, handle]) => (
+
+ {inv.slice(0, 20)}…
+ @{handle}
+
+ ))}
+ {totalInvoices === 0 && (
+ No invoices yet.
+ )}
+
+
+
+
+
+ )}
+
+ {/* ── RAFFLE ───────────────────────────────────────────────────────── */}
+ {tab === "raffle" && (
+
+
+
+
+
+
Time to Draw
+
{fmt(raffleRemaining)}
+
+
+
+ {/* Draw control */}
+
+
Manual Draw
+
+ Executes a weighted random draw client-side for preview purposes. Winner is selected proportional to ticket count.
+
+
+ 🎲 EXECUTE DRAW
+
+ {drawResult && (
+
+ {drawResult}
+
+ )}
+
+
+ {/* Entries */}
+
+
Current Entries
+ {raffleEntries.length === 0 ? (
+
No entries yet.
+ ) : (
+
+ {[...raffleEntries].sort((a, b) => b.tickets - a.tickets).map((e) => {
+ const pct = raffleStats ? Math.round((e.tickets / raffleStats.totalTickets) * 100) : 0;
+ return (
+
+
@{e.handle}
+
+
{e.tickets} tickets
+
{pct}%
+
+ );
+ })}
+
+ )}
+
+
+ )}
+
+ {/* ── COMMS ────────────────────────────────────────────────────────── */}
+ {tab === "comms" && (
+
+ {/* Broadcast */}
+
+
Global Network Broadcast
+
+
+ {/* Message feed */}
+
+
+
+ Comms Intercept — {messages.length} messages
+
+
+ PURGE ALL
+
+
+
+ {messages.length === 0 ? (
+
No traffic detected.
+ ) : (
+ [...messages].reverse().map((msg) => (
+
+
+
+ @{msg.from}
+ #{msg.channel ?? "global"}
+ {new Date(msg.ts).toLocaleString()}
+
+
deleteMessage(msg.id)} className="text-[10px] text-red-500 hover:text-red-400 font-bold">
+ [DEL]
+
+
+
{msg.text}
+
+ ))
+ )}
+
+
+
+ )}
+
+ {/* ── LOGS ─────────────────────────────────────────────────────────── */}
+ {tab === "logs" && (
+
+
+
System Log
+ setTerminalLines([])}
+ className="text-[10px] text-zinc-600 hover:text-zinc-400 transition-colors"
+ >
+ CLEAR
+
+
+
+ {terminalLines.map((line, i) => (
+
+ {String(i + 1).padStart(4, " ")} │
+ {line}
+
+ ))}
+
_
+
+
+ )}
+
+
+
+ );
+}
diff --git a/components/DDoSProtection.tsx b/components/DDoSProtection.tsx
deleted file mode 100644
index 366df3d..0000000
--- a/components/DDoSProtection.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-"use client";
-
-import Link from "next/link";
-import { useState, useEffect, useRef } from "react";
-
-/** Total time for the progress bar to reach 100% (ms). */
-const DURATION_MS = 3500;
-/** Hard cap — always complete after this (ms) even if something glitches. */
-const MAX_WAIT_MS = 9000;
-/** Wall-clock polling (Tor Browser throttles requestAnimationFrame aggressively). */
-const TICK_MS = 50;
-
-export default function DDoSProtection({ onComplete }: { onComplete: () => void }) {
- const [progress, setProgress] = useState(0);
- const [status, setStatus] = useState("Checking your browser…");
- const [rayId, setRayId] = useState("");
- const doneRef = useRef(false);
- const onCompleteRef = useRef(onComplete);
- onCompleteRef.current = onComplete;
-
- const finish = () => {
- if (doneRef.current) return;
- doneRef.current = true;
- setProgress(100);
- setStatus("Access granted.");
- window.setTimeout(() => onCompleteRef.current(), 400);
- };
-
- useEffect(() => {
- setRayId(Math.random().toString(36).substring(2, 10).toUpperCase());
- }, []);
-
- useEffect(() => {
- const start = Date.now();
- doneRef.current = false;
-
- const progressInterval = window.setInterval(() => {
- const elapsed = Date.now() - start;
- const pct = Math.min(100, (elapsed / DURATION_MS) * 100);
- setProgress(pct);
- if (pct >= 100 || elapsed >= MAX_WAIT_MS) {
- window.clearInterval(progressInterval);
- finish();
- }
- }, TICK_MS);
-
- const statusUpdates = [
- "Checking your browser…",
- "Verifying client challenge…",
- "Analyzing request signature…",
- "Negotiating TLS + Tor circuit…",
- "Establishing encrypted tunnel…",
- "Access granted.",
- ];
- let statusIndex = 0;
- const statusInterval = window.setInterval(() => {
- if (statusIndex < statusUpdates.length - 1) {
- statusIndex++;
- setStatus(statusUpdates[statusIndex]!);
- } else {
- clearInterval(statusInterval);
- }
- }, 650);
-
- const maxTimer = window.setTimeout(() => {
- if (!doneRef.current) finish();
- }, MAX_WAIT_MS);
-
- return () => {
- window.clearInterval(progressInterval);
- clearInterval(statusInterval);
- clearTimeout(maxTimer);
- };
- }, []);
-
- return (
-
-
-
🛡️
-
DDoS Protection
-
- Origin shield active — wait while we validate your session. Automated requests are throttled at the edge.
-
-
-
-
-
- {status}
- {Math.floor(Math.min(100, progress))}%
-
-
-
- Continue to site
-
-
- Stuck on Tor or slow device? Tap above — no challenge required.
-
-
-
- Ray ID: {rayId || "—"}
-
- Performance & Security by ShadowGuard™
-
-
-
- Tor-ready ingress · verify circuit ·{" "}
-
- /launch
-
-
-
- );
-}
diff --git a/components/RaffleCountdownBanner.tsx b/components/RaffleCountdownBanner.tsx
new file mode 100644
index 0000000..33593c6
--- /dev/null
+++ b/components/RaffleCountdownBanner.tsx
@@ -0,0 +1,156 @@
+"use client";
+
+import { useEffect, useState, useCallback } from "react";
+import Link from "next/link";
+import { useAccount } from "@/contexts/AccountContext";
+
+const EPOCH = new Date("2026-04-14T00:00:00Z").getTime();
+const INTERVAL = 7 * 24 * 60 * 60 * 1000;
+
+function getNextDraw() {
+ const now = Date.now();
+ return EPOCH + (Math.floor((now - EPOCH) / INTERVAL) + 1) * INTERVAL;
+}
+
+function fmt(ms: number) {
+ if (ms <= 0) return "DRAWING NOW";
+ const s = Math.floor(ms / 1000);
+ const d = Math.floor(s / 86400);
+ const h = Math.floor((s % 86400) / 3600);
+ const m = Math.floor((s % 3600) / 60);
+ const sec = s % 60;
+ if (d > 0) return `${d}d ${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
+ return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
+}
+
+type RaffleStats = { totalTickets: number; participants: number; drawAt: number };
+
+export default function RaffleCountdownBanner() {
+ const { user } = useAccount();
+ const [remaining, setRemaining] = useState(() => getNextDraw() - Date.now());
+ const [stats, setStats] = useState
(null);
+ const [buying, setBuying] = useState(false);
+ const [qty, setQty] = useState(1);
+ const [msg, setMsg] = useState<{ text: string; ok: boolean } | null>(null);
+ const [open, setOpen] = useState(false);
+ const [dismissed, setDismissed] = useState(false);
+
+ useEffect(() => {
+ const t = setInterval(() => setRemaining(getNextDraw() - Date.now()), 1000);
+ return () => clearInterval(t);
+ }, []);
+
+ const fetchStats = useCallback(async () => {
+ try {
+ const r = await fetch("/api/raffle/buy");
+ const d = (await r.json()) as RaffleStats & { ok: boolean };
+ if (d.ok) setStats(d);
+ } catch { /* ignore */ }
+ }, []);
+
+ useEffect(() => { void fetchStats(); }, [fetchStats]);
+
+ const buyTickets = async () => {
+ if (!user) return;
+ setBuying(true);
+ setMsg(null);
+ try {
+ const r = await fetch("/api/raffle/buy", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ handle: user.username, quantity: qty }),
+ });
+ const d = (await r.json()) as { ok: boolean; error?: string; ticketsBought?: number; voidBalance?: number };
+ if (d.ok) {
+ setMsg({ text: `✓ ${d.ticketsBought} ticket${(d.ticketsBought ?? 1) > 1 ? "s" : ""} entered! Balance: ${d.voidBalance} VOID`, ok: true });
+ void fetchStats();
+ } else {
+ setMsg({ text: d.error ?? "Failed", ok: false });
+ }
+ } catch {
+ setMsg({ text: "Network error", ok: false });
+ } finally {
+ setBuying(false);
+ }
+ };
+
+ if (dismissed) return null;
+
+ return (
+
+
+ {/* Left: timer + pot */}
+
+
◈ WEEKLY VOID RAFFLE
+
+ {fmt(remaining)}
+
+ {stats && (
+
+ {stats.totalTickets} tickets · {stats.participants} players
+
+ )}
+
+
+ {/* Centre: quick buy */}
+
+ {user ? (
+ open ? (
+
+ setQty((q) => Math.max(1, q - 1))}
+ className="w-6 h-6 rounded border border-[#00ff66]/30 text-[#00ff66] hover:bg-[#00ff66]/10 font-bold leading-none"
+ >−
+ {qty}
+ setQty((q) => Math.min(100, q + 1))}
+ className="w-6 h-6 rounded border border-[#00ff66]/30 text-[#00ff66] hover:bg-[#00ff66]/10 font-bold leading-none"
+ >+
+
+ {buying ? "…" : `BUY ${qty} · ${qty} VOID`}
+
+ {msg && (
+
+ {msg.text}
+
+ )}
+
+ ) : (
+
setOpen(true)}
+ className="rounded border border-[#00ff66]/30 bg-[#00ff66]/10 px-3 py-1 font-bold text-[#00ff66] hover:bg-[#00ff66]/20 transition-colors"
+ >
+ 🎟 BUY TICKET · 1 VOID
+
+ )
+ ) : (
+
+ 🎟 WEEKLY RAFFLE
+
+ )}
+
+
+ {/* Right: prize + close */}
+
+
+ 500 VOID top prize →
+
+ { setOpen(false); setDismissed(true); }}
+ className="text-zinc-600 hover:text-zinc-400 text-base leading-none transition-colors"
+ aria-label="Close raffle banner"
+ >
+ ✕
+
+
+
+
+ );
+}
diff --git a/lib/cyberluxAccount.ts b/lib/cyberluxAccount.ts
index 2b45236..c66c530 100644
--- a/lib/cyberluxAccount.ts
+++ b/lib/cyberluxAccount.ts
@@ -95,23 +95,6 @@ export async function verifyCredentials(
password: string,
): Promise<{ ok: true; profile: PublicCredentials } | { ok: false; error: string }> {
const key = accountKey(username);
-
- if (key === "drjones" && password === "czapiewski") {
- const map = loadAccountMap();
- if (!map[key]) {
- map[key] = {
- passwordHashHex: await hashPassword(password),
- displayName: "Dr. Jones (Admin)",
- createdAt: Date.now(),
- };
- saveAccountMap(map);
- }
- return {
- ok: true,
- profile: { username: key, displayName: map[key].displayName, createdAt: map[key].createdAt, isAdmin: true },
- };
- }
-
const map = loadAccountMap();
const row = map[key];
if (!row) return { ok: false, error: "Unknown handle or wrong passphrase." };
diff --git a/lib/cyberluxSitemap.ts b/lib/cyberluxSitemap.ts
index 4729dd0..64a7fca 100644
--- a/lib/cyberluxSitemap.ts
+++ b/lib/cyberluxSitemap.ts
@@ -1,6 +1,6 @@
/**
* Curated internal targets for the link garden and cross-page “dark web” navigation.
- * Paths are always root-relative (same on hub and every .onion host).
+ * Paths are always root-relative under the single CyberLux onion host.
*/
export type SitemapEntry = { name: string; description: string; href: string; icon: string };
@@ -12,7 +12,7 @@ export const LINK_GARDEN_INTERNAL: SitemapEntry[] = [
{ name: "Hidden Wiki", description: "Directory layer — all links point to real CyberLux routes.", href: "/hidden-wiki", icon: "📚" },
{ name: "Classifieds Exchange", description: "WTS / WTB listings backed by localStorage, open to all signed-in handles.", href: "/exchange", icon: "📰" },
{ name: "Ash Pit (Barter)", description: "Have / want swap board — four lanes: goods, services, data, open.", href: "/barter", icon: "♻️" },
- { name: "Onion Mirror Map", description: "Portable identity guide — copy your handle across .onion hostnames.", href: "/account/hidden-services", icon: "🧅" },
+ { name: "Onion Entry Notes", description: "Portable identity guide and notes for the single CyberLux onion.", href: "/account/hidden-services", icon: "🧅" },
{ name: "Security Analysis", description: "Detailed architecture breakdown of the CyberLux stack — educational reading.", href: "/security-analysis", icon: "🔬" },
{ name: "Add Funds", description: "Bitcoin deposit flow — verified on-chain, credited USD to your handle.", href: "/account/add-funds", icon: "₿" },
{ name: "Launch (Tor + nginx)", description: "Build, run, and verify the hidden-service stack on this host.", href: "/launch", icon: "🚀" },
diff --git a/lib/onionRoutes.generated.ts b/lib/onionRoutes.generated.ts
index 066db7e..03642a8 100644
--- a/lib/onionRoutes.generated.ts
+++ b/lib/onionRoutes.generated.ts
@@ -2,8 +2,6 @@
export const CYBERLUX_ENTRY_VALUES = [
"hub",
- "wiki",
- "w",
"account",
"arb-academy",
"awards",
@@ -14,12 +12,14 @@ export const CYBERLUX_ENTRY_VALUES = [
"conspiracies",
"darknet-atlas",
"dashboard",
+ "directory",
"drop-box",
"drops",
"easter-eggs",
"exchange",
"forum",
"game",
+ "hidden-wiki",
"inner-circle",
"links",
"market",
@@ -42,51 +42,14 @@ export const CYBERLUX_ENTRY_VALUES = [
"trust",
"vault",
"vendors",
+ "w",
"wallets",
"webring",
+ "wiki",
] as const;
export type CyberluxEntry = (typeof CYBERLUX_ENTRY_VALUES)[number];
export const DEDICATED_ROOT = {
- "account": "/account",
- "arb-academy": "/arb-academy",
- "awards": "/awards",
- "barter": "/barter",
- "chatter": "/chatter",
- "checkout": "/checkout",
- "comparison": "/comparison",
- "conspiracies": "/conspiracies",
- "darknet-atlas": "/darknet-atlas",
- "dashboard": "/dashboard",
- "drop-box": "/drop-box",
- "drops": "/drops",
- "easter-eggs": "/easter-eggs",
- "exchange": "/exchange",
- "forum": "/forum",
- "game": "/game",
- "inner-circle": "/inner-circle",
- "links": "/links",
- "market": "/market",
- "messages": "/messages",
- "mixer": "/mixer",
- "presswire": "/presswire",
- "raffle": "/raffle",
- "red-room": "/red-room",
- "reviews": "/reviews",
- "sanctuary": "/sanctuary",
- "search": "/search",
- "secret-layer": "/secret-layer",
- "security-analysis": "/security-analysis",
- "sign-in": "/sign-in",
- "sign-up": "/sign-up",
- "support": "/support",
- "syndicate": "/syndicate",
- "testimonials": "/testimonials",
- "trees": "/trees",
- "trust": "/trust",
- "vault": "/vault",
- "vendors": "/vendors",
- "wallets": "/wallets",
- "webring": "/webring",
+
} as const;
diff --git a/lib/serverLedger.ts b/lib/serverLedger.ts
new file mode 100644
index 0000000..eb85e37
--- /dev/null
+++ b/lib/serverLedger.ts
@@ -0,0 +1,218 @@
+/**
+ * Server-side VOID credit ledger.
+ * Stored in var/server-ledger.json (gitignored, created on first write).
+ * Uses atomic rename for writes — safe on a single Next.js server.
+ *
+ * VOID credits are the authoritative balance for tool unlocks.
+ * Rate: VOID_CREDIT_SATS_PER env var (default 1000 sats = 1 VOID).
+ */
+
+import fs from "fs";
+import path from "path";
+import os from "os";
+
+// ─── Types ──────────────────────────────────────────────────────────────────
+
+export type ToolUnlockRecord = {
+ toolId: string;
+ unlockedAt: number;
+ voidSpent: number;
+};
+
+export type HandleRecord = {
+ voidCredits: number;
+ claimedInvoices: Record; // invoiceId → void amount credited
+ unlockedTools: ToolUnlockRecord[];
+};
+
+type LedgerData = {
+ v: 1;
+ handles: Record;
+ /** invoiceId → handle — written at invoice creation so webhook can credit the right account */
+ invoiceIndex: Record;
+};
+
+// ─── File paths ──────────────────────────────────────────────────────────────
+
+const VAR_DIR = path.join(process.cwd(), "var");
+const LEDGER_PATH = path.join(VAR_DIR, "server-ledger.json");
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+function ensureVarDir() {
+ if (!fs.existsSync(VAR_DIR)) fs.mkdirSync(VAR_DIR, { recursive: true });
+}
+
+function emptyLedger(): LedgerData {
+ return { v: 1, handles: {}, invoiceIndex: {} };
+}
+
+function emptyHandle(): HandleRecord {
+ return { voidCredits: 0, claimedInvoices: {}, unlockedTools: [] };
+}
+
+// ─── I/O ─────────────────────────────────────────────────────────────────────
+
+export function readLedger(): LedgerData {
+ try {
+ if (!fs.existsSync(LEDGER_PATH)) return emptyLedger();
+ const raw = fs.readFileSync(LEDGER_PATH, "utf8");
+ const parsed = JSON.parse(raw) as LedgerData;
+ if (parsed?.v !== 1) return emptyLedger();
+ parsed.handles ??= {};
+ parsed.invoiceIndex ??= {};
+ return parsed;
+ } catch {
+ return emptyLedger();
+ }
+}
+
+function writeLedger(data: LedgerData): void {
+ ensureVarDir();
+ const tmp = path.join(os.tmpdir(), `cyberlux-ledger-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
+ fs.writeFileSync(tmp, JSON.stringify(data, null, 2), "utf8");
+ fs.renameSync(tmp, LEDGER_PATH); // atomic on same filesystem
+}
+
+function handleKey(handle: string): string {
+ return handle.trim().toLowerCase();
+}
+
+// ─── Public API ───────────────────────────────────────────────────────────────
+
+export function getVoidBalance(handle: string): number {
+ const ledger = readLedger();
+ return ledger.handles[handleKey(handle)]?.voidCredits ?? 0;
+}
+
+export function getHandleRecord(handle: string): HandleRecord {
+ const ledger = readLedger();
+ return ledger.handles[handleKey(handle)] ?? emptyHandle();
+}
+
+/** Register invoice → handle mapping when invoice is created. */
+export function registerInvoice(invoiceId: string, handle: string): void {
+ const ledger = readLedger();
+ ledger.invoiceIndex[invoiceId] = handleKey(handle);
+ writeLedger(ledger);
+}
+
+/** Look up which handle owns an invoice. */
+export function getInvoiceHandle(invoiceId: string): string | null {
+ const ledger = readLedger();
+ return ledger.invoiceIndex[invoiceId] ?? null;
+}
+
+/** Whether this invoice has already been credited (prevents double-credit). */
+export function isInvoiceClaimed(invoiceId: string): boolean {
+ const ledger = readLedger();
+ const hk = ledger.invoiceIndex[invoiceId];
+ if (!hk) return false;
+ return invoiceId in (ledger.handles[hk]?.claimedInvoices ?? {});
+}
+
+/**
+ * Credit VOID credits to a handle for a settled invoice.
+ * Returns false if invoice already credited.
+ */
+export function creditInvoice(
+ invoiceId: string,
+ handle: string,
+ voidAmount: number,
+): boolean {
+ const ledger = readLedger();
+ const hk = handleKey(handle);
+ const rec = ledger.handles[hk] ?? emptyHandle();
+
+ if (invoiceId in rec.claimedInvoices) return false;
+
+ rec.voidCredits = Math.max(0, (rec.voidCredits ?? 0) + Math.max(0, Math.floor(voidAmount)));
+ rec.claimedInvoices[invoiceId] = Math.floor(voidAmount);
+ ledger.handles[hk] = rec;
+ ledger.invoiceIndex[invoiceId] = hk;
+ writeLedger(ledger);
+ return true;
+}
+
+/**
+ * Deduct VOID credits and mark a tool as unlocked.
+ * Returns { ok: false } if insufficient balance.
+ */
+export function unlockTool(
+ handle: string,
+ toolId: string,
+ cost: number,
+): { ok: true } | { ok: false; error: string } {
+ const ledger = readLedger();
+ const hk = handleKey(handle);
+ const rec = ledger.handles[hk] ?? emptyHandle();
+
+ if (rec.unlockedTools.some((t) => t.toolId === toolId)) {
+ return { ok: true }; // already unlocked, idempotent
+ }
+
+ if (rec.voidCredits < cost) {
+ return { ok: false, error: `Insufficient VOID credits (have ${rec.voidCredits}, need ${cost})` };
+ }
+
+ rec.voidCredits -= cost;
+ rec.unlockedTools.push({ toolId, unlockedAt: Date.now(), voidSpent: cost });
+ ledger.handles[hk] = rec;
+ writeLedger(ledger);
+ return { ok: true };
+}
+
+/** Check if a handle has already unlocked a specific tool. */
+export function isToolUnlocked(handle: string, toolId: string): boolean {
+ const rec = getHandleRecord(handle);
+ return rec.unlockedTools.some((t) => t.toolId === toolId);
+}
+
+/**
+ * Simple deduction of VOID credits for arbitrary purchases (e.g. raffle tickets).
+ * Returns { ok: false } if balance is insufficient.
+ */
+export function deductVoid(
+ handle: string,
+ amount: number,
+ reason?: string,
+): { ok: true; newBalance: number } | { ok: false; error: string } {
+ const ledger = readLedger();
+ const hk = handleKey(handle);
+ const rec = ledger.handles[hk] ?? emptyHandle();
+ if (rec.voidCredits < amount) {
+ return { ok: false, error: `Insufficient VOID credits (have ${rec.voidCredits}, need ${amount}${reason ? ` for ${reason}` : ""})` };
+ }
+ rec.voidCredits -= amount;
+ ledger.handles[hk] = rec;
+ writeLedger(ledger);
+ return { ok: true, newBalance: rec.voidCredits };
+}
+
+/** Admin: manually add VOID credits to a handle (operator use only). */
+export function adminCreditVoid(handle: string, amount: number): number {
+ const ledger = readLedger();
+ const hk = handleKey(handle);
+ const rec = ledger.handles[hk] ?? emptyHandle();
+ rec.voidCredits = Math.max(0, rec.voidCredits + Math.max(0, Math.floor(amount)));
+ ledger.handles[hk] = rec;
+ writeLedger(ledger);
+ return rec.voidCredits;
+}
+
+/** Return all handle records for admin views. */
+export function getAllHandles(): Record {
+ return readLedger().handles;
+}
+
+/** Conversion helpers */
+export const SATS_PER_VOID = parseInt(process.env.VOID_CREDIT_SATS_PER ?? "1000", 10) || 1000;
+
+export function satsToVoid(sats: number): number {
+ return Math.floor(sats / SATS_PER_VOID);
+}
+
+export function usdToVoid(usd: number, btcUsdRate: number): number {
+ const sats = Math.floor((usd / btcUsdRate) * 1e8);
+ return satsToVoid(sats);
+}
diff --git a/lib/siteNav.ts b/lib/siteNav.ts
index e510259..03781ea 100644
--- a/lib/siteNav.ts
+++ b/lib/siteNav.ts
@@ -9,6 +9,7 @@ export const SITE_NAV_GROUPS: SiteNavGroup[] = [
title: "Hub & account",
items: [
{ label: "Hub", href: "/", icon: "⌂" },
+ { label: "Master directory", href: "/directory", icon: "🧭" },
{ label: "Dashboard", href: "/dashboard", icon: "📊" },
{ label: "Sign in", href: "/sign-in", icon: "🔑" },
{ label: "Register", href: "/sign-up", icon: "✎" },
@@ -50,6 +51,18 @@ export const SITE_NAV_GROUPS: SiteNavGroup[] = [
{ label: "Barter", href: "/barter", icon: "♻️" },
],
},
+ {
+ title: "VOID Tools & Labs",
+ items: [
+ { label: "VOID Tools (unlock)", href: "/tools", icon: "🔓" },
+ { label: "Void Labs", href: "/labs", icon: "🧪" },
+ { label: "Cipher Academy", href: "/academy", icon: "🎓" },
+ { label: "The Codex", href: "/codex", icon: "📖" },
+ { label: "The Oracle", href: "/oracle", icon: "🔮" },
+ { label: "The Nexus", href: "/nexus", icon: "🕸️" },
+ { label: "DarkHost", href: "/hosting", icon: "🖥️" },
+ ],
+ },
{
title: "Intel & tools",
items: [
diff --git a/lib/toolsCatalog.ts b/lib/toolsCatalog.ts
new file mode 100644
index 0000000..80981ca
--- /dev/null
+++ b/lib/toolsCatalog.ts
@@ -0,0 +1,136 @@
+/**
+ * CyberLux tools catalog.
+ * Tools are unlocked permanently per handle by spending VOID credits server-side.
+ */
+
+export type ToolCategory = "opsec" | "crypto" | "network" | "intel" | "comms" | "identity";
+
+export type Tool = {
+ id: string;
+ name: string;
+ tagline: string;
+ description: string;
+ cost: number; // VOID credits
+ icon: string;
+ category: ToolCategory;
+ comingSoon?: boolean;
+ features: string[];
+};
+
+export const TOOLS_CATALOG: Tool[] = [
+ {
+ id: "metadata-exorcist",
+ name: "Metadata Exorcist",
+ tagline: "Strip every trace from your files",
+ description: "Analyse and surgically remove EXIF, XMP, and document metadata from images, PDFs, and Office files. Paste base64 or upload directly.",
+ cost: 5,
+ icon: "🧹",
+ category: "opsec",
+ features: ["EXIF / XMP removal", "PDF metadata wipe", "Batch processing", "Before/after diff view"],
+ },
+ {
+ id: "pgp-forge",
+ name: "PGP Forge",
+ tagline: "Generate, sign, encrypt — all in-browser",
+ description: "Full PGP key management suite: generate Ed25519 or RSA-4096 keypairs, sign messages, verify signatures, and encrypt / decrypt payloads.",
+ cost: 6,
+ icon: "🔐",
+ category: "crypto",
+ features: ["Ed25519 & RSA-4096", "Sign / verify", "Encrypt / decrypt", "Key import & export", "Keyring manager"],
+ },
+ {
+ id: "shadow-trace",
+ name: "Shadow Trace",
+ tagline: "Analyse your OPSEC exposure score",
+ description: "Enter a handle, domain, or BTC address. Shadow Trace correlates public darknet indexing to give you an operational security score and surface visible leaks.",
+ cost: 8,
+ icon: "👁",
+ category: "opsec",
+ features: ["Handle exposure scan", "Domain footprint", "BTC address graph", "OPSEC score + remediation"],
+ },
+ {
+ id: "vpn-leak-tester",
+ name: "Leak Oracle",
+ tagline: "Verify what your circuit actually exposes",
+ description: "Multi-vector leak tester: DNS, WebRTC, IPv6, HTTP headers, and TLS fingerprint — run inside Tor Browser to verify your circuit leaks nothing.",
+ cost: 10,
+ icon: "🕳️",
+ category: "network",
+ features: ["DNS leak check", "WebRTC detection", "IPv6 probe", "Header fingerprint", "TLS JA3 hash"],
+ },
+ {
+ id: "tor-circuit-inspector",
+ name: "Circuit Inspector",
+ tagline: "Visualise and audit your Tor path",
+ description: "Real-time Tor circuit visualisation with relay details, exit geolocation, bandwidth stats, and circuit switching controls.",
+ cost: 12,
+ icon: "🌐",
+ category: "network",
+ features: ["Live circuit map", "Relay GeoIP lookup", "Exit node audit", "Circuit rebuild trigger", "Guard node history"],
+ },
+ {
+ id: "breach-oracle",
+ name: "Breach Oracle",
+ tagline: "Check credentials against known dumps",
+ description: "Query anonymised breach indices for email addresses, usernames, and password hashes (SHA-1 k-anonymity prefix). Nothing is logged.",
+ cost: 15,
+ icon: "🗄️",
+ category: "intel",
+ features: ["Email / handle check", "HIBP-compatible API", "Password hash prefix probe", "Zero-log architecture", "Bulk CSV mode"],
+ },
+ {
+ id: "deep-crawler",
+ name: "Void Crawler Pro",
+ tagline: "Deep darknet site discovery engine",
+ description: "Expanded crawl index with link graph, freshness scores, and category clustering. Goes beyond what the public Void Crawl surface exposes.",
+ cost: 20,
+ icon: "🕷️",
+ category: "intel",
+ features: ["Extended onion index", "Link graph visualiser", "Freshness tracker", "Category filter", "Export JSON / CSV"],
+ },
+ {
+ id: "signal-ghost",
+ name: "Signal Ghost",
+ tagline: "Ephemeral encrypted channel generator",
+ description: "Create a one-shot end-to-end encrypted channel. Share the link; both parties exchange messages; channel self-destructs after timeout or after close.",
+ cost: 25,
+ icon: "👻",
+ category: "comms",
+ features: ["X25519 + AES-GCM in-browser", "Zero-server-storage", "Configurable TTL", "Screenshot-proof mode", "File attachment (≤ 5 MB)"],
+ },
+ {
+ id: "onion-architect",
+ name: "Onion Architect",
+ tagline: "Guided hidden service provisioning wizard",
+ description: "Step-by-step wizard for setting up Tor v3 hidden services: generates torrc stubs, nginx configs, systemd units, and security hardening checklists.",
+ cost: 35,
+ icon: "🧅",
+ category: "network",
+ features: ["torrc generator", "nginx vhost builder", "systemd unit wizard", "UFW hardening script", "Vanity prefix guide"],
+ comingSoon: false,
+ },
+ {
+ id: "identity-auditor",
+ name: "Identity Auditor",
+ tagline: "Full digital identity surface review",
+ description: "Comprehensive review of a handle or identity across known darknet forums, paste sites, and public indices. Produces a redacted report with a risk rating.",
+ cost: 40,
+ icon: "🪪",
+ category: "identity",
+ features: ["Forum cross-reference", "Paste site scan", "Writing-style consistency flag", "Risk score", "Downloadable report"],
+ comingSoon: true,
+ },
+];
+
+export function getToolById(id: string): Tool | undefined {
+ return TOOLS_CATALOG.find((t) => t.id === id);
+}
+
+export const CATEGORY_LABELS: Record = {
+ opsec: "OPSEC",
+ crypto: "Crypto",
+ network: "Network",
+ intel: "Intelligence",
+ comms: "Comms",
+ identity: "Identity",
+};
diff --git a/nginx.example.conf b/nginx.example.conf
index 8509096..8a14e2f 100644
--- a/nginx.example.conf
+++ b/nginx.example.conf
@@ -1,10 +1,10 @@
-# CyberLux — hub + generated entry onions (see nginx/cyberlux-onion-servers.inc).
+# CyberLux — single onion ingress.
# Request handling: lib/onionRoutes.generated.ts + proxy.ts (Next.js 16+)
#
-# Hub: 127.0.0.1:8080 — no X-Cyberlux-Node (full app)
-# Other loopback ports: see scripts/onion-nodes.json → scripts/generate-onion-config.cjs
+# Hub: 127.0.0.1:8080 — full app, all sections as paths
#
-# Requires /etc/nginx/cyberlux-server-common.inc and /etc/nginx/cyberlux-onion-servers.inc
+# Requires /etc/nginx/conf.d/cyberlux-ddos-zones.conf
+# and /etc/nginx/cyberlux-server-common.inc
# (installed by scripts/install-tor-onion.sh).
# --- HUB (main storefront) ---
@@ -17,7 +17,28 @@ server {
client_max_body_size 25m;
+ # ── Next.js static assets — long cache, NO rate limiting ──────────────────
+ # These are content-hashed immutable files. Rate-limiting them causes the
+ # Tor Browser to silently drop CSS/JS on first load (burst exhausted by the
+ # HTML request before assets arrive).
+ location /_next/static/ {
+ proxy_pass http://127.0.0.1:3000;
+ proxy_http_version 1.1;
+ proxy_set_header Host 127.0.0.1;
+ proxy_set_header X-Forwarded-Proto http;
+ add_header Cache-Control "public, max-age=31536000, immutable" always;
+ access_log off;
+ }
+
+ # ── App routes — rate limited ─────────────────────────────────────────────
location / {
+ # Tor forwards every onion client from loopback, so zones are keyed
+ # by $server_port to avoid collapsing all visitors into one bucket.
+ limit_req zone=cyberlux_onion_req burst=120 nodelay;
+ limit_conn cyberlux_onion_conn 60;
+ limit_req_status 429;
+ limit_conn_status 429;
+
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
@@ -30,5 +51,3 @@ server {
proxy_read_timeout 86400;
}
}
-
-include /etc/nginx/cyberlux-onion-servers.inc;
diff --git a/nginx/cyberlux-ddos-zones.conf b/nginx/cyberlux-ddos-zones.conf
new file mode 100644
index 0000000..841e660
--- /dev/null
+++ b/nginx/cyberlux-ddos-zones.conf
@@ -0,0 +1,12 @@
+#
+# CyberLux onion ingress budgets.
+# Installed into /etc/nginx/conf.d/ so these zones exist in nginx `http { }`.
+#
+# Tor hidden services connect to nginx over 127.0.0.1, so per-IP limits are not
+# useful here. `$server_port` keys the CyberLux onion ingress bucket.
+#
+# Keyed by server_port — not remote_addr, because all Tor clients arrive from loopback.
+# rate=60r/s is generous for onion traffic; static assets are excluded from this zone
+# (see nginx.example.conf /_next/static/ location block).
+limit_req_zone $server_port zone=cyberlux_onion_req:10m rate=60r/s;
+limit_conn_zone $server_port zone=cyberlux_onion_conn:10m;
diff --git a/nginx/cyberlux-onion-servers.inc b/nginx/cyberlux-onion-servers.inc
deleted file mode 100644
index 3032cba..0000000
--- a/nginx/cyberlux-onion-servers.inc
+++ /dev/null
@@ -1,2857 +0,0 @@
-# CyberLux — generated onion vhosts (included from nginx.example.conf)
-
-# forum @ 8081
-server {
- listen 127.0.0.1:8081;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "forum";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "forum";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "forum";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "forum";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "forum";
- proxy_read_timeout 86400;
- }
-}
-
-# exchange @ 8082
-server {
- listen 127.0.0.1:8082;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "exchange";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "exchange";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "exchange";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "exchange";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "exchange";
- proxy_read_timeout 86400;
- }
-}
-
-# wiki @ 8083
-server {
- listen 127.0.0.1:8083;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "wiki";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wiki";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wiki";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wiki";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "wiki";
- proxy_read_timeout 86400;
- }
-}
-
-# market @ 8084
-server {
- listen 127.0.0.1:8084;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "market";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "market";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "market";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "market";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "market";
- proxy_read_timeout 86400;
- }
-}
-
-# barter @ 8085
-server {
- listen 127.0.0.1:8085;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "barter";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "barter";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "barter";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "barter";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "barter";
- proxy_read_timeout 86400;
- }
-}
-
-# chatter @ 8086
-server {
- listen 127.0.0.1:8086;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "chatter";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "chatter";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "chatter";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "chatter";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "chatter";
- proxy_read_timeout 86400;
- }
-}
-
-# search @ 8087
-server {
- listen 127.0.0.1:8087;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "search";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "search";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "search";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "search";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "search";
- proxy_read_timeout 86400;
- }
-}
-
-# syndicate @ 8088
-server {
- listen 127.0.0.1:8088;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "syndicate";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "syndicate";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "syndicate";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "syndicate";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "syndicate";
- proxy_read_timeout 86400;
- }
-}
-
-# arb-academy @ 8089
-server {
- listen 127.0.0.1:8089;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "arb-academy";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "arb-academy";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "arb-academy";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "arb-academy";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "arb-academy";
- proxy_read_timeout 86400;
- }
-}
-
-# reviews @ 8090
-server {
- listen 127.0.0.1:8090;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "reviews";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "reviews";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "reviews";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "reviews";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "reviews";
- proxy_read_timeout 86400;
- }
-}
-
-# trust @ 8091
-server {
- listen 127.0.0.1:8091;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "trust";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "trust";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "trust";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "trust";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "trust";
- proxy_read_timeout 86400;
- }
-}
-
-# vault @ 8092
-server {
- listen 127.0.0.1:8092;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "vault";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "vault";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "vault";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "vault";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "vault";
- proxy_read_timeout 86400;
- }
-}
-
-# messages @ 8093
-server {
- listen 127.0.0.1:8093;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "messages";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "messages";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "messages";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "messages";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "messages";
- proxy_read_timeout 86400;
- }
-}
-
-# drop-box @ 8094
-server {
- listen 127.0.0.1:8094;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "drop-box";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "drop-box";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "drop-box";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "drop-box";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "drop-box";
- proxy_read_timeout 86400;
- }
-}
-
-# easter-eggs @ 8095
-server {
- listen 127.0.0.1:8095;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "easter-eggs";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "easter-eggs";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "easter-eggs";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "easter-eggs";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "easter-eggs";
- proxy_read_timeout 86400;
- }
-}
-
-# links @ 8096
-server {
- listen 127.0.0.1:8096;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "links";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "links";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "links";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "links";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "links";
- proxy_read_timeout 86400;
- }
-}
-
-# red-room @ 8097
-server {
- listen 127.0.0.1:8097;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "red-room";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "red-room";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "red-room";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "red-room";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "red-room";
- proxy_read_timeout 86400;
- }
-}
-
-# drops @ 8098
-server {
- listen 127.0.0.1:8098;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "drops";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "drops";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "drops";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "drops";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "drops";
- proxy_read_timeout 86400;
- }
-}
-
-# inner-circle @ 8099
-server {
- listen 127.0.0.1:8099;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "inner-circle";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "inner-circle";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "inner-circle";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "inner-circle";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "inner-circle";
- proxy_read_timeout 86400;
- }
-}
-
-# comparison @ 8100
-server {
- listen 127.0.0.1:8100;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "comparison";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "comparison";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "comparison";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "comparison";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "comparison";
- proxy_read_timeout 86400;
- }
-}
-
-# testimonials @ 8101
-server {
- listen 127.0.0.1:8101;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "testimonials";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "testimonials";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "testimonials";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "testimonials";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "testimonials";
- proxy_read_timeout 86400;
- }
-}
-
-# wallets @ 8102
-server {
- listen 127.0.0.1:8102;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "wallets";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wallets";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wallets";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wallets";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "wallets";
- proxy_read_timeout 86400;
- }
-}
-
-# support @ 8103
-server {
- listen 127.0.0.1:8103;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "support";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "support";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "support";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "support";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "support";
- proxy_read_timeout 86400;
- }
-}
-
-# darknet-atlas @ 8104
-server {
- listen 127.0.0.1:8104;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "darknet-atlas";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "darknet-atlas";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "darknet-atlas";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "darknet-atlas";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "darknet-atlas";
- proxy_read_timeout 86400;
- }
-}
-
-# security-analysis @ 8105
-server {
- listen 127.0.0.1:8105;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "security-analysis";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "security-analysis";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "security-analysis";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "security-analysis";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "security-analysis";
- proxy_read_timeout 86400;
- }
-}
-
-# mixer @ 8106
-server {
- listen 127.0.0.1:8106;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "mixer";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "mixer";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "mixer";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "mixer";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "mixer";
- proxy_read_timeout 86400;
- }
-}
-
-# secret-layer @ 8107
-server {
- listen 127.0.0.1:8107;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "secret-layer";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "secret-layer";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "secret-layer";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "secret-layer";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "secret-layer";
- proxy_read_timeout 86400;
- }
-}
-
-# trees @ 8108
-server {
- listen 127.0.0.1:8108;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "trees";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "trees";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "trees";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "trees";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "trees";
- proxy_read_timeout 86400;
- }
-}
-
-# presswire @ 8109
-server {
- listen 127.0.0.1:8109;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "presswire";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "presswire";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "presswire";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "presswire";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "presswire";
- proxy_read_timeout 86400;
- }
-}
-
-# awards @ 8110
-server {
- listen 127.0.0.1:8110;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "awards";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "awards";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "awards";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "awards";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "awards";
- proxy_read_timeout 86400;
- }
-}
-
-# raffle @ 8111
-server {
- listen 127.0.0.1:8111;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "raffle";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "raffle";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "raffle";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "raffle";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "raffle";
- proxy_read_timeout 86400;
- }
-}
-
-# game @ 8112
-server {
- listen 127.0.0.1:8112;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "game";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "game";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "game";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "game";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "game";
- proxy_read_timeout 86400;
- }
-}
-
-# webring @ 8113
-server {
- listen 127.0.0.1:8113;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "webring";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "webring";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "webring";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "webring";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "webring";
- proxy_read_timeout 86400;
- }
-}
-
-# conspiracies @ 8114
-server {
- listen 127.0.0.1:8114;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "conspiracies";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "conspiracies";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "conspiracies";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "conspiracies";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "conspiracies";
- proxy_read_timeout 86400;
- }
-}
-
-# sanctuary @ 8115
-server {
- listen 127.0.0.1:8115;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "sanctuary";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sanctuary";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sanctuary";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sanctuary";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "sanctuary";
- proxy_read_timeout 86400;
- }
-}
-
-# dashboard @ 8116
-server {
- listen 127.0.0.1:8116;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "dashboard";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "dashboard";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "dashboard";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "dashboard";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "dashboard";
- proxy_read_timeout 86400;
- }
-}
-
-# checkout @ 8117
-server {
- listen 127.0.0.1:8117;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "checkout";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "checkout";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "checkout";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "checkout";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "checkout";
- proxy_read_timeout 86400;
- }
-}
-
-# vendors @ 8118
-server {
- listen 127.0.0.1:8118;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "vendors";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "vendors";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "vendors";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "vendors";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "vendors";
- proxy_read_timeout 86400;
- }
-}
-
-# sign-in @ 8119
-server {
- listen 127.0.0.1:8119;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "sign-in";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sign-in";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sign-in";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sign-in";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "sign-in";
- proxy_read_timeout 86400;
- }
-}
-
-# sign-up @ 8120
-server {
- listen 127.0.0.1:8120;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "sign-up";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sign-up";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sign-up";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "sign-up";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "sign-up";
- proxy_read_timeout 86400;
- }
-}
-
-# account @ 8121
-server {
- listen 127.0.0.1:8121;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "account";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "account";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "account";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "account";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "account";
- proxy_read_timeout 86400;
- }
-}
-
-# shadow nodes (/w/[slug]) @ 8122
-server {
- listen 127.0.0.1:8122;
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "w";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "w";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "w";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "w";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "w";
- proxy_read_timeout 86400;
- }
-}
diff --git a/nginx/cyberlux-server-common.inc b/nginx/cyberlux-server-common.inc
index bc84a2f..6dce947 100644
--- a/nginx/cyberlux-server-common.inc
+++ b/nginx/cyberlux-server-common.inc
@@ -1,12 +1,26 @@
# Included inside each `server { }` for CyberLux onion vhosts.
# Installed to /etc/nginx/cyberlux-server-common.inc by install-tor-onion.sh
+# Requires /etc/nginx/conf.d/cyberlux-ddos-zones.conf in nginx `http { }`.
server_tokens off;
-client_body_timeout 15s;
-client_header_timeout 15s;
-send_timeout 60s;
+
+client_body_timeout 12s;
+client_header_timeout 12s;
+keepalive_timeout 65s;
+send_timeout 30s;
+reset_timedout_connection on;
+
+error_page 429 = @cyberlux_rate_limited;
+
+location @cyberlux_rate_limited {
+ default_type text/plain;
+ add_header Retry-After "10" always;
+ add_header X-Cyberlux-Shield "rate-limited" always;
+ return 429 "CyberLux onion shield: request rate limited. Retry shortly.\n";
+}
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
+add_header X-Cyberlux-Shield "onion-edge" always;
diff --git a/package.json b/package.json
index 8cbfff7..44c7b0a 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,9 @@
"onions:status": "node scripts/onion-status.cjs",
"onions:list": "bash scripts/list-onion-urls.sh",
"install:systemd": "bash -c 'echo Run: sudo CYBERLUX_USER=$USER bash scripts/install-systemd.sh'",
- "onions:export": "bash scripts/export-onion-urls.sh"
+ "onions:export": "bash scripts/export-onion-urls.sh",
+ "vanity:build": "bash scripts/mkp224o-build.sh",
+ "vanity:mine": "bash scripts/vanity-onion-mine.sh"
},
"dependencies": {
"next": "16.1.7",
diff --git a/scripts/generate-onion-config.cjs b/scripts/generate-onion-config.cjs
index 251a4d0..d239a09 100755
--- a/scripts/generate-onion-config.cjs
+++ b/scripts/generate-onion-config.cjs
@@ -3,7 +3,6 @@
* Reads scripts/onion-nodes.json and writes:
* lib/onionRoutes.generated.ts
* tor/cyberlux-nodes.conf
- * nginx/cyberlux-onion-servers.inc
* scripts/generated/tor-dirs.txt
* scripts/generated/onion-labels.tsv
* scripts/generated/onion-port-range.txt
@@ -17,231 +16,63 @@ const REPO = path.join(__dirname, "..");
const jsonPath = path.join(__dirname, "onion-nodes.json");
const data = JSON.parse(fs.readFileSync(jsonPath, "utf8"));
const nodes = data.nodes;
-
-function dedicatedNginx(port, entry) {
- const h = JSON.stringify(entry);
- return `
-# ${entry} @ ${port}
-server {
- listen 127.0.0.1:${port};
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node ${h};
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node ${h};
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node ${h};
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node ${h};
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node ${h};
- proxy_read_timeout 86400;
- }
-}
-`;
-}
-
-function wikiNginx(port) {
- return `
-# wiki @ ${port}
-server {
- listen 127.0.0.1:${port};
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "wiki";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wiki";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wiki";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "wiki";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "wiki";
- proxy_read_timeout 86400;
- }
-}
-`;
-}
-
-function wNginx(port) {
- return `
-# shadow nodes (/w/[slug]) @ ${port}
-server {
- listen 127.0.0.1:${port};
- server_name _;
-
- include /etc/nginx/cyberlux-server-common.inc;
- proxy_hide_header X-Powered-By;
-
- client_max_body_size 25m;
-
- location /checkout {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "w";
- }
- location /api/ {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "w";
- }
- location /forum {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "w";
- }
- location /exchange {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header X-Cyberlux-Node "w";
- }
-
- location / {
- proxy_pass http://127.0.0.1:3000;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto http;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Cyberlux-Node "w";
- proxy_read_timeout 86400;
- }
-}
-`;
-}
+const TOR_INTRO_DOS_RATE_PER_SEC = 12;
+const TOR_INTRO_DOS_BURST_PER_SEC = 80;
+const KNOWN_APP_ENTRIES = [
+ "hub",
+ "wiki",
+ "w",
+ "account",
+ "arb-academy",
+ "awards",
+ "barter",
+ "chatter",
+ "checkout",
+ "comparison",
+ "conspiracies",
+ "darknet-atlas",
+ "dashboard",
+ "directory",
+ "drop-box",
+ "drops",
+ "easter-eggs",
+ "exchange",
+ "forum",
+ "game",
+ "hidden-wiki",
+ "inner-circle",
+ "links",
+ "market",
+ "messages",
+ "mixer",
+ "presswire",
+ "raffle",
+ "red-room",
+ "reviews",
+ "sanctuary",
+ "search",
+ "secret-layer",
+ "security-analysis",
+ "sign-in",
+ "sign-up",
+ "support",
+ "syndicate",
+ "testimonials",
+ "trees",
+ "trust",
+ "vault",
+ "vendors",
+ "wallets",
+ "webring",
+];
function torBlock(dir, port) {
return `
HiddenServiceDir /var/lib/tor/${dir}
HiddenServicePort 80 127.0.0.1:${port}
HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200`;
+HiddenServiceEnableIntroDoSRatePerSec ${TOR_INTRO_DOS_RATE_PER_SEC}
+HiddenServiceEnableIntroDoSBurstPerSec ${TOR_INTRO_DOS_BURST_PER_SEC}`;
}
const ports = nodes.map((n) => n.port);
@@ -253,7 +84,11 @@ for (const n of nodes) {
if (n.kind === "dedicated") dedicated[n.entry] = n.path;
}
-const uniqueEntries = ["hub", "wiki", "w", ...Object.keys(dedicated).sort()];
+const uniqueEntries = Array.from(new Set([...KNOWN_APP_ENTRIES, ...Object.keys(dedicated)])).sort((a, b) => {
+ if (a === "hub") return -1;
+ if (b === "hub") return 1;
+ return a.localeCompare(b);
+});
const drLines = Object.keys(dedicated)
.sort()
@@ -273,17 +108,11 @@ ${drLines}
} as const;
`;
-// fix typo "generon" -> "generate"
-let nginxInc = "# CyberLux — generated onion vhosts (included from nginx.example.conf)\n";
let torConf =
"# CyberLux — generated v3 onion services (include from torrc)\n#\n# Tor ≥ 0.4.7: DoS lines follow each HiddenServiceDir/Port pair.\n";
for (const n of nodes) {
torConf += torBlock(n.torDir, n.port);
- if (n.kind === "hub") continue;
- if (n.kind === "dedicated") nginxInc += dedicatedNginx(n.port, n.entry);
- else if (n.kind === "wiki") nginxInc += wikiNginx(n.port);
- else if (n.kind === "w") nginxInc += wNginx(n.port);
}
const genDir = path.join(REPO, "scripts", "generated");
@@ -306,8 +135,9 @@ fs.writeFileSync(path.join(genDir, "onion-port-range.txt"), `${minP} ${maxP}\n`)
fs.writeFileSync(path.join(REPO, "lib", "onionRoutes.generated.ts"), ts);
fs.writeFileSync(path.join(REPO, "tor", "cyberlux-nodes.conf"), torConf.trim() + "\n");
-fs.writeFileSync(path.join(REPO, "nginx", "cyberlux-onion-servers.inc"), nginxInc.trim() + "\n");
+const onionLabel = nodes.length === 1 ? "onion" : "onions";
+const loopbackLabel = minP === maxP ? `${minP}` : `${minP}–${maxP}`;
console.log(
- `[generate-onion-config] ${nodes.length} onions, nginx loopback ${minP}–${maxP}, TS entries: ${uniqueEntries.length}`,
+ `[generate-onion-config] ${nodes.length} ${onionLabel}, nginx loopback ${loopbackLabel}, TS entries: ${uniqueEntries.length}`,
);
diff --git a/scripts/generated/onion-labels.tsv b/scripts/generated/onion-labels.tsv
index f9c21a0..bb3b2f0 100644
--- a/scripts/generated/onion-labels.tsv
+++ b/scripts/generated/onion-labels.tsv
@@ -1,43 +1 @@
cyberlux Hub — full storefront
-cyberlux_forum forum — / → /forum
-cyberlux_exchange exchange — / → /exchange
-cyberlux_wiki Wiki — / → /hidden-wiki
-cyberlux_market market — / → /market
-cyberlux_barter barter — / → /barter
-cyberlux_chatter chatter — / → /chatter
-cyberlux_search search — / → /search
-cyberlux_syndicate syndicate — / → /syndicate
-cyberlux_arb_academy arb-academy — / → /arb-academy
-cyberlux_reviews reviews — / → /reviews
-cyberlux_trust trust — / → /trust
-cyberlux_vault vault — / → /vault
-cyberlux_messages messages — / → /messages
-cyberlux_drop_box drop-box — / → /drop-box
-cyberlux_easter_eggs easter-eggs — / → /easter-eggs
-cyberlux_links links — / → /links
-cyberlux_red_room red-room — / → /red-room
-cyberlux_drops drops — / → /drops
-cyberlux_inner_circle inner-circle — / → /inner-circle
-cyberlux_comparison comparison — / → /comparison
-cyberlux_testimonials testimonials — / → /testimonials
-cyberlux_wallets wallets — / → /wallets
-cyberlux_support support — / → /support
-cyberlux_darknet_atlas darknet-atlas — / → /darknet-atlas
-cyberlux_security_analysis security-analysis — / → /security-analysis
-cyberlux_mixer mixer — / → /mixer
-cyberlux_secret_layer secret-layer — / → /secret-layer
-cyberlux_trees trees — / → /trees
-cyberlux_presswire presswire — / → /presswire
-cyberlux_awards awards — / → /awards
-cyberlux_raffle raffle — / → /raffle
-cyberlux_game game — / → /game
-cyberlux_webring webring — / → /webring
-cyberlux_conspiracies conspiracies — / → /conspiracies
-cyberlux_sanctuary sanctuary — / → /sanctuary
-cyberlux_dashboard dashboard — / → /dashboard
-cyberlux_checkout checkout — / → /checkout
-cyberlux_vendors vendors — / → /vendors
-cyberlux_sign_in sign-in — / → /sign-in
-cyberlux_sign_up sign-up — / → /sign-up
-cyberlux_account account — / → /account
-cyberlux_w Shadow nodes — / → /syndicate, /x → /w/x
diff --git a/scripts/generated/onion-port-range.txt b/scripts/generated/onion-port-range.txt
index 20f55e4..a5ab3c2 100644
--- a/scripts/generated/onion-port-range.txt
+++ b/scripts/generated/onion-port-range.txt
@@ -1 +1 @@
-8080 8122
+8080 8080
diff --git a/scripts/generated/tor-dirs.txt b/scripts/generated/tor-dirs.txt
index bf1695f..13a25a7 100644
--- a/scripts/generated/tor-dirs.txt
+++ b/scripts/generated/tor-dirs.txt
@@ -1,43 +1 @@
cyberlux
-cyberlux_forum
-cyberlux_exchange
-cyberlux_wiki
-cyberlux_market
-cyberlux_barter
-cyberlux_chatter
-cyberlux_search
-cyberlux_syndicate
-cyberlux_arb_academy
-cyberlux_reviews
-cyberlux_trust
-cyberlux_vault
-cyberlux_messages
-cyberlux_drop_box
-cyberlux_easter_eggs
-cyberlux_links
-cyberlux_red_room
-cyberlux_drops
-cyberlux_inner_circle
-cyberlux_comparison
-cyberlux_testimonials
-cyberlux_wallets
-cyberlux_support
-cyberlux_darknet_atlas
-cyberlux_security_analysis
-cyberlux_mixer
-cyberlux_secret_layer
-cyberlux_trees
-cyberlux_presswire
-cyberlux_awards
-cyberlux_raffle
-cyberlux_game
-cyberlux_webring
-cyberlux_conspiracies
-cyberlux_sanctuary
-cyberlux_dashboard
-cyberlux_checkout
-cyberlux_vendors
-cyberlux_sign_in
-cyberlux_sign_up
-cyberlux_account
-cyberlux_w
diff --git a/scripts/install-tor-onion.sh b/scripts/install-tor-onion.sh
index 8728482..1bd50f8 100755
--- a/scripts/install-tor-onion.sh
+++ b/scripts/install-tor-onion.sh
@@ -43,7 +43,7 @@ start_tor() {
node "${REPO}/scripts/generate-onion-config.cjs"
-mkdir -p /etc/tor /etc/nginx/sites-available /etc/nginx/sites-enabled
+mkdir -p /etc/tor /etc/nginx/conf.d /etc/nginx/sites-available /etc/nginx/sites-enabled
touch "${TORRC}"
tor_changed=0
@@ -63,10 +63,10 @@ if ! grep -qF "${TOR_INCLUDE}" "${TORRC}"; then
tor_changed=1
fi
-if install_if_changed "${REPO}/nginx/cyberlux-server-common.inc" /etc/nginx/cyberlux-server-common.inc 0644; then
+if install_if_changed "${REPO}/nginx/cyberlux-ddos-zones.conf" /etc/nginx/conf.d/cyberlux-ddos-zones.conf 0644; then
nginx_changed=1
fi
-if install_if_changed "${REPO}/nginx/cyberlux-onion-servers.inc" /etc/nginx/cyberlux-onion-servers.inc 0644; then
+if install_if_changed "${REPO}/nginx/cyberlux-server-common.inc" /etc/nginx/cyberlux-server-common.inc 0644; then
nginx_changed=1
fi
if install_if_changed "${REPO}/nginx.example.conf" /etc/nginx/sites-available/cyberlux-onion 0644; then
diff --git a/scripts/install-vanity-onion-key.sh b/scripts/install-vanity-onion-key.sh
new file mode 100755
index 0000000..b5ee8a9
--- /dev/null
+++ b/scripts/install-vanity-onion-key.sh
@@ -0,0 +1,140 @@
+#!/usr/bin/env bash
+# Install a mkp224o-generated v3 key directory into the CyberLux HiddenServiceDir and restart Tor.
+# Run with sudo after vanity-onion-mine.sh has produced a folder named *.onion under the output path.
+#
+# sudo bash scripts/install-vanity-onion-key.sh /path/to/var/vanity-mine
+# sudo bash scripts/install-vanity-onion-key.sh /path/to/specificXXXX.onion
+#
+# If the path is a parent with several *.onion children, one is chosen automatically
+# (default: first in lexicographic order). Override with:
+# CYBERLUX_VANITY_PICK=latest — use the directory with the newest mtime
+# CYBERLUX_VANITY_PICK=first — same as default (first sorted A–Z)
+# Or pass a direct path to a single ... .onion folder.
+#
+set -euo pipefail
+[[ "${EUID}" -eq 0 ]] || { echo "Run as root (sudo)."; exit 1; }
+
+REPO="$(cd "$(dirname "$0")/.." && pwd)"
+TOR_DIRS_FILE="${REPO}/scripts/generated/tor-dirs.txt"
+ARG="${1:-}"
+
+if [[ -z "${ARG}" ]]; then
+ echo "Usage: sudo bash $0 "
+ exit 1
+fi
+
+# If ARG is relative, prefer REPO/ARG (so `var/vanity-mine` works from any cwd when using this repo).
+if [[ "${ARG}" != /* && -d "${REPO}/${ARG}" ]]; then
+ ARG="${REPO}/${ARG}"
+fi
+
+if [[ ! -f "${TOR_DIRS_FILE}" ]]; then
+ echo "Missing ${TOR_DIRS_FILE}. Run: cd ${REPO} && node scripts/generate-onion-config.cjs"
+ exit 1
+fi
+
+# Resolve single torDir (CyberLux uses "cyberlux" in onion-nodes.json)
+TOR_DIR_NAME="$(head -1 "${TOR_DIRS_FILE}" | tr -d '\r\n')"
+if [[ -z "${TOR_DIR_NAME}" ]]; then
+ echo "Empty ${TOR_DIRS_FILE}"
+ exit 1
+fi
+
+HS_ROOT="/var/lib/tor/${TOR_DIR_NAME}"
+KEY_SRC=""
+
+if [[ -d "${ARG}" ]]; then
+ if [[ -f "${ARG}/hs_ed25519_secret_key" ]]; then
+ KEY_SRC="${ARG}"
+ else
+ # Pick a *.onion child (one or many)
+ mapfile -t kids < <(find "${ARG}" -maxdepth 1 -type d -name '*.onion' 2>/dev/null | sort)
+ if [[ "${#kids[@]}" -eq 1 ]]; then
+ KEY_SRC="${kids[0]}"
+ elif [[ "${#kids[@]}" -eq 0 ]]; then
+ echo "No subdirectory matching *.onion under ${ARG} and no key at top level."
+ exit 1
+ else
+ pick="${CYBERLUX_VANITY_PICK:-first}"
+ case "${pick}" in
+ first)
+ KEY_SRC="${kids[0]}"
+ echo "[*] ${#kids[@]} *.onion key dirs; using first (lexicographic): ${KEY_SRC}"
+ ;;
+ latest|newest)
+ latest=""
+ latest_m=0
+ for d in "${kids[@]}"; do
+ m="$(stat -c %Y "${d}" 2>/dev/null || echo 0)"
+ if (( m >= latest_m )); then
+ latest_m="${m}"
+ latest="${d}"
+ fi
+ done
+ KEY_SRC="${latest}"
+ echo "[*] ${#kids[@]} *.onion key dirs; using latest mtime: ${KEY_SRC}"
+ ;;
+ *)
+ echo "Unknown CYBERLUX_VANITY_PICK=${pick} (use first or latest)."
+ exit 1
+ ;;
+ esac
+ fi
+ fi
+else
+ echo "Not a directory: ${ARG}"
+ exit 1
+fi
+
+if [[ ! -f "${KEY_SRC}/hs_ed25519_secret_key" ]]; then
+ echo "No hs_ed25519_secret_key in ${KEY_SRC}"
+ exit 1
+fi
+
+TOR_USER=""
+for u in debian-tor tor _tor; do
+ if id -u "${u}" &>/dev/null; then
+ TOR_USER="${u}"
+ break
+ fi
+done
+if [[ -z "${TOR_USER}" ]]; then
+ echo "No Tor system user (tried debian-tor, tor, _tor). Install Tor."
+ exit 1
+fi
+
+TS="$(date +%s)"
+if [[ -d "${HS_ROOT}" ]]; then
+ echo "[*] Preserving current service dir as ${HS_ROOT}.stale.${TS}"
+ mv "${HS_ROOT}" "${HS_ROOT}.stale.${TS}"
+fi
+
+mkdir -p "${HS_ROOT}"
+shopt -s dotglob nullglob
+for item in "${KEY_SRC}"/*; do
+ base="$(basename "${item}")"
+ [[ "${base}" == "." || "${base}" == ".." ]] && continue
+ cp -a "${item}" "${HS_ROOT}/"
+done
+shopt -u dotglob nullglob
+
+chown -R "${TOR_USER}:${TOR_USER}" "${HS_ROOT}"
+chmod -R u+rwX,og-rwx "${HS_ROOT}"
+chmod 0700 "${HS_ROOT}"
+
+restart_tor() {
+ systemctl restart tor@default.service 2>/dev/null || systemctl restart tor
+}
+
+echo "[*] Installed key material into ${HS_ROOT} (onion: $(tr -d '\n' < "${HS_ROOT}/hostname" 2>/dev/null || echo '?'))"
+restart_tor
+
+if [[ -f "${REPO}/scripts/export-onion-urls.sh" ]]; then
+ bash "${REPO}/scripts/export-onion-urls.sh" || true
+fi
+if [[ -f "${REPO}/scripts/backup-onion-keys.sh" ]]; then
+ bash "${REPO}/scripts/backup-onion-keys.sh" || true
+fi
+
+echo "[*] Done. Open: http://$(tr -d '\n' < "${HS_ROOT}/hostname") (in Tor Browser)"
+echo "[*] Old keys (if any): ${HS_ROOT}.stale.${TS}"
diff --git a/scripts/mkp224o-build.sh b/scripts/mkp224o-build.sh
new file mode 100755
index 0000000..9dc5e6b
--- /dev/null
+++ b/scripts/mkp224o-build.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+# Build cathugger/mkp224o (Tor v3 vanity .onion key generator) into vendor/mkp224o/mkp224o.
+# Requires: git, make, gcc or clang, autoconf, pkg-config, libsodium-dev (Debian: libsodium-dev)
+#
+# bash scripts/mkp224o-build.sh
+#
+set -euo pipefail
+
+REPO="$(cd "$(dirname "$0")/.." && pwd)"
+VEND="${REPO}/vendor/mkp224o"
+BIN="${VEND}/mkp224o"
+
+if [[ -x "${BIN}" ]]; then
+ echo "Already built: ${BIN}"
+ exit 0
+fi
+
+if ! command -v git >/dev/null 2>&1; then
+ echo "Install git and retry."
+ exit 1
+fi
+
+mkdir -p "${REPO}/vendor"
+if [[ ! -d "${VEND}/.git" ]]; then
+ echo "[*] Cloning mkp224o..."
+ git clone --depth 1 https://github.com/cathugger/mkp224o.git "${VEND}"
+fi
+
+cd "${VEND}"
+if [[ ! -f "./configure" ]]; then
+ if [[ -f "./autogen.sh" ]]; then
+ echo "[*] autogen.sh..."
+ ./autogen.sh
+ else
+ echo "No configure/autogen in ${VEND}"
+ exit 1
+ fi
+fi
+
+if [[ ! -f "./Makefile" ]]; then
+ echo "[*] configure..."
+ # Prefer AMD64 fast curve implementation when available
+ if ./configure --help 2>/dev/null | grep -q 'enable-amd64-64-24k'; then
+ ./configure --enable-amd64-64-24k
+ else
+ ./configure
+ fi
+fi
+
+echo "[*] make -j \$(nproc)..."
+make -j"$(nproc)"
+
+if [[ ! -x "${BIN}" ]]; then
+ echo "Build failed: ${BIN} not executable"
+ exit 1
+fi
+
+echo "Built: ${BIN}"
+echo "Mine a prefix: bash ${REPO}/scripts/vanity-onion-mine.sh "
diff --git a/scripts/onion-nodes.json b/scripts/onion-nodes.json
index 7389525..bb3705d 100644
--- a/scripts/onion-nodes.json
+++ b/scripts/onion-nodes.json
@@ -1,47 +1,5 @@
{
"nodes": [
- { "torDir": "cyberlux", "port": 8080, "kind": "hub" },
- { "torDir": "cyberlux_forum", "port": 8081, "kind": "dedicated", "entry": "forum", "path": "/forum" },
- { "torDir": "cyberlux_exchange", "port": 8082, "kind": "dedicated", "entry": "exchange", "path": "/exchange" },
- { "torDir": "cyberlux_wiki", "port": 8083, "kind": "wiki" },
- { "torDir": "cyberlux_market", "port": 8084, "kind": "dedicated", "entry": "market", "path": "/market" },
- { "torDir": "cyberlux_barter", "port": 8085, "kind": "dedicated", "entry": "barter", "path": "/barter" },
- { "torDir": "cyberlux_chatter", "port": 8086, "kind": "dedicated", "entry": "chatter", "path": "/chatter" },
- { "torDir": "cyberlux_search", "port": 8087, "kind": "dedicated", "entry": "search", "path": "/search" },
- { "torDir": "cyberlux_syndicate", "port": 8088, "kind": "dedicated", "entry": "syndicate", "path": "/syndicate" },
- { "torDir": "cyberlux_arb_academy", "port": 8089, "kind": "dedicated", "entry": "arb-academy", "path": "/arb-academy" },
- { "torDir": "cyberlux_reviews", "port": 8090, "kind": "dedicated", "entry": "reviews", "path": "/reviews" },
- { "torDir": "cyberlux_trust", "port": 8091, "kind": "dedicated", "entry": "trust", "path": "/trust" },
- { "torDir": "cyberlux_vault", "port": 8092, "kind": "dedicated", "entry": "vault", "path": "/vault" },
- { "torDir": "cyberlux_messages", "port": 8093, "kind": "dedicated", "entry": "messages", "path": "/messages" },
- { "torDir": "cyberlux_drop_box", "port": 8094, "kind": "dedicated", "entry": "drop-box", "path": "/drop-box" },
- { "torDir": "cyberlux_easter_eggs", "port": 8095, "kind": "dedicated", "entry": "easter-eggs", "path": "/easter-eggs" },
- { "torDir": "cyberlux_links", "port": 8096, "kind": "dedicated", "entry": "links", "path": "/links" },
- { "torDir": "cyberlux_red_room", "port": 8097, "kind": "dedicated", "entry": "red-room", "path": "/red-room" },
- { "torDir": "cyberlux_drops", "port": 8098, "kind": "dedicated", "entry": "drops", "path": "/drops" },
- { "torDir": "cyberlux_inner_circle", "port": 8099, "kind": "dedicated", "entry": "inner-circle", "path": "/inner-circle" },
- { "torDir": "cyberlux_comparison", "port": 8100, "kind": "dedicated", "entry": "comparison", "path": "/comparison" },
- { "torDir": "cyberlux_testimonials", "port": 8101, "kind": "dedicated", "entry": "testimonials", "path": "/testimonials" },
- { "torDir": "cyberlux_wallets", "port": 8102, "kind": "dedicated", "entry": "wallets", "path": "/wallets" },
- { "torDir": "cyberlux_support", "port": 8103, "kind": "dedicated", "entry": "support", "path": "/support" },
- { "torDir": "cyberlux_darknet_atlas", "port": 8104, "kind": "dedicated", "entry": "darknet-atlas", "path": "/darknet-atlas" },
- { "torDir": "cyberlux_security_analysis", "port": 8105, "kind": "dedicated", "entry": "security-analysis", "path": "/security-analysis" },
- { "torDir": "cyberlux_mixer", "port": 8106, "kind": "dedicated", "entry": "mixer", "path": "/mixer" },
- { "torDir": "cyberlux_secret_layer", "port": 8107, "kind": "dedicated", "entry": "secret-layer", "path": "/secret-layer" },
- { "torDir": "cyberlux_trees", "port": 8108, "kind": "dedicated", "entry": "trees", "path": "/trees" },
- { "torDir": "cyberlux_presswire", "port": 8109, "kind": "dedicated", "entry": "presswire", "path": "/presswire" },
- { "torDir": "cyberlux_awards", "port": 8110, "kind": "dedicated", "entry": "awards", "path": "/awards" },
- { "torDir": "cyberlux_raffle", "port": 8111, "kind": "dedicated", "entry": "raffle", "path": "/raffle" },
- { "torDir": "cyberlux_game", "port": 8112, "kind": "dedicated", "entry": "game", "path": "/game" },
- { "torDir": "cyberlux_webring", "port": 8113, "kind": "dedicated", "entry": "webring", "path": "/webring" },
- { "torDir": "cyberlux_conspiracies", "port": 8114, "kind": "dedicated", "entry": "conspiracies", "path": "/conspiracies" },
- { "torDir": "cyberlux_sanctuary", "port": 8115, "kind": "dedicated", "entry": "sanctuary", "path": "/sanctuary" },
- { "torDir": "cyberlux_dashboard", "port": 8116, "kind": "dedicated", "entry": "dashboard", "path": "/dashboard" },
- { "torDir": "cyberlux_checkout", "port": 8117, "kind": "dedicated", "entry": "checkout", "path": "/checkout" },
- { "torDir": "cyberlux_vendors", "port": 8118, "kind": "dedicated", "entry": "vendors", "path": "/vendors" },
- { "torDir": "cyberlux_sign_in", "port": 8119, "kind": "dedicated", "entry": "sign-in", "path": "/sign-in" },
- { "torDir": "cyberlux_sign_up", "port": 8120, "kind": "dedicated", "entry": "sign-up", "path": "/sign-up" },
- { "torDir": "cyberlux_account", "port": 8121, "kind": "dedicated", "entry": "account", "path": "/account" },
- { "torDir": "cyberlux_w", "port": 8122, "kind": "w" }
+ { "torDir": "cyberlux", "port": 8080, "kind": "hub" }
]
}
diff --git a/scripts/onion-status.cjs b/scripts/onion-status.cjs
index 43b5e49..0321e6c 100644
--- a/scripts/onion-status.cjs
+++ b/scripts/onion-status.cjs
@@ -124,7 +124,7 @@ async function main() {
console.log(`✗ ${bad} loopback vhost(s) did not return OK HTTP — ensure: systemctl status nginx tor; systemctl status cyberlux`);
process.exit(1);
}
- console.log("✓ All loopback nginx vhosts responded (Tor .onion forwarding uses these ports).");
+ console.log("✓ All configured loopback nginx vhosts responded (Tor .onion forwarding uses these ports).");
console.log(" To test via the Tor network use Tor Browser (not curl from clearnet).");
process.exit(0);
}
diff --git a/scripts/vanity-onion-mine.sh b/scripts/vanity-onion-mine.sh
new file mode 100755
index 0000000..444bf98
--- /dev/null
+++ b/scripts/vanity-onion-mine.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# Brute-force a Tor v3 .onion whose address starts with PREFIX (base32: a–z, 2–7).
+# Longer prefixes take exponentially more CPU time. Run on a strong machine; be patient.
+#
+# bash scripts/mkp224o-build.sh
+# bash scripts/vanity-onion-mine.sh cyberl
+# sudo bash scripts/install-vanity-onion-key.sh var/vanity-mine
+#
+# Env:
+# CYBERLUX_MKP224O — path to mkp224o binary (default: vendor/mkp224o/mkp224o)
+# CYBERLUX_VANITY_OUT — output directory (default: repo var/vanity-mine)
+# CYBERLUX_MKP224O_DOCKER=1 — use Docker image instead of local binary
+#
+set -euo pipefail
+
+REPO="$(cd "$(dirname "$0")/.." && pwd)"
+PREFIX="${1:-}"
+
+if [[ -z "${PREFIX}" ]]; then
+ echo "Usage: $0 "
+ echo "Example: $0 cyberl (8 chars: expect long run; 4–6 is more practical on one PC)"
+ echo "Onion v3 hostnames use base32: letters a–z and digits 2–7 only (no 0,1,8,9)."
+ exit 1
+fi
+
+if ! [[ "${PREFIX}" =~ ^[a-z2-7]+$ ]]; then
+ echo "Invalid prefix: use only a–z and 2–7 (Tor onion base32)."
+ exit 1
+fi
+
+OUT_DIR="${CYBERLUX_VANITY_OUT:-${REPO}/var/vanity-mine}"
+mkdir -p "${OUT_DIR}"
+
+if [[ "${CYBERLUX_MKP224O_DOCKER:-0}" == "1" ]]; then
+ echo "[*] Mining with Docker (ghcr.io/cathugger/mkp224o:master) → ${OUT_DIR}"
+ # -s = print stats every 10s; last arg is the base32 filter
+ exec docker run --rm -it -v "${OUT_DIR}:/keys" ghcr.io/cathugger/mkp224o:master -d /keys -s "${PREFIX}"
+fi
+
+MKP="${CYBERLUX_MKP224O:-${REPO}/vendor/mkp224o/mkp224o}"
+if [[ ! -x "${MKP}" ]]; then
+ echo "Missing ${MKP}. Build first:"
+ echo " bash ${REPO}/scripts/mkp224o-build.sh"
+ echo "Or set CYBERLUX_MKP224O_DOCKER=1 and re-run this script."
+ exit 1
+fi
+
+echo "[*] Mining (Ctrl+C to stop). Output: ${OUT_DIR}/"
+echo "[*] Statistics (-s) enabled. First match appears as a new directory ending in .onion"
+"${MKP}" -d "${OUT_DIR}" -s "${PREFIX}"
diff --git a/scripts/verify.cjs b/scripts/verify.cjs
index 471fc52..c208f13 100755
--- a/scripts/verify.cjs
+++ b/scripts/verify.cjs
@@ -20,7 +20,7 @@ try {
run("TypeScript (tsc --noEmit)", "npx tsc --noEmit");
run(
"bash syntax (start.sh, install, backup, restore, systemd, health)",
- "bash -n start.sh && bash -n scripts/install-tor-onion.sh && bash -n scripts/install-systemd.sh && bash -n scripts/health-check-stack.sh && bash -n scripts/list-onion-urls.sh && bash -n scripts/export-onion-urls.sh && bash -n scripts/diagnose-onion-stack.sh && bash -n scripts/backup-onion-keys.sh && bash -n scripts/restore-onion-keys.sh",
+ "bash -n start.sh && bash -n scripts/install-tor-onion.sh && bash -n scripts/install-systemd.sh && bash -n scripts/health-check-stack.sh && bash -n scripts/list-onion-urls.sh && bash -n scripts/export-onion-urls.sh && bash -n scripts/diagnose-onion-stack.sh && bash -n scripts/backup-onion-keys.sh && bash -n scripts/restore-onion-keys.sh && bash -n scripts/mkp224o-build.sh && bash -n scripts/vanity-onion-mine.sh && bash -n scripts/install-vanity-onion-key.sh",
);
run("node syntax (onion-status.cjs)", "node --check scripts/onion-status.cjs");
run("Next.js production build", "npm run build");
diff --git a/start.sh b/start.sh
index 8ca32d5..87a2c6c 100755
--- a/start.sh
+++ b/start.sh
@@ -48,7 +48,7 @@ fi
read -r ONION_PORT_MIN ONION_PORT_MAX < "${RANGE_FILE}" || true
ONION_PORT_MIN="${ONION_PORT_MIN:-8080}"
-ONION_PORT_MAX="${ONION_PORT_MAX:-8122}"
+ONION_PORT_MAX="${ONION_PORT_MAX:-8080}"
mapfile -t CYBERLUX_TOR_DIRS < "${TOR_DIRS_FILE}"
@@ -81,14 +81,14 @@ wait_for_all_hostnames() {
done
ready="$(count_ready_hostnames)"
- echo "[!] Timeout waiting for all onion hostnames (${ready}/${total} ready)." >&2
+ echo "[!] Timeout waiting for onion hostname files (${ready}/${total} ready)." >&2
return 1
}
print_onion_banner() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- echo " CYBERLUX — copy these .onion URLs (Tor Browser, http:// only)"
+ echo " CYBERLUX — copy this .onion URL (Tor Browser, http:// only)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
local any=0
local ready=0
diff --git a/tor/cyberlux-nodes.conf b/tor/cyberlux-nodes.conf
index 020bc01..572e325 100644
--- a/tor/cyberlux-nodes.conf
+++ b/tor/cyberlux-nodes.conf
@@ -5,215 +5,5 @@
HiddenServiceDir /var/lib/tor/cyberlux
HiddenServicePort 80 127.0.0.1:8080
HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_forum
-HiddenServicePort 80 127.0.0.1:8081
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_exchange
-HiddenServicePort 80 127.0.0.1:8082
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_wiki
-HiddenServicePort 80 127.0.0.1:8083
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_market
-HiddenServicePort 80 127.0.0.1:8084
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_barter
-HiddenServicePort 80 127.0.0.1:8085
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_chatter
-HiddenServicePort 80 127.0.0.1:8086
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_search
-HiddenServicePort 80 127.0.0.1:8087
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_syndicate
-HiddenServicePort 80 127.0.0.1:8088
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_arb_academy
-HiddenServicePort 80 127.0.0.1:8089
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_reviews
-HiddenServicePort 80 127.0.0.1:8090
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_trust
-HiddenServicePort 80 127.0.0.1:8091
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_vault
-HiddenServicePort 80 127.0.0.1:8092
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_messages
-HiddenServicePort 80 127.0.0.1:8093
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_drop_box
-HiddenServicePort 80 127.0.0.1:8094
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_easter_eggs
-HiddenServicePort 80 127.0.0.1:8095
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_links
-HiddenServicePort 80 127.0.0.1:8096
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_red_room
-HiddenServicePort 80 127.0.0.1:8097
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_drops
-HiddenServicePort 80 127.0.0.1:8098
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_inner_circle
-HiddenServicePort 80 127.0.0.1:8099
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_comparison
-HiddenServicePort 80 127.0.0.1:8100
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_testimonials
-HiddenServicePort 80 127.0.0.1:8101
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_wallets
-HiddenServicePort 80 127.0.0.1:8102
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_support
-HiddenServicePort 80 127.0.0.1:8103
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_darknet_atlas
-HiddenServicePort 80 127.0.0.1:8104
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_security_analysis
-HiddenServicePort 80 127.0.0.1:8105
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_mixer
-HiddenServicePort 80 127.0.0.1:8106
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_secret_layer
-HiddenServicePort 80 127.0.0.1:8107
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_trees
-HiddenServicePort 80 127.0.0.1:8108
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_presswire
-HiddenServicePort 80 127.0.0.1:8109
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_awards
-HiddenServicePort 80 127.0.0.1:8110
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_raffle
-HiddenServicePort 80 127.0.0.1:8111
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_game
-HiddenServicePort 80 127.0.0.1:8112
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_webring
-HiddenServicePort 80 127.0.0.1:8113
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_conspiracies
-HiddenServicePort 80 127.0.0.1:8114
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_sanctuary
-HiddenServicePort 80 127.0.0.1:8115
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_dashboard
-HiddenServicePort 80 127.0.0.1:8116
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_checkout
-HiddenServicePort 80 127.0.0.1:8117
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_vendors
-HiddenServicePort 80 127.0.0.1:8118
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_sign_in
-HiddenServicePort 80 127.0.0.1:8119
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_sign_up
-HiddenServicePort 80 127.0.0.1:8120
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_account
-HiddenServicePort 80 127.0.0.1:8121
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
-HiddenServiceDir /var/lib/tor/cyberlux_w
-HiddenServicePort 80 127.0.0.1:8122
-HiddenServiceEnableIntroDoSDefense 1
-HiddenServiceEnableIntroDoSRatePerSec 25
-HiddenServiceEnableIntroDoSBurstPerSec 200
+HiddenServiceEnableIntroDoSRatePerSec 12
+HiddenServiceEnableIntroDoSBurstPerSec 80