Skip to content
Hunt Web Documentation

Install Hunt Web on a Linux Server or VPS

Install Hunt Web on a headless VPS, with private SSH access or an HTTPS domain.

Hunt Web Server brings the CLI, Dashboard, Hermes, scanner tools, and PDF reporting to a VPS without a graphical desktop. It supports Blackbox and Greybox Environment assessments, browser-based progress monitoring, and continuation of an existing Run through Hermes Chat. This guide covers installation, private SSH access or an HTTPS domain, account setup, and a service that stays running after SSH logout.

  1. 1Prepare the serverUbuntu 24.04 x86_64, a regular sudo user, and at least 30 GiB free.
  2. 2Choose the access routePrivate SSH or an HTTPS domain. Decide before installing.
  3. 3InstallRun install.sh in server mode with the chosen origin.
  4. 4ConnectOpen an SSH tunnel, or publish through Nginx or a Cloudflare Tunnel.
  5. 5Configure Hermes and the AdminSet the provider, then create the first Admin with the setup code.
  6. 6Keep it runningInstall the user service and enable lingering.
  7. 7Check Health and sign inConfirm component status and test a fresh login.
Conceptual overview of the workflow.

1. Prepare the Server

The supported installer platform is Ubuntu 24.04 x86_64 with Python 3.12. Use a regular account with sudo access, and run installation and configuration as that same account. If the VPS initially provides only root access, create a regular runtime account first.

RequirementWhat to prepare
AccessSSH access and a user-owned application directory.
NetworkDependency downloads, access to the selected model provider, and outbound connections to assessment targets.
StorageBudget at least 30 GiB free initially, plus room for results, captures, and backups.
PortsDashboard 3053 and Hermes Gateway 9119 available on the VPS loopback interface.
Domain, if usedA domain under the deployment administrator's control and an HTTPS proxy or Tunnel configured separately.

The installer manages the private Hermes runtime, tools, and Chromium. A separate global Hermes installation is not required beforehand. Server mode does not require a graphical session.

Obtain the release archive and published checksum from the official Hunt Web release channel, then transfer the archive to the VPS. These examples use ~/hunt-web-2.0.tar.gz:

sha256sum "$HOME/hunt-web-2.0.tar.gz"

Compare the result with the published checksum. Once it matches, extract into a new application directory:

mkdir "$HOME/hunt-web-v2" &&
tar -xzf "$HOME/hunt-web-2.0.tar.gz" --strip-components=1 -C "$HOME/hunt-web-v2" &&
cd "$HOME/hunt-web-v2"

The application lives in ~/hunt-web-v2; private data defaults to ~/.local/share/hunt-web-v2. Keep those directories separate, use paths without spaces or symlinks, and retain their locations after installation. For an existing installation, follow the package's upgrade guide instead of extracting over it.

2. Choose the Access Address Before Installing

Choose one route. During installation, Hunt Web saves its origin: the scheme, hostname, and port used for browser access.

RouteSaved originHow users connect
A. Private SSHhttp://127.0.0.1:3053An SSH tunnel from their computer to the VPS.
B. HTTPS domainhttps://dashboard.example.comA domain served through an HTTPS proxy or Tunnel.

Choose the access route before installing

Changing DNS later does not change Hunt Web's saved origin. Choose the domain route if the deployment requires domain-based Dashboard access. Moving an existing instance between these routes requires a planned configuration change; do not assume that adding a proxy converts a private installation automatically.

Route A — private SSH:

./install.sh --mode server --time-zone Asia/Jakarta --configure-later

Route B — HTTPS domain: replace the example domain with the deployment's domain, without a trailing slash.

./install.sh --mode server --origin https://dashboard.example.com --time-zone Asia/Jakarta --configure-later

--mode server selects Linux Server / VPS, option 2 in the interactive installer. Use the required IANA time zone in place of Asia/Jakarta. --configure-later separates dependency installation from account/model setup. Wait for installation to complete successfully before continuing. It generates the instance's dashboard.sh launcher.

The installer does not publish the Dashboard

The installer does not configure DNS, HTTPS, reverse proxies, firewalls, or Cloudflare. The Dashboard and Gateway remain on loopback; keep ports 3053 and 9119 private.

3. Configure the Access Connection

Follow the subsection matching the selected route, then continue to account setup.

Route A: Open a Private SSH Tunnel

On the client computer, open another terminal and run:

ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:3053:127.0.0.1:3053 operator@vps.example.com

