- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The old rule dropped every outbound TCP RST unconditionally, including the raw socket's own legitimate resets (openflux-server now sets SO_MARK 0x2547 on them) - not just the kernel's unwanted auto-RST it was meant to suppress. Confirmed live via "[RAW-NIC2] Sendto failed: operation not permitted". Removes the old unscoped rule on redeploy (if present) before adding the mark-scoped one, so an existing install actually picks up the fix instead of the stale rule shadowing it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
| .gitignore | ||
| COPYRIGHT | ||
| install.sh | ||
| LICENSE | ||
| NOTICE | ||
| README.md | ||
| README.ru.md | ||
OpenFlux deployer
English | Русский
A fork of p1neappleXpress/OpenFlux. This repo holds
install.sh: a script that asks a handful of questions and rolls out
openflux-server's controlplane — Postgres, the
systemd service, Nginx, and an HTTPS certificate (Let's Encrypt) with auto-renewal — on a fresh
Debian/Ubuntu or AlmaLinux/RHEL-family VPS.
Usage
Run it directly on the target VPS, as root:
curl -fsSL https://raw.githubusercontent.com/wlruscfd/openflux-deploy/main/install.sh | sudo bash
(Not orchestrated remotely over SSH from your own machine - simpler and more robust to just run it where it's actually provisioning things.)
It will ask for:
- Which
openflux-serverrepo/branch to deploy (defaults to thewlruscfdone, override for your own fork). - TLS mode:
domain(standard Let's Encrypt via certbot's Nginx plugin - you'll need a domain already pointed at this server's IP, plus an email for the Let's Encrypt account) orip(no domain needed; attempts Let's Encrypt's short-lived IP-address certificate, falling back to a self-signed certificate - with a clear warning - if that doesn't succeed, so the panel is still reachable over HTTPS either way). - An admin token (or press Enter to generate one) - this is what you'll paste into the admin panel
at
https://<your-domain-or-ip>/admin/afterwards. - For
domain/ipmode: which HTTPS port to use (default443) - only worth changing if something else on the server already owns it. - For
domain/ipmode: whether to reserve port 80 for another service on this machine (default no - normal Let's Encrypt issuance/renewal, which needs port 80 reachable). Say "y" only if something else on this server needs port 80 for itself; this skips Let's Encrypt entirely and uses a self-signed certificate on the HTTPS port only, with nginx never listening on 80 at all. - Whether to install the full SvelteKit web panel (requires Bun; default yes): it serves the
dashboard at
/admin/behind Nginx next to controlplane's/v1/*. Say "n" and you get the original, self-contained panel that's embedded inside the controlplane binary itself (still served at/admin/). Saying "y" here never breaks an install — if Bun can't be installed or the panel fails to build, the script degrades to the embedded panel and says so. - Whether to register a first exit node right away.
If that node runs here (RUN_NODE_HERE, raw mode), its outbound-ports-per-key setting defaults to
96 and is set via the NODE_PORT_RANGE_SIZE env var - not an interactive prompt, and remembered
across redeploys the same way CONTROLPLANE_PORT is. Lower it to fit more keys on this one node;
raise it if a single key's traffic needs more than ~96 simultaneous outbound connections at once
(observed in practice: Telegram opens quite a few while loading media in an active chat).
At the end it prints the panel URL, the admin token (save it - it's stored hashed and can't be recovered from the server afterwards), and, if you registered one, the first exit node's token and the exact flags to hand to whoever runs that exit node:
./universal-bypass-tool --exit-node --managed \
--control-url "https://<your-domain-or-ip>" \
--node-token "<node token>"
Re-running the script later redeploys a newer branch/tag of openflux-server in place.
Redeploys preserve your data
Re-running install.sh on a server it's already set up (upgrading to a newer openflux-server, or
just via the app's "Deploy again") keeps the existing database, admin token, and token pepper -
every key, node, and ingest token you've already issued keeps working. Before touching anything, it
also dumps the database to /opt/openflux/backups/<timestamp>/openflux.sql (plus a copy of the env
file) as a just-in-case safety net. A first-time install has nothing to preserve or back up yet, so
none of this applies to it.
Non-interactive / automated use
Every prompt is skipped if its variable is already set in the environment (REPO_URL, GIT_REF,
TLS_MODE, DOMAIN, LE_EMAIL, SERVER_IP, HTTPS_PORT, RESERVE_PORT_80, ADMIN_TOKEN,
DB_PASSWORD, REGISTER_NODE, NODE_NAME, NODE_MAX_KEYS, WEB_PANEL - the exact names used
inside the script), so it can be driven without a human at the keyboard. RESERVE_PORT_80 (default
n, domain/ip modes only) - set to y to skip Let's Encrypt entirely and use a self-signed
certificate with no port-80 listener at all, so port 80 stays free for another service on the same
machine:
REPO_URL=https://github.com/wlruscfd/openflux-server.git GIT_REF=main \
TLS_MODE=domain DOMAIN=panel.example.com LE_EMAIL=you@example.com \
ADMIN_TOKEN="$(openssl rand -hex 32)" DB_PASSWORD="$(openssl rand -hex 24)" \
REGISTER_NODE=y NODE_NAME=node-1 NODE_MAX_KEYS=500 WEB_PANEL=y \
bash install.sh
This is exactly what the openflux-app Android app's
Deploy tab does over SSH, so you never see a prompt when deploying from the app. Non-interactive
callers that don't pre-set WEB_PANEL get the embedded panel - the script does not prompt where
stdin isn't interactive.
What it sets up
openfluxsystem user,/opt/openflux/{bin,server,web},/etc/openflux/controlplane.env(mode600, holds the DB URL / token pepper / admin token).- A local Postgres role + database.
openflux-controlplane.service(systemd unit, embedded in install.sh), enabled and started.- With the web panel: Bun at
/opt/openflux/bun, the built SvelteKit app at/opt/openflux/web, andopenflux-web.service(bun server.json127.0.0.1:3000,CONTROLPLANE_UPSTREAMholding the controlplane address it forwards/v1/*to). - Nginx:
/admin/→ the web panel (or controlplane's embedded panel, when Bun was skipped),/v1/+/healthz→ controlplane on127.0.0.1:8080(override with theCONTROLPLANE_PORTenv var if something else on the server already holds 8080 - a redeploy remembers whatever port was used last time), all over TLS per the mode above. Inhttpmode without a web panel the split doesn't apply and controlplane answers directly.
Honesty about the IP-certificate path
Let's Encrypt's short-lived certificates for bare IP addresses are newer and less battle-tested
than the domain path, and need a recent certbot (--ip-address needs 5.3+, webroot support for it
needs 5.4+) - the certbot package in Debian/Ubuntu's apt or AlmaLinux's EPEL is normally far older
than that and doesn't support IP certificates at all, so this script installs certbot via snap specifically to get a current
enough one. That said, this is still a newer Let's Encrypt capability with its own moving parts;
if issuance still fails for you, the script notices and falls back to a self-signed certificate
rather than leaving the install half-finished. If you can get a domain pointed at the server
instead, that path is the well-trodden one.