Skip to main content
Version: 4.1

Third-party artifacts

A server a customer runs downloads things it did not build: firewalls, PHP tooling, a webmail client, container-orchestration binaries, TLS clients, distribution packages. Every one of those downloads is a dependency on somebody else staying online, staying honest and not changing the bytes behind a URL. This page is the inventory of that surface: what moved onto our own mirror with a version and a checksum we compute ourselves, and what still calls out to a third party on purpose, with the reason and what it would take to change that later.

The mechanism, in hitechcloudcli: hitechadmin/config/vendor.json (hitechcloud-configuration) pins each artifact's version, file name, upstream URL and a SHA-256 computed by downloading the file and hashing it. native/vendor.rs's native_vendor::fetch tries mirrors.hitechcloud.org/vendor/<name>/<file> first, the manifest's url second, and checks the SHA-256 against whichever source answered — every time a server fetches the artifact, not once when it was pinned. Nothing resolves "latest" at install time: picking up a newer release means a person editing the manifest, computing a new hash, and committing both. Shell scripts that still need this call the same logic through hitechcloudcli vendor fetch <name> <dest>.

Moved onto the mirror​

ArtifactWasNow pinned to
MailFlow webmailgit clone of the main branch of a personal GitHub account (maathimself/mailflow) — no version, no checksum, the worst case of the lot3.5.6 (a real tag)
ConfigServer Firewall (csf)a tarball fetched from a mirror/fallback chain with no checksum at all15.10
Composergetcomposer.org/composer-stable.phar — a floating "stable" alias2.10.3
WP-CLIthe gh-pages branch's HEAD phar on mirrors.hitechcloud.org2.12.0
Docker Compose (amd64, arm64)resolved via mirrors.hitechcloud.org/api/repos/docker/compose/releases/latest at every run5.5.1
Traefik (amd64, arm64)releases/latest, or a hardcoded v3.1.4 when that lookup failed3.7.13
acme.shget.acme.sh, whose --install-online mode re-fetches the current default branch during install3.1.6
restic (amd64)releases/latest, checked against a SHA256SUMS fetched live from the same release0.19.1
rclone (amd64)curl https://rclone.org/install.sh | bash — a third party's script piped straight into a root shell1.75.1
ionCube Loader (amd64, arm64)downloads.ioncube.com, which carries no version in its URL or filename at alla dated snapshot, pinned 2026-09-24 (loader version 15.5.1 read out of the archive)

