Thành phần từ bên thứ ba
Một máy chủ khách hàng vận hành tải về những thứ không do nó tự build: tường lửa, công cụ PHP, phần mềm webmail, tệp nhị phân điều phối container, phần mềm TLS, gói của bản phân phối. Mỗi lượt tải đó là một sự phụ thuộc vào việc người khác vẫn trực tuyến, vẫn trung thực và không thay đổi các byte đằng sau một URL. Trang này là danh mục của bề mặt đó: những gì đã chuyển sang mirror riêng của chúng tôi kèm phiên bản và checksum do chính chúng tôi tính, và những gì vẫn cố ý gọi tới bên thứ ba, kèm lý do và những gì cần có để thay đổi điều đó sau này.
Cơ chế, trong hitechcloudcli: hitechadmin/config/vendor.json
(hitechcloud-configuration) cố định phiên bản, tên tệp, URL
upstream của từng thành phần và một SHA-256 được tính bằng cách tải tệp về và băm nó.
native_vendor::fetch của native/vendor.rs thử
mirrors.hitechcloud.org/vendor/<name>/<file> trước, url trong manifest
sau, và kiểm tra SHA-256 với bất kỳ nguồn nào đã trả lời — mỗi
lần máy chủ tải thành phần, không phải một lần khi nó được cố định. Không có gì
phân giải "latest" lúc cài đặt: dùng bản phát hành mới hơn nghĩa là một
người sửa manifest, tính hash mới, và commit cả hai.
Các script shell vẫn cần việc này gọi cùng logic qua
hitechcloudcli vendor fetch <name> <dest>.
Đã chuyển sang mirror
| Thành phần | Trước đây | Nay cố định ở |
|---|---|---|
| Webmail MailFlow | git clone nhánh main của một tài khoản GitHub cá nhân (maathimself/mailflow) — không phiên bản, không checksum, trường hợp tệ nhất trong số này | 3.5.6 (một tag thực sự) |
| ConfigServer Firewall (csf) | một tarball tải từ chuỗi mirror/dự phòng hoàn toàn không có checksum | 15.10 |
| Composer | getcomposer.org/composer-stable.phar — một alias "stable" thay đổi liên tục | 2.10.3 |
| WP-CLI | tệp phar ở HEAD của nhánh gh-pages trên mirrors.hitechcloud.org | 2.12.0 |
| Docker Compose (amd64, arm64) | phân giải qua mirrors.hitechcloud.org/api/repos/docker/compose/releases/latest ở mỗi lần chạy | 5.5.1 |
| Traefik (amd64, arm64) | releases/latest, hoặc v3.1.4 cố định trong mã khi lần tra cứu đó thất bại | 3.7.13 |
| acme.sh | get.acme.sh, có chế độ --install-online tải lại nhánh mặc định hiện tại trong lúc cài | 3.1.6 |
| restic (amd64) | releases/latest, kiểm tra với SHA256SUMS tải trực tiếp từ cùng bản phát hành | 0.19.1 |
| rclone (amd64) | curl https://rclone.org/install.sh | bash — script của bên thứ ba được pipe thẳng vào shell root | 1.75.1 |
| ionCube Loader (amd64, arm64) | downloads.ioncube.com, hoàn toàn không có phiên bản trong URL hay tên tệp | một bản chụp theo ngày, cố định 2026-09-24 (phiên bản loader 15.5.1 đọc từ bên trong gói) |
Mọi checksum ở trên đều được tính tại đây — thành phần được tải về và
băm, không sao chép từ một trang nào. Khi nhà phát hành cũng cung cấp checksum
riêng (các tệp .sha256 của Docker Compose, checksums.txt của Traefik,
.sha256 của WP-CLI, SHA256SUMS của restic và rclone), hash tính được
ở đây khớp ngay lần đầu; đó là kiểm tra chéo, không phải nguồn sự thật
được ghi trong manifest.
ionCube là mục duy nhất không có phiên bản thực sự để cố định: URL tải và tên tệp của gói từ nhà cung cấp không bao giờ thay đổi, nên không có gì để cố định ngoài các byte. Cố định lại sau này nghĩa là tải lại, băm lại và ghi lại ngày hôm đó — manifest tự nó không thể biết một lần tải mới từ URL đó là loader nó đã có hay một loader mới.
tinyphotogallery, Roundcube và phpMyAdmin dùng cùng cơ chế, được cố định
trong một thay đổi đi kèm; chúng không được đề cập ở đây.
IP công khai do máy chủ tự trả lời thay vì hỏi người lạ
Tám vị trí gọi từng hỏi ip.hitechcloud.org (của chúng tôi) về IP công khai của máy chủ
và, khi thất bại, chuyển sang ifconfig.me — dịch vụ echo của
người lạ, cho một câu hỏi mà máy chủ có IP công khai được gán trực tiếp (trường hợp
thông thường ở đây — không NAT) có thể tự trả lời. Ở bảy trong tám vị trí,
một phương án dự phòng cục bộ (hostname -I, hoặc đọc địa chỉ phạm vi global từ
ip addr) đã có sẵn ở tầng thấp hơn chính vì lý do này;
ifconfig.me đã bị loại khỏi chuỗi, chuyển thẳng từ dịch vụ
của chúng tôi sang câu trả lời tự có:
sentinel.rs, user/login.rs, domains/add.rs, user/backup.rs,
user/transfer.rs, user/restore.rs, server/migrate.rs.
Vị trí thứ tám, license.rs, được cố ý để nguyên. public_ip() của nó
cung cấp cho /api/license/verify — việc xác thực giấy phép cần địa chỉ mà
thế giới bên ngoài thực sự thấy máy chủ này, điều mà địa chỉ giao diện cục bộ của
máy chủ sau NAT hoặc có nhiều đường mạng không phải lúc nào cũng khớp. Thay bằng
câu trả lời cục bộ ở đó có nguy cơ khiến giấy phép chỉ tình cờ hoạt động trên các máy chủ
được gán địa chỉ trực tiếp và âm thầm hỏng trên những máy không như vậy. Một ý kiến
bên ngoài thứ hai, độc lập, đáng được giữ cho riêng lời gọi đó; nếu
bản thân ifconfig.me là mối lo ở đó, cách sửa là một endpoint thứ hai do chúng tôi
vận hành, không phải câu trả lời cục bộ.
Vẫn từ xa: kho gói và khoá GPG của chúng
Mirror một script khởi tạo kho dạng curl | bash hay một khoá ký không phải
cùng công việc với mirror một tarball: kho mà nó cấu hình vẫn phải
truy cập được sau đó cho mọi lần apt/dnf update trong tương lai, nên mirror một nửa
(bắt được script khởi tạo nhưng không bắt được kho mà nó trỏ tới)
không loại bỏ được sự phụ thuộc nào mà còn thêm một bản sao thứ hai, khác biệt tinh vi, của cùng
chuỗi tin cậy phải giữ đồng bộ. Mirror đúng cách một kho apt/dnf
(chỉ mục Packages/repodata, mọi .deb/.rpm được tham chiếu,
đồng bộ theo lịch, phục vụ qua mirror riêng của panel với khoá ký
riêng) là một dự án hạ tầng thực sự, riêng biệt - không phải thứ để
làm nửa vời bên trong dự án này. Tất cả những mục sau vẫn ở từ xa vì lý do đó:
| Nguồn | Dùng cho | Ở đâu |
|---|---|---|
deb.nodesource.com / rpm.nodesource.com | Node.js | native/install.rs, native/install.sh |
dl.cloudsmith.io (Cloudsmith) | Caddy | native/install.rs, native/install.sh, enterprise.rs |
rspamd.com/apt-stable, /rpm-stable, khoá gpg của nó | rspamd | native/install.rs, native/install.sh |
rpms.remirepo.net | Remi (PHP trên dòng RHEL) | native/php.rs |
packages.microsoft.com | MSSQL Server | native/mssql.rs |
repo.mongodb.org, pgp.mongodb.com | MongoDB | native/mongodb.rs |
artifacts.opensearch.org | OpenSearch | native/install.rs, native/install.sh |
artifacts.elastic.co | Elasticsearch | native/install.rs, native/install.sh |
repo.litespeed.sh | LiteSpeed | native/install.rs, native/install.sh |
nginx.org/keys, nginx.org/packages | nginx mainline | native/install.rs, native/install.sh |
packages.sury.org | PHP (Debian/Ubuntu, Sury) | native/php.rs |
get.docker.com/rootless | Docker CE, chế độ rootless | user/add.sh |
Để thay đổi điều này sau: dựng một mirror kho thực sự (reposync/aptly hoặc
tương đương, chạy theo lịch, đặt sau mirrors.hitechcloud.org), trỏ một
bản phân phối+kiến trúc vào đó làm thử nghiệm, và chỉ khi đó mới viết lại bước khởi tạo để
thêm kho đó thay vì kho của nhà cung cấp. Cho đến khi hạ tầng đó tồn tại,
ghi URL kho của chính nhà cung cấp trong script cài đặt không phải lựa chọn
thiết kế cần xem lại — đó là cách duy nhất hoạt động.
Vẫn từ xa: trình cài của sản phẩm có giấy phép
Loại thứ hai, có liên quan nhưng khác biệt: các script khởi tạo kiểu install.sh
cho sản phẩm thương mại được kích hoạt với máy chủ giấy phép riêng của nhà cung cấp,
và tiếp tục gọi về sau đó để cập nhật bất kể
c ái gì đã tải trình cài. Cố định script trình cài sẽ không loại bỏ
sự phụ thuộc — sản phẩm vẫn gọi về để kích hoạt và tự
cập nhật — nên nó chỉ thêm một bản sao lỗi thời của script mà không thực sự thu hẹp
bề mặt bên thứ ba:
| Nguồn | Sản phẩm | Ở đâu |
|---|---|---|
repo.cloudlinux.com/cloudlinux/sources/cln/cldeploy | CloudLinux OS | enterprise.rs |
repo.cloudlinux.com/kernelcare/kc-install.sh | KernelCare | enterprise.rs |
repo.jetlicense.com/.../jetapps-repo-latest.{rpm,deb} | JetBackup/JetApps | enterprise.rs |
repo.imunify360.cloudlinux.com/defence360/*-deploy.sh | ImunifyAV / Imunify360 | imunify.rs |
pkg.cpguard.io/installer.sh | cPGuard | enterprise.rs |
files.softaculous.com/install.sh | Softaculous | enterprise.rs |
files.sitepad.com/install.sh | SitePad | enterprise.rs |
Để thay đổi điều này sau: hỏi từng nhà cung cấp xem giao thức kích hoạt của họ
có chấp nhận trình cài được lưu đệm cục bộ hay không (một số gắn chính trình cài
với khoá giấy phép, không chỉ sản phẩm sau đó); nếu có, hãy cố định
script đó giống cách vendor.json cố định mọi thứ khác, nhưng các
lời gọi về liên tục của sản phẩm vẫn còn - theo định nghĩa không có câu trả lời cục bộ cho
việc kiểm tra giấy phép.
Vẫn từ xa: dữ liệu trực tiếp
Một số lời gọi tới bên thứ ba hoàn toàn không phải "tải một thành phần" — câu trả lời phải là điều đang đúng ngay lúc này, nên mirror sẽ trả câu trả lời của hôm qua như thể là của hôm nay:
- Dải IP của Cloudflare (
www.cloudflare.com/ips-v4,/ips-v6,enterprise.rs) — dùng để tin cậyX-Forwarded-Fortừ edge của Cloudflare. Cloudflare thêm và ngừng dùng các dải; phục vụ danh sách cũ hoặc sẽ tin một IP Cloudflare không còn sở hữu, hoặc ngừng tin một IP họ vừa bắt đầu dùng. Để thay đổi điều này sau: không có gì để thay đổi — phải tải trực tiếp, theo lịch, chừng nào còn tin cậy Cloudflare. api.wordpress.org/core/stable-checkvàwordpress.org/wordpress-<ver>.tar.gzmà nó chỉ ra (websites/wp_autodownload.rs) — khách hàng tạo website WordPress mới được cố ý cung cấp bất cứ phiên bản nào WordPress hiện coi là ổn định, không phải phiên bản mà panel này chọn từ nhiều tháng trước. Cố định nó sẽ đi ngược mục đích của tính năng. Để thay đổi điều này sau: nếu một phiên bản WordPress chậm hơn, đã được xem xét, trở thành mặc định mong muốn, đó là một quyết định sản phẩm để cố định có chủ ý một bản phát hành WordPress cụ thể (và khi đó nó sẽ thuộc vềvendor.jsonnhư mọi thứ được cố định khác) - không phải một bản sửa về mirror.www.php.net/releases/index.php?json(native/phpselector.rs) — cung cấp điểm bảo mật/EOL theo từng phiên bản mà PHP Selector hiển thị, từ dữ liệu phát hành và thời gian hỗ trợ của chính PHP. Lịch đó thay đổi khi php.net cập nhật (một nhánh hết vòng đời, một bản vá mới); bản sao lưu đệm sai đúng lúc quan trọng nhất - trong một sự cố bảo mật. Để thay đổi điều này sau: không có gì để thay đổi, cùng lý do như trên; bộ nhớ đệm cục bộ định kỳ có hiển thị tuổi dữ liệu sẽ là thoả hiệp an toàn duy nhất, không phải một mirror tĩnh.- Tra cứu MTA-STS (
https://<domain>/.well-known/mta-sts.txt,native/mailautoconfig.rs) — đây hoàn toàn không phải yêu cầu tới một nhà cung cấp; chúng kiểm tra bất kỳ chính sách nào mà tên miền thư của khách hàng (hoặc tên miền gửi thư tới nó) đang công bố, vốn theo thiết kế có thể thay đổi bất kỳ lúc nào và khác nhau với mỗi tên miền. Không có gì để mirror.
Các liên kết docs.hitechcloud.org của chính website
Văn bản chú thích/trợ giúp trong toàn bộ hitechcloudcli và các panel liên kết tới
hitechcloud.org/docs/... và community.hitechcloud.org — tài liệu và diễn đàn
riêng của dự án này, không phải bên thứ ba. Không thuộc danh mục này.
Tìm thấy trong lần rà soát này, chưa chuyển đổi
gist.githubusercontent.com/hitechcloud-vietnam/.../imav_email.sh(imunify.rs, hook thông báo virus của ImunifyAV) hiện trả về 404. Tải gist theo ID của nó cho thấy nó thuộc về một tài khoản GitHub hoàn toàn khác và nội dung tham chiếu đường dẫn của một sản phẩm khác — tàn dư của một lượt đổi thương hiệu sớm, chưa hoàn tất, có vẻ chưa bao giờ được cập nhật. Đây không phải việc mirror: bản thân nội dung cần được viết lại cho dự án này trước khi đáng được lưu trữ ở bất kỳ đâu. Để lại như một lỗi cho vòng tiếp theo, không cố định nguyên trạng.- Từ điển độ mạnh mật khẩu (
hitechcloud.org/steveklabnik/password-cracker,user/add.sh) là một tệp tĩnh không có lý do dữ liệu trực tiếp nào để thay đổi, vàhitechcloudcli vendor-fetch(thay đổi này) có thể phục vụ nó. Nó chưa được chuyển đổi ở đây chỉ vìuser/add.shlà đường chỉ dùng shell trong vòng này; vòng tiếp theo cần một mục manifest và sửa một dòng (wget -qO "$dict" "$url"→hitechcloudcli vendor-fetch password-dictionary "$dict"). - MySQL 8.4 community server (
cdn.mysql.com/dev.mysql.com,native/mysql84.sh) chưa được chuyển đổi: cần kiểm tra điều khoản phân phối lại của Oracle cho các tệp nhị phân community trước khi lưu trữ lại bất cứ thứ gì, đây là câu hỏi pháp lý, không phải kỹ thuật, và nằm ngoài phạm vi của lượt này.