From 7d6e43892461a7d95af19b45e8289c9888598252 Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Thu, 30 Jul 2026 20:40:38 +0800 Subject: [PATCH] feat(app): add Resin Package Resin 1.1.2 and latest with V1 authentication, persistent state, health checks, and localized metadata. Document the explicitly accepted vulnerabilities in the current upstream image. --- apps/resin/1.1.2/.env.sample | 6 ++ apps/resin/1.1.2/data.yml | 85 +++++++++++++++++++++++++ apps/resin/1.1.2/data/.gitkeep | 0 apps/resin/1.1.2/docker-compose.yml | 32 ++++++++++ apps/resin/1.1.2/scripts/init.sh | 3 + apps/resin/1.1.2/scripts/uninstall.sh | 3 + apps/resin/1.1.2/scripts/upgrade.sh | 3 + apps/resin/README.md | 40 ++++++++++++ apps/resin/data.yml | 33 ++++++++++ apps/resin/latest/.env.sample | 6 ++ apps/resin/latest/data.yml | 85 +++++++++++++++++++++++++ apps/resin/latest/data/.gitkeep | 0 apps/resin/latest/docker-compose.yml | 32 ++++++++++ apps/resin/latest/scripts/init.sh | 3 + apps/resin/latest/scripts/uninstall.sh | 3 + apps/resin/latest/scripts/upgrade.sh | 3 + apps/resin/logo.png | Bin 0 -> 4198 bytes 17 files changed, 337 insertions(+) create mode 100644 apps/resin/1.1.2/.env.sample create mode 100644 apps/resin/1.1.2/data.yml create mode 100644 apps/resin/1.1.2/data/.gitkeep create mode 100644 apps/resin/1.1.2/docker-compose.yml create mode 100755 apps/resin/1.1.2/scripts/init.sh create mode 100755 apps/resin/1.1.2/scripts/uninstall.sh create mode 100755 apps/resin/1.1.2/scripts/upgrade.sh create mode 100644 apps/resin/README.md create mode 100644 apps/resin/data.yml create mode 100644 apps/resin/latest/.env.sample create mode 100644 apps/resin/latest/data.yml create mode 100644 apps/resin/latest/data/.gitkeep create mode 100644 apps/resin/latest/docker-compose.yml create mode 100755 apps/resin/latest/scripts/init.sh create mode 100755 apps/resin/latest/scripts/uninstall.sh create mode 100755 apps/resin/latest/scripts/upgrade.sh create mode 100644 apps/resin/logo.png diff --git a/apps/resin/1.1.2/.env.sample b/apps/resin/1.1.2/.env.sample new file mode 100644 index 000000000..6fcf17437 --- /dev/null +++ b/apps/resin/1.1.2/.env.sample @@ -0,0 +1,6 @@ +PANEL_APP_PORT_HTTP=2260 +RESIN_ADMIN_TOKEN=replace-with-a-strong-random-admin-token +RESIN_PROXY_TOKEN=replace-with-a-strong-random-proxy-token +APP_DATA_DIR=./data +TZ=Asia/Shanghai +CONTAINER_NAME=resin diff --git a/apps/resin/1.1.2/data.yml b/apps/resin/1.1.2/data.yml new file mode 100644 index 000000000..d314690fd --- /dev/null +++ b/apps/resin/1.1.2/data.yml @@ -0,0 +1,85 @@ +additionalProperties: + formFields: + - default: 2260 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Web and Proxy Port + labelZh: Web 与代理端口 + label: + en: Web and Proxy Port + zh: Web 与代理端口 + zh-Hant: Web 與代理連接埠 + ja: Web・プロキシポート + ko: Web 및 프록시 포트 + ru: Порт Web и прокси + ms: Port Web dan Proksi + pt-br: Porta Web e de Proxy + required: true + rule: paramPort + type: number + - default: "" + edit: true + envKey: RESIN_ADMIN_TOKEN + labelEn: Admin Token + labelZh: 管理令牌 + label: + en: Admin Token + zh: 管理令牌 + zh-Hant: 管理權杖 + ja: 管理トークン + ko: 관리자 토큰 + ru: Токен администратора + ms: Token Pentadbir + pt-br: Token de Administrador + random: true + required: true + type: password + - default: "" + edit: true + envKey: RESIN_PROXY_TOKEN + labelEn: Proxy Token + labelZh: 代理令牌 + label: + en: Proxy Token + zh: 代理令牌 + zh-Hant: 代理權杖 + ja: プロキシトークン + ko: 프록시 토큰 + ru: Токен прокси + ms: Token Proksi + pt-br: Token de Proxy + random: true + required: true + 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: Diretório de Dados + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Timezone + labelZh: 时区 + label: + en: Timezone + zh: 时区 + zh-Hant: 時區 + ja: タイムゾーン + ko: 시간대 + ru: Часовой пояс + ms: Zon waktu + pt-br: Fuso horário + required: true + type: text diff --git a/apps/resin/1.1.2/data/.gitkeep b/apps/resin/1.1.2/data/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/apps/resin/1.1.2/docker-compose.yml b/apps/resin/1.1.2/docker-compose.yml new file mode 100644 index 000000000..c7bc2199f --- /dev/null +++ b/apps/resin/1.1.2/docker-compose.yml @@ -0,0 +1,32 @@ +services: + resin: + image: "ghcr.io/resinat/resin:1.1.2" + container_name: ${CONTAINER_NAME} + restart: unless-stopped + environment: + - RESIN_AUTH_VERSION=V1 + - RESIN_ADMIN_TOKEN=${RESIN_ADMIN_TOKEN} + - RESIN_PROXY_TOKEN=${RESIN_PROXY_TOKEN} + - RESIN_LISTEN_ADDRESS=0.0.0.0 + - RESIN_PORT=2260 + - TZ=${TZ} + ports: + - "${PANEL_APP_PORT_HTTP}:2260" + volumes: + - "${APP_DATA_DIR}/cache:/var/cache/resin" + - "${APP_DATA_DIR}/state:/var/lib/resin" + - "${APP_DATA_DIR}/log:/var/log/resin" + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:2260/healthz >/dev/null || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s + labels: + createdBy: "Apps" + networks: + - 1panel-network + +networks: + 1panel-network: + external: true diff --git a/apps/resin/1.1.2/scripts/init.sh b/apps/resin/1.1.2/scripts/init.sh new file mode 100755 index 000000000..8c3cbfc39 --- /dev/null +++ b/apps/resin/1.1.2/scripts/init.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exit 0 diff --git a/apps/resin/1.1.2/scripts/uninstall.sh b/apps/resin/1.1.2/scripts/uninstall.sh new file mode 100755 index 000000000..891c61f0d --- /dev/null +++ b/apps/resin/1.1.2/scripts/uninstall.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker-compose down --volumes diff --git a/apps/resin/1.1.2/scripts/upgrade.sh b/apps/resin/1.1.2/scripts/upgrade.sh new file mode 100755 index 000000000..8c3cbfc39 --- /dev/null +++ b/apps/resin/1.1.2/scripts/upgrade.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exit 0 diff --git a/apps/resin/README.md b/apps/resin/README.md new file mode 100644 index 000000000..b66f2bd66 --- /dev/null +++ b/apps/resin/README.md @@ -0,0 +1,40 @@ +# Resin + +## 产品介绍 + +Resin 是一个高性能智能代理池网关,可将多个代理订阅聚合为统一的 HTTP、SOCKS5 和反向代理入口,并提供健康检查、智能调度、会话保持和可观测性。 + +## 主要功能 + +- 导入 sing-box、Clash、URI、Base64 及纯文本代理订阅 +- 提供 HTTP、SOCKS5 和 URL 反向代理入口 +- 支持节点健康探测、熔断、智能调度和粘性会话 +- 通过 WebUI 管理订阅、节点、平台、租约和请求日志 +- 持久化状态、缓存、指标与请求日志 + +## 访问说明 + +- 安装后通过 `http://<服务器 IP>:` 打开管理界面,并使用安装时生成的管理令牌登录。 +- HTTP 和 SOCKS5 正向代理与管理界面共用容器内的 `2260` 端口;客户端使用安装时生成的代理令牌认证。 +- 新安装固定使用 Resin `V1` 认证格式;HTTP 和 SOCKS5 代理用户名格式为 `平台.账户`,未指定时可使用 `Default`。 +- WebUI 中新增自定义接入点时,还需要在 1Panel 编排中发布对应端口。Docker 无法为已经运行的容器动态增加端口映射。 + +## 安全说明 + +当前上游 `1.1.2` 镜像包含 Trivy 报告的 `CVE-2026-33186` Critical 漏洞以及若干 High 漏洞。本应用按维护者明确接受的安全例外提供,部署前应结合网络暴露范围评估风险,并在上游发布修复镜像后尽快升级。 + +## Introduction + +Resin is a high-performance intelligent proxy pool gateway. It combines multiple proxy subscriptions behind unified HTTP, SOCKS5, and reverse-proxy entry points with health monitoring, smart routing, sticky sessions, and observability. + +## Features + +- Import sing-box, Clash, URI, Base64, and plain-text proxy subscriptions +- Serve HTTP, SOCKS5, and URL-based reverse proxy traffic +- Monitor node health and provide circuit breaking, smart scheduling, and sticky sessions +- Manage subscriptions, nodes, platforms, leases, and request logs through the WebUI +- Persist state, cache, metrics, and request logs + +## Security Notice + +The current upstream `1.1.2` image contains the Trivy-reported Critical vulnerability `CVE-2026-33186` and several High vulnerabilities. This package is provided under an explicitly accepted maintainer exception. Review the exposure risk before deployment and upgrade when upstream publishes a fixed image. diff --git a/apps/resin/data.yml b/apps/resin/data.yml new file mode 100644 index 000000000..d0aeca89f --- /dev/null +++ b/apps/resin/data.yml @@ -0,0 +1,33 @@ +name: Resin +tags: + - 网络工具 + - 面板 +title: 高性能智能代理池网关 +description: 高性能智能代理池网关 +additionalProperties: + key: resin + name: Resin + tags: + - Network + - Tool + shortDescZh: 高性能智能代理池网关 + shortDescEn: High-performance intelligent proxy pool gateway + description: + en: Turn large proxy subscriptions into a stable, intelligent, and observable gateway with sticky sessions. + zh: 将大量代理订阅整合为稳定、智能、可观测并支持会话保持的统一网关。 + zh-Hant: 將大量代理訂閱整合為穩定、智慧、可觀測並支援工作階段保持的統一閘道。 + ja: 大量のプロキシサブスクリプションを、セッション維持に対応した安定的でインテリジェントかつ観測可能な統合ゲートウェイに集約します。 + ko: 대규모 프록시 구독을 세션 고정 기능을 갖춘 안정적이고 지능적이며 관찰 가능한 통합 게이트웨이로 구성합니다. + ru: Объединяйте множество подписок на прокси в стабильный, интеллектуальный и наблюдаемый шлюз с закреплением сеансов. + ms: Satukan langganan proksi berskala besar menjadi get laluan yang stabil, pintar dan boleh dipantau dengan sesi melekat. + pt-br: Reuna grandes assinaturas de proxy em um gateway estável, inteligente e observável com sessões persistentes. + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/Resinat/Resin + github: https://github.com/Resinat/Resin + document: https://github.com/Resinat/Resin/blob/v1.1.2/README.zh-CN.md + architectures: + - amd64 + - arm64 diff --git a/apps/resin/latest/.env.sample b/apps/resin/latest/.env.sample new file mode 100644 index 000000000..6fcf17437 --- /dev/null +++ b/apps/resin/latest/.env.sample @@ -0,0 +1,6 @@ +PANEL_APP_PORT_HTTP=2260 +RESIN_ADMIN_TOKEN=replace-with-a-strong-random-admin-token +RESIN_PROXY_TOKEN=replace-with-a-strong-random-proxy-token +APP_DATA_DIR=./data +TZ=Asia/Shanghai +CONTAINER_NAME=resin diff --git a/apps/resin/latest/data.yml b/apps/resin/latest/data.yml new file mode 100644 index 000000000..d314690fd --- /dev/null +++ b/apps/resin/latest/data.yml @@ -0,0 +1,85 @@ +additionalProperties: + formFields: + - default: 2260 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Web and Proxy Port + labelZh: Web 与代理端口 + label: + en: Web and Proxy Port + zh: Web 与代理端口 + zh-Hant: Web 與代理連接埠 + ja: Web・プロキシポート + ko: Web 및 프록시 포트 + ru: Порт Web и прокси + ms: Port Web dan Proksi + pt-br: Porta Web e de Proxy + required: true + rule: paramPort + type: number + - default: "" + edit: true + envKey: RESIN_ADMIN_TOKEN + labelEn: Admin Token + labelZh: 管理令牌 + label: + en: Admin Token + zh: 管理令牌 + zh-Hant: 管理權杖 + ja: 管理トークン + ko: 관리자 토큰 + ru: Токен администратора + ms: Token Pentadbir + pt-br: Token de Administrador + random: true + required: true + type: password + - default: "" + edit: true + envKey: RESIN_PROXY_TOKEN + labelEn: Proxy Token + labelZh: 代理令牌 + label: + en: Proxy Token + zh: 代理令牌 + zh-Hant: 代理權杖 + ja: プロキシトークン + ko: 프록시 토큰 + ru: Токен прокси + ms: Token Proksi + pt-br: Token de Proxy + random: true + required: true + 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: Diretório de Dados + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Timezone + labelZh: 时区 + label: + en: Timezone + zh: 时区 + zh-Hant: 時區 + ja: タイムゾーン + ko: 시간대 + ru: Часовой пояс + ms: Zon waktu + pt-br: Fuso horário + required: true + type: text diff --git a/apps/resin/latest/data/.gitkeep b/apps/resin/latest/data/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/apps/resin/latest/docker-compose.yml b/apps/resin/latest/docker-compose.yml new file mode 100644 index 000000000..ba821d7b2 --- /dev/null +++ b/apps/resin/latest/docker-compose.yml @@ -0,0 +1,32 @@ +services: + resin: + image: "ghcr.io/resinat/resin:latest" + container_name: ${CONTAINER_NAME} + restart: unless-stopped + environment: + - RESIN_AUTH_VERSION=V1 + - RESIN_ADMIN_TOKEN=${RESIN_ADMIN_TOKEN} + - RESIN_PROXY_TOKEN=${RESIN_PROXY_TOKEN} + - RESIN_LISTEN_ADDRESS=0.0.0.0 + - RESIN_PORT=2260 + - TZ=${TZ} + ports: + - "${PANEL_APP_PORT_HTTP}:2260" + volumes: + - "${APP_DATA_DIR}/cache:/var/cache/resin" + - "${APP_DATA_DIR}/state:/var/lib/resin" + - "${APP_DATA_DIR}/log:/var/log/resin" + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:2260/healthz >/dev/null || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s + labels: + createdBy: "Apps" + networks: + - 1panel-network + +networks: + 1panel-network: + external: true diff --git a/apps/resin/latest/scripts/init.sh b/apps/resin/latest/scripts/init.sh new file mode 100755 index 000000000..8c3cbfc39 --- /dev/null +++ b/apps/resin/latest/scripts/init.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exit 0 diff --git a/apps/resin/latest/scripts/uninstall.sh b/apps/resin/latest/scripts/uninstall.sh new file mode 100755 index 000000000..891c61f0d --- /dev/null +++ b/apps/resin/latest/scripts/uninstall.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker-compose down --volumes diff --git a/apps/resin/latest/scripts/upgrade.sh b/apps/resin/latest/scripts/upgrade.sh new file mode 100755 index 000000000..8c3cbfc39 --- /dev/null +++ b/apps/resin/latest/scripts/upgrade.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exit 0 diff --git a/apps/resin/logo.png b/apps/resin/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0411c2e549fb1a38059d9e9720464b6744b265cd GIT binary patch literal 4198 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