Skip to main content
Version: 4.1

3.6.0

The patch release that closes the Rust migration. 3.5.0 moved the two panels and the CLI onto their Rust twins route by route; this release finishes the batches that were in flight, fixes what porting them uncovered in the code they were ported from, and draws the line: what is still Go stays Go. New features and changes from here are written in Rust — in hitechcloud-rustpanel, hitechcloud-rustadmin or hitechcloud-rustcli — behind the same hand-over, which now lets a twin decline a request it matched.

Upgrading is hitechcloudcli update, as always; nothing to migrate in the database, the configuration or the templates.

Fixed​

These are bugs customers could hit, all of them found by comparing a Rust twin against the Go or shell it replaces:

  • The autoresponder list was always empty. The page and its API passed GetEmailList's raw * address ( used / limit ) lines to the autoresponder reader instead of the addresses, so every row failed validation and no autoresponder was ever listed, however many were configured.
  • The Web Application Firewall's decision log was wrong on every page it appears. Blocked-versus-detected came from a guess at the severity rather than from the firewall's own verdict, so a site in detect-only mode showed its ERROR entries to the customer as blocked traffic; the rule table was a placeholder; the action and rule-id filters, paging and ?output=json did nothing; and the warnings carried invented identifiers. The reader is now a faithful port of the Go one, with the counts taken over the same window.
  • Two firewall pages returned the error page. /server/waf/{domain} and /server/waf/log did not load the decision-table partial, so they could not render at all.
  • Numbers over a million printed in the wrong form wherever a template showed a float64 — an access log's timestamps, for one. Go writes 1.7580000005e+09; the twin wrote 1758000000.5.
  • Mail stopped at a reboot without anything saying so. hitechcloudcli native-mail check reads configuration, so a server whose dovecot.service was stopped and disabled passed every check while no mailbox could be opened and the panel's webmail sign-in hand-off fell back to the sign-in page on every attempt. The check now asks whether Dovecot is running, enabled and answering IMAPS; the mail component's install enables the unit (a package manager leaves it disabled on the RHEL family).
  • A new account got no FTP login, and deleting one left services behind. native/user.sh called ftp/add.sh, native/memcached.sh and native/varnish.sh — scripts that no longer exist — so the calls silently did nothing. user-delete also left /etc/sudoers.d/hitechcloud-jail-<account> behind.
  • A site verification TXT record was never written. native-dns add called a function that did not exist; bash printed command not found to stderr and carried on.
  • A new site ignored its owner's PHP Selector version and took the server default.
  • Two search engines on one host could be told they were on the same port. The installer read the REST port back with a sed that returned the empty string it had just written.
  • Certificate renewals from acme.sh's cron could skip the vhost re-render, because the scripts called the dispatcher by name and cron's PATH does not contain it.
  • The installer died on minimal RHEL-family images — no hostname binary, and the failure was an exit code with no message.
  • A password whose only special character is a space scored differently in the panel and in the CLI. Both rubrics are documented; unifying them is a product decision, not a porting one.
  • plan-create / plan-edit rejected the stored form 1 GB, and PATCH /api/plans/{id} without a name blanked the plan's name.
  • settings/modules?output=json and the IP blocker's JSON encoded an empty list where Go writes null.
  • Flash messages with non-ASCII text were dropped on a hand-over; they travel as base64 now.
  • WordPress hardening on nginx wrote rules the engine refused to load.

Changed​

  • Installing an application no longer forces one path. On every install page the location can be typed by hand — an absolute path is accepted as long as it stays inside the domain's document root, normalised and checked — or picked from the folders that already exist under it, one level at a time. The WordPress installer also rejects a subdirectory that escapes the document root, which the other seventeen already did.
  • A twin may now decline a request it matched (X-Hitech-Pass). Go registers whole families of API routes as one catch-all and dispatches on the suffix; a twin can take the route, serve the suffixes it implements and hand the rest back, so a customer's request is answered by whichever half implements it and an unknown suffix still gets Go's own 404.
  • Community's account limit now applies on the native stack. It lived in a script that a native install never reaches, so it had never been enforced there. A Community server already over three accounts will be refused the next one.

Moved to Rust since 3.5.0​

Nothing about these routes changed for the customer: same URLs, same templates, same JSON, proven page by page by a test that renders both engines and requires the same bytes.

  • User panel — the mail service pages (blocked senders, spam filter, greylisting, forwarders, mailbox disk usage), the Sieve filter editors and the autoresponder with their parser and writer, mailbox and alias management, the mailbox detail API, the Postfix mail-log reader and the spam quarantine; the database modules end to end (PostgreSQL, MSSQL and the rest of MySQL: every page, every session write and the REST API, plus the catch-all suffixes that are not downloads); the account sessions page, cron reads, Git Deployment JSON, resource reports and their CSV, FTP client configuration files, snapshots, the PHP JSON API, Composer and pm2 logs, WordPress's hardening list, the App Toolkit's hardening pages, the container status, the Website Builder's reads and its remove and detach, the DNS zones module, MongoDB, the firewall pages, /api/domains and /api/dns.
  • Admin panel — server SSH and its configuration, the cluster node, the databases page with its kill/limits/phpMyAdmin sign-on, resource history, applications, process and swap actions; the services logs, crash logs, update log, limits, FTP and monitored services; search; the SSL store, permission groups, the account export writes, the Overview switches, /user/new and /user/import; the emails relay, send limits, queue, report pages, mailbox list and rate limits; settings locales, mirror, Caddy, PHP versions, updates, modules and notifications; the WAF rule sets; the VirtualHost and front-end configuration editors; the resellers and malware pages.
  • CLI — native-mail, native-mailrelay, native-mailpolicy, native-mailautoconfig, native-webmail, native-multiweb, native-varnish, native-healthcheck, native-cache, native-search, native-dns, native-user, native-install, native-migrate, sentinel, the six database tools (native-mysql84, native-postgres, native-pgadmin, native-phpmyadmin, native-mongodb, native-mssql), native-usage, native-sslstore, native-firewall, native-meet, update --check. Every native/*.sh is now a hand-over wrapper, and no Rust command starts a shell to read a library any more.
  • Audit compliance — the hash-chained store's format is written down and its chain is ported, with tests that reproduce digests taken from the Go implementation and prove a tampered record is detected. The routes stay in Go for now.

What stays in Go, on purpose​

Passwords, sessions, two-factor, passkeys and token minting; the streams (install and clone progress, service journals, the web terminal); multipart uploads and file downloads; phpMyAdmin's sign-on ticket; the visitor list, whose order is undefined at the source; the compliance routes; the container-stack halves of the podman pages; and user/add.sh's container-era provisioning. Each is the server's own decision to keep, not a gap: where behaviour cannot be reproduced byte for byte, the Go half answers.

Operator notes​

  • version/3.6.0/UPDATE.sh refreshes the CLI tree, fetches any twin the release publishes, checks each answers routes, restarts both panels, probes :2083/healthz and :2087/login, and restores the previous binaries if a panel does not come up.
  • The twins remain required, and remain static musl binaries: they run on glibc 2.28 hosts (AlmaLinux 8) as well as current distributions.
  • A support matrix for this release was produced by installing it on 113 operating systems in CI; the results are in the repository's issues under os-certification.
Was this helpful?