Lead with thesis and declaration; keep operator table and ops intact. Closing line marks README as product intent. Made-with: Cursor
269 lines
8.1 KiB
Markdown
269 lines
8.1 KiB
Markdown
# CYBERLUX
|
||
|
||
> **The clearnet is a showroom. The onion is the door. One engine behind every door.**
|
||
|
||
We did not build forty-three repos. We built **one** Next.js stack and **refused** to fracture it—then we **projected** it through Tor until every vertical had its own v3 address, its own myth, its own entry point. Nginx sits in the middle like a bouncer; Tor does the rest. Same codebase. Same deploy. **Different `.onion` front doors** with host-aware rewrites (`proxy.ts` + `X-Cyberlux-Node`).
|
||
|
||
This is not a route demo. It is **infrastructure with intent**: stable `HiddenServiceDir` names, backup and restore for onion keys, Tor + nginx generated from **one JSON source of truth**. It is built to **boot, survive operator mistakes, and stay legible when everything else is on fire**.
|
||
|
||
---
|
||
|
||
## The thesis
|
||
|
||
- **One truth, many masks** — one build, dozens of onions; no fork army.
|
||
- **Identity persists** — keys and dirs are first-class; restarts don’t erase your address book.
|
||
- **Loopback only** — Next and nginx don’t audition on the public internet; Tor publishes what you mean to publish.
|
||
- **Verify or rot** — `npm run verify` is the line between shipping and LARP.
|
||
|
||
---
|
||
|
||
## Operator controls
|
||
|
||
| Command | What |
|
||
|--------|------|
|
||
| `./start.sh` | Full pipeline: generate → build → Tor/nginx → print **every `.onion` URL** → `next start` on `127.0.0.1:3000` |
|
||
| `npm run onions:list` | Print all `http://….onion` URLs from `/var/lib/tor/*/hostname` (use `sudo` if needed) |
|
||
| `npm run health:stack` | **Terminal A:** keep `npm run start:onion` running · **Terminal B:** curl Tor/nginx/Next loopbacks |
|
||
| `npm run onions:status` | URLs + HTTP probe each nginx vhost |
|
||
| `sudo bash scripts/install-systemd.sh` | Install `cyberlux.service` for boot-time Next |
|
||
| **`DEPLOY.md`** | Firewall posture, compliance reminder, full systemd notes |
|
||
|
||
**Tor on a phone:** **Onion Browser** (iOS) or **Tor Browser for Android** — Safari and Chrome will **never** resolve `.onion`. Paste the full `http://` + 56-char host + `.onion`. Some carriers fight Tor; Wi‑Fi often wins.
|
||
|
||
---
|
||
|
||
## What ships in the box
|
||
|
||
- `43` Tor v3 services
|
||
- stable loopback range `127.0.0.1:8080–8122`
|
||
- Next bound only to `127.0.0.1:3000`
|
||
- one `.onion` per major surface
|
||
- persistent hidden-service identity keyed by `HiddenServiceDir`
|
||
- self-healing backup / restore of onion key directories
|
||
|
||
## What it does (the map)
|
||
|
||
CyberLux boots **one** Next.js app and **projects** it through multiple onion entry points.
|
||
|
||
- `hub` — main storefront
|
||
- `forum` — Void Aggregate
|
||
- `exchange` — classifieds stack
|
||
- `market` — full catalog vertical
|
||
- `search` — Void Crawler
|
||
- `wiki` — hidden-wiki layer
|
||
- `w` — syndicate shell network
|
||
- dozens more dedicated onions map to top-level app routes
|
||
|
||
The routing layer uses host-aware rewrites so a dedicated onion **feels** like its own property without splitting the app into forty-three deployments.
|
||
|
||
## One-command launch
|
||
|
||
Install system deps on Debian/Ubuntu:
|
||
|
||
```bash
|
||
sudo apt install tor nginx
|
||
```
|
||
|
||
Then:
|
||
|
||
```bash
|
||
chmod +x start.sh
|
||
./start.sh
|
||
```
|
||
|
||
What `./start.sh` does:
|
||
|
||
1. regenerates Tor / nginx / app route maps from `scripts/onion-nodes.json`
|
||
2. runs `git pull --ff-only` if the repo has `.git` (failure is non-fatal)
|
||
3. runs `npm install`
|
||
4. repairs `.next` ownership if a root-owned build left it unwritable
|
||
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 actually changed
|
||
8. waits for all onion hostname files, not just the hub
|
||
9. refreshes the onion key backup set
|
||
10. prints every live `.onion` URL
|
||
11. starts Next on `127.0.0.1:3000`
|
||
|
||
Open in Tor Browser:
|
||
|
||
```text
|
||
http://<56-char-v3-address>.onion
|
||
```
|
||
|
||
## Persistent onion addresses
|
||
|
||
Yes — the onion addresses are **meant** to persist.
|
||
|
||
Each service uses a fixed Tor directory:
|
||
|
||
```tor
|
||
HiddenServiceDir /var/lib/tor/<service-dir>
|
||
HiddenServicePort 80 127.0.0.1:<loopback-port>
|
||
```
|
||
|
||
The `.onion` stays stable as long as:
|
||
|
||
- `torDir` names in `scripts/onion-nodes.json` do not change
|
||
- `/var/lib/tor/<service-dir>` is preserved
|
||
- or the backup set can restore those directories
|
||
|
||
Normal app restarts, rebuilds, and standard Tor restarts do **not** rotate addresses by design.
|
||
|
||
## Self-healing onion identity
|
||
|
||
- `scripts/backup-onion-keys.sh`
|
||
- `scripts/restore-onion-keys.sh`
|
||
|
||
Backup location:
|
||
|
||
```text
|
||
/var/backups/cyberlux-onion-keys/current
|
||
```
|
||
|
||
After boot, ready onion service directories are backed up. If a service dir is missing from `/var/lib/tor` next boot, it is restored from backup. That is the gap between **screenshotware** and **survives a tired operator**.
|
||
|
||
## Tor / nginx topology
|
||
|
||
Source of truth: `scripts/onion-nodes.json`
|
||
|
||
Generated artifacts:
|
||
|
||
- `tor/cyberlux-nodes.conf`
|
||
- `nginx/cyberlux-onion-servers.inc`
|
||
- `lib/onionRoutes.generated.ts`
|
||
- `scripts/generated/tor-dirs.txt`
|
||
- `scripts/generated/onion-labels.tsv`
|
||
- `scripts/generated/onion-port-range.txt`
|
||
|
||
Install path:
|
||
|
||
- `/etc/tor/cyberlux-nodes.conf`
|
||
- `/etc/nginx/cyberlux-server-common.inc`
|
||
- `/etc/nginx/cyberlux-onion-servers.inc`
|
||
- `/etc/nginx/sites-available/cyberlux-onion`
|
||
|
||
Runtime:
|
||
|
||
- Next.js: `127.0.0.1:3000`
|
||
- nginx onion vhosts: `127.0.0.1:8080–8122`
|
||
- Tor exposes the public `.onion` endpoints
|
||
|
||
## Manual ops
|
||
|
||
Install or refresh Tor/nginx config:
|
||
|
||
```bash
|
||
sudo bash scripts/install-tor-onion.sh
|
||
```
|
||
|
||
Back up onion keys:
|
||
|
||
```bash
|
||
sudo bash scripts/backup-onion-keys.sh
|
||
```
|
||
|
||
Restore missing onion keys:
|
||
|
||
```bash
|
||
sudo bash scripts/restore-onion-keys.sh
|
||
```
|
||
|
||
Local-only, skip Tor/nginx:
|
||
|
||
```bash
|
||
CYBERLUX_SKIP_TOR=1 ./start.sh
|
||
```
|
||
|
||
Start app without the helper:
|
||
|
||
```bash
|
||
npm run build
|
||
npm run start:onion
|
||
```
|
||
|
||
## Boot at startup (systemd)
|
||
|
||
Generate the unit with your Unix user and repo path:
|
||
|
||
```bash
|
||
sudo CYBERLUX_USER=$USER bash scripts/install-systemd.sh
|
||
sudo systemctl enable --now tor.service nginx.service cyberlux.service
|
||
# use `tor@default.service` instead of `tor.service` if your distro names it that way
|
||
```
|
||
|
||
The installer writes `/etc/systemd/system/cyberlux.service` and `/etc/default/cyberlux`. Legacy template notes live in `scripts/cyberlux.service` (prefer the generator).
|
||
|
||
Tor + nginx must already be configured (`./start.sh` or `sudo bash scripts/install-tor-onion.sh` at least once).
|
||
|
||
## Verification
|
||
|
||
```bash
|
||
npm run verify
|
||
```
|
||
|
||
Checks: onion config generation, TypeScript, shell syntax for boot/install/backup/restore scripts, full Next production build.
|
||
|
||
## Common failure: `.next` permission hell
|
||
|
||
If you built with `sudo`, `.next` may be root-owned and Next fails with `EACCES`.
|
||
|
||
```bash
|
||
sudo bash scripts/fix-next-perms.sh
|
||
./start.sh
|
||
```
|
||
|
||
## Security (read twice)
|
||
|
||
CyberLux is hardened for a **demo stack**, not sold as magic invisibility.
|
||
|
||
- Next and nginx bind to loopback only
|
||
- Tor exposes the onion endpoints
|
||
- do **not** publish `3000` or `8080–8122` to the public internet
|
||
- optional host firewall: `sudo bash scripts/classroom-ufw.sh`
|
||
- bad application logic stays bad behind Tor
|
||
- operational mistakes beat branding every time
|
||
|
||
Tor obscures **reachability** better than raw-IP hosting. It does not forgive bad code, bad habits, or bad judgment.
|
||
|
||
## Site map
|
||
|
||
Core verticals:
|
||
|
||
- `/` hub storefront
|
||
- `/market` full catalog
|
||
- `/forum` Void Aggregate
|
||
- `/exchange` classifieds
|
||
- `/barter` Ash Pit
|
||
- `/search` Void Crawler
|
||
- `/hidden-wiki` wiki layer
|
||
- `/darknet-atlas` taxonomy / atlas
|
||
- `/syndicate` shell network
|
||
- `/dashboard` personal relay
|
||
- `/account/hidden-services` mirror map
|
||
|
||
Additional dedicated onions exist for many top-level routes beyond these.
|
||
|
||
## Stack
|
||
|
||
- Next.js `16`
|
||
- React `19`
|
||
- Tailwind CSS `4`
|
||
- nginx
|
||
- Tor hidden services
|
||
- generated route / host mapping
|
||
|
||
---
|
||
|
||
## Final word
|
||
|
||
If you are running this, you are **past cosplay**. The stack exists to:
|
||
|
||
- keep **onion identities** across rebuilds when you respect `torDir` names and backups
|
||
- expose **only** what Tor publishes — not your loopback to the raw internet
|
||
- fail **loud** in verification instead of silently rotting
|
||
|
||
Read **`DEPLOY.md`** before you point real people at it. **You** own jurisdiction, opsec, and what you ship. The network does not owe you anonymity; **you** owe the network discipline.
|
||
|
||
**This README is the product’s declaration of intent. The code is the rest.**
|