Configuration Reference

Updated Oct 4, 2026 Markdown

Configuration File

Location: /etc/whost/agent.conf (YAML format)

File permissions: 600, owner root (readable only by root). The agent resets the mode to 600 at every start.


The installer writes a working configuration with sane defaults — most operators never need to edit it directly: most keys below are changed from the panel, which writes this file and applies the change to the service concerned. The sections below describe what each block controls so you know where to look when something does need adjustment.

How the file is written. The installer writes the first version with the blocks it needs. From then on the agent rewrites the whole file from the settings it holds in memory: at its first start, which adds every block below with its default values, and on every change saved from the panel. Comments, key order and formatting added by hand are not kept, and a key the agent does not know (a misspelled one included) is ignored without a warning and dropped at the next write. Broken YAML, or a value of the wrong type (text where a number or true/false is expected), stops the agent from starting; the reason is appended to /var/log/whost/agent.log.

Secrets. Passwords and secrets are stored in this file in plain text (the administrator password as a bcrypt hash). The agent moves them into an in-memory vault while it runs; on disk the file's 600 root mode is their only protection, so keep every copy and backup of the file equally restricted.

Settings kept elsewhere. Update preferences (/etc/whost/update_settings.json, see the last section), the notification channels and relay of Settings › Notifications (/etc/whost/notification_prefs.json), remote backup destinations (/etc/whost/remote_backup.json), API keys (/var/lib/whost/api_keys.json), plugin state (/etc/whost/plugins.json) and the server time zone (a system setting) are not in this file.

Reading the tables. Default is the value the agent uses when the key is missing; where the installer writes a different value, it is named. Changed from names the panel page. file — only by editing this file (see Applying Changes at the end). agent — written by the installer or the agent: do not edit it, a hand-written value breaks the service that uses it. — — the key has no effect in this release.


Section Details

server

Identity of the server, and the agent's own listener.

