What is the Node Hub?
Klever Node Hub is a free, open-source, self-hosted web dashboard for Klever validator operators. It manages and monitors all your nodes across multiple servers, without SSH sessions and manual scripts. It has two parts:
- Dashboard: a web application you run on one of your servers. This is your control centre, reachable from any browser.
- Agent: a lightweight program on every server that hosts Klever nodes. It talks to the dashboard over an encrypted WebSocket connection.
What it replaces
| Before | With the Node Hub |
|---|---|
| SSH into each server by hand | One dashboard for all servers |
| Run Docker commands manually | Buttons for start, stop, restart, upgrade |
| No monitoring unless you build Prometheus and Grafana | Built-in metrics, charts and alerting |
| Nobody tells you when a node stalls | Automatic nonce stall detection with Telegram, Pushover, webhook or browser notifications |
| Copy config files with scp | Edit configs remotely, push them to many nodes at once |
| Generate validator keys on the command line | Generate, import and export keys in the dashboard |
| Manual Docker image upgrades | One-click upgrades with rollback |
What it is not
- Not a cloud service: everything runs on your own infrastructure.
- Not a wallet: it does not handle KLV or transactions.
- Not a staking service: it manages the infrastructure, not the staking itself.
- Your node servers need no extra open ports: the agents connect outbound to the dashboard.
For one or a few servers and a simple text menu, the Node Manager script is enough. Choose the Hub when you run several servers and want a web dashboard with live metrics, alerts and remote management. The two work side by side: the agent discovers nodes that were created with the script.
Architecture
- The dashboard is the brain: it serves the web interface, stores its data in SQLite and orchestrates all actions.
- The agents are the hands: they sit on each node server, run the Docker commands, collect metrics and stream logs.
- Dashboard and agents authenticate each other with mTLS (mutual TLS with Ed25519 certificates). No SSH keys are stored and no passwords are shared.
- On first start the dashboard creates its own certificate authority. Every agent that registers receives a signed client certificate.
Install the dashboard
The dashboard runs on one of your servers (or a separate management server). Browsers and all agents must be able to reach it on port 9443.
Option A: Docker (recommended)
docker run -d \ -p 9443:9443 \ -v klever-data:/root/.klever-node-hub \ --name klever-node-hub \ ctjaeger/klever-node-hub:latest \ --domain your-server.example.com
The --domain flag is optional. You only need it for passkey login, because WebAuthn requires a domain.
Password login works with a plain IP address.
If you also add -v /var/run/docker.sock:/var/run/docker.sock, the dashboard can pull a new image and recreate its own container when you click
Update Now. Leave the mount off if you prefer to update by hand with docker pull and docker run; the dashboard then shows you the docker pull command instead.
The socket gives root-equivalent control of the Docker daemon, so only mount it if you trust the dashboard accordingly.
Option B: Binary
wget https://github.com/CTJaeger/KleverNodeHub/releases/latest/download/klever-node-hub-linux-amd64 chmod +x klever-node-hub-linux-amd64 ./klever-node-hub-linux-amd64 --domain your-server.example.com
For ARM servers use klever-node-hub-linux-arm64. Every release also contains a checksums.txt with SHA-256 sums, and builds for macOS and Windows.
Option C: Build from source
You need Go 1.26 or newer.
git clone https://github.com/CTJaeger/KleverNodeHub.git cd KleverNodeHub make build-linux scp bin/klever-node-hub-linux user@your-server:/opt/klever/klever-node-hub ./klever-node-hub --domain your-server.example.com
Dashboard flags
| Flag | Default | Description |
|---|---|---|
--addr | :9443 | Listen address (host:port) |
--domain | localhost | Domain for the TLS certificate and the passkey relying-party ID |
--data-dir | ~/.klever-node-hub | Data directory: database, certificates, backups |
--reset-recovery-codes | – | Generate new recovery codes and exit |
After the start the dashboard creates a self-signed certificate and is available at https://your-server:9443.
Your browser will warn about the certificate until you put a reverse proxy in front (next section).
Trusted HTTPS with a reverse proxy
With the built-in self-signed certificate, browsers show a warning and a phone will not offer to install the dashboard as an app (a trusted certificate is needed for that). Put a reverse proxy with a Let's Encrypt certificate in front of the dashboard.
Agents log in with mTLS client certificates, which a reverse proxy strips. So agents must reach port 9443 directly; only browsers go through the proxy.
Binding the dashboard to 127.0.0.1:9443 only works if all agents run on the same host as the dashboard. With remote agents, bind 9443 to a LAN or public address and restrict it to your agents' IPs with the firewall.
Browsers ──HTTPS:443──▶ Reverse proxy ──HTTPS:9443──▶ Dashboard Agents ──mTLS:9443─────────────────────────────▶ Dashboard
Prerequisites: a domain pointing to your server, ports 80 and 443 open, and Certbot with the plugin for your web server.
The --domain flag of the dashboard must match the domain you use in the proxy.
Example: Apache
sudo apt install certbot python3-certbot-apache sudo a2enmod proxy proxy_http proxy_wstunnel ssl rewrite headers sudo systemctl restart apache2 sudo certbot certonly --apache -d your-domain.example.com
Create /etc/apache2/sites-available/klever-node-hub.conf:
<VirtualHost *:80>
ServerName your-domain.example.com
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName your-domain.example.com
SSLEngine on
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCertificateFile /etc/letsencrypt/live/your-domain.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.example.com/privkey.pem
# Proxy to the dashboard (self-signed backend certificate)
ProxyPreserveHost On
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
# The dashboard uses the forwarded protocol and client address for rate limiting and lockout
RequestHeader set X-Forwarded-Proto "https"
# WebSocket support (live metrics and log streaming)
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule ^/(.*)$ https://127.0.0.1:9443/$1 [P,L]
ProxyPass / https://127.0.0.1:9443/
ProxyPassReverse / https://127.0.0.1:9443/
</VirtualHost>
sudo a2ensite klever-node-hub.conf sudo apache2ctl configtest sudo systemctl reload apache2
Certbot renews the certificate automatically. Check it with sudo certbot renew --dry-run.
Configurations for Nginx and Caddy are in the reverse proxy guide in the repository.
Open https://your-domain.example.com: the padlock should show a valid certificate, and the live metrics should update (that proves WebSocket proxying works).
Install the agents
Every server that runs Klever nodes needs an agent. It connects outbound to your dashboard, so the node server needs no extra open port. Repeat these steps for each server; a token works only once.
- Generate a registration token Open the dashboard, click Add Server, then Generate Token and copy the install command shown. The token is valid for one hour.
-
Run the install command on the node server
Option A, the install script (recommended):
curl -sSL https://raw.githubusercontent.com/CTJaeger/KleverNodeHub/main/scripts/install-agent.sh \ | sudo bash -s -- --token <YOUR_TOKEN> --dashboard https://<DASHBOARD_IP>:9443
The script installs Docker if needed, downloads the right agent for your architecture (amd64 or arm64), registers it with the token, creates aklever-agentsystemd service, starts it and discovers the Klever nodes that already run on the server. - See the server appear As soon as the agent connects, the server shows up in the dashboard together with its nodes.
You can read the install script in the
repository first.
If you prefer not to pipe a script into bash, use one of the two options below.
Option B: Docker
docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ --name klever-agent \ ctjaeger/klever-agent:latest \ --dashboard-url https://<DASHBOARD_IP>:9443 \ --register-token <YOUR_TOKEN>
Option C: Manual binary
wget https://github.com/CTJaeger/KleverNodeHub/releases/latest/download/klever-agent-linux-amd64 chmod +x klever-agent-linux-amd64 ./klever-agent-linux-amd64 --dashboard-url https://<DASHBOARD_IP>:9443 --register-token <YOUR_TOKEN>
Agent flags
| Flag | Default | Description |
|---|---|---|
--config-dir | ~/.klever-agent | Config directory (stores the mTLS certificate) |
--dashboard-url | – | Dashboard URL, required for the first registration |
--register-token | – | One-time registration token |
--docker-socket | /var/run/docker.sock | Docker socket path |
After registration the agent keeps its certificate and reconnects by itself after a restart, no token needed.
First login and setup wizard
When you open https://your-server:9443 for the first time, the setup wizard starts.
- Set a passwordChoose a strong one (at least 8 characters). It is your main login.
- Register a passkey (optional)Log in with Face ID, Touch ID, Windows Hello or a hardware key such as a YubiKey. This needs a domain (
--domain). - Save your recovery codesThe wizard creates 8 single-use codes. They are your way back in if you lose the password and all passkeys. Keep them safe.
- Link your Klever wallet (optional)With the Klever Extension in your browser you can log in with your wallet. The dashboard checks ownership with a signature challenge.
| Login method | Requirements | Use it for |
|---|---|---|
| Password | Works with an IP address or a domain | The default, always available |
| Passkey | Domain and a browser with WebAuthn | Fast biometric login |
| Klever Extension | Browser extension and a linked wallet | One-click wallet login |
| Recovery code | Single-use codes from the setup | Emergency access |
If the codes get lost, start the dashboard once with --reset-recovery-codes to create new ones.
The dashboard at a glance
Overview
All servers and nodes on one page with live status, CPU, memory and disk bars. Flat list or grouped by BLS key (main node on top, fallbacks indented), with search and filters.
Server page
Hostname, IP, region (detected from the public IP), operating system, live system gauges, agent version and the nodes on that server.
Node page
Status and sync progress, nonce, epoch and slot, finalized nonce, consensus state, peers and TPS, plus charts for CPU, memory, disk and network. Start, stop, restart, upgrade, downgrade and delete from here.
Validators page
Your validators matched by BLS key: state (elected, jailed, waiting), commission, self-stake, allowance, blocks produced and missed, and a timeline of the last 100 blocks per validator.
Alerts
Alert rules, active alerts with a badge on every page, and the alert history.
Live logs
Stream the Docker log of a node right in the browser.
The dashboard is mobile-first and an installable progressive web app: add it to your phone's home screen and it behaves like a native app, with push notifications.
Batch operations
Select several nodes with the checkboxes on the overview page and start, stop, restart or upgrade them together. Batch upgrades run one node after the other so your quorum is kept.
Provision new nodes
You can set up a brand new Klever node from the dashboard, no SSH needed.
- Open the serverGo to the detail page of the server and click Provision Node.
- Choose the optionsNode name (or several nodes in one run, with automatically increasing REST API ports), Main or Fallback role, the network, and the sync mode.
- StartClick Provision and follow the progress live.
The agent runs a preflight check (Docker, disk space, connectivity), pulls the Klever Docker image, creates the folders, downloads the initial configuration from the official Klever servers, creates and starts the container and finally verifies that the node answers. If a step fails, the agent cleans up.
Sync modes
| Fast bootstrap | Starts from the latest epoch. Quickest way to a running node. |
| Full DB snapshot | Loads the official full-node snapshot, so you get an archival node in one step. |
| Full sync | Syncs from genesis. |
Chain DB restore
For an existing node you can replace the chain database with the official full-node snapshot. The snapshot is streamed straight to disk after a disk-space check, and the previous database is kept for a rollback. This is how you turn a fast-bootstrapped node into a full archival node, for example for indexers.
Configuration and keys
Edit config files remotely
Open a node, go to Config, pick a file and edit it. Every save creates a backup of the previous version, and you can restore any backup with one click.
Push to several nodes
Edit a file on one node, click Push to Other Nodes, choose the target nodes and confirm. The Batch Config tool changes one parameter across all nodes at once, shows the current value of each node side by side and can restart the nodes afterwards.
Config upgrade
When you upgrade to a new image, the dashboard can fetch a fresh configuration from the official Klever servers, keep a versioned backup of your current one and apply the new one.
Validator keys
- Generate: creates a new BLS key inside the node's container and shows the public key.
- Import: paste an existing PEM file; it is written to the node's key folder.
- Export: shows or downloads the PEM, for backup or migration.
- Key operations create backups automatically.
Keys travel over the encrypted mTLS connection. They are never stored in the dashboard database, only on the node server's disk.
Upgrades and downgrades
- Pick the versionOpen the node and click Upgrade. The Docker image tags come from Docker Hub (cached for 15 minutes). An indicator shows which nodes are not on the latest version, and stable releases are ranked above release candidates.
- ConfirmThe agent pulls the image, stops the container, creates a new one with the same settings and the new image, starts it and checks that it runs.
- RollbackIf the upgrade fails, the agent returns to the previous image. To go back later, use Downgrade and pick an older tag.
Batch upgrades run sequentially to keep the quorum, optionally refreshing the configuration at the same time.
Monitoring and alerts
Metrics
The dashboard collects server metrics (CPU, memory, disk, network) and Klever node metrics from /node/status
(76 values, including nonce, sync state, epoch, peers, consensus participation, TPS and transaction pool load) regularly from every node.
| Storage | Resolution | Kept for |
|---|---|---|
| Recent | every 10 seconds | 7 days |
| Archive | 5-minute averages | 90 days |
A daily background job condenses the recent data into the archive and removes old records. The charts are drawn with a small built-in chart library, without external dependencies.
Alert rules
The alert engine checks all rules every 15 seconds. A condition that holds for the configured time fires an alert; when the condition clears, the alert resolves.
| Alert | Condition | Severity | Default |
|---|---|---|---|
| Nonce Stall | The node's nonce does not increase | Critical | 16 seconds (4 missed slots) |
| Node Down | Container not running | Critical | 60 seconds |
| High CPU | CPU usage above the threshold | Warning | 90 % |
| High Memory | Memory usage above the threshold | Warning | 90 % |
| Disk Full | Disk usage above the threshold | Critical | 85 % |
| Low Peers | Connected peers below the threshold | Warning | 5 peers |
| Sync Lag | Blocks behind above the threshold | Warning | 100 blocks |
Nonce stall detection is the most important alert for validators: if a node has not moved its nonce for 16 seconds or more, it has produced or finalized nothing for four slot cycles, and a critical alert fires immediately.
- Custom rules: on the Alerts page, change threshold, cooldown, duration and the notification channels per rule.
- History: every firing and resolution is logged with time, severity, node or server, notified channels and resolution time.
- Acknowledge: silences an active alert without resolving it.
- Maintenance aware: nodes you stop from the dashboard count as maintenance and do not fire offline alerts; this ends automatically once they run again.
- Version performance: flags a new node version that processes blocks measurably slower, with a before and after report per node.
Tools
Slot Inspector
Enter a slot, pick nodes, and the Hub pulls the matching logs from every agent and compares validatorTime and lowerBound in a table.
Server benchmark
Runs the official Klever benchmark (disk I/O, network, CPU, memory, key-value store) and shows a score and a grade.
Docker cleanup
Frees disk space from old klever-go images left behind by upgrades. Images still used by a container are protected.
Notifications
| Channel | Description |
|---|---|
| Telegram | Alerts to a Telegram bot, with Markdown formatting. |
| Pushover | Push notifications to any device; critical alerts map to emergency priority. |
| Webhook | HTTP POST with JSON (type, severity, message, node, server, time) to any URL. Custom headers, retries with exponential backoff. |
| Web Push | Browser notifications, even when the dashboard tab is closed. |
Set up a channel
- Open the settingsGo to Settings → Notifications and click Add Channel.
- Enter the access dataTelegram: bot token (from @BotFather) and chat ID. Pushover: user key and API token. Webhook: URL and optional headers. Web Push: switch it on and allow notifications in the browser.
- Test and saveUse the Test button to check that a message arrives.
Each channel can be filtered by severity (info, warning, critical) and by alert type (node_down, nonce_stall, resource, metric, resolved).
For example: all critical alerts to Telegram, but only nonce stalls to Pushover. A history of all sent notifications is under Settings → Notifications → History.
Updating agents and dashboard
Agents
Agents are updated from the dashboard, no SSH needed. Open Agent Update in the sidebar, pick a version from the list (it comes from the GitHub releases) and download it. The dashboard only downloads the builds your servers need. Then select the agents in the table, choose the target version and click Update.
Each agent shows its progress (waiting, updating, restarting, done or failed). The agent checks the SHA-256 checksum, keeps a backup of its current program, replaces it atomically and restarts. The dashboard waits up to 15 seconds for the agent to come back with the new version. To roll back, update to an earlier version from the same list. You can also restart an agent from the dashboard without touching the running nodes.
Dashboard
The dashboard checks for updates itself. With the Docker socket mounted, Update Now swaps the container cleanly and can roll back. Without it, the dashboard shows the docker pull command to run.
The binary version replaces itself and restarts.
Security
| Layer | How it is protected |
|---|---|
| Dashboard login | Password (Argon2id), WebAuthn passkeys, Klever Extension (Ed25519 challenge and response) |
| Rate limiting | 5 login attempts per 15 minutes per IP address, then HTTP 429 |
| Account recovery | Single-use recovery codes, stored as Argon2id hashes |
| Config storage | AES-256-GCM encryption at rest |
| Agent communication | mTLS with Ed25519 certificates, TLS 1.3, the dashboard acts as certificate authority |
| Agent commands | Whitelist of known commands only (start, stop, upgrade, config and key operations, ...). No shell access. |
| Sessions | Short-lived JWT access tokens (15 minutes) with refresh rotation |
| File access | Config and key operations check paths against directory traversal |
| Browser | Security headers such as Content-Security-Policy, X-Frame-Options and HSTS |
Because the agents only run a fixed set of commands, a compromised dashboard still cannot run arbitrary commands on your node servers.
The code is open source under the MIT license. Security follows Kerckhoffs's principle: knowing the source code does not help an attacker without the keys. Report vulnerabilities through GitHub's private vulnerability reporting, not in public issues.
- Use a domain, a reverse proxy and a trusted certificate for the dashboard.
- Restrict port 9443 with your firewall to your agent servers (and your proxy).
- Think twice before mounting the Docker socket into the dashboard container.
FAQ
Do I need to open ports on my node servers?
No. The agent connects outbound to the dashboard. Only the dashboard needs an open port (9443 by default), and agents must be able to reach it.
Does it work with nodes I already run?
Yes. When you install the agent on a server that already runs Klever nodes, it discovers all kleverapp/klever-go containers and they appear in the dashboard right away.
What happens to my nodes if the dashboard goes down?
They keep running. The dashboard is a management layer and does not affect node operation. When it is back, the agents reconnect automatically.
Can several people use it?
Currently there is a single admin account. Several people can be logged in at the same time with the same credentials.
Which architectures are supported?
linux/amd64 (standard servers) and linux/arm64 (for example Raspberry Pi, Ampere or Graviton servers).
Is there a mobile app?
The dashboard is a progressive web app. Install it from your phone's browser to the home screen; it works like a native app, including push notifications.
How much does the agent use?
Very little: typically under 20 MB of memory and negligible CPU. It is a single Go program without dependencies.
Where is the data stored?
The dashboard keeps a SQLite database in ~/.klever-node-hub/ (change it with --data-dir). The agent keeps its certificate in ~/.klever-agent/ (change it with --config-dir).
Does it work with testnet nodes?
Yes. It works with mainnet and testnet nodes; you choose the network when you provision a node.
Just one server? The Node Manager script creates, updates and manages your nodes from a simple menu.
Klever Node Hub is an independent community project by CryptoJaeger and is not affiliated with or endorsed by Klever. Source, releases and the full documentation: github.com/CTJaeger/KleverNodeHub.