Replace the SSH username and server address. Keep this terminal open. Requests to http://127.0.0.1:3053 on the client computer will reach the VPS Dashboard once its launcher starts.

Local port 3053 must be free. If a Desktop instance already uses it, stop that instance normally when idle, or choose a different port during VPS installation using --port, then use the matching port in the tunnel and browser URL. Without the tunnel, the client computer's localhost does not point to the VPS.

Route B: Publish Through HTTPS

Use an existing HTTPS reverse proxy, the Nginx example below, or the optional Cloudflare route. Replace dashboard.example.com everywhere with the exact domain passed to the installer.

Nginx and a Public TLS Certificate

For a new Ubuntu VPS, point the domain's DNS A record to the server. Add an AAAA record only if the server also serves that domain over IPv6. For this direct Nginx route, allow inbound HTTP/HTTPS ports 80 and 443 in both the provider and host firewalls while preserving SSH access. The certificate method below uses HTTP validation on port 80. Certbot's Nginx documentation describes certificate issuance and installation.

Install the proxy and certificate components on the VPS:

sudo apt-get update
sudo apt-get install nginx certbot python3-certbot-nginx

Create /etc/nginx/sites-available/hunt-web.conf, using a new site file rather than replacing an existing website. Start with this HTTP configuration for certificate setup:

server {
    listen 80;
    server_name dashboard.example.com;
    location / { return 404; }
}

Enable the site, validate it, then request the certificate:

sudo ln -s /etc/nginx/sites-available/hunt-web.conf /etc/nginx/sites-enabled/hunt-web.conf
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d dashboard.example.com

Complete Certbot's contact and agreement prompts and enable HTTP-to-HTTPS redirection. Retain the certificate paths and TLS directives it generates. In the HTTPS server block, replace location / with:

location / {
    proxy_pass http://127.0.0.1:3053;
    proxy_http_version 1.1;
    proxy_set_header Host dashboard.example.com;
    proxy_set_header X-Forwarded-Host dashboard.example.com;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $hunt_web_connection;
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 300s;
    client_max_body_size 20m;
}

Add this map at the top of the site file, outside the server blocks. Ubuntu's standard Nginx configuration includes site files in its http context:

map $http_upgrade $hunt_web_connection {
    default upgrade;
    '' close;
}

The proxy supplies the public host and scheme, avoids buffering streamed responses, and forwards connection upgrades. The 20m limit is an example transport limit; Hunt Web's own upload limits still apply. See the Nginx proxy directives and WebSocket proxying guide.

Validate and reload the configuration, then check certificate renewal:

sudo nginx -t && sudo systemctl reload nginx
sudo certbot renew --dry-run

Verify that certificate renewal is scheduled on the VPS. Continue to step 4; the proxy cannot serve Hunt Web until its launcher is running.

Cloudflare Is Optional

Cloudflare Tunnel is an alternative for publishing the same HTTPS origin. Its connector establishes outbound connections from the VPS, so this route can work without opening inbound HTTP/HTTPS ports on the origin server. Follow the official Tunnel setup guide and connection requirements.

Run the connector on the VPS and route the public hostname to http://127.0.0.1:3053. Ensure the application receives the correct Host, X-Forwarded-Host, and X-Forwarded-Proto: https; use a loopback proxy to set these if necessary. A connector in a different container or machine has a different localhost. Keep connector credentials private and use the Tunnel's DNS route for the hostname.

Cloudflare Access is a separate, optional authentication layer. Without Access configured, team members open the domain and sign in to Hunt Web directly. The Hunt Web installer does not impose Cloudflare email rules or require a Cloudflare administrator login. See Cloudflare's Access application guide when configuring that additional layer.

Keep private pages and APIs out of proxy caches. Test login, uploads, Hermes technical messages, and streaming through the enabled WAF rules. Adjust a specific rule if a legitimate request is incorrectly blocked. This proxy protects incoming Dashboard traffic; the scanner's outbound target requests still originate from the VPS.

4. Configure Hermes and Create the First Admin

Return to the application directory on the VPS:

cd "$HOME/hunt-web-v2"
./configure.sh

The guided configuration covers:

  • Hermes provider and model: configure the selected provider for scanning and chat. Server setup uses the terminal flow without opening a browser window on the VPS.
  • Optional tool keys: ProjectDiscovery and Shodan credentials are separate from the model-provider key. Configure them for tools or data sources that require those credentials; unused optional keys can be skipped.
  • Initial Admin setup: save the one-time setup code shown in the terminal. It expires after ten minutes. Answer n when asked to start Dashboard setup now, because the next command starts it explicitly.

