From 4c1ca77bdcdaf0fefa1684405d117665e46b87a4 Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Tue, 28 Jul 2026 07:20:35 +0800 Subject: [PATCH] Add Zoraxy app --- apps/zoraxy/3.3.3/.env.sample | 7 ++ apps/zoraxy/3.3.3/data.yml | 103 ++++++++++++++++ apps/zoraxy/3.3.3/data/.gitkeep | 1 + apps/zoraxy/3.3.3/docker-compose.yml | 55 +++++++++ apps/zoraxy/3.3.3/scripts/entrypoint.sh | 155 ++++++++++++++++++++++++ apps/zoraxy/3.3.3/scripts/init.sh | 75 ++++++++++++ apps/zoraxy/3.3.3/scripts/uninstall.sh | 2 + apps/zoraxy/3.3.3/scripts/upgrade.sh | 4 + apps/zoraxy/README.md | 85 +++++++++++++ apps/zoraxy/data.yml | 30 +++++ apps/zoraxy/logo-LICENSE.txt | 9 ++ apps/zoraxy/logo.png | Bin 0 -> 4592 bytes 12 files changed, 526 insertions(+) create mode 100644 apps/zoraxy/3.3.3/.env.sample create mode 100644 apps/zoraxy/3.3.3/data.yml create mode 100644 apps/zoraxy/3.3.3/data/.gitkeep create mode 100644 apps/zoraxy/3.3.3/docker-compose.yml create mode 100755 apps/zoraxy/3.3.3/scripts/entrypoint.sh create mode 100755 apps/zoraxy/3.3.3/scripts/init.sh create mode 100755 apps/zoraxy/3.3.3/scripts/uninstall.sh create mode 100755 apps/zoraxy/3.3.3/scripts/upgrade.sh create mode 100644 apps/zoraxy/README.md create mode 100644 apps/zoraxy/data.yml create mode 100644 apps/zoraxy/logo-LICENSE.txt create mode 100644 apps/zoraxy/logo.png diff --git a/apps/zoraxy/3.3.3/.env.sample b/apps/zoraxy/3.3.3/.env.sample new file mode 100644 index 000000000..36ce8cd31 --- /dev/null +++ b/apps/zoraxy/3.3.3/.env.sample @@ -0,0 +1,7 @@ +PANEL_APP_PORT_HTTP=8000 +PANEL_APP_PORT_PROXY_HTTP=8080 +PANEL_APP_PORT_PROXY_HTTPS=8443 +ADMIN_USERNAME=admin +ADMIN_PASSWORD= +APP_DATA_DIR=./data +CONTAINER_NAME= diff --git a/apps/zoraxy/3.3.3/data.yml b/apps/zoraxy/3.3.3/data.yml new file mode 100644 index 000000000..2f7836643 --- /dev/null +++ b/apps/zoraxy/3.3.3/data.yml @@ -0,0 +1,103 @@ +additionalProperties: + formFields: + - default: 8000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Management Port + labelZh: 管理端口 + label: + en: Management Port + zh: 管理端口 + zh-Hant: 管理連接埠 + ja: 管理ポート + ko: 관리 포트 + ru: Порт управления + ms: Port Pengurusan + pt-br: Porta de Gerenciamento + required: true + rule: paramPort + type: number + - default: 8080 + edit: true + envKey: PANEL_APP_PORT_PROXY_HTTP + labelEn: HTTP Proxy Port + labelZh: HTTP 代理端口 + label: + en: HTTP Proxy Port + zh: HTTP 代理端口 + zh-Hant: HTTP 代理連接埠 + ja: HTTP プロキシポート + ko: HTTP 프록시 포트 + ru: Порт HTTP-прокси + ms: Port Proksi HTTP + pt-br: Porta do Proxy HTTP + required: true + rule: paramPort + type: number + - default: 8443 + edit: true + envKey: PANEL_APP_PORT_PROXY_HTTPS + labelEn: HTTPS Proxy Port + labelZh: HTTPS 代理端口 + label: + en: HTTPS Proxy Port + zh: HTTPS 代理端口 + zh-Hant: HTTPS 代理連接埠 + ja: HTTPS プロキシポート + ko: HTTPS 프록시 포트 + ru: Порт HTTPS-прокси + ms: Port Proksi HTTPS + pt-br: Porta do Proxy HTTPS + required: true + rule: paramPort + type: number + - default: admin + edit: true + envKey: ADMIN_USERNAME + labelEn: Administrator Username + labelZh: 管理员用户名 + label: + en: Administrator Username + zh: 管理员用户名 + zh-Hant: 管理員使用者名稱 + ja: 管理者ユーザー名 + ko: 관리자 사용자 이름 + ru: Имя администратора + ms: Nama Pengguna Pentadbir + pt-br: Nome de Usuario Administrador + required: true + type: text + - default: "" + edit: true + envKey: ADMIN_PASSWORD + labelEn: Administrator Password + labelZh: 管理员密码 + label: + en: Administrator Password + zh: 管理员密码 + zh-Hant: 管理員密碼 + ja: 管理者パスワード + ko: 관리자 비밀번호 + ru: Пароль администратора + ms: Kata Laluan Pentadbir + pt-br: Senha do Administrador + random: true + required: true + rule: paramComplexity + type: password + - default: ./data + edit: true + envKey: APP_DATA_DIR + labelEn: Data Directory + labelZh: 数据目录 + label: + en: Data Directory + zh: 数据目录 + zh-Hant: 資料目錄 + ja: データディレクトリ + ko: 데이터 디렉터리 + ru: Каталог данных + ms: Direktori Data + pt-br: Diretorio de Dados + required: true + type: text diff --git a/apps/zoraxy/3.3.3/data/.gitkeep b/apps/zoraxy/3.3.3/data/.gitkeep new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/apps/zoraxy/3.3.3/data/.gitkeep @@ -0,0 +1 @@ + diff --git a/apps/zoraxy/3.3.3/docker-compose.yml b/apps/zoraxy/3.3.3/docker-compose.yml new file mode 100644 index 000000000..b1a48af02 --- /dev/null +++ b/apps/zoraxy/3.3.3/docker-compose.yml @@ -0,0 +1,55 @@ +services: + zoraxy: + image: "zoraxydocker/zoraxy:v3.3.3@sha256:229fd5bff4a6605b2f261dd66da8dddcfb98688b01c4034c117ed125c0605c45" + container_name: ${CONTAINER_NAME} + restart: unless-stopped + user: "0:0" + working_dir: /opt/zoraxy/config + entrypoint: + - /bin/sh + - /opt/1panel/entrypoint.sh + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:8000" + - "${PANEL_APP_PORT_PROXY_HTTP}:80" + - "${PANEL_APP_PORT_PROXY_HTTPS}:443" + cap_drop: + - ALL + cap_add: + - CHOWN + - DAC_OVERRIDE + - KILL + - SETUID + - SETGID + security_opt: + - no-new-privileges:true + read_only: true + tmpfs: + - /tmp:nodev,noexec,nosuid,size=64M + healthcheck: + test: + - CMD + - python3 + - -c + - >- + import urllib.request; + raise SystemExit(0 if urllib.request.urlopen( + 'http://127.0.0.1:8000/api/auth/userCount', timeout=5 + ).read().strip() == b'1' else 1) + interval: 30s + timeout: 10s + start_period: 30s + retries: 3 + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - "${APP_DATA_DIR}:/data" + - "${APP_DATA_DIR}/config:/opt/zoraxy/config" + - "./scripts/entrypoint.sh:/opt/1panel/entrypoint.sh:ro" + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/zoraxy/3.3.3/scripts/entrypoint.sh b/apps/zoraxy/3.3.3/scripts/entrypoint.sh new file mode 100755 index 000000000..279b5c6e9 --- /dev/null +++ b/apps/zoraxy/3.3.3/scripts/entrypoint.sh @@ -0,0 +1,155 @@ +#!/bin/sh +set -eu +export LC_ALL=C + +CONFIG_DIR=/data/config +PLUGIN_DIR=/data/plugins +CREDENTIAL_FILE=/data/.bootstrap-credentials + +chown 65534:65534 "$CONFIG_DIR" "$PLUGIN_DIR" + +bootstrap_pid= +stop_bootstrap() { + if [ -n "$bootstrap_pid" ] && kill -0 "$bootstrap_pid" 2>/dev/null; then + kill -TERM -"$bootstrap_pid" 2>/dev/null || true + for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do + kill -0 -"$bootstrap_pid" 2>/dev/null || break + sleep 0.1 + done + if kill -0 -"$bootstrap_pid" 2>/dev/null; then + kill -KILL -"$bootstrap_pid" 2>/dev/null || true + fi + wait "$bootstrap_pid" 2>/dev/null || true + fi +} +trap stop_bootstrap EXIT +trap 'stop_bootstrap; exit 143' HUP INT TERM + +setsid su -s /bin/sh nobody -c \ + 'exec /usr/local/bin/zoraxy \ + -autorenew=86400 \ + -cfgupgrade=true \ + -conf=/data/config/conf \ + -db=auto \ + -dbpath=/data/config/sys.db \ + -default_inbound_enabled=false \ + -docker=true \ + -earlyrenew=30 \ + -enablelog=true \ + -fastgeoip=false \ + -log=/data/config/log \ + -mdns=false \ + -noauth=false \ + -plugin=/data/plugins/ \ + -port=127.0.0.1:8000 \ + -sshlb=false \ + -tmp=/data/config/tmp \ + -uuid=/data/config/sys.uuid' & +bootstrap_pid=$! + +account_count="$(python3 -c ' +import sys +import time +import urllib.request + +url = "http://127.0.0.1:8000/api/auth/userCount" +for _ in range(60): + try: + value = urllib.request.urlopen(url, timeout=1).read().decode().strip() + if value.isdigit(): + print(value) + raise SystemExit(0) + except Exception: + pass + time.sleep(0.5) +raise SystemExit("Zoraxy bootstrap listener did not become ready") +')" + +case "$account_count" in + 0) + [ -f "$CREDENTIAL_FILE" ] || { + printf '%s\n' 'Bootstrap credentials are missing' >&2 + exit 1 + } + [ "$(stat -c '%a' "$CREDENTIAL_FILE")" = 400 ] || + [ "$(stat -c '%a' "$CREDENTIAL_FILE")" = 600 ] || { + printf '%s\n' 'Bootstrap credentials have unsafe permissions' >&2 + exit 1 + } + sed -n '1p' "$CREDENTIAL_FILE" | grep -Eq '^[A-Za-z0-9][A-Za-z0-9._-]{2,63}$' || { + printf '%s\n' 'Bootstrap username is invalid' >&2 + exit 1 + } + [ "$(wc -l <"$CREDENTIAL_FILE" | tr -d ' ')" = 2 ] || { + printf '%s\n' 'Bootstrap credential file must contain exactly two lines' >&2 + exit 1 + } + LC_ALL=C sed -n '2p' "$CREDENTIAL_FILE" | grep -Eq '^[[:graph:]]+$' || { + printf '%s\n' 'Bootstrap password must contain 16 to 256 printable ASCII characters without spaces' >&2 + exit 1 + } + password_length="$(sed -n '2p' "$CREDENTIAL_FILE" | wc -c | tr -d ' ')" + if [ "$password_length" -lt 17 ] || [ "$password_length" -gt 257 ]; then + printf '%s\n' 'Bootstrap password must contain 16 to 256 printable ASCII characters without spaces' >&2 + exit 1 + fi + python3 -c ' +import http.cookiejar +import re +import sys +import urllib.parse +import urllib.request + +username = sys.stdin.buffer.readline().rstrip(b"\n").decode() +password = sys.stdin.buffer.readline().rstrip(b"\n").decode() +jar = http.cookiejar.CookieJar() +opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar)) +page = opener.open("http://127.0.0.1:8000/login.html", timeout=5).read().decode() +match = re.search(r"name=\"zoraxy.csrf.Token\" content=\"([^\"]+)\"", page) +if match is None: + raise SystemExit("Unable to obtain the Zoraxy CSRF token") +request = urllib.request.Request( + "http://127.0.0.1:8000/api/auth/register", + data=urllib.parse.urlencode({"username": username, "password": password}).encode(), + headers={"X-CSRF-Token": match.group(1)}, +) +if opener.open(request, timeout=5).read().strip() != b"\"OK\"": + raise SystemExit("Zoraxy administrator registration failed") +' <"$CREDENTIAL_FILE" + ;; + 1) ;; + *) + printf 'Unexpected Zoraxy account count: %s\n' "$account_count" >&2 + exit 1 + ;; +esac + +[ "$(python3 -c 'import urllib.request; print(urllib.request.urlopen("http://127.0.0.1:8000/api/auth/userCount", timeout=5).read().decode().strip())')" = 1 ] || { + printf '%s\n' 'Zoraxy administrator bootstrap verification failed' >&2 + exit 1 +} + +stop_bootstrap +bootstrap_pid= +rm -f "$CREDENTIAL_FILE" +trap - EXIT HUP INT TERM + +exec su -s /bin/sh nobody -c \ + 'exec /usr/local/bin/zoraxy \ + -autorenew=86400 \ + -cfgupgrade=true \ + -conf=/data/config/conf \ + -db=auto \ + -dbpath=/data/config/sys.db \ + -docker=true \ + -earlyrenew=30 \ + -enablelog=true \ + -fastgeoip=false \ + -log=/data/config/log \ + -mdns=false \ + -noauth=false \ + -plugin=/data/plugins/ \ + -port=:8000 \ + -sshlb=false \ + -tmp=/data/config/tmp \ + -uuid=/data/config/sys.uuid' diff --git a/apps/zoraxy/3.3.3/scripts/init.sh b/apps/zoraxy/3.3.3/scripts/init.sh new file mode 100755 index 000000000..cd8edfd8b --- /dev/null +++ b/apps/zoraxy/3.3.3/scripts/init.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +set -euo pipefail +export LC_ALL=C + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}" + +read_env_value() { + local key="$1" + [[ -f "$ENV_FILE" ]] || return 0 + local value + value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)" + case "$value" in + \"*\") value="${value#\"}"; value="${value%\"}" ;; + \'*\') value="${value#\'}"; value="${value%\'}" ;; + esac + printf '%s\n' "$value" +} + +configured_value() { + local key="$1" + local default_value="$2" + local value="${!key:-}" + if [[ -z "$value" ]]; then + value="$(read_env_value "$key")" + fi + printf '%s\n' "${value:-$default_value}" +} + +data_raw="$(configured_value APP_DATA_DIR ./data)" +admin_username="$(configured_value ADMIN_USERNAME admin)" +admin_password="$(configured_value ADMIN_PASSWORD '')" + +[[ -n "$data_raw" && "$data_raw" != /* ]] || { + printf '%s\n' 'APP_DATA_DIR must be a non-empty relative path' >&2 + exit 1 +} +data_dir="$(realpath -m -- "$ROOT_DIR/${data_raw#./}")" +case "$data_dir" in + "$ROOT_DIR"/*) ;; + *) + printf '%s\n' 'APP_DATA_DIR must remain inside the application version directory' >&2 + exit 1 + ;; +esac + +[[ "$admin_username" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{2,63}$ ]] || { + printf '%s\n' 'ADMIN_USERNAME must contain 3 to 64 letters, digits, dots, underscores, or hyphens' >&2 + exit 1 +} +[[ "$admin_password" =~ ^[[:graph:]]{16,256}$ ]] || { + printf '%s\n' 'ADMIN_PASSWORD must contain 16 to 256 printable ASCII characters without spaces' >&2 + exit 1 +} + +install -d -m 0755 "$data_dir" +install -d -m 0750 "$data_dir/config" "$data_dir/plugins" +data_dir="$(realpath -e -- "$data_dir")" +case "$data_dir" in + "$ROOT_DIR"/*) ;; + *) + printf '%s\n' 'APP_DATA_DIR resolves outside the application version directory' >&2 + exit 1 + ;; +esac + +credential_file="$data_dir/.bootstrap-credentials" +credential_temporary="$(mktemp "$data_dir/.bootstrap-credentials.tmp.XXXXXX")" +umask 077 +{ + printf '%s\n' "$admin_username" + printf '%s\n' "$admin_password" +} >"$credential_temporary" +chmod 0600 "$credential_temporary" +mv -f -- "$credential_temporary" "$credential_file" diff --git a/apps/zoraxy/3.3.3/scripts/uninstall.sh b/apps/zoraxy/3.3.3/scripts/uninstall.sh new file mode 100755 index 000000000..6e877466e --- /dev/null +++ b/apps/zoraxy/3.3.3/scripts/uninstall.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +set -euo pipefail diff --git a/apps/zoraxy/3.3.3/scripts/upgrade.sh b/apps/zoraxy/3.3.3/scripts/upgrade.sh new file mode 100755 index 000000000..c7388c078 --- /dev/null +++ b/apps/zoraxy/3.3.3/scripts/upgrade.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euo pipefail + +bash "$(dirname "$0")/init.sh" diff --git a/apps/zoraxy/README.md b/apps/zoraxy/README.md new file mode 100644 index 000000000..3ce83bde6 --- /dev/null +++ b/apps/zoraxy/README.md @@ -0,0 +1,85 @@ +# Zoraxy + +## 产品介绍 + +Zoraxy 是面向家庭实验室和自托管环境的反向代理与网络管理平台,提供基于域名的 HTTP/HTTPS 转发、自动证书管理、访问规则、流代理、运行状态监控和 WebSSH 工具。 + +## 主要功能 + +- HTTP、HTTPS、WebSocket、TCP 和 UDP 代理 +- ACME 证书申请和自动续期 +- 主机名、路径、请求头、访问列表和可信代理规则 +- 运行状态监控、流量统计、WebSSH 和网络诊断工具 +- 可选插件和 ZorxAuth 单点登录 + +## 访问说明 + +安装后通过 `http://<服务器 IP>:<管理端口>/` 打开管理后台,使用安装时设置的管理员用户名和随机密码登录。初始化期间管理接口只监听容器回环地址;适配脚本创建唯一管理员并验证成功后,才会重启为正式监听,因此远程客户端不能抢注首个账户。 + +默认端口映射为:管理后台 `8000`、HTTP 代理 `8080`、HTTPS 代理 `8443`。若要从公网提供标准 Web 服务,请在路由器或上级防火墙中将外部 80/443 分别转发到安装表单中的 HTTP/HTTPS 代理端口。管理端口不应暴露到公网;Zoraxy 后台本身只提供明文 HTTP,且本适配未增加登录限速,应放在可信 HTTPS 反向代理之后并限制来源地址、增加登录限速。 + +本包不挂载 `/var/run/docker.sock`。因此后台可以显示 Docker 集成功能入口,但相关容器枚举 API 会失败关闭;不要为了便利添加 Docker socket,因为这会让后台获得主机级容器控制能力。`host.docker.internal` 指向宿主机网关,1Panel 网络中的其他应用可使用容器名作为上游地址。 + +## 数据与凭据 + +`APP_DATA_DIR/config` 保存数据库、代理规则、证书、日志和运行配置,`APP_DATA_DIR/plugins` 保存已安装插件。数据目录必须位于应用版本目录内,默认为 `./data`;初始化脚本拒绝绝对路径和目录逃逸。升级、迁移或卸载前请备份,卸载不会删除绑定目录中的用户数据。 + +1Panel 将生成的管理员密码保存在应用 `.env` 中。安装脚本另建权限为 `0600` 的一次性凭据文件;容器只在回环接口注册账户,完成后立即删除该文件,正式 Zoraxy 进程的参数和环境均不包含密码。能够读取 1Panel 应用配置的人仍能得到明文密码,应限制 1Panel 和主机文件权限,且不要复用该密码。 + +上游将管理密码保存为无盐 SHA-512 摘要,不具备 Argon2、scrypt 或 bcrypt 的离线破解成本。必须使用安装时生成的高强度唯一密码,并保护 `sys.db` 备份。正式进程以 UID/GID 65534 运行,有效 capability 为零,启用 `no-new-privileges`,根文件系统只读;只有启动包装器短暂保留切换用户、调整两个数据目录所有权和终止回环初始化进程所需的最小能力。 + +## 安全与漏洞警告 + +- 2026-07-28 对固定镜像的全新 Trivy 扫描结果为 `0 Critical / 23 High`,对应 22 个不同漏洞。版本 3.3.3 的标签提交日期为 2026-05-31,上游仓库最后活动时间为 2026-07-26。修复镜像发布后应重新验证并尽快升级。 +- `CVE-2026-39829`、`CVE-2026-39830`、`CVE-2026-39835` 和 `CVE-2026-46597` 可影响 Zoraxy 的已认证 WebSSH 客户端:管理员连接恶意或已被入侵的 SSH 服务时,特制密钥、证书、响应或 AES-GCM 数据包可能造成 CPU、内存、资源泄漏或进程崩溃。仅连接可信 SSH 主机;WebSSH 使用 `ssh.InsecureIgnoreHostKey()`,不会验证主机密钥,因此还必须防范中间人攻击。其余 SSH High 是服务端授权、硬件密钥、agent 或 known_hosts 路径,Zoraxy 默认客户端流程不使用这些边界。 +- `CVE-2026-39821` 位于 `x/net/idna` 的错误 Punycode 标签处理。该库通过 Go 网络栈间接链接,未发现 Zoraxy 将 IDNA 转换结果用于本地特权允许列表的明确路径,因此没有证明默认提权可达;但域名仍参与代理路由、证书和管理员配置。避免不受信任的国际化域名,限制后台访问,并在修复版本可用后升级。 +- `CVE-2026-25681` 和 `CVE-2026-27136` 需要 `x/net/html` 的 Parse-to-Render 树转换。Zoraxy 的输入清理经 bluemonday 使用 `html.NewTokenizer`,没有走受影响的树解析再渲染模式,默认管理输入路径不满足漏洞前置条件。仍不要向不可信用户开放管理后台。 +- `CVE-2026-34040`、`CVE-2026-41567` 和 `CVE-2026-42306` 针对 Docker daemon 的授权或镜像归档处理。镜像只链接 Docker 客户端 SDK,本包既不运行 daemon 也不挂载 socket;已认证的 `/api/docker/*` 请求因此失败关闭。 +- `GHSA-hrxh-6v49-42gf` 位于 gRPC-Go 的 xDS RBAC/HTTP2 路径。gRPC 仅由可选且需管理员配置的 Yandex Cloud ACME DNS 提供商间接引入;Zoraxy 默认不提供 gRPC 服务或 xDS 管理面。`CVE-2026-39822` 涉及 `os.Root`,固定二进制中未发现相关易受影响符号。 +- `CVE-2026-45186`、`CVE-2026-56131`、`CVE-2026-56407` 和 `CVE-2026-56408` 位于镜像的 Expat;`CVE-2026-45447` 位于 OpenSSL `PKCS7_verify()`。Zoraxy 主程序是静态 Go 二进制,不链接这些系统库;本包的 Python 初始化只通过回环 HTTP 创建管理员,不解析 XML、PKCS#7 或 S/MIME。这些休眠组件仍需由上游镜像更新。 +- Zoraxy 启动时会通过明文 HTTP 请求 `checkip.amazonaws.com` 获取公网 IP,并通过 HTTPS 从 GitHub 同步官方插件索引。插件安装会下载并以 Zoraxy 的非 root 身份执行第三方二进制;只安装已核验来源和许可证的插件。mDNS、ZeroTier、快速 GeoIP、SSH 回环访问和 Docker socket 均未默认启用。 + +反向代理会直接处理公网不可信流量。启用 HTTPS、最小化公开路由、对上游服务保留其自身认证和限速、定期备份,并持续关注 Zoraxy 与固定镜像的安全更新。 + +## Introduction + +Zoraxy is a reverse proxy and network management platform for homelabs and self-hosted environments. It supports domain-based HTTP/HTTPS routing, automated certificates, access rules, stream proxying, uptime monitoring, and WebSSH. + +## Features + +- HTTP, HTTPS, WebSocket, TCP, and UDP proxying +- ACME certificate issuance and automated renewal +- Host, path, header, access-list, and trusted-proxy rules +- Uptime monitoring, traffic analytics, WebSSH, and network diagnostics +- Optional plugins and ZorxAuth single sign-on + +Open `http://:/` and sign in with the administrator username and random password selected during installation. The bootstrap listener is loopback-only until the sole administrator account has been created and verified, preventing remote first-user registration races. + +The default mappings are management `8000`, HTTP proxy `8080`, and HTTPS proxy `8443`. Forward external 80/443 to the selected proxy ports when publishing services. Never expose the management port directly to the Internet; it serves plain HTTP, and this adapter adds no login rate limiter. Protect it with a trusted HTTPS proxy, source restrictions, and login rate limiting. + +The package does not mount `/var/run/docker.sock`. Docker integration therefore fails closed. Do not add the socket: doing so would give the administration surface host-level container control. Persistent configuration, certificates, logs, and rules live under `APP_DATA_DIR/config`; plugins live under `APP_DATA_DIR/plugins`. + +1Panel retains the generated password in the app `.env`. A mode-`0600` one-time credential file is consumed over loopback and deleted before the final process starts, so the final Zoraxy environment and arguments contain no password. Upstream stores the password as an unsalted SHA-512 digest, which is weak against offline database cracking. Use the generated unique password and protect all `sys.db` backups. + +The final process runs as UID/GID 65534 with zero effective capabilities, `no-new-privileges`, and a read-only root filesystem. The short-lived root wrapper retains only the capabilities needed to set data-directory ownership, drop privileges, and terminate the loopback bootstrap process. + +## Security And Vulnerability Warning + +- A fresh scan of the pinned image on 2026-07-28 reports `0 Critical / 23 High`, covering 22 distinct vulnerabilities. Tag 3.3.3 was committed on 2026-05-31; the repository was active on 2026-07-26. Revalidate and upgrade promptly when a fixed official image is published. +- `CVE-2026-39829`, `CVE-2026-39830`, `CVE-2026-39835`, and `CVE-2026-46597` can affect the authenticated WebSSH client. A malicious or compromised administrator-selected SSH server may cause CPU, memory, resource-leak, or process-crash denial of service with crafted keys, certificates, responses, or AES-GCM packets. Connect only to trusted SSH servers. WebSSH also uses `ssh.InsecureIgnoreHostKey()` and is vulnerable to machine-in-the-middle substitution. The other SSH High findings concern server authorization, security keys, agents, or known_hosts paths absent from the default client flow. +- `CVE-2026-39821` affects malformed Punycode handling in `x/net/idna`. The package is linked indirectly; no Zoraxy local-privilege allowlist driven by post-IDNA output was found. Practical default privilege escalation is therefore unproven, but domains still influence proxy routing, certificates, and administrator configuration. Avoid untrusted internationalized domains and restrict panel access. +- `CVE-2026-25681` and `CVE-2026-27136` require an `x/net/html` Parse-to-Render tree flow. Zoraxy sanitizes management inputs through bluemonday's `html.NewTokenizer` path instead, so the vulnerable transformation is not reached by the reviewed default input paths. +- `CVE-2026-34040`, `CVE-2026-41567`, and `CVE-2026-42306` affect Docker daemon authorization or image/archive processing. Zoraxy embeds only a client SDK, and this package runs no daemon and mounts no socket. Authenticated `/api/docker/*` calls fail closed. +- `GHSA-hrxh-6v49-42gf` affects gRPC-Go xDS RBAC/HTTP2 behavior. gRPC is linked through the optional administrator-configured Yandex Cloud ACME DNS provider; Zoraxy exposes no default gRPC server or xDS control plane. Vulnerable `os.Root` symbols for `CVE-2026-39822` were not found in the pinned binary. +- Expat `CVE-2026-45186`, `CVE-2026-56131`, `CVE-2026-56407`, and `CVE-2026-56408`, plus OpenSSL `CVE-2026-45447`, reside in image OS packages. The static Go server does not link them. The adapter's Python bootstrap performs only loopback HTTP and parses no XML, PKCS#7, or S/MIME. They still require an upstream image refresh. +- At startup, Zoraxy sends a plain-HTTP request to `checkip.amazonaws.com` for public-IP detection and retrieves the official plugin index from GitHub over HTTPS. Installed plugins are downloaded executables that run as the Zoraxy non-root user. Install only plugins with reviewed provenance and licensing. mDNS, ZeroTier, fast GeoIP, SSH loopback access, and the Docker socket are disabled by default. + +The reverse proxy processes public untrusted traffic. Enforce HTTPS, publish only necessary routes, retain authentication and rate limiting on every upstream, keep backups, and monitor upstream security updates. + +## References + +- Project, source, and AGPL-3.0 license: +- Official Docker deployment: +- Release: +- Go vulnerability database: +- OpenSSL advisory: diff --git a/apps/zoraxy/data.yml b/apps/zoraxy/data.yml new file mode 100644 index 000000000..e417a2861 --- /dev/null +++ b/apps/zoraxy/data.yml @@ -0,0 +1,30 @@ +name: Zoraxy +tags: + - Network +title: 反向代理与证书管理平台 +description: 反向代理与证书管理平台 +additionalProperties: + key: zoraxy + name: Zoraxy + tags: + - Network + shortDescZh: 反向代理与证书管理平台 + shortDescEn: Reverse proxy and certificate management platform + description: + en: Reverse proxy and certificate management platform + zh: 反向代理与证书管理平台 + zh-Hant: 反向代理與憑證管理平台 + ja: リバースプロキシと証明書管理プラットフォーム + ko: 리버스 프록시 및 인증서 관리 플랫폼 + ru: Платформа обратного прокси и управления сертификатами + ms: Platform proksi songsang dan pengurusan sijil + pt-br: Plataforma de proxy reverso e gerenciamento de certificados + type: website + crossVersionUpdate: true + limit: 0 + website: https://zoraxy.aroz.org/ + github: https://github.com/tobychui/zoraxy + document: https://github.com/tobychui/zoraxy/blob/v3.3.3/docker/README.md + architectures: + - amd64 + - arm64 diff --git a/apps/zoraxy/logo-LICENSE.txt b/apps/zoraxy/logo-LICENSE.txt new file mode 100644 index 000000000..35b96af0c --- /dev/null +++ b/apps/zoraxy/logo-LICENSE.txt @@ -0,0 +1,9 @@ +Zoraxy logo + +Source: https://github.com/tobychui/zoraxy/blob/v3.3.3/docs/favicon.png +Source commit: 9ed5fdc4399c0a4c74cf0824bb99a55edb3fa5ce +Source SHA-256: 833096908aa92fd1447fa07021d5677c28783d005e08bad527c1fb60b963cb0d +License: GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later) +License text: https://github.com/tobychui/zoraxy/blob/v3.3.3/LICENSE + +The store asset is the unchanged 512 x 512 upstream favicon. diff --git a/apps/zoraxy/logo.png b/apps/zoraxy/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..03345e0b481dfd5f436fc24d424bc613800c0c00 GIT binary patch literal 4592 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 literal 0 HcmV?d00001