Every checksum above was computed here — the artifact was downloaded and hashed, not copied from a page. Where the publisher also ships its own checksum (Docker Compose's .sha256 files, Traefik's checksums.txt, WP-CLI's .sha256, restic's and rclone's SHA256SUMS), the hash computed here matched it on the first try; that is a cross-check, not the source of truth recorded in the manifest.

ionCube is the one entry without a real version to pin: the vendor's own download URL and the archive's filename never change, so there is nothing to pin but the bytes. Re-pinning it later means downloading it again, hashing it again, and recording that day's date — the manifest cannot tell on its own whether a fresh download of that URL is the loader it already has or a new one.

tinyphotogallery, Roundcube and phpMyAdmin are the same mechanism, pinned in a companion change; they are not covered here.

Public IP self-answered instead of asked of a stranger​

Eight call sites asked ip.hitechcloud.org (ours) for the server's public IP and, when that failed, fell back to ifconfig.me — a stranger's echo service, for a question a server with a directly assigned public IP (the normal case here — no NAT) can answer about itself. In seven of the eight, a local fallback (hostname -I, or reading the global-scope address off ip addr) already existed one tier further down for exactly this reason; ifconfig.me was removed from the chain, moving straight from our own service to the self-answer:

sentinel.rs, user/login.rs, domains/add.rs, user/backup.rs, user/transfer.rs, user/restore.rs, server/migrate.rs.

The eighth, license.rs, was left alone on purpose. Its public_ip() feeds /api/license/verify — licence validation needs the address the outside world actually sees this server at, which a NAT'd or multi-homed box's local interface address will not always match. Swapping in a local answer there risks a licence that only functions on directly-addressed servers by accident and breaks quietly on the ones that are not. A second, independent external opinion is worth keeping for that one call; if ifconfig.me itself is a concern there, the fix is a second endpoint we operate, not a local answer.

Stays remote: package repositories and their GPG keys​

Mirroring a curl | bash repo-bootstrap script or a signing key is not the same job as mirroring a tarball: the repo it configures still has to be reachable afterwards for every future apt/dnf update, so half-mirroring it (catching the bootstrap script but not the repository it points at) removes none of the dependency and adds a second, subtly different copy of the same trust chain to keep in sync. Properly mirroring an apt/dnf repository (its Packages/repodata index, every referenced .deb/.rpm, kept in sync on a schedule, served over the panel's own mirror with its own signing key) is a real, separate infrastructure project - not something to half-do inside this one. These all stay remote for that reason:

SourceUsed forWhere
deb.nodesource.com / rpm.nodesource.comNode.jsnative/install.rs, native/install.sh
dl.cloudsmith.io (Cloudsmith)Caddynative/install.rs, native/install.sh, enterprise.rs
rspamd.com/apt-stable, /rpm-stable, its gpg keyrspamdnative/install.rs, native/install.sh
rpms.remirepo.netRemi (PHP on RHEL-family)native/php.rs
packages.microsoft.comMSSQL Servernative/mssql.rs
repo.mongodb.org, pgp.mongodb.comMongoDBnative/mongodb.rs
artifacts.opensearch.orgOpenSearchnative/install.rs, native/install.sh
artifacts.elastic.coElasticsearchnative/install.rs, native/install.sh
repo.litespeed.shLiteSpeednative/install.rs, native/install.sh
nginx.org/keys, nginx.org/packagesnginx mainlinenative/install.rs, native/install.sh
packages.sury.orgPHP (Debian/Ubuntu, Sury)native/php.rs
get.docker.com/rootlessDocker CE, rootless modeuser/add.sh

To change this later: stand up a real repository mirror (reposync/aptly or equivalent, on a schedule, behind mirrors.hitechcloud.org), point one distro+arch at it as a pilot, and only then rewrite the bootstrap step to add that repo instead of the vendor's. Until that infrastructure exists, naming the vendor's own repo URL in an install script is not a design choice to revisit — it is the only thing that works.

Stays remote: licensed product installers​

A second category, related but distinct: install.sh-style bootstrap scripts for commercial products that are activated against the vendor's own licence servers, and keep calling home afterwards for updates regardless of what fetched the installer. Pinning the installer script would not remove the dependency — the product still phones home to activate and to update itself — so it would add a stale copy of a script for no real reduction in the third-party surface:

SourceProductWhere
repo.cloudlinux.com/cloudlinux/sources/cln/cldeployCloudLinux OSenterprise.rs
repo.cloudlinux.com/kernelcare/kc-install.shKernelCareenterprise.rs
repo.jetlicense.com/.../jetapps-repo-latest.{rpm,deb}JetBackup/JetAppsenterprise.rs
repo.imunify360.cloudlinux.com/defence360/*-deploy.shImunifyAV / Imunify360imunify.rs
pkg.cpguard.io/installer.shcPGuardenterprise.rs
files.softaculous.com/install.shSoftaculousenterprise.rs
files.sitepad.com/install.shSitePadenterprise.rs

To change this later: ask each vendor whether their activation protocol tolerates a locally-cached installer at all (some tie the installer itself to a licence key, not just the product afterwards); if one does, pin that one script the same way vendor.json pins everything else, but the product's own ongoing calls home stay - there is no local answer for a licence check by definition.

Stays remote: live data​

Some third-party calls are not "download an artifact" at all — the answer has to be whatever is true right now, so a mirror would serve yesterday's answer as if it were today's:

  • Cloudflare's IP ranges (www.cloudflare.com/ips-v4, /ips-v6, enterprise.rs) — used to trust X-Forwarded-For from Cloudflare's edge. Cloudflare adds and retires ranges; serving a stale list either trusts an IP Cloudflare no longer owns or stops trusting one it has just started using. To change this later: nothing to change — this has to be fetched live, on a schedule, for as long as Cloudflare is trusted at all.
  • api.wordpress.org/core/stable-check and the wordpress.org/wordpress-<ver>.tar.gz it names (websites/wp_autodownload.rs) — a customer creating a new WordPress site is deliberately handed whatever WordPress currently considers stable, not a version this panel picked months ago. Pinning it would defeat the feature's purpose. To change this later: if a slower, reviewed WordPress version ever becomes the intended default, that is a product decision to pin a specific WordPress release deliberately (and it would then belong in vendor.json like anything else pinned) - not a mirroring fix.
  • www.php.net/releases/index.php?json (native/phpselector.rs) — feeds the per-version security/EOL score the PHP Selector shows, from PHP's own release and support-window data. That calendar changes as php.net updates it (a branch reaching end of life, a new patch release); a cached copy goes wrong exactly when it matters most - during a security incident. To change this later: nothing to change, for the same reason as above; a periodic local cache with a visible age would be the only safe compromise, not a static mirror.
  • MTA-STS lookups (https://<domain>/.well-known/mta-sts.txt, native/mailautoconfig.rs) — these are not requests to one vendor at all; they check whatever policy a customer's own mail domain (or a domain sending it mail) currently publishes, which by design can change at any time and is different for every domain. There is nothing to mirror.

Comment/help text throughout hitechcloudcli and the panels links to hitechcloud.org/docs/... and community.hitechcloud.org — this project's own documentation and forum, not a third party. Not part of this inventory.

Found during this audit, not converted​

  • gist.githubusercontent.com/hitechcloud-vietnam/.../imav_email.sh (imunify.rs, the ImunifyAV virus-notification hook) resolves to a 404 today. Fetching the gist by its ID shows it is owned by a different GitHub account entirely and its content references a different product's paths — a leftover from an early, unfinished rebrand pass that was apparently never updated. This is not a mirroring job: the content itself needs to be rewritten for this project before it is worth hosting anywhere. Left as a bug for a follow-up, not pinned as-is.
  • The password-strength dictionary (hitechcloud.org/steveklabnik/password-cracker, user/add.sh) is a static file with no live-data reason to float, and hitechcloudcli vendor-fetch (this change) could serve it. It was not converted here only because user/add.sh is a shell-only path this round; a follow-up needs one manifest entry and a one-line edit (wget -qO "$dict" "$url" → hitechcloudcli vendor-fetch password-dictionary "$dict").
  • MySQL 8.4 community server (cdn.mysql.com/dev.mysql.com, native/mysql84.sh) was not converted: it needs a check of Oracle's redistribution terms for the community binaries before anything is re-hosted, which is a legal question, not a technical one, and out of scope for this pass.
Was this helpful?