Key Default Changed from What it does
hostname installer: the host name (--hostname) Settings › General › Hostname The panel's host name (FQDN). A save from the panel also runs hostnamectl, rewrites /etc/hosts, sets mail.hostname, reloads Postfix and Dovecot and rewrites the panel's nginx vhost. Notification e-mails link to https://<hostname>, and it is the fallback origin of the password-reset link (see frontend.public_url).
server_ip installer: the server's primary IPv4 address Settings › General › Server IP Address The primary public IPv4 address: an account gets it unless another address is assigned, the account's DNS zone points at it, and the panel vhost answers on it. A save from the panel rewrites the DNS A records that carried the old address.
force_ssl true Settings › General › Force HTTPS Redirection Redirects the panel's HTTP requests to HTTPS; a request that a proxy or CDN forwards with X-Forwarded-Proto: https is served without the redirect. The save rewrites the panel vhost and reloads nginx.
host, port 0.0.0.0, 2000 (installer: 127.0.0.1, 2000) file They do not move the listener: the agent listens on 127.0.0.1:2000 as its service unit sets it (--host, --port; the unit also reserves ports below 2001 to root — net.ipv4.ip_unprivileged_port_start = 2001, kept in /etc/sysctl.d/60-whost-agent-port.conf — so no process of an account can listen on the agent's port, not even while the agent restarts; processes that do not run as root cannot listen on ports 1024–2000), and the panel's nginx proxy and the update pipeline use that address. port is still read by the firewall rule that keeps tenant processes away from the agent and by the port list Under-Attack mode never drops — keep it 2000.
ssl_cert, ssl_key /etc/whost/ssl/cert.pem, /etc/whost/ssl/key.pem — Not read; see the certificate note below.
workers 1 — Always 1: any other value is logged and replaced with 1.

Panel certificate. The pair /etc/whost/ssl/cert.pem and /etc/whost/ssl/key.pem is created self-signed for the host name at install. The same pair serves the panel's nginx vhost on port 443, Postfix and Dovecot TLS, the OpenLiteSpeed listener when LiteSpeed serves the sites, and the agent's loopback listener. To serve a trusted certificate, replace the two files (the certificate with its chain in cert.pem), check with nginx -t, then reload nginx, Postfix and Dovecot.

auth

HMAC-SHA256 authentication of API requests (machine-to-machine; the panels use session cookies).

Key Default Changed from What it does
api_key, api_secret generated by the installer agent The API key pair the installer generated (also saved in /etc/whost/api_key and /etc/whost/api_secret). At its first start the agent copies it into the API key list as Default API Key (Settings › API Access), where it is managed like any other key; revoke or delete it there to retire it. A deleted installer key stays retired: it does not answer through this copy and is not copied back at the next start. A pair a later installer run writes answers until it is managed the same way.
allowed_ips [] file Copied onto that key's IP allowlist when the agent adds the key to the list; afterwards the allowlist is edited in Settings › API Access, and this list no longer applies to the key.
api_key_encryption_secret generated at first start agent Encrypts the stored API key secrets and the credentials of remote backup destinations. Never change or remove it: the stored secrets could no longer be decrypted.

webserver

Which web server stack serves the sites, and its global connection tuning. type takes one of:

  • nginx: Nginx handles all HTTP traffic directly
  • apache: Apache handles all HTTP traffic directly
  • nginx_apache: Nginx as reverse proxy (port 80/443) + Apache backend (apache_port, 8080)
  • openlitespeed, litespeed: OpenLiteSpeed or LiteSpeed Enterprise, set when the matching plugin is activated on the Plugins page; PHP then runs through LSAPI

The installer writes nginx_apache or nginx; it refuses the other values (see Installation).

Key Default Changed from What it does
type nginx_apache (installer: --webserver) Settings › General › Default Web Server (nginx, nginx_apache; apache is offered and accepted only on a server installed with Apache alone) The stack the agent writes every site configuration, certificate renewal hook and WAF setup for. The General save changes only this value — it does not install, start or reconfigure a web server — so change it only after the server's stack has been changed to match. With OpenLiteSpeed or LiteSpeed the field is read-only (the plugin owns it). At start the agent logs WEBSERVER_BINDING_DRIFT when the process listening on port 443 does not match.
max_clients, keepalive_timeout 256, 65 Settings › General › Max Clients (1–10000), Keep-Alive Timeout (0–300 s) Written to the web server when saved from the panel: Nginx worker_connections and keepalive_timeout in nginx.conf (only where those lines exist; nginx -t, then reload), Apache KeepAliveTimeout only (apachectl configtest, then reload), OpenLiteSpeed/LiteSpeed maxConnections and keepAliveTimeout (the server restarts). A failed test restores the previous file. The page shows the configured values, not the running server's.
apache_port 8080 file The Apache port nginx proxies to in nginx_apache site configurations. Apache's own Listen port is set by the installer and does not follow this key.
php_handler fpm agent fpm (PHP-FPM pools) or lsapi; set to lsapi whenever type is OpenLiteSpeed or LiteSpeed.
ols_admin_port, ols_admin_user, ols_admin_password 7080, admin, empty agent The OpenLiteSpeed/LiteSpeed WebAdmin console. The LiteSpeed Enterprise plugin generates the password when it installs the server (a value already here is reused on a reinstall); read it here when you need the console.
lscache_enabled true file Adds LSCache to OpenLiteSpeed/LiteSpeed site configurations.
litespeed_serial — agent The LiteSpeed Enterprise serial the plugin was activated with.
nginx_port 80 — Not read.

php

Multiple PHP versions can be installed simultaneously, and each hosting account can use a different one.

Key Default Changed from What it does
default_version 8.4 (installer: --php-default) Settings › General › Default PHP Version; PHP › Default PHP Settings PHP version of new accounts; must be one of installed_versions.
installed_versions 7.4, 8.0–8.5 (installer: the versions it installed, --php-versions) PHP page, version switches Versions offered to accounts. A version can be switched on only when its packages are installed; the default version and a version a domain still uses cannot be switched off.
default_upload_max_filesize, default_post_max_size 64M PHP › Default PHP Settings A size with an optional K/M/G; -1 is refused.
default_memory_limit 256M PHP › Default PHP Settings A size, or -1 for unlimited.
default_max_execution_time 300 PHP › Default PHP Settings Seconds, 0–86400.
default_max_input_time 300 PHP › Default PHP Settings Seconds, -1–86400.
default_max_input_vars 1000 PHP › Default PHP Settings 1–1000000.
default_display_errors false PHP › Default PHP Settings true or false.

The seven default_* values are the ini values an account's pool is rendered with until the account saves its own; an account's saved values live in its metadata and survive a version, worker or plan change. Changing a default does not rewrite existing pools: an account without values of its own gets the new default the next time its pool is rendered.

python

Python application hosting (the Python Hosting plugin). The plugin's on/off state is client_features.python_apps, not a key of this block.

Key Default Changed from What it does
installed_versions 3.10, 3.11, 3.12, 3.13 file Python versions offered to apps; only those whose interpreter is installed on the server are listed.
default_timeout, default_max_requests 120, 1000 file Gunicorn timeout and max_requests of an app that has not set its own.
allowed_manage_commands migrate, collectstatic, createsuperuser, showmigrations, check, shell file The Django manage.py commands the panel may run for an app; any other command is refused.
socket_dir, venv_base_dir /run/whost, venvs agent Where app sockets and (under the account's home) virtual environments are created.
enabled, default_version, default_app_server, default_workers, default_worker_class, max_workers_per_app — — Not read.

node

Node.js application hosting (the Node.js Hosting plugin). The plugin's on/off state is client_features.node_apps, not a key of this block.

Key Default Changed from What it does
installed_versions 18, 20, 22 file Node.js versions offered to apps; only those whose runtime is installed on the server are listed.
allowed_npm_scripts start, build, test, lint, migrate, seed file The npm run scripts the panel may run for an app; any other script is refused.
socket_dir, wrappers_dir /run/whost, /etc/whost/wrappers agent Where app sockets and the per-app start wrappers are created.
enabled, default_version, default_app_type, default_package_manager, default_instances, max_instances_per_app, default_max_memory_mb, runtime_base_dir — — Not read.

mysql

The agent's MariaDB connection and the MariaDB tuning it applies for you.

Key Default Changed from What it does
host, port localhost, 3306 agent The agent's MariaDB connection.
root_password set by the installer agent MariaDB root password (also in /etc/whost/mysql_root_password).
max_connections 151 Settings › General (1–10000) max_connections.
buffer_pool_size 256 (MB) Settings › General (16–65536) innodb_buffer_pool_size.
connect_timeout, wait_timeout, interactive_timeout 300 (seconds) Settings › General (1–86400) The MariaDB variables of the same name.
sort_buffer_size, read_buffer_size, max_allowed_packet 4M, 4M, 64M Settings › General A non-zero K/M/G size (4M, 256K, 1G).

A save from Settings › General that changes a database value rewrites the drop-in /etc/mysql/mariadb.conf.d/99-whost-tuning.cnf (/etc/my.cnf.d/ on RHEL) from the agent's template with all eight values and applies each one live with SET GLOBAL, so no restart follows. The drop-in also carries local_infile = 0 and secure_file_priv = /var/lib/mysql-files, which MariaDB reads at its next restart. The installer writes its own version of this file, sized to the server's RAM (InnoDB buffer pool 37.5% of RAM, at least 256 MB; max_connections = 300; InnoDB log and flush settings); the first database save from the panel replaces it with the eight values the page shows. Editing these keys in this file does not change MariaDB.

dns

PowerDNS integration via its HTTP API.

Key Default Changed from What it does
enabled true (installer: false with --no-dns) file Whether PowerDNS is installed. While false, accounts are created without a DNS zone, and an account's address change or a nameserver change is not pushed to zones.
nameservers ns1.example.com, ns2.example.com (installer: --nameservers, default ns1.<hostname>, ns2.<hostname>) Settings › General › Nameservers (up to four, filled in order) NS records of every zone the agent creates; the first entry is the SOA primary. A save from the panel also rewrites the NS records and SOA primary of every existing zone; a hand edit reaches only zones created after the restart. Set them to your real nameserver host names, as the delegation at the registrar names them.
api_url, api_key http://127.0.0.1:8081, set by the installer agent The PowerDNS HTTP API and its key (also in /etc/whost/pdns_api_key).
default_ttl 3600 file TTL of the records the agent creates.
soa_content ns1.example.com hostmaster.example.com 0 10800 3600 604800 3600 file Only its last four numbers — refresh, retry, expire and negative-cache TTL — are used; the SOA primary is the first nameserver and the contact is hostmaster.<zone>.
type powerdns — Not read; PowerDNS is the only DNS server.

mail

Postfix (SMTP) + Dovecot (IMAP/POP3) + OpenDKIM. The mail system uses a MariaDB database for virtual mailbox management.

Key Default Changed from What it does
enabled true (installer: false with --no-mail) file Whether the mail stack is installed. While false the agent does not install or refresh the WHost Mail Policy service (whost-policyd) that applies the hourly sending limits.
hostname mail.example.com (installer: --mail-hostname, default mail.<hostname>) file The mail host name recorded at install; a host-name change in Settings › General replaces it with the new server host name.
default_hourly_limit 500 Settings › General › Default Hourly Email Limit (0–100000) Messages an account may send per hour when its plan sets no limit of its own; 0 = unlimited. A save from the panel re-renders and restarts whost-policyd; a hand edit reaches it at the next agent start.
max_email_size 25 (MB) Settings › General › Maximum Email Size (1–100 MB) Written to Postfix message_size_limit when saved from the panel (Postfix reloads); a hand edit does not change Postfix.
dkim_selector, dkim_key_dir default, /etc/opendkim/keys agent Selector and key directory of the DKIM keys the agent creates (<selector>._domainkey.<domain> records).
maildir_base, vmail_uid, vmail_gid /var/vmail, 5000, 5000 agent Mailbox storage and its owner, as installed.
mysql_host, mysql_port, mysql_user, mysql_password, mysql_database localhost, 3306, vmail, set by the installer, vmail agent The virtual-mailbox database (password also in /etc/whost/mail_db_password).
dovecot_master_user, dovecot_master_password whost_master, set with webmail agent The Dovecot master login used for webmail single sign-on.

ssl

Let's Encrypt integration via certbot. Orders validate over HTTP from the domain's own document root, are named after the domain and install a renewal hook that refreshes the files the vhost points at and reloads the web server; renewals run on certbot's own schedule (its systemd timer, or the daily cron line the installer adds where there is no timer). Deleting a certificate removes the lineage.

Key Default Changed from What it does
email empty (installer: --ssl-email) Settings › General › Let's Encrypt Email Account e-mail of the orders, required: an order is refused with 400 SSL_EMAIL_REQUIRED while it is empty.
staging false file true sends orders to the Let's Encrypt staging environment, whose certificates browsers do not trust — for testing without hitting rate limits. Restart the agent after changing it.
auto_renew true Settings › General › Auto-SSL for New Domains Stored only in this release: the account and addon-domain forms carry their own Auto-SSL choice.
provider, webroot_path, renew_days_before certbot, /var/www/letsencrypt, 30 — Not read.

ftp

Pure-FTPd with MariaDB authentication. Each hosting account can have multiple FTP sub-accounts.

Key Default Changed from What it does
enabled true (installer: false with --no-ftp) file Whether Pure-FTPd is installed.
passive_ports 30000:30100 Settings › General › Passive Port Range START:END, 1024–65535, START lower than END. Written to Pure-FTPd's PassivePortRange when saved from the panel. The installer opens 30000:30100 in the firewall; open a new range on the Firewall page as a START:END port rule.
max_clients 50 Settings › General › Max Clients (1–1000) MaxClientsNumber.
max_per_ip 10 Settings › General › Max Connections per IP (1–100) MaxClientsPerIP.
passive_mode, bandwidth_limit true, 0 (KB/s) API only (the form does not show them) Stored only: the save keeps and echoes them, but no Pure-FTPd directive is written for them.
mysql_host, mysql_port, mysql_user, mysql_password, mysql_database localhost, 3306, pureftpd, set by the installer, pureftpd agent The Pure-FTPd authentication database (password also in /etc/whost/ftp_db_password).

A save that changes passive_ports, max_clients or max_per_ip writes the three directives (/etc/pure-ftpd/conf/ on Debian/Ubuntu, /etc/pure-ftpd/pure-ftpd.conf on RHEL) and restarts Pure-FTPd; a hand edit does not change Pure-FTPd.

backup

Local backup storage and its retention.

Key Default Changed from What it does
enabled true Backups › Settings › Backup System While false, creating, restoring and scheduling backups is refused (403 BACKUP_DISABLED) and scheduled runs are skipped.
local_path /var/whost/backups file Where local archives are kept, one directory per account.
retention_days 7 (installer: 30) Backups › Settings › Retention Days (1–365) Once a day, on the scheduler's first run at or after 04:00 UTC, every account backup older than this is deleted; 0 in this file turns pruning off.
schedule.enabled true Backups › Settings › Schedule System Starts the built-in scheduler, which runs the backup schedules and the retention pruning.
schedule.max_per_account 3 Backups › Settings › Max Schedules per Account (1–20) A schedule beyond this is refused (403 BACKUP_SCHEDULE_LIMIT).
schedule.check_interval 300 (seconds) file Time between scheduler runs.
remote enabled: false, type: s3 — Parsed but not used; see below.

The scheduler starts with the agent only while both enabled and schedule.enabled are true, and schedule.check_interval is read at that moment: a change of schedule.enabled — also when saved from the panel — takes effect at the next agent start, and so does switching enabled back on when it was off at start. While the scheduler is not running, neither scheduled backups nor retention pruning run.

Remote destinations are not configured in this file: they are managed from the panel (Backups › Remote Storage) and stored encrypted in /etc/whost/remote_backup.json (per-account ones under /etc/whost/accounts/<user>/remote_backup.json).

logging

Key Default Changed from What it does
level info file debug, info, warning, error or critical (an unknown name means info). In production, info is recommended; use debug only for troubleshooting.
file /var/log/whost/agent.log file Keep the default: the service unit appends the process output to this path, the fail2ban whost-agent jail watches it and the post-update check writes to it. The file is kept at mode 640.
max_size, keep 100M, 10 file The agent rotates the file itself when it reaches max_size (a number with an optional K, M or G; any other suffix stops the agent from starting) and keeps keep old copies. No logrotate rule covers it.

license

license.state_file selects the persistent license state file; its default is /etc/whost/license.state. The companion HMAC file appends .hmac to that path. State loading, saving, and independent endpoint, service, startup and runtime checks use the selected file. An old state file at the default location does not substitute for a missing file at the configured location.

Keep both files owned by root with mode 0600. Startup normalizes their modes to 0600. Restart the agent after changing the setting; avoid repeated restarts, which consume license verification limits. The installation's boot token stays at /etc/whost/.boot_token; prior activation evidence in either the selected or default state file prevents silent regeneration of a missing or malformed token.

License grace and cached-token validity use the license server's verified UTC time advanced by elapsed kernel boot time. Moving the system clock backward does not add grace time. The state HMAC also protects the clock anchor, allowing an agent restart within the same operating-system boot to preserve elapsed time. After an operating-system reboot, or when upgrading a cache without this anchor, the agent requires online license verification before cached grace can be used. Keep NTP enabled: TLS certificate validation and other system services still depend on the system clock.

Cached activation and grace require the original RSA-signed license assertion and its expiry. A valid local HMAC alone does not authorize cached access. Missing signature fields, a missing signed expiry, modified assertions, and expired tokens discard the cache and require online verification. Activation and periodic verification both persist the signed assertion. Do not edit or remove token fields when restoring a state file.

The other keys of this block are maintained by the agent — do not edit them. key and the license secrets are written when the license is activated on the License page; a hand-edited key that differs from the activated one is replaced with the activated key at the next start.

rate_limit

API rate limiting per client address (the visitor's address as the agent resolves it behind the panel's nginx), using slowapi. A request over its limit is answered 429 RATE_LIMIT with a Retry-After header. Values follow the format {count}/{period} (e.g., 120/minute, 5/minute).

YAML
rate_limit:
  default: "60/minute"
  read: "120/minute"
  write: "30/minute"
  delete: "20/minute"
  heavy: "5/minute"
  auth: "5/minute"

All six values are read from this file at agent start and applied.

defaultApplied by the limiter middleware to the few routes that carry no class of their own (deploy event streams, the update status stream, the SSO endpoints, the frontend debug beacon). /health, the panel's root files (/config.json, favicon, logo), / and the page fallback are exempt
readLimit for GET (read) endpoints, including the public GET /api/v1/auth/ip-check allowlist probe used by the login page
writeLimit for POST, PUT, PATCH (write) endpoints
deleteLimit for DELETE endpoints
heavyLimit for resource-intensive operations: backups and restores, file upload, compress and extract, Let's Encrypt orders, plugin installs, license activation, password and second-factor changes, password-reset requests
authLimit for authentication endpoints (admin and client login, 2FA)

fail2ban

Key Default Changed from What it does
enabled true — Not read: the panel manages fail2ban whenever fail2ban-client answers.
bantime, findtime, maxretry 3600, 600, 5 — Not read: the installer writes jail.local with its own values, and per-jail changes on the Fail2Ban page go to /etc/fail2ban/jail.d/<jail>.local.
ignoreip 127.0.0.1/8, ::1 file Shown as the whitelist only when no jail answers; the live whitelist is the jails' ignoreip set, edited on the Fail2Ban page and persisted in jail.local.

modsecurity

WHost enforces ModSecurity at the nginx tier (nginx and nginx_apache); with another web server the settings are saved but not applied to traffic. /etc/modsecurity/modsecurity.conf is rendered from this block when the WAF page changes a setting or a rule — after a web-server configuration test — so a hand edit reaches it only at the next such change.

Key Default Changed from What it does
enabled, default_account_waf true, true file An account that has not chosen its own WAF state gets modsecurity on in its site configuration only while both are true (picked up when the configuration is next rendered). enabled: false also makes the WAF page report the WAF as inactive.
engine_mode detection_only WAF page on (block), detection_only (log only) or off; rendered as SecRuleEngine. A new installation starts in detection_only; an existing one keeps the mode it has.
crs_paranoia_level 1 WAF page OWASP CRS paranoia level, 1–4.
audit_log true WAF page SecAuditEngine RelevantOnly (5xx and 4xx responses except 404) or Off.
audit_log_path /var/log/modsecurity/audit.log file The serial audit log the WAF page reads; the installer's logrotate rule (daily, 30 kept, copytruncate) names the default path.
owasp_crs true file Loads the OWASP Core Rule Set from <rules_path>/crs.
rules_path, custom_rules_path /etc/modsecurity, /etc/modsecurity/custom file The rule set's base directory, and the custom rules directory (included only while it holds a .conf).
per_account_overrides true file Per-account WAF state and rule exclusions under /etc/modsecurity/accounts/; while false the account-scope WAF writes answer 409 FEATURE_DISABLED.

security

Key Default Changed from What it does
admin_allowed_ips empty Settings › Security › Admin Panel IP Whitelist IP/CIDR entries, one per line (a YAML block string); empty allows every address. nginx answers 404 for the /admin pages from any other address, and the agent refuses admin sign-in and admin sessions from it (403 IP_NOT_ALLOWED). A save from the panel rewrites /etc/nginx/conf.d/whost-admin-geo.conf and /etc/nginx/snippets/whost-admin-ip-whitelist.conf (after nginx -t), and a changed non-empty list signs out every admin and client session; a list that leaves out your own address is refused unless you confirm it. A hand edit changes only the agent's check.
two_factor_enforcement, two_factor_enforcement_method false, both Settings › Security › Two-Factor Authentication Enforcement The switch and the method it demands (totp, email, or both = either). While it is on, the login and session endpoints answer requires_2fa_setup: true (with required_2fa_method) for an identity that has no second factor yet, and the panels keep that identity on its enrolment page (admin Settings › Profile, client Settings › Security) until it enrols.
ssh_port, ssh_root_login, ssh_password_auth, ssh_key_auth, ssh_allowed_ips 22, true, true, true, empty Settings › Security › SSH Access Restrictions Written to /etc/ssh/sshd_config.d/00-whost.conf when saved from the panel (after sshd -t; a port change restarts sshd and updates the firewall and fail2ban, other changes reload it). At least one of password and key authentication stays on, and a port another service holds is refused (PORT_IN_USE). ssh_allowed_ips (one IP/CIDR per line) denies SSH logins from every other address. ssh_port is also the SSH port the firewall and Under-Attack mode protect. A hand edit does not change sshd.
auto_configure_dkim, auto_configure_spf, auto_configure_dmarc, dmarc_policy true, true, true, none Settings › Security › DKIM / SPF / DMARC Which mail records the agent adds when it creates an account's mail DNS: the DKIM key record, SPF (v=spf1 a mx ip4:<server_ip> ~all) and DMARC (v=DMARC1; p=<policy>; rua=mailto:postmaster@<domain>, policy none, quarantine or reject). Existing zones are not rewritten.
trusted_origins empty file Extra origins allowed to send cookie-authenticated writes (POST, PUT, PATCH, DELETE) whose Origin differs from the host they are sent to, whitespace separated as host[:port]. The panel calling its own API under whatever name it was opened always passes, and HMAC-signed calls are not checked; any other cross-origin write that carries a panel session cookie is refused with 403 CROSS_ORIGIN_DENIED.
spam_reject_threshold, spam_add_header_threshold, spam_greylist_threshold 15, 6, 4 — Not read: the spam scores are set on the Spam Filter page.

admin

The built-in administrator, the sign-in protection of both panels and the session lifetimes.

Key Default Changed from What it does
enabled true file While false, cookie sign-in is off for both panels: the admin sign-in answers 404, admin and client session cookies are no longer accepted, and only HMAC-signed API calls are served.
username admin file The administrator signs in with this name or with email.
email empty Settings › Profile Recovery address and second sign-in name of the administrator; admin notification e-mails and e-mail sign-in codes are sent to it.
password set by the installer Settings › Profile (password change) A bcrypt hash; a plain-text value is never accepted at sign-in. A change signs out every other admin and client session.
language auto Settings › Profile The administrator's panel language (auto keeps the language chosen at sign-in).
session_timeout 3600 (seconds; installer: 3600) Settings › Security › Session Timeout (5–1440 minutes) Lifetime of an admin or client session; a session in use is renewed once half of it has passed.
remember_me_timeout 2592000 (30 days) file Lifetime of a "remember me" session, in both panels.
session_max_lifetime 604800 (7 days) file Hard limit counted from sign-in, whatever the activity, in both panels.
allow_concurrent_sessions false file Off: a sign-in ends the earlier sessions of the same identity (the administrator, or that client account) and a sign-out ends them all. On: earlier sessions keep working until they time out, a sign-out ends only the browser it is made in, and session_max_lifetime counts from the identity's latest sign-in or sign-out; a password change still signs everyone out.
session_secret set by the installer agent Signs admin and client session cookies. The agent replaces it when the admin password changes and when the admin IP whitelist is changed to a non-empty list; any change signs everyone out.
two_factor.enabled, two_factor.method false, totp Settings › Profile The administrator's own second factor (totp or email).
two_factor.email empty Settings › Profile Where the administrator's e-mail sign-in codes go; it follows email unless set to another address here.
two_factor.trusted_ip_days 0 file How long an address that passed the administrator's second factor skips it: 0 = with no expiry while sign-ins come from that address, -1 = the code is always asked, N = N days.
two_factor.smtp_host, two_factor.smtp_port, two_factor.smtp_user, two_factor.smtp_password, two_factor.smtp_tls localhost, 587, empty, empty, true file The relay of the sign-in code e-mails of both panels and of the client password-reset e-mail — not the relay of Settings › Notifications. With the defaults the local Postfix is used on port 25. In this release these messages are sent without SMTP authentication even when smtp_user and smtp_password are set, so smtp_host must name a relay that accepts this server without a login.
recaptcha.enabled, recaptcha.provider, recaptcha.min_score false, recaptcha, 0.5 Settings › Security › CAPTCHA Protection Sign-in captcha of both panels; provider recaptcha, hcaptcha or turnstile; min_score (0.0–1.0) is the reCAPTCHA v3 threshold. Switching it on requires the selected provider's site key and secret key. The public GET /api/v1/auth/captcha-config publishes only the enabled flag, the provider and its site key.
recaptcha.<provider>_site_key, recaptcha.<provider>_secret_key empty Settings › Security › CAPTCHA Protection The key pair of each provider; the page shows secret keys masked.
notification_smtp_password empty Settings › Notifications Password of the notification relay. The rest of that SMTP block (host, port, user name, encryption and sender) is stored in /etc/whost/notification_prefs.json; only the password is kept here. Notification e-mails use that block, then fall back to the two_factor.smtp_* keys, then to the local relay.
two_factor.totp_secret, backup_codes, pending_*, totp_last_step, avatar_url, last_login — agent Maintained by the Profile page and the sign-in flow (the TOTP secret, hashed backup codes, an enrolment in progress, the avatar).

frontend

Static panel bundle served by nginx.

Key Default Changed from What it does
public_url empty file The address the panel is reached at from outside (https://panel.example.com): the origin of the password-reset link the panel mails. When it is empty the link uses https://<server.hostname>, and only without a host name the bare https://<server_ip> — a name matches the certificate the panel serves, an address does not. Notification e-mails link to https://<server.hostname> whatever this key says.
default_language auto Settings › General › Language Settings auto or one of the panel's locale codes: the language of a browser that has not chosen one. Written to the panel's config.json when saved and at every agent start.
debug_log false file Opens the browser debug beacon route (POST /api/v1/debug-log); its file /var/log/whost/frontend-debug.log is rotated daily by the installer's /etc/logrotate.d/whost (seven copies kept).
enabled, path true, /opt/whost/frontend/out agent The agent's copy of the panel files; nginx serves /var/www/whost/panel, which the installer copies from it.

client_features

Eleven switches (file_manager, dns, backups, cron, ssl, php, email, ftp, databases, python_apps, node_apps), all true by default, edited from Settings › General. A switch that is off is enforced at the API for every client route of that surface (409 FEATURE_DISABLED, keyed on the request path — /client/emails and /client/spam for email, /client/files for file_manager, the per-domain /client/domains/{domain}/php/* routes for php); the client profile carries the switches as features, and the client panel hides the sidebar entry and the dashboard tiles of a surface that is off. A switch that is off does not stop the backup scheduler: backups off refuses the client's backup routes only, and the account's existing schedules keep running.

python_apps and node_apps are also the on/off state of the Python Hosting and Node.js Hosting plugins: activating or deactivating the plugin on the Plugins page sets them (deactivation is refused while apps are deployed), and while one is off every Python or Node.js app route — the administrator's included — answers 503 PLUGIN_DISABLED.

whitelabel

enabled, company_name, four logo addresses (logo_light, logo_dark, favicon, favicon_dark), the sign-in page video and its cover for each panel (login_video_admin, login_poster_admin, login_video_client, login_poster_client; empty = the default video), six HSL colours (primary_color, secondary_color, nav_color and their _dark twins, "H S% L%" with H 0–360 and S, L 0–100) and hide_login_branding (default true). Edited on the Whitelabel page (account menu at the top right); every change writes a settings_updated audit row and rewrites config.json in the panel trees. While the whitelabel license addon is not active, the page's saves, logo and login video uploads and removals and reset are refused with 403 LICENSE_ADDON_REQUIRED; the values already in this block stay, and the public branding read answers active: false until the addon is active. A licence check that grants or withdraws the addon rewrites config.json at once, so the panel follows without a restart. A hand edit is published at the next agent start while the addon is active.

A logo field holds the address of a file the agent stores under /var/lib/whost/branding/ — /branding/<field>.<digest>.<png|jpg|webp|svg>, served by the panel's nginx (location ^~ /branding/ in /etc/nginx/snippets/whost-panel-locations.conf) with a one-year immutable cache and a sandboxing content policy; the name changes with the content, and a replaced or removed logo's file is deleted. Only such an address (or an inline data:image/ URL, see below) is published; any other hand-written value stays private. Uploads (2 MB per file) are shaped before they are stored: a raster logo to fit 512 × 160 px (width × height), a favicon to a square PNG of at most 256 px with transparent padding; an image above 25 megapixels is refused (400 IMAGE_DIMENSIONS_TOO_LARGE), a file that does not decode as its type too (400 INVALID_IMAGE); SVG is sanitised and kept. A sign-in video field holds /branding/login_video_<admin|client>.<digest>.mp4 — an MP4 whose video track is H.264, at most 5 MB, stored as uploaded (the panel compresses a larger video in the browser before it uploads it) — and its cover /branding/login_poster_<admin|client>.<digest>.<jpg|png|webp>, scaled to fit 1920 × 1080 (1080 × 1920 upright); each publishes only a file written for that field. Logos an earlier release stored inline as data: URLs move to files at the first agent start that finds the panel nginx serving /branding/: the original values are copied first to /var/lib/whost/branding-legacy-<timestamp>.yaml (mode 0600), the logos are shaped as uploads are, and the block is saved once; a value that does not decode stays as it was. Include /var/lib/whost/branding/ in host backups.

update preferences (not an agent.conf block)

agent.conf carries no update: block; an update: block left by an older install is not read by any code and is dropped the next time the agent writes the file. The update preferences live in /etc/whost/update_settings.json (root, 0600): channel (stable | beta), auto_update, auto_update_type (all | security | patch | minor), backup_before_update, notify_available, notify_installed, os_packages_check_enabled, os_packages_notify_security, allow_vendor_critical_override. auto_update_type decides what installs on its own: security only releases the vendor flags as critical (and only while allow_vendor_critical_override is on), patch a patch step, minor a minor or patch step, all every release; a vendor-flagged critical release also installs under the other types while allow_vendor_critical_override is on. The installer writes the file once on a new server with the channel of the release it installs (beta for a -beta.N release, stable otherwise) and leaves an existing file alone; afterwards the file is written by the Updates page (Settings tab, PUT /system/update/settings) and read by the install pipeline and the scheduler; an absent file means the defaults (auto-update of vendor-flagged critical releases on), a file that cannot be parsed is logged and treated as auto_update: false until it is repaired. The check cadence is fixed: five minutes after every agent start, then every 24 hours (up to 30 minutes of jitter).


Environment Variables

The agent reads its settings from this YAML file only; no key of this file can be set through an environment variable. The service unit (/etc/systemd/system/whost-agent.service) sets the environment the agent runs with — among it WHOST_CONFIG_PATH=/etc/whost/agent.conf, the path of this file — together with hardening switches. Keep the unit as installed: the installer and the agent's start-up permission check work on /etc/whost/agent.conf.


Applying Changes

Settings saved from the panel take effect at once: the agent writes this file itself and applies the change to the service concerned, as the tables describe. To change a key the panel does not offer (file in the tables):

  1. Keep a copy, for example cp -p /etc/whost/agent.conf /root/agent.conf.bak — it holds the same secrets, so keep it at mode 600.
  2. Edit the file, then restart the agent before saving anything in the panel; until the restart, the next panel save writes the agent's in-memory settings back over the edit.
  3. Check that the agent came back: curl -sk https://127.0.0.1:2000/health answers {"status":"ok",...} once the start has finished (a few seconds). If it does not, read the end of /var/log/whost/agent.log.
shell
systemctl restart whost-agent
curl -sk https://127.0.0.1:2000/health

A hand edit changes what the agent reads; it does not rewrite the service configurations a panel save writes (web server tuning, MariaDB, Pure-FTPd, the Postfix message size, sshd, the nginx admin whitelist, DNS zones, the panel vhost). Change those keys from the panel. Every agent start verifies the license with the license server; avoid repeated restarts.


Developed by WISECP LLC. Contact: [email protected]

Still Need Help?

Our support team is here around the clock for anything you can't find above.