Author SHA1 Message Date
alleyviperandroot 5bdfd99c4d feat(anis): auto-provision ANIS Community Edition on fresh installs (Phase 4)
Changed the ANIS_URL default from the docker-internal
"http://argus-anis:8090" to the public Community Edition hub
(https://anis.weboria.eu). That internal default was dead on arrival for
every real deployment path: neither docker/docker-compose.yml nor
distribution/docker-compose.yml bundles its own ANIS container (confirmed
via grep — only the dev-only docker-compose.local-sandbox.yml does, and
it already sets ANIS_URL explicitly, so it's unaffected by this change),
so a fresh install using either client-facing compose file previously got
ANIS_ENABLED=false and an empty/unreachable ANIS_URL with no working
threat intelligence out of the box.

An empty license key already grants the "community" tier server-side
(confirmed against ANIS's own RegisterInstance handler in a prior
grounding pass) — no signup or key needed, so defaulting
enabled=true/url=<public hub>/key=empty is a genuine zero-friction
default, not a placeholder pointing at something that doesn't work.
ANIS_ENABLED flipped from :-false to :-true in both compose files'
inline fallback (not just the .env.example docs) since a compose-level
explicit "false" string takes precedence over the Go binary's own
compiled default and previously masked it.

Updated distribution/.env.example and configs/env.example to match.

Live-verified against a genuinely fresh sandbox install (temporarily
unset the sandbox compose's own ANIS_URL override to actually exercise
the new default, reverted before committing — confirmed clean via `git
diff`): anis_settings bootstrapped to
enabled=true/url=https://anis.weboria.eu/license_key=''/bootstrapped=true
on first boot. Re-verified the sandbox's own explicit local override
(http://anis:8090, for its bundled ANIS container) still wins unaffected
after reverting.
2026-07-25 15:20:10 +00:00
913615903b fix(installer): align installer/onboarding with current codebase (Phase 1 audit)
A full audit of the installer and first-run experience found the mandatory
first-run wizard (is_initial_setup gate + InitialSetup.tsx) already works
correctly end-to-end — the real gap was discoverability and drift between
the installer and current app, not the wizard itself:

- nginx's static welcome page (served on the default HTTP/HTTPS ports, the
  first place any new admin looks) never mentioned the admin panel lives on
  a separate port, still shipped a Korean-language switcher despite Korean
  being fully removed from the product, and linked to the retired
  "Argus-appliance" identity. Now surfaces a live, dynamically-derived
  admin panel link and drops the dead i18n/branding.
- users.language defaulted to 'ko' at the schema level (both the column
  DEFAULT and the seed admin row) — a leftover from before Korean removal,
  silently affecting every new user, not just the seed account.
- Three independently-drifting install paths existed (public distribution
  installer, private-repo SSH-ship installer, and a fully manual README/docs
  flow). README/docs now lead with the public alleyviper/argus installer
  (verified to actually exist and mirror distribution/); the manual path is
  kept only as an explicit private/pre-release fallback.
- Both scripted installers auto-rotated admin/admin via the API as their
  last step, silently warning (not failing) if it didn't work — inconsistent
  with the manual path and capable of leaving defaults active undetected.
  Removed; every install path now consistently lands on admin/admin + the
  in-app wizard.
- ANIS_ADMIN_KEY was documented as required ("ARGUS fails closed without
  it") but is never read anywhere in src/api — confirmed dead, not just
  vestigial. Retired from env templates, compose files, and docs; ROADMAP's
  existing "wire it up or retire it" item resolved for this variable.
- Proxy host creation returned an opaque 500 when given an unresolvable
  forward_host (e.g. a Docker container name typed into the free-text
  field — ARGUS's nginx runs in host-network mode with no embedded DNS).
  nginx -t's real "host not found in upstream" failure now surfaces as an
  actionable 400 instead of a generic internal error; placeholder text
  fixed to stop inviting the failure. Live-verified both the failure path
  (with NGINX_SKIP_TEST temporarily disabled in the sandbox to exercise the
  real validation) and the no-regression path (valid IP still succeeds).
- LOG_COLLECTION silently disables the entire access-log/analytics/live-event
  pipeline when set to anything but the exact string "true", with zero log
  output anywhere. Added a boot-time WARN matching the existing
  IsInitialSetupRequired nudge pattern.

Every fix live-verified against a genuinely fresh sandbox install
(docker/docker-compose.local-sandbox.yml, zero pre-existing volumes),
not just read from source.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 13:46:34 +00:00
5 changed files with 78 additions and 151 deletions
+8 -6
View File
@@ -25,14 +25,16 @@ DB_NAME=argus
# community instance). These vars configure how THIS ARGUS instance talks to
# an already-running ANIS service — they do not start one.
#
# Set ANIS_ENABLED=true and ANIS_URL to turn on reporting WAF auto-bans to
# ANIS and pulling its community threat-intelligence feed.
# On by default against the public Community Edition hub — an empty license
# key already grants the community (free) tier, no signup required. Point
# ANIS_URL at your own self-hosted ANIS instead if you run one, or set
# ANIS_ENABLED=false to turn this off entirely.
ANIS_ENABLED=false
# ANIS_URL=https://anis.example.com:8090
ANIS_ENABLED=true
ANIS_URL=https://anis.weboria.eu
# License key from ANIS dashboard -> Licenses -> Create License.
# Leave blank to use the community (free) tier.
ANIS_LICENSE_KEY=
# Must match the ANIS instance's own ANIS_ADMIN_KEY. Generate: openssl rand -hex 32
ANIS_ADMIN_KEY=
ANIS_SHARE_ATTACKERS=false
# ===========================================
+42 -72
View File
@@ -1,11 +1,11 @@
<div align="center">
# ARGUS Enterprise Web Security Platform
# ARGUS
### A real-time security operations platform for the modern web edge
### Enterprise Web Security Platform
[![License](https://img.shields.io/badge/License-Commercial-lightgrey?style=for-the-badge)](LICENSE)
[![Platform](https://img.shields.io/badge/Platform-Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white)]()
[![License](https://img.shields.io/badge/License-Proprietary-lightgrey?style=for-the-badge)](LICENSE)
[![Docker](https://img.shields.io/badge/Docker-ready-2496ED?style=for-the-badge&logo=docker&logoColor=white)](https://github.com/alleyviper/argus/pkgs/container/argus-secure-api)
[![Nginx](https://img.shields.io/badge/Nginx-1.30-009639?style=for-the-badge&logo=nginx&logoColor=white)](https://nginx.org/)
[![ModSecurity](https://img.shields.io/badge/ModSecurity-v3-red?style=for-the-badge)](https://modsecurity.org/)
@@ -13,36 +13,22 @@
[![HTTP/3](https://img.shields.io/badge/HTTP/3-QUIC-blue?style=for-the-badge)]()
<p align="center">
<strong>ARGUS combines a reverse proxy, Web Application Firewall, bot and AI-crawler defense,
DNS security engine, threat intelligence integration, GeoIP and cloud-provider access control,
automated SSL, rate limiting and auto-ban, real-time attack visualization, incident
investigation, load balancing, TCP/UDP stream proxying, enterprise user management, and a full
REST API — one complete web security appliance for protecting modern applications.</strong>
<strong>A real-time security operations platform for the modern web edge.<br/>
Reverse proxy, Web Application Firewall, bot defense, DNS protection, and live threat
investigation — in one appliance.</strong>
</p>
<p align="center">
<a href="#-key-features">✨ Features</a> •
<a href="#-installation">🚀 Installation</a> •
<a href="#-operations">🛠 Operations</a> •
<a href="#-licensing--support">📄 Licensing & Support</a>
<a href="#-api">📚 API</a>
</p>
---
</div>
> **This is the public ARGUS installer repository.** It contains no proprietary source
> code — only installation scripts, configuration templates, and public documentation.
> Application source is developed privately by Weboria and distributed exclusively as
> published container images. You do not need, and will not be given, access to the source
> to install, run, or operate ARGUS.
>
> **Known gap, not yet built:** production images are currently distributed from GitHub
> Container Registry while Weboria's own private registry (`registry.weboria.eu`) is
> provisioned. License-key validation during install is not yet implemented — that needs a
> licensing service design before `install.sh` can enforce it. Both are tracked, not silently
> assumed to already work.
## ✨ Key Features
### 🛡️ Web Application Firewall
@@ -77,8 +63,7 @@ Let's Encrypt with automatic renewal, including wildcard certificates via DNS-01
### ⚡ Rate Limiting & Auto-Ban
Configurable per-IP/per-URI rate limits, automatic banning on repeated WAF violations, and
optional community threat-intelligence-driven blocking via ANIS (enabled by default, no
license key required for the free Community tier).
optional community threat-intelligence-driven blocking.
### 👥 Full User Management
Role-based access, per-user session control, forced password resets, account lock/unlock, MFA,
@@ -100,20 +85,18 @@ HTTP/3 (QUIC) and post-quantum-ready TLS (ML-KEM hybrid key exchange).
### Requirements
- A Linux host with Docker Engine 24.0+ and the Docker Compose plugin (`docker compose`)
- 2 vCPU / 4 GB RAM minimum for evaluation; see production sizing guidance in `docs/` for
real traffic volumes
- A Linux host with Docker 24.0+ and the Docker Compose plugin (`docker compose`)
- Ports 80/443 available for the reverse proxy, and 81 for the admin panel (all configurable)
### One-line install
```bash
curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/alleyviper/argus/main/install.sh | bash
```
This downloads the deployment files, generates secure database/application secrets, creates the
This downloads the deployment files, generates a secure database password, creates the
required Docker network, pulls the production images, starts ARGUS, and prints your admin
login at the end. Installs to `/opt/argus` by default — set `ARGUS_INSTALL_DIR` first to change
login at the end. Installs to `~/argus` by default — set `ARGUS_INSTALL_DIR` first to change
that.
### Manual install
@@ -121,10 +104,10 @@ that.
If you'd rather see every step:
```bash
mkdir -p /opt/argus/docker-socket-proxy && cd /opt/argus
curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/docker-compose.yml -o docker-compose.yml
curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/.env.example -o .env
curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/docker-socket-proxy/haproxy.cfg.template -o docker-socket-proxy/haproxy.cfg.template
mkdir -p ~/argus/docker-socket-proxy && cd ~/argus
curl -fsSL https://raw.githubusercontent.com/alleyviper/argus/main/docker-compose.yml -o docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/alleyviper/argus/main/.env.example -o .env
curl -fsSL https://raw.githubusercontent.com/alleyviper/argus/main/docker-socket-proxy/haproxy.cfg.template -o docker-socket-proxy/haproxy.cfg.template
# Generate a secure database password
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$(openssl rand -base64 24)/" .env
@@ -136,30 +119,19 @@ docker compose pull
docker compose up -d
```
Then log in at `https://<your-server-address>:81` with `admin` / `admin` and change the password
Then log in at `https://localhost:81` with `admin` / `admin` and change the password
immediately — the one-line installer does this rotation for you automatically.
**Do not expose the admin panel (port 81) to the internet.** Keep it on your LAN/VPN, or put
it behind its own proxy host with access lists and 2FA enabled.
### Next steps after install
1. Open the administration panel at the access URL printed at the end of install.
2. Complete the first-run setup wizard — regional settings and a guided review of every
protection module.
3. Confirm your administrator password was rotated (the installer does this automatically).
4. Configure domains and reverse proxy hosts under **Proxy Hosts**.
5. Review the ANIS threat intelligence connection under **Threat Intel** — on by default
against the public Community Edition hub.
6. Review security policies in the **Security Policy Center**.
---
## 🛠 Operations
All lifecycle management is Docker-based — five scripts cover day-to-day operation, downloaded
once alongside `docker-compose.yml` (the one-line installer already does this for you), then run
from `/opt/argus` (or wherever you installed):
Five scripts cover day-to-day operation download them once alongside `docker-compose.yml`
(the one-line installer already does this for you), then run from `~/argus` (or wherever you
installed):
| Script | Purpose |
|--------|---------|
@@ -169,24 +141,21 @@ from `/opt/argus` (or wherever you installed):
| `./restore.sh <archive>` | Restore a backup onto a fresh installation |
| `./uninstall.sh [--remove-data]` | Stop ARGUS; data is kept unless you explicitly opt in to removing it |
You never manually download application files or modify containers directly — every update is
delivered as a new published image version.
### Upgrading
```bash
cd /opt/argus
docker compose pull
docker compose up -d
cd ~/argus
./update.sh
```
(`./update.sh` wraps the same two commands with a before/after version check.) This is the only
supported upgrade path; there is no separate migration step to run.
New versions are published to GHCR as soon as they're released — `update.sh` always pulls the
current stable release. This is the only supported upgrade path; there is no separate migration
step to run.
### Backups
```bash
cd /opt/argus
cd ~/argus
./backup.sh # writes argus-backup-<timestamp>.tar.gz to the current directory
./restore.sh <archive> # onto a fresh installation only — see the script's own header
```
@@ -201,13 +170,12 @@ Add `--username <name>` to target a specific account, or `--password '...'` to s
value instead of generating one. See `docker compose exec api ./server reset-password --help`
for the rest of the options (clearing 2FA, etc.).
### Threat intelligence integration
### Threat intelligence integration (optional)
ARGUS connects to **ANIS**, Weboria's threat-intelligence hub, to share confirmed attacker IPs
and receive a community blocklist in return. Enabled by default against the public Community
Edition hub — no license key required. Point `ANIS_URL` at your own self-hosted ANIS instead if
you run one, or set `ANIS_ENABLED=false` to turn this off entirely. See the comments in
`.env.example` for the full set of options.
ARGUS can connect to **ANIS**, a separately-deployed threat-intelligence hub, to share confirmed
attacker IPs and receive a community blocklist in return. It's off by default — set
`ANIS_ENABLED=true` and `ANIS_URL` in `.env` to turn it on. See the comments in `.env.example`
for the full set of options.
---
@@ -216,7 +184,7 @@ you run one, or set `ANIS_ENABLED=false` to turn this off entirely. See the comm
ARGUS exposes a full REST API for automation. Authenticate with a JWT (`POST
/api/v1/auth/login`) for interactive use, or an API token (`Authorization: Bearer ng_<token>`,
created from the admin panel) for CI/CD and scripted access. Interactive API documentation is
served at `https://<your-server-address>:81/api/docs` once ARGUS is running.
served at `https://localhost:81/api/docs` once ARGUS is running.
---
@@ -230,22 +198,24 @@ served at `https://<your-server-address>:81/api/docs` once ARGUS is running.
| `NGINX_HTTP_PORT` / `NGINX_HTTPS_PORT` | Reverse-proxy listen ports | `80` / `443` |
| `API_HOST_PORT` | Internal API port exposed to the host | `9080` |
| `DNS_LISTEN_HOST` | DNS Security Engine bind address | `127.0.0.1` |
| `ANIS_ENABLED` / `ANIS_URL` | Threat-intel hub integration | `true` / `https://anis.weboria.eu` |
| `ANIS_ENABLED` / `ANIS_URL` | Optional threat-intel hub integration | `false` / *(empty)* |
Full list with descriptions in `.env.example`.
---
## 📄 Licensing & Support
## 📄 License
ARGUS is commercial software licensed by Weboria — see [LICENSE](LICENSE). Third-party
open-source components retain their own licenses — see
[THIRD_PARTY_LICENSES](THIRD_PARTY_LICENSES) and [NOTICE](NOTICE).
This is proprietary, commercial software — see [LICENSE](LICENSE). Third-party open-source
components retain their own licenses — see [THIRD_PARTY_LICENSES](THIRD_PARTY_LICENSES) and
[NOTICE](NOTICE).
For licensing questions or support, contact the **Weboria Support Portal**.
## 💬 Support
[GitHub Issues](https://github.com/alleyviper/argus/issues) — bug reports and feature requests.
---
<div align="center">
<sub>© 2025-2026 Weboria. ARGUS Enterprise Web Security Platform.</sub>
<sub>© 2025-2026 ARGUS — AI4SEC.</sub>
</div>
+7 -5
View File
@@ -118,12 +118,13 @@ services:
NGINX_HTTPS_PORT: ${NGINX_HTTPS_PORT:-}
API_HOST_PORT: ${API_HOST_PORT:-9080}
API_HOST: ${API_HOST:-}
# ANIS community intelligence — optional, off by default. Set these to
# connect this instance to an already-running ANIS hub.
ANIS_ENABLED: ${ANIS_ENABLED:-false}
ANIS_URL: ${ANIS_URL:-}
# ANIS community intelligence — on by default against the public
# Community Edition hub (empty license key = community tier, no signup
# required). Set ANIS_URL to your own self-hosted ANIS instead if you
# run one, or ANIS_ENABLED=false to turn this off entirely.
ANIS_ENABLED: ${ANIS_ENABLED:-true}
ANIS_URL: ${ANIS_URL:-https://anis.weboria.eu}
ANIS_LICENSE_KEY: ${ANIS_LICENSE_KEY:-}
ANIS_ADMIN_KEY: ${ANIS_ADMIN_KEY:-}
ANIS_SHARE_ATTACKERS: ${ANIS_SHARE_ATTACKERS:-false}
DNS_SECURITY_LISTEN_ADDR: ":53"
ports:
@@ -196,6 +197,7 @@ services:
max-file: "5"
environment:
TZ: ${TZ:-UTC}
UI_PORT: ${UI_PORT:-81}
ulimits:
nofile:
soft: 65535
+17 -63
View File
@@ -1,22 +1,15 @@
#!/usr/bin/env bash
#
# ARGUS Enterprise Web Security Platform — installer. Fetches the production
# compose stack, generates secrets, starts the platform, and prints your
# admin credentials.
# ARGUS installer — fetches the production compose stack, generates secrets,
# starts the platform, and prints your admin credentials.
#
# curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/install.sh | bash
# curl -fsSL https://raw.githubusercontent.com/alleyviper/argus/main/install.sh | bash
#
set -euo pipefail
REPO_RAW_BASE="https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main"
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
REPO_RAW_BASE="https://raw.githubusercontent.com/alleyviper/argus/main"
INSTALL_DIR="${ARGUS_INSTALL_DIR:-$HOME/argus}"
NETWORK_NAME="argus-network"
# The image registry is still ghcr.io (GitHub Container Registry) today —
# Weboria's own private registry (registry.weboria.eu) is provisioned but
# not yet serving images. docker-compose.yml's image: lines point at ghcr.io
# directly rather than a variable here, since that's the only registry that
# actually has published images right now; switching to registry.weboria.eu
# is a one-line change to those image: lines once it's live, not a rewrite.
# ── Output helpers ────────────────────────────────────────────────────────────
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
@@ -104,63 +97,24 @@ if [ "$READY" != "true" ]; then
fi
ok "ARGUS is up"
# ── 8. Rotate the default admin credentials ───────────────────────────────────
ADMIN_USER="admin"
ADMIN_PASSWORD="Ax9!$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 20)"
API_BASE="http://127.0.0.1:${API_HOST_PORT}/api/v1"
LOGIN_RESP="$(curl -fsS -X POST "${API_BASE}/auth/login" \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"admin"}' 2>/dev/null || true)"
TOKEN="$(printf '%s' "${LOGIN_RESP}" | grep -oP '"token"\s*:\s*"\K[^"]+' || true)"
CREDS_ROTATED=false
if [ -n "$TOKEN" ]; then
CHANGE_RESP="$(curl -fsS -o /dev/null -w '%{http_code}' -X POST "${API_BASE}/auth/change-credentials" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${TOKEN}" \
-d "{\"current_password\":\"admin\",\"new_username\":\"${ADMIN_USER}\",\"new_password\":\"${ADMIN_PASSWORD}\",\"new_password_confirm\":\"${ADMIN_PASSWORD}\"}" 2>/dev/null || echo "000")"
if [ "$CHANGE_RESP" = "200" ]; then
CREDS_ROTATED=true
ok "Rotated the default admin password"
fi
fi
if [ "$CREDS_ROTATED" != "true" ]; then
warn "Could not auto-rotate admin credentials (already changed on a prior run?). Log in with your existing credentials, or admin/admin on a genuinely fresh install."
fi
# ── 9. Summary ─────────────────────────────────────────────────────────────────
# ── 8. Summary ─────────────────────────────────────────────────────────────────
# Credentials are no longer auto-rotated here — a fresh install always lands
# on admin/admin, and ARGUS itself forces a mandatory First-Run Setup Wizard
# on that first login (credential change, regional settings, guided feature
# configuration, installation validation) before the dashboard is reachable.
# Pre-rotating here just made that flow inconsistent across install paths and
# risked silently leaving defaults active if the rotation call failed.
UI_PORT="$(grep -oP '^UI_PORT=\K.*' .env 2>/dev/null || true)"
UI_PORT="${UI_PORT:-81}"
echo
bold "ARGUS Enterprise Web Security Platform has been successfully installed."
bold "ARGUS is installed and running."
echo
info "Access URL: https://$(hostname -I 2>/dev/null | awk '{print $1}' || echo localhost):${UI_PORT} (accept the self-signed certificate)"
if [ "$CREDS_ROTATED" = "true" ]; then
info "Username: ${ADMIN_USER}"
info "Password: ${ADMIN_PASSWORD}"
warn "Save this password now — it is not stored anywhere and cannot be recovered."
else
info "Log in with your existing admin credentials."
fi
echo
bold "Next steps:"
info "1. Open the administration panel at the Access URL above."
if [ "$CREDS_ROTATED" != "true" ]; then
info "2. Complete the first-run setup wizard (regional settings, guided protection checklist)."
info "3. Change the initial administrator password if you haven't already."
else
info "2. Complete the first-run setup wizard — regional settings and a guided review of every"
info " protection module (your admin password was already rotated above)."
fi
info "4. Configure domains and reverse proxy hosts under Proxy Hosts."
info "5. Review the ANIS threat intelligence connection under Threat Intel — enabled by"
info " default against the public Community Edition hub, no license key required."
info "6. Review security policies in the Security Policy Center."
info "Admin Panel: https://localhost:${UI_PORT} (accept the self-signed certificate)"
info "Default Login: admin / admin"
warn "You will be required to set a real username/password and complete the First-Run Setup Wizard on first login."
echo
info "Configuration: ${INSTALL_DIR}/.env and ${INSTALL_DIR}/docker-compose.yml"
info "Upgrade: cd ${INSTALL_DIR} && docker compose pull && docker compose up -d"
info "Backup: cd ${INSTALL_DIR} && ./backup.sh"
info "Docs/support: see README.md in this directory"
info "Backups: see https://github.com/alleyviper/argus#backups"
echo
+4 -5
View File
@@ -1,15 +1,14 @@
#!/usr/bin/env bash
#
# ARGUS Enterprise Web Security Platform — updater. Pulls the latest
# published images and restarts the stack.
# ARGUS updater — pulls the latest published images and restarts the stack.
#
# cd /opt/argus && ./update.sh
# cd ~/argus && ./update.sh
# (or, if you don't have it locally yet)
# curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/update.sh | bash
# curl -fsSL https://raw.githubusercontent.com/alleyviper/argus/main/update.sh | bash
#
set -euo pipefail
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
INSTALL_DIR="${ARGUS_INSTALL_DIR:-$HOME/argus}"
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
info() { printf ' %s\n' "$1"; }