Start the setup launcher:

./dashboard.sh --setup

Open the matching address in a browser on the client computer:

RouteSetup pageNormal sign-in page
Private SSH, with tunnel connectedhttp://127.0.0.1:3053/setuphttp://127.0.0.1:3053/sign-in
HTTPS domainhttps://dashboard.example.com/setuphttps://dashboard.example.com/sign-in

Enter the setup code and create the first Admin account. There is no default username or password. If the code expires before setup is completed, use ./configure.sh --setup-code to issue another code and follow its prompts.

After account creation, stop the setup launcher with Ctrl+C on the VPS, then start normal operation:

./dashboard.sh

Sign in using the newly created account. For an Admin on an HTTPS/domain installation, complete the required authenticator setup in Profile → Security before opening scan pages. Add the displayed account to an authenticator app and enter its current six-digit code. These codes are generated by the app; they are not emailed. Save recovery codes privately for use if the authenticator becomes unavailable.

The private loopback route also offers authenticator protection, but does not apply the same mandatory Admin onboarding rule. Create team accounts through Users & Roles, assigning the role and feature permissions each person needs.

5. Keep Hunt Web Running After SSH Logout

Once setup is complete and no Run or Hermes execution is active, stop the foreground launcher. From the same runtime user's SSH session, install and start the user service:

./dashboard.sh install-service
sudo loginctl enable-linger "$(id -u)"
./dashboard.sh start
./dashboard.sh status

The launcher installs and enables an instance-specific systemd user service. Lingering allows that user's services to run after logout and at boot. The systemd loginctl manual explains this behavior. Record the unit name reported by status; use that name when reading its journal.

For domain access, the HTTPS address remains accessible after the runtime user's SSH session closes. For private access, the service continues running, but each user's SSH forwarding connection must remain open or be reconnected. Starting the service does not automatically resume a paused scan.

6. Check Health and the First Login

Open Health and check the CLI, database, Hermes connection, and required tools. Then test a fresh browser session: sign in, complete MFA where required, open permitted menus, refresh a page, and log out and back in.

Figure 1. Server Health distinguishes available services from interactive Greybox Browser, which requires a Desktop installation. This screenshot is from an existing workspace.
Hunt Web Health on Server mode showing configured services and Greybox Browser unavailable

Server installs Chromium headless for scanner tools that need browser automation. Greybox Browser's visible login window remains unavailable in Server mode; installing headless Chromium does not provide a visible Browser window on the client computer. Blackbox, Greybox Environment, Hermes continuation, and PDF reports are available when their required components are configured.

A successful login confirms the access path. Health shows component readiness. To check the complete workflow, create a small authorized test Target, prepare its Scope, start a Run, and inspect the saved results and report.

7. Common Setup Issues

SymptomWhat to check
SSH forwarding reports an occupied portCheck the client computer for a local Dashboard or another tunnel using the same port. Match the saved origin rather than changing only the browser URL.
Setup or login fails through a domainCheck HTTPS, the exact saved origin, and forwarded host/scheme headers. Use the configured domain consistently.
An Admin can sign in but scan menus remain unavailableComplete authenticator onboarding through Profile → Security when prompted.
Dependency installation was interruptedCorrect the reported network, disk, or package issue, then rerun the original install command with the same user, paths, and options.
Greybox Browser says unavailable in Server modeThis is expected for interactive Browser. Use Greybox Environment here, or the Desktop installation for visible Browser login.
Service fails after logout or rebootCheck ./dashboard.sh status, the reported unit's journal, and user-service lingering.
Domain returns 502Check the Dashboard service, local upstream, and proxy/connector logs before changing access rules.

For Cloudflare Tunnel specifically, a 502 stating that it cannot reach the origin means the connector cannot reach the configured local service; it does not by itself show a WAF block. Cloudflare's troubleshooting guide explains how to distinguish these failures.

Keep SSH available for service inspection and recovery. On an HTTPS-bound installation, forwarding port 3053 to an HTTP localhost address is not a transparent replacement for domain login: the saved origin and secure cookies still apply. Plan an HTTPS recovery path that preserves that hostname and TLS.

Keep private backups of application data and deployment configuration, including proxy/TLS and any Tunnel settings. Use the packaged docs/operations.md for maintenance and backup procedures. Continue with Hunt Web's scanning workflow, or see the Linux Desktop installation guide for interactive Greybox Browser.