diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..ee2873b
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,48 @@
+**Purpose**: 让 AI 编码代理快速在本仓库中上手,列出关键文件、构建/调试命令、项目约定和注意事项。
+
+**Big Picture**:
+- **核心二进制(后端)**: Go 源码为主,入口/关键文件为 `ech-workers.go`、`go.mod`。构建脚本在仓库根目录。
+- **平台 GUI/前端**: 每个平台放在独立目录,分别为 `ech-workers-linux-gui-src/`、`ech-workers-mac-gui-src/`、`ech-workers-windows-gui-src/`、`ech-workers-android-gui-src/`。它们各自包含自己的 README 和构建脚本(例如 `ech_worker_gui.py`、`gui.py`、`build.bat`)。
+- **原生/JNI 代码(Android)**: 位于 `ech-workers-android-gui-src/src/jni/hev-socks5-tunnel/`,包含 `Makefile`、`Android.mk`、`Application.mk`、`conf/main.yml` 等原生构建资源。
+
+**重要文件/目录(快速引用)**:
+- `gobuild.sh` — 全平台 Go 编译脚本(会在 `build/` 下产出二进制)。
+- `build.sh` — 发布/打包脚本,包含多个跨编译/打包函数(注意:脚本中大量从 OpenList 拷贝的逻辑,修改前请谨慎)。
+- `README.md`(仓库根)— 包含运行示例(例如 `ech-win ...`)。
+- `ech-workers-*-gui-src/` — 平台 GUI 源码和本地 README(请先阅读每个子目录下的 README)。
+- `ech-workers-android-gui-src/src/jni/hev-socks5-tunnel/` — C 源、头文件与 Android NDK 构建文件。
+
+**常用命令(可直接复制执行)**:
+```
+# 构建所有预设平台(gobuild.sh 会创建 build/ 下的产物)
+./gobuild.sh
+
+# 运行发布脚本(包含多平台/交叉编译与打包逻辑)
+./build.sh
+
+# 运行本地 Go 二进制(在未交叉编译时,可用 go run 测试)
+go run .
+```
+
+注意:`gobuild.sh` 与 `build.sh` 都使用 `go build` 并设置 `GOOS/GOARCH`,需要在容器/机器上安装 `go`。`build.sh` 的某些步骤会下载外部工具链、需要 `sudo`、`curl`、`unzip`、`jq` 等依赖。
+
+**约定与模式(此项目的特定点)**:
+- 二进制输出目录统一使用 `build/`。
+- 发布构建会通过 ldflags 注入版本信息(在 `build.sh` 中有 `builtAt`、`gitCommit`、`version` 三个变量),参考 `ldflags` 的设定不要随意改名。
+- Android JNI/本地库与 Go 代码分离:原生代码位于 `ech-workers-android-gui-src/src/jni/hev-socks5-tunnel/`,该目录包含自己的 `Makefile` 与 `Application.mk`,若需改动需按 NDK/Makefile 流程编译。
+- 多前端并存:不同平台的 GUI 不是共享同一构建流程,修改 GUI 功能时先在对应子目录内查 README 和脚本。
+
+**修改/PR 指南(给 AI agent 的可执行建议)**:
+- 修改核心 Go 代码:先运行 `go vet`、`go build` 或 `./gobuild.sh` 的单平台命令验证二进制能正常构建。
+- 修改发布脚本或交叉编译逻辑:谨慎,`build.sh` 中包含外部下载与重用的逻辑块(已注明为“OpenList 原版”)。若更改,请在 PR 描述中说明为何替换外部工具链或移除下载步骤。
+- 修改 Android JNI/C 代码:在更改后,先在有 NDK 的环境验证本地编译(参考目录 `ech-workers-android-gui-src/src/jni/hev-socks5-tunnel/` 中的 `Makefile`)。
+
+**快速调查点(定位 bug/行为)**:
+- 若需找程序入口/CLI参数:查看 `ech-workers.go`(或以 `_worker.js` 为辅助的脚本)。
+- 若需查运行示例:查看仓库根 `README.md` 中的 usage 与示例命令。
+
+**不能仅凭 AI 自动修改的地方**:
+- `build.sh` 中大量依赖外部二进制或工具链下载(会用到 GITHUB_TOKEN、sudo 等),自动化 修改可能破坏发布流水线。
+- Android NDK / JNI 构建和系统级交叉编译步骤,需要真实环境验证(AI 不应直接替换这些脚本而不标注风险)。
+
+如果这份说明有遗漏或你希望我把某个子目录的构建/运行步骤展开成更详尽的检查清单(例如 Android NDK 本地编译步骤或 macOS GUI 打包说明),请告诉我想要先覆盖的目标平台/目录,我会继续补充并提交更新。
diff --git a/.github/workflows/build-armv7.yml b/.github/workflows/build-armv7.yml
new file mode 100644
index 0000000..8d31ba0
--- /dev/null
+++ b/.github/workflows/build-armv7.yml
@@ -0,0 +1,821 @@
+name: 🔨 Build ARMv7 for Hi3798MV100
+
+on:
+ push:
+ branches: [ main, master ]
+ tags: [ 'v*' ] # 标签触发时创建正式发布
+ pull_request:
+ branches: [ main, master ]
+ workflow_dispatch: # 手动触发
+ inputs:
+ version:
+ description: '自定义版本号 (如 v1.0.0)'
+ required: false
+ default: 'auto'
+ clean_build:
+ description: '清理构建缓存'
+ required: false
+ default: false
+
+env:
+ GO_VERSION: '1.21'
+ PROJECT_NAME: 'ech-workers'
+ BUILD_TARGET: 'hi3798mv100'
+ OUTPUT_DIR: 'artifacts'
+ CACHE_KEY: ${{ github.ref }}
+
+jobs:
+ build-check:
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ outputs:
+ should_build: ${{ steps.check.outputs.should_build }}
+ build_version: ${{ steps.version.outputs.build_version }}
+
+ steps:
+ - name: 🔍 检查构建条件
+ id: check
+ run: |
+ # 跳过文档和配置文件的变更
+ if [[ "${{ github.event.head_commit.message }}" =~ ^(docs|chore|style) ]]; then
+ echo "::warning::跳过构建(仅文档/配置变更)"
+ echo "should_build=false" >> $GITHUB_OUTPUT
+ else
+ echo "should_build=true" >> $GITHUB_OUTPUT
+ fi
+
+ - name: 🏷️ 确定版本号
+ id: version
+ run: |
+ if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.version }}" != "auto" ]]; then
+ VERSION="${{ github.event.inputs.version }}"
+ elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
+ VERSION="${GITHUB_REF#refs/tags/}"
+ else
+ DATE=$(date +%Y%m%d)
+ COMMIT=${GITHUB_SHA:0:8}
+ VERSION="nightly-${DATE}-${COMMIT}"
+ fi
+ echo "版本号: $VERSION"
+ echo "build_version=$VERSION" >> $GITHUB_OUTPUT
+
+ build-armv7:
+ runs-on: ubuntu-latest
+ needs: build-check
+ if: needs.build-check.outputs.should_build == 'true'
+
+ strategy:
+ fail-fast: false
+ matrix:
+ build_type: [standard, static]
+
+ steps:
+ - name: 📥 检出代码
+ uses: actions/checkout@v4
+ with:
+ repository: hhsw2015/ech_workers
+ fetch-depth: 0
+ lfs: true
+
+ - name: 🔧 设置 Go 环境
+ uses: actions/setup-go@v4
+ with:
+ go-version: ${{ env.GO_VERSION }}
+ cache: true
+ cache-dependency-path: go.sum
+
+ - name: 📦 初始化构建环境
+ run: |
+ mkdir -p ${{ env.OUTPUT_DIR }}
+ echo "BUILD_DATE=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
+ echo "GO_VERSION=$(go version | cut -d' ' -f3)" >> $GITHUB_ENV
+
+ # 显示构建信息
+ echo "📋 构建信息:"
+ echo "项目: ${{ env.PROJECT_NAME }}"
+ echo "目标设备: ${{ env.BUILD_TARGET }}"
+ echo "版本: ${{ needs.build-check.outputs.build_version }}"
+ echo "构建类型: ${{ matrix.build_type }}"
+ echo "Go版本: $(go version)"
+
+ - name: 🛠️ 构建 ARMv7 版本
+ id: build
+ run: |
+ set -e
+
+ VERSION="${{ needs.build-check.outputs.build_version }}"
+ COMMIT=$(git rev-parse --short HEAD)
+
+ echo "🚀 开始构建 ${{ matrix.build_type }} 版本..."
+
+ # 设置构建参数
+ if [ "${{ matrix.build_type }}" = "static" ]; then
+ LD_FLAGS="-w -s -extldflags \"-static\""
+ OUTPUT_SUFFIX="-static"
+ CGO_ENABLED="0"
+ else
+ LD_FLAGS="-w -s"
+ OUTPUT_SUFFIX=""
+ CGO_ENABLED="1"
+ fi
+
+ # 设置完整版本信息
+ FULL_VERSION="${VERSION}+${COMMIT}"
+
+ # 交叉编译命令
+ GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=$CGO_ENABLED \
+ go build \
+ -v \
+ -trimpath \
+ -o "${{ env.OUTPUT_DIR }}/${{ env.PROJECT_NAME }}-armv7${OUTPUT_SUFFIX}" \
+ -ldflags="${LD_FLAGS} \
+ -X 'main.Version=$FULL_VERSION' \
+ -X 'main.BuildTime=${{ env.BUILD_DATE }}' \
+ -X 'main.GoVersion=${{ env.GO_VERSION }}' \
+ -X 'main.Commit=$COMMIT'" \
+ .
+
+ echo "✅ 构建完成"
+
+ # 输出构建信息
+ echo "build_output=${{ env.OUTPUT_DIR }}/${{ env.PROJECT_NAME }}-armv7${OUTPUT_SUFFIX}" >> $GITHUB_OUTPUT
+ echo "build_suffix=${OUTPUT_SUFFIX}" >> $GITHUB_OUTPUT
+
+ - name: 🔍 验证二进制文件
+ run: |
+ echo "🔍 验证构建结果:"
+ ls -lh ${{ env.OUTPUT_DIR }}/
+
+ FILE="${{ steps.build.outputs.build_output }}"
+ echo "📄 文件信息:"
+ file "$FILE"
+
+ echo "📦 文件大小:"
+ ls -lh "$FILE"
+
+ echo "🔢 检查 ELF 头部:"
+ readelf -h "$FILE" | grep -E "(机器|类型|入口点)" || true
+
+ - name: 🧪 QEMU 模拟测试
+ run: |
+ echo "🧪 使用 QEMU 进行基本测试..."
+ sudo apt-get update
+ sudo apt-get install -y qemu-user-static qemu-user
+
+ TEST_BIN="${{ steps.build.outputs.build_output }}"
+ chmod +x "$TEST_BIN"
+
+ echo "测试帮助命令:"
+ timeout 5s qemu-arm-static "$TEST_BIN" --help 2>&1 | head -20 || \
+ echo "⚠️ QEMU 测试可能受限,继续构建流程..."
+
+ echo "✅ QEMU 测试完成"
+
+ - name: 🔒 创建校验和
+ run: |
+ echo "🔒 生成文件校验和..."
+
+ BIN_FILE="${{ steps.build.outputs.build_output }}"
+ BASE_NAME=$(basename "$BIN_FILE")
+
+ cd ${{ env.OUTPUT_DIR }}
+
+ # 创建多种校验和
+ sha256sum "$BASE_NAME" > "$BASE_NAME.sha256"
+ sha1sum "$BASE_NAME" > "$BASE_NAME.sha1"
+ md5sum "$BASE_NAME" > "$BASE_NAME.md5"
+
+ # 创建 BLAKE3 校验和(更现代)
+ if command -v b3sum &> /dev/null; then
+ sudo apt-get install -y b3sum
+ b3sum "$BASE_NAME" > "$BASE_NAME.b3sum"
+ fi
+
+ echo "📋 校验和列表:"
+ cat *.sha256
+ cat *.sha1
+ cat *.md5
+ [ -f *.b3sum ] && cat *.b3sum || true
+
+ - name: 📄 创建版本信息文件
+ run: |
+ echo "📝 创建版本信息..."
+
+ cat > "${{ env.OUTPUT_DIR }}/BUILD_INFO.txt" << EOF
+# ${{ env.PROJECT_NAME }} - ${{ env.BUILD_TARGET }} 构建信息
+构建时间: ${{ env.BUILD_DATE }}
+版本: ${{ needs.build-check.outputs.build_version }}
+提交: $(git rev-parse HEAD)
+分支: ${{ github.ref_name }}
+构建类型: ${{ matrix.build_type }}
+
+## 环境信息
+GitHub Actions URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+触发事件: ${{ github.event_name }}
+触发者: ${{ github.actor }}
+
+## 构建配置
+Go 版本: ${{ env.GO_VERSION }}
+操作系统: $(uname -s)
+架构: $(uname -m)
+构建参数: GOOS=linux GOARCH=arm GOARM=7
+
+## 文件信息
+二进制文件: $(basename ${{ steps.build.outputs.build_output }})
+文件大小: $(du -h ${{ steps.build.outputs.build_output }} | cut -f1)
+ELF 类型: $(file ${{ steps.build.outputs.build_output }} | cut -d':' -f2-)
+
+## 依赖版本
+$(go version)
+$(go list -m all | grep -E "(ech|workers|cloudflare)" || echo "无特殊依赖")
+EOF
+
+ echo "✅ 版本信息文件已创建"
+
+ - name: 📦 打包构建结果
+ run: |
+ echo "📦 打包构建结果..."
+
+ VERSION="${{ needs.build-check.outputs.build_version }}"
+ BUILD_TYPE="${{ matrix.build_type }}"
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
+
+ cd ${{ env.OUTPUT_DIR }}
+
+ # 创建打包目录
+ PACKAGE_DIR="${{ env.PROJECT_NAME }}-${VERSION}-armv7-${BUILD_TYPE}"
+ mkdir -p "$PACKAGE_DIR"
+
+ # 复制所有文件
+ cp ${{ env.PROJECT_NAME }}-armv7${steps.build.outputs.build_suffix}* "$PACKAGE_DIR/"
+ cp BUILD_INFO.txt "$PACKAGE_DIR/"
+
+ # 创建安装脚本
+ cat > "$PACKAGE_DIR/install.sh" << 'EOF'
+#!/bin/bash
+# ech-workers Hi3798MV100 ARMv7 安装脚本
+# 版本: ${{ needs.build-check.outputs.build_version }}
+
+set -e
+
+# 配置参数
+INSTALL_DIR="/usr/local/bin"
+SERVICE_DIR="/etc/systemd/system"
+CONFIG_DIR="/etc/ech-workers"
+LOG_DIR="/var/log/ech-workers"
+TEMP_DIR="/tmp/ech-workers-install"
+
+# 颜色定义
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+# 日志函数
+log() {
+ echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
+}
+
+success() {
+ echo -e "${GREEN}✓${NC} $1"
+}
+
+warn() {
+ echo -e "${YELLOW}⚠${NC} $1"
+}
+
+error() {
+ echo -e "${RED}✗${NC} $1"
+ exit 1
+}
+
+# 显示横幅
+show_banner() {
+ echo "╔══════════════════════════════════════════════════════════╗"
+ echo "║ ech-workers Hi3798MV100 ARMv7 安装程序 ║"
+ echo "║ 版本: ${{ needs.build-check.outputs.build_version }} ║"
+ echo "╚══════════════════════════════════════════════════════════╝"
+ echo ""
+}
+
+# 检查系统
+check_system() {
+ log "检查系统环境..."
+
+ # 检查架构
+ local arch=$(uname -m)
+ case "$arch" in
+ armv7l|armhf)
+ success "检测到 ARMv7 架构 ($arch)"
+ ;;
+ *)
+ warn "检测到架构: $arch (预期: ARMv7)"
+ read -p "是否继续?[y/N]: " -n 1 -r
+ echo
+ [[ $REPLY =~ ^[Yy]$ ]] || error "安装中止"
+ ;;
+ esac
+
+ # 检查内存
+ local mem=$(free -m | awk '/^Mem:/{print $2}')
+ if [ "$mem" -lt 128 ]; then
+ warn "系统内存较低 ($mem MB),建议至少有 256MB 内存"
+ fi
+
+ # 检查磁盘空间
+ local disk=$(df -m / | awk 'NR==2 {print $4}')
+ if [ "$disk" -lt 50 ]; then
+ warn "磁盘空间紧张 ($disk MB 可用)"
+ fi
+}
+
+# 安装依赖
+install_dependencies() {
+ log "检查系统依赖..."
+
+ local deps_missing=false
+
+ # 检查必需的命令
+ for cmd in curl systemctl ip; do
+ if ! command -v "$cmd" &> /dev/null; then
+ warn "缺少命令: $cmd"
+ deps_missing=true
+ fi
+ done
+
+ if [ "$deps_missing" = true ]; then
+ log "尝试安装依赖..."
+
+ if command -v apt-get &> /dev/null; then
+ apt-get update
+ apt-get install -y curl iproute2 ca-certificates || warn "部分依赖安装失败"
+ elif command -v yum &> /dev/null; then
+ yum install -y curl iproute ca-certificates || warn "部分依赖安装失败"
+ elif command -v opkg &> /dev/null; then
+ opkg update
+ opkg install curl ca-certificates || warn "部分依赖安装失败"
+ else
+ warn "无法自动安装依赖,请手动安装"
+ fi
+ fi
+}
+
+# 安装主程序
+install_binary() {
+ log "安装 ech-workers 主程序..."
+
+ # 创建安装目录
+ mkdir -p "$INSTALL_DIR"
+
+ # 备份旧版本
+ local binary_path="$INSTALL_DIR/ech-workers"
+ if [ -f "$binary_path" ]; then
+ local backup_path="${binary_path}.backup.$(date +%Y%m%d_%H%M%S)"
+ cp "$binary_path" "$backup_path"
+ success "旧版本已备份到: $backup_path"
+ fi
+
+ # 查找二进制文件
+ local binary_source
+ for file in ech-workers-*; do
+ if [[ "$file" == ech-workers-* && ! "$file" == *.* ]]; then
+ binary_source="$file"
+ break
+ fi
+ done
+
+ if [ -z "$binary_source" ]; then
+ error "找不到可安装的二进制文件"
+ fi
+
+ # 安装新版本
+ cp "$binary_source" "$binary_path"
+ chmod +x "$binary_path"
+ chown root:root "$binary_path"
+
+ # 验证安装
+ if [ -x "$binary_path" ]; then
+ local version_info=$("$binary_path" --help 2>&1 | head -5)
+ success "程序安装成功"
+ echo "版本信息:"
+ echo "$version_info" | sed 's/^/ /'
+ else
+ error "程序安装失败"
+ fi
+}
+
+# 创建配置文件
+create_config() {
+ log "创建配置文件..."
+
+ mkdir -p "$CONFIG_DIR"
+
+ # 主配置文件
+ cat > "$CONFIG_DIR/config.env" << 'CONFIGEOF'
+# ech-workers 配置文件
+# 生成时间: $(date)
+
+# 基本配置
+LISTEN_ADDR="0.0.0.0:30000"
+WORKER_URL="your-worker.workers.dev:443"
+TOKEN="your_token_here"
+
+# 高级配置 (可选)
+# FALLBACK_PROXY=""
+# PREFERRED_IP=""
+# DNS_SERVER="223.5.5.5/dns-query"
+# ECH_DOMAIN="cloudflare.ech.com"
+
+# 性能调整
+# CONNECTION_LIMIT=100
+# TIMEOUT=30
+# BUFFER_SIZE=4096
+CONFIGEOF
+
+ # 创建示例启动脚本
+ cat > "$CONFIG_DIR/start-example.sh" << 'EXAMPLEEOF'
+#!/bin/bash
+# ech-workers 启动示例
+
+source /etc/ech-workers/config.env
+
+# 构建命令行参数
+ARGS="-l \"\$LISTEN_ADDR\" -f \"\$WORKER_URL\" -token \"\$TOKEN\""
+
+[ -n "\$FALLBACK_PROXY" ] && ARGS="\$ARGS -pyip \"\$FALLBACK_PROXY\""
+[ -n "\$PREFERRED_IP" ] && ARGS="\$ARGS -ip \"\$PREFERRED_IP\""
+[ -n "\$DNS_SERVER" ] && ARGS="\$ARGS -dns \"\$DNS_SERVER\""
+[ -n "\$ECH_DOMAIN" ] && ARGS="\$ARGS -ech \"\$ECH_DOMAIN\""
+
+echo "启动命令:"
+echo "/usr/local/bin/ech-workers \$ARGS"
+
+# 实际执行(取消注释以启用)
+# exec /usr/local/bin/ech-workers \$ARGS
+EXAMPLEEOF
+
+ chmod +x "$CONFIG_DIR/start-example.sh"
+ chmod 600 "$CONFIG_DIR/config.env"
+
+ success "配置文件已创建: $CONFIG_DIR/"
+}
+
+# 创建 systemd 服务
+create_systemd_service() {
+ log "创建 systemd 服务..."
+
+ local service_file="$SERVICE_DIR/ech-workers.service"
+
+ cat > "$service_file" << SERVICEEOF
+[Unit]
+Description=ech-workers Proxy Service (Hi3798MV100)
+Description=基于 Cloudflare Workers 的代理服务
+After=network.target network-online.target
+Wants=network-online.target
+Documentation=https://github.com/${{ github.repository }}
+Before=syslog.target
+
+[Service]
+Type=simple
+User=root
+Group=root
+WorkingDirectory=/tmp
+
+# 从配置文件读取参数
+EnvironmentFile=-/etc/ech-workers/config.env
+
+# 启动命令
+ExecStart=/usr/local/bin/ech-workers \\
+ -l \${LISTEN_ADDR:-0.0.0.0:30000} \\
+ -f \${WORKER_URL} \\
+ -token \${TOKEN} \\
+ \${FALLBACK_PROXY:+-pyip "\${FALLBACK_PROXY}"} \\
+ \${PREFERRED_IP:+-ip "\${PREFERRED_IP}"} \\
+ \${DNS_SERVER:+-dns "\${DNS_SERVER}"} \\
+ \${ECH_DOMAIN:+-ech "\${ECH_DOMAIN}"}
+
+# 重启策略
+Restart=on-failure
+RestartSec=10
+RestartPreventExitStatus=0
+StartLimitInterval=60
+StartLimitBurst=3
+
+# 资源限制
+LimitNOFILE=65536
+MemoryMax=256M
+MemoryHigh=200M
+CPUQuota=80%
+
+# 安全设置
+NoNewPrivileges=true
+ProtectSystem=strict
+ProtectHome=true
+PrivateTmp=true
+PrivateDevices=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectControlGroups=true
+RestrictAddressFamilies=AF_INET AF_INET6
+RestrictNamespaces=true
+RestrictRealtime=true
+SystemCallArchitectures=native
+SystemCallFilter=@system-service
+
+# 日志设置
+StandardOutput=journal
+StandardError=journal
+SyslogIdentifier=ech-workers
+LogLevelMax=info
+
+# 环境变量
+Environment="GODEBUG=netdns=go"
+Environment="TZ=Asia/Shanghai"
+
+[Install]
+WantedBy=multi-user.target
+SERVICEEOF
+
+ # 重新加载 systemd
+ systemctl daemon-reload
+
+ success "systemd 服务文件已创建: $service_file"
+}
+
+# 设置日志轮转
+setup_logrotate() {
+ log "设置日志轮转..."
+
+ cat > /etc/logrotate.d/ech-workers << 'LOGROTATE'
+/var/log/ech-workers/*.log {
+ daily
+ rotate 7
+ compress
+ delaycompress
+ missingok
+ notifempty
+ create 0640 root root
+ sharedscripts
+ postrotate
+ systemctl try-reload-or-restart ech-workers >/dev/null 2>&1 || true
+ endscript
+}
+LOGROTATE
+
+ # 创建日志目录
+ mkdir -p "$LOG_DIR"
+ chmod 750 "$LOG_DIR"
+
+ success "日志轮转配置完成"
+}
+
+# 防火墙配置
+configure_firewall() {
+ log "配置防火墙..."
+
+ local port=${LISTEN_ADDR##*:}
+
+ if command -v ufw &> /dev/null; then
+ ufw allow "$port/tcp"
+ ufw reload
+ success "UFW 防火墙已配置 (端口: $port)"
+ elif command -v iptables &> /dev/null; then
+ iptables -A INPUT -p tcp --dport "$port" -j ACCEPT
+ success "iptables 规则已添加 (端口: $port)"
+ elif command -v firewall-cmd &> /dev/null; then
+ firewall-cmd --permanent --add-port="$port/tcp"
+ firewall-cmd --reload
+ success "firewalld 已配置 (端口: $port)"
+ else
+ warn "未找到支持的防火墙工具,请手动开放端口 $port"
+ fi
+}
+
+# 创建管理脚本
+create_management_scripts() {
+ log "创建管理脚本..."
+
+ # 状态检查脚本
+ cat > "/usr/local/bin/ech-workers-status" << 'STATUSEOF'
+#!/bin/bash
+# ech-workers 状态检查脚本
+
+SERVICE="ech-workers"
+PORT=$(grep -oP 'LISTEN_ADDR=".*:\K\d+' /etc/ech-workers/config.env 2>/dev/null || echo "30000")
+
+echo "🔍 ech-workers 状态检查"
+echo "========================"
+
+# 检查服务状态
+if systemctl is-active --quiet "$SERVICE"; then
+ echo "✅ 服务状态: 运行中"
+ echo " PID: $(systemctl show -p MainPID "$SERVICE" | cut -d= -f2)"
+else
+ echo "❌ 服务状态: 未运行"
+fi
+
+# 检查端口监听
+if ss -tln | grep -q ":$PORT "; then
+ echo "✅ 端口监听: 正常 (端口: $PORT)"
+else
+ echo "❌ 端口监听: 异常"
+fi
+
+# 检查配置文件
+if [ -f "/etc/ech-workers/config.env" ]; then
+ echo "✅ 配置文件: 存在"
+else
+ echo "⚠️ 配置文件: 缺失"
+fi
+
+# 测试连接(可选)
+if [ "$1" == "--test" ]; then
+ echo -n "测试代理连接: "
+ if timeout 5 curl -s --proxy "http://127.0.0.1:$PORT" http://httpbin.org/ip >/dev/null; then
+ echo "✅ 成功"
+ else
+ echo "❌ 失败"
+ fi
+fi
+STATUSEOF
+
+ chmod +x "/usr/local/bin/ech-workers-status"
+
+ success "管理脚本已创建"
+}
+
+# 显示安装完成信息
+show_completion() {
+ echo ""
+ echo "╔══════════════════════════════════════════════════════════╗"
+ echo "║ 安装完成! ║"
+ echo "╚══════════════════════════════════════════════════════════╝"
+ echo ""
+ echo "📋 安装摘要:"
+ echo " • 程序文件: $INSTALL_DIR/ech-workers"
+ echo " • 配置文件: $CONFIG_DIR/"
+ echo " • 服务文件: $SERVICE_DIR/ech-workers.service"
+ echo " • 日志目录: $LOG_DIR/"
+ echo ""
+ echo "🚀 启动服务:"
+ echo " sudo systemctl start ech-workers"
+ echo ""
+ echo "📊 服务管理:"
+ echo " sudo systemctl status ech-workers # 查看状态"
+ echo " sudo systemctl restart ech-workers # 重启服务"
+ echo " sudo journalctl -u ech-workers -f # 查看日志"
+ echo ""
+ echo "🔧 配置修改:"
+ echo " 编辑配置文件: sudo nano /etc/ech-workers/config.env"
+ echo " 然后重启: sudo systemctl restart ech-workers"
+ echo ""
+ echo "🌐 代理地址:"
+ echo " HTTP/HTTPS: http://$(hostname -I | awk '{print $1}'):${LISTEN_ADDR##*:}"
+ echo " SOCKS5: socks5://$(hostname -I | awk '{print $1}'):${LISTEN_ADDR##*:}"
+ echo ""
+ echo "💡 快速测试:"
+ echo " curl --proxy http://127.0.0.1:${LISTEN_ADDR##*:} http://httpbin.org/ip"
+ echo ""
+ echo "📝 版本信息:"
+ /usr/local/bin/ech-workers --help 2>&1 | grep -E "(版本|Version)" | head -2 || true
+}
+
+# 主安装流程
+main() {
+ show_banner
+ check_system
+ install_dependencies
+ install_binary
+ create_config
+ create_systemd_service
+ setup_logrotate
+ configure_firewall
+ create_management_scripts
+ show_completion
+
+ log "安装完成!建议重启服务使所有配置生效。"
+ echo ""
+ read -p "是否立即启动服务?[Y/n]: " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]] || [ -z "$REPLY" ]; then
+ systemctl start ech-workers
+ systemctl enable ech-workers
+ success "服务已启动并设置为开机自启"
+ fi
+}
+
+# 运行主函数
+main "$@"
+EOF
+
+ chmod +x "$PACKAGE_DIR/install.sh"
+
+ # 创建 tar 包
+ tar -czf "${PACKAGE_DIR}.tar.gz" "$PACKAGE_DIR"
+
+ # 清理临时目录
+ rm -rf "$PACKAGE_DIR"
+
+ echo "✅ 打包完成: ${PACKAGE_DIR}.tar.gz"
+
+ - name: 🏷️ 重命名文件
+ run: |
+ cd ${{ env.OUTPUT_DIR }}
+
+ VERSION="${{ needs.build-check.outputs.build_version }}"
+ BUILD_TYPE="${{ matrix.build_type }}"
+
+ # 重命名主要文件
+ for ext in "" .sha256 .sha1 .md5 .b3sum; do
+ if [ -f "${{ env.PROJECT_NAME }}-armv7${steps.build.outputs.build_suffix}${ext}" ]; then
+ mv "${{ env.PROJECT_NAME }}-armv7${steps.build.outputs.build_suffix}${ext}" \
+ "${{ env.PROJECT_NAME }}-${VERSION}-armv7${BUILD_TYPE}${ext}"
+ fi
+ done
+
+ echo "📁 最终文件列表:"
+ ls -lh *
+
+ - name: 📤 上传构建产物
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.PROJECT_NAME }}-${{ needs.build-check.outputs.build_version }}-${{ matrix.build_type }}
+ path: ${{ env.OUTPUT_DIR }}/*
+ retention-days: 30
+ if-no-files-found: error
+
+ create-release:
+ runs-on: ubuntu-latest
+ needs: [build-check, build-armv7]
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
+
+ steps:
+ - name: 📥 下载所有构建产物
+ uses: actions/download-artifact@v4
+ with:
+ path: artifacts
+ pattern: ${{ env.PROJECT_NAME }}-*
+ merge-multiple: true
+
+ - name: 🏷️ 创建 GitHub Release
+ uses: softprops/action-gh-release@v1
+ with:
+ name: Release ${{ needs.build-check.outputs.build_version }}
+ body: |
+ # ech-workers Hi3798MV100 ARMv7 版本
+
+ ## 📋 版本信息
+ - **版本号**: ${{ needs.build-check.outputs.build_version }}
+ - **构建时间**: ${{ env.BUILD_DATE }}
+ - **目标设备**: Hi3798MV100 (ARMv7)
+ - **Go版本**: ${{ env.GO_VERSION }}
+
+ ## 📦 包含的构建
+ - **标准版本**: 动态链接库,体积较小
+ - **静态版本**: 完全静态编译,无需外部依赖
+
+ ## 🚀 快速开始
+ 1. 下载对应的 tar.gz 文件
+ 2. 解压: `tar -xzf ech-workers-*.tar.gz`
+ 3. 运行安装脚本: `sudo ./install.sh`
+
+ ## 🔧 使用说明
+ 详细使用说明请参考解压后的 README 文件
+
+ ## 📝 变更日志
+ ${{ github.event.head_commit.message }}
+
+ ## 🔒 校验和
+ 下载后请验证文件校验和确保完整性
+ draft: false
+ prerelease: false
+ files: |
+ artifacts/*.tar.gz
+ artifacts/*.sha256
+ artifacts/*.md5
+ artifacts/BUILD_INFO.txt
+
+ - name: 📢 发布通知
+ if: success()
+ run: |
+ echo "🎉 发布成功!"
+ echo "版本: ${{ needs.build-check.outputs.build_version }}"
+ echo "Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.build-check.outputs.build_version }}"
+
+ cleanup:
+ runs-on: ubuntu-latest
+ needs: [build-armv7, create-release]
+ if: always()
+
+ steps:
+ - name: 🧹 清理工作流
+ run: |
+ echo "🧹 清理构建缓存..."
+ if [ "${{ github.event.inputs.clean_build }}" = "true" ]; then
+ echo "清理所有缓存"
+ # 这里可以添加缓存清理逻辑
+ fi
+
+ echo "✅ 工作流执行完成"
+ echo "状态: ${{ job.status }}"
diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml
new file mode 100644
index 0000000..c39fa4a
--- /dev/null
+++ b/.github/workflows/build-ios.yml
@@ -0,0 +1,125 @@
+name: 🍏 Build iOS App
+
+on:
+ push:
+ branches: [ main, master ]
+ tags: [ 'ios-*' ]
+ pull_request:
+ branches: [ main, master ]
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Version tag'
+ required: false
+ default: 'v1.0.0'
+
+env:
+ GO_VERSION: '1.21'
+ IOS_DEPLOYMENT_TARGET: '15.0'
+
+jobs:
+ build-ios:
+ runs-on: macos-latest
+
+ steps:
+ - name: 📥 Checkout code
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ fetch-depth: 0
+
+ - name: 🔧 Setup Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: ${{ env.GO_VERSION }}
+ cache: true
+
+ - name: 🏗️ Setup iOS build environment
+ run: |
+ # 安装 gomobile
+ go install golang.org/x/mobile/cmd/gomobile@latest
+ ~/go/bin/gomobile init
+
+ # 检查 Xcode 版本
+ xcodebuild -version
+
+ - name: 🛠️ Build iOS framework
+ run: |
+ cd ios/bridge
+
+ # 编译为 iOS 框架
+ ~/go/bin/gomobile bind -target=ios \
+ -ldflags="-w -s" \
+ -o EchWorkers.xcframework \
+ .
+
+ ls -lh EchWorkers.xcframework
+
+ - name: 📦 Create unsigned IPA
+ run: |
+ # 创建简单的 iOS 应用包
+ mkdir -p Payload
+ mkdir -p Payload/ECHWorkers.app
+
+ # 创建 Info.plist
+ cat > Payload/ECHWorkers.app/Info.plist << EOF
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ECH SOCKS5 Proxy
+ CFBundleExecutable
+ ECHWorkers
+ CFBundleIdentifier
+ com.ech.workers.ios
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ECHWorkers
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
+EOF
+
+ # 压缩为 IPA
+ zip -qr ECHWorkers-unsigned.ipa Payload
+
+ - name: 📤 Upload artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: ech-workers-ios
+ path: |
+ ECHWorkers-unsigned.ipa
+ ios/bridge/EchWorkers.xcframework
+ retention-days: 30
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
deleted file mode 100644
index 513c2b5..0000000
--- a/.github/workflows/build.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-name: Release All Platforms
-
-on:
- release:
- types: [published]
- workflow_dispatch:
- inputs:
- version:
- description: 'Release tag(例如 v1.5.0 或 nightly-20251129)'
- required: true
- type: string
-
-permissions:
- contents: write
-
-jobs:
- # Main release job for all platforms
- release:
- runs-on: ubuntu-latest
- steps:
-
- - name: Free Disk Space (Ubuntu)
- if: matrix.target-platform == ''
- uses: jlumbroso/free-disk-space@main
- with:
- tool-cache: false
- android: true
- dotnet: true
- haskell: true
- large-packages: true
- docker-images: true
- swap-storage: true
-
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version: '1.25.0'
-
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - name: Install dependencies
- run: |
- sudo snap install zig --classic --beta
- docker pull crazymax/xgo:latest
- go install github.com/crazy-max/xgo@latest
- sudo apt install upx
-
- - name: Build
- run: |
- bash build.sh release ${{ matrix.build-type == 'lite' && 'lite' || '' }} ${{ matrix.target-platform }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Upload assets
- uses: softprops/action-gh-release@v2
- with:
- files: build/compress/*
- prerelease: false
- tag_name: ${{ inputs.version }}
-
-
-
-
diff --git a/.github/workflows/hi3798mv100.yml b/.github/workflows/hi3798mv100.yml
new file mode 100644
index 0000000..0a54bd2
--- /dev/null
+++ b/.github/workflows/hi3798mv100.yml
@@ -0,0 +1,306 @@
+name: Build for Hi3798MV100 (Fixed)
+
+on:
+ workflow_dispatch:
+ push:
+ branches: [ main, master ]
+ release:
+ types: [created]
+
+jobs:
+ build-hi3798:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: '1.21'
+ cache: true
+
+ - name: Install musl cross compiler (Fixed)
+ run: |
+ echo "安装交叉编译工具链..."
+
+ # 方法1: 使用 musl.cc(最简单)
+ #echo "方法1: 使用 musl.cc 工具链"
+ #wget -q https://musl.cc/arm-linux-musleabihf-cross.tgz
+ #tar -xzf arm-linux-musleabihf-cross.tgz
+ #export PATH="$PWD/arm-linux-musleabihf-cross/bin:$PATH"
+
+ # 验证
+ #echo "验证工具链..."
+ #arm-linux-musleabihf-gcc --version
+
+ # 方法2: 使用 apt 安装(备用)
+ echo "方法2: 安装备用工具链"
+ sudo apt-get update
+ sudo apt-get install -y \
+ gcc-arm-linux-gnueabihf \
+ gcc-aarch64-linux-gnu \
+ musl-tools
+
+ # 创建符号链接
+ sudo ln -sf /usr/bin/arm-linux-gnueabihf-gcc /usr/local/bin/arm-linux-musleabihf-gcc 2>/dev/null || true
+
+ - name: Build static binary
+ run: |
+ echo "开始构建..."
+
+ # 设置环境变量
+ export CC="arm-linux-musleabihf-gcc"
+ export GOOS="linux"
+ export GOARCH="arm"
+ export GOARM="7"
+ export CGO_ENABLED="1"
+
+ # 版本信息
+ VERSION="v1.0.0-$(date +%Y%m%d)"
+ COMMIT=$(git rev-parse --short HEAD)
+ DATE=$(date -u '+%Y-%m-%d_%H:%M:%S')
+
+ echo "构建信息:"
+ echo "- 版本: $VERSION"
+ echo "- Commit: $COMMIT"
+ echo "- 日期: $DATE"
+ echo "- 编译器: $CC"
+ which $CC
+
+ # 静态编译
+ echo "执行静态编译..."
+ go build -a -v \
+ -o "ech-workers-hi3798mv100" \
+ -ldflags="-w -s \
+ -linkmode external \
+ -extldflags '-static' \
+ -X 'main.version=$VERSION' \
+ -X 'main.commit=$COMMIT' \
+ -X 'main.buildTime=$DATE'" \
+ .
+
+ # 验证文件
+ echo "验证构建结果..."
+ file ech-workers-hi3798mv100
+ ls -lh ech-workers-hi3798mv100
+
+ # 检查是否静态链接
+ echo "检查链接状态..."
+ ldd ech-workers-hi3798mv100 2>&1 | grep -q "not a dynamic" && \
+ echo "✓ 静态链接成功" || \
+ echo "⚠ 可能不是完全静态"
+
+ - name: Build pure Go version (fallback)
+ run: |
+ echo "构建纯 Go 版本(备用)..."
+
+ export GOOS="linux"
+ export GOARCH="arm"
+ export GOARM="7"
+ export CGO_ENABLED="0"
+
+ VERSION="v1.0.0-purego-$(date +%Y%m%d)"
+
+ go build \
+ -o "ech-workers-hi3798mv100-purego" \
+ -ldflags="-w -s -X 'main.version=$VERSION'" \
+ .
+
+ file ech-workers-hi3798mv100-purego
+ ls -lh ech-workers-hi3798mv100-purego
+
+ - name: Create checksums
+ run: |
+ echo "创建校验和..."
+ for file in ech-workers-hi3798mv100*; do
+ if [ -f "$file" ] && [[ "$file" != *.sha256 ]] && [[ "$file" != *.md5 ]]; then
+ sha256sum "$file" > "$file.sha256"
+ md5sum "$file" > "$file.md5"
+ echo " $file:"
+ cat "$file.sha256"
+ fi
+ done
+
+ - name: Create release package
+ run: |
+ echo "创建发布包..."
+ mkdir -p release
+
+ # 复制文件
+ cp ech-workers-hi3798mv100* release/ 2>/dev/null || true
+
+ # 创建安装脚本
+ cat > release/install.sh << 'EOF'
+ #!/bin/bash
+ # ech-workers Hi3798MV100 安装脚本
+
+ set -e
+
+ echo "========================================"
+ echo " ech-workers Hi3798MV100 安装程序"
+ echo "========================================"
+
+ # 默认参数
+ DEVICE_IP=""
+ INSTALL_DIR="/usr/local/bin"
+ SERVICE_NAME="ech-workers"
+
+ # 解析参数
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ echo "使用方法: $0 [选项] <设备IP>"
+ echo "选项:"
+ echo " -h, --help 显示帮助"
+ echo " -d, --dir DIR 安装目录 (默认: /usr/local/bin)"
+ echo " -s, --service 创建 systemd 服务"
+ exit 0
+ ;;
+ -d|--dir)
+ INSTALL_DIR="$2"
+ shift 2
+ ;;
+ -s|--service)
+ CREATE_SERVICE=1
+ shift
+ ;;
+ *)
+ DEVICE_IP="$1"
+ shift
+ ;;
+ esac
+ done
+
+ if [ -z "$DEVICE_IP" ]; then
+ echo "错误: 必须指定设备IP地址"
+ echo "示例: $0 192.168.1.100"
+ exit 1
+ fi
+
+ # 选择要安装的版本
+ echo "选择安装版本:"
+ echo "1) 静态版本 (ech-workers-hi3798mv100)"
+ echo "2) 纯Go版本 (ech-workers-hi3798mv100-purego)"
+ read -p "请输入选择 [1-2] (默认 1): " choice
+ choice=${choice:-1}
+
+ case $choice in
+ 1) BINARY="ech-workers-hi3798mv100" ;;
+ 2) BINARY="ech-workers-hi3798mv100-purego" ;;
+ *) BINARY="ech-workers-hi3798mv100" ;;
+ esac
+
+ if [ ! -f "$BINARY" ]; then
+ echo "错误: 找不到文件 $BINARY"
+ exit 1
+ fi
+
+ echo "安装信息:"
+ echo "- 设备: $DEVICE_IP"
+ echo "- 版本: $BINARY"
+ echo "- 目录: $INSTALL_DIR"
+
+ # 传输文件
+ echo -e "\n传输文件..."
+ scp "$BINARY" root@${DEVICE_IP}:/tmp/ech-workers-new
+ scp "$BINARY.sha256" root@${DEVICE_IP}:/tmp/ 2>/dev/null || true
+
+ # 执行安装
+ echo -e "\n正在安装..."
+ ssh root@${DEVICE_IP} << SSH_EOF
+ set -e
+
+ echo "备份旧版本..."
+ if [ -f "$INSTALL_DIR/ech-workers" ]; then
+ BACKUP="\$INSTALL_DIR/ech-workers.backup.\$(date +%Y%m%d_%H%M%S)"
+ cp "\$INSTALL_DIR/ech-workers" "\$BACKUP"
+ echo "已备份到: \$BACKUP"
+ fi
+
+ echo "安装新版本..."
+ cp /tmp/ech-workers-new "\$INSTALL_DIR/ech-workers"
+ chmod +x "\$INSTALL_DIR/ech-workers"
+
+ echo -e "\n验证安装:"
+ file "\$INSTALL_DIR/ech-workers"
+ "\$INSTALL_DIR/ech-workers" --help 2>&1 | head -5
+
+ # 创建 systemd 服务
+ if [ -n "$CREATE_SERVICE" ]; then
+ echo -e "\n创建 systemd 服务..."
+ cat > /etc/systemd/system/ech-workers.service << SERVICE_EOF
+ [Unit]
+ Description=ECH Workers Proxy
+ After=network.target
+
+ [Service]
+ Type=simple
+ ExecStart=$INSTALL_DIR/ech-workers \\
+ -l 0.0.0.0:30000 \\
+ -f your-worker.workers.dev:443 \\
+ -token YOUR_TOKEN_HERE \\
+ -pyip backup.proxy.com:8080 \\
+ -ip 104.16.132.229
+ Restart=always
+ RestartSec=10
+
+ [Install]
+ WantedBy=multi-user.target
+ SERVICE_EOF
+
+ systemctl daemon-reload
+ systemctl enable ech-workers
+ echo "服务已创建并启用"
+ fi
+
+ echo -e "\n安装完成!"
+ echo "运行命令: \$INSTALL_DIR/ech-workers [参数]"
+ SSH_EOF
+
+ echo -e "\n✅ 安装完成!"
+ EOF
+
+ chmod +x release/install.sh
+
+ # 创建配置文件模板
+ cat > release/config-example.sh << 'EOF'
+ #!/bin/bash
+ # ech-workers 配置示例
+
+ # 基本配置
+ LISTEN_ADDR="0.0.0.0:30000"
+ WORKER_URL="your-app.workers.dev:443"
+ TOKEN="your_token_here"
+
+ # 高级配置
+ FALLBACK_PROXY="backup.proxy.com:8080"
+ TARGET_IP="104.16.132.229"
+ DNS_SERVER="1.1.1.1/dns-query"
+ ECH_DOMAIN="cloudflare-ech.com"
+
+ # 运行命令
+ CMD="/usr/local/bin/ech-workers \
+ -l \"\$LISTEN_ADDR\" \
+ -f \"\$WORKER_URL\" \
+ -token \"\$TOKEN\" \
+ -pyip \"\$FALLBACK_PROXY\" \
+ -ip \"\$TARGET_IP\" \
+ -dns \"\$DNS_SERVER\" \
+ -ech \"\$ECH_DOMAIN\""
+
+ echo "运行命令:"
+ echo \$CMD
+ # eval \$CMD
+ EOF
+
+ chmod +x release/config-example.sh
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: hi3798mv100-build
+ path: |
+ ech-workers-hi3798mv100*
+ release/
+ retention-days: 30
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e09f24d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+# iOS 构建产物
+ios/bridge/EchWorkers.xcframework
+Payload/
+*.ipa
+DerivedData/
diff --git a/README.md b/README.md
index dde97c8..8c5df01 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,56 @@
-```
-命令行执行如下:
-ech-win -l 127.0.0.1:30000 -f cf绑定域名[pages.dev]:443 -pyip tw.william.us.ci -token xxx -ip 优选域名或者ip(ipv4或ipv6)
-ech-win -f cf绑定域名:443 -pyip tw.william.us.ci -token xxx -ip 104.16.0.0
-ech-win -f cf绑定域名:443 -pyip 211.48.77.114:12312 -token xxx -ip 104.16.0.0
-
-Usage of ech-win:
- -dns string
- ECH 查询 DoH 服务器 (default "dns.alidns.com/dns-query")
- -ech string
- ECH 查询域名 (default "cloudflare-ech.com")
- -f string
- 服务端地址 (格式: x.x.workers.dev:443)
- -ip string
- 指定服务端 IP(绕过 DNS 解析)
- -l string
- 代理监听地址 (支持 SOCKS5 和 HTTP) (default "127.0.0.1:30000")
- -pyip string
- 代理服务器 IP(用于 Worker 连接回退)
- -token string
- 身份验证令牌
-```
-##### 注:workers、pages、snippets三种部署都支持, TOKEN=xxx 部署时请更换
+在hi3798mv100设备上部署了ech-workers代理服务,并且配置了systemd服务。以下是安装和设置过程的详细步骤总结:
+(Ubuntu 20.04.6 LTS (GNU/Linux 4.4.35_ecoo_81112068 armv7l0
+安装和设置过程
+1. 获取ech-workers程序
+确保你已经获得了ech-workers可执行程序,并将其放置到/usr/local/bin/目录下,并给予执行权限。
+
+bash
+# 假设ech-workers程序在当前目录
+sudo cp ech-workers /usr/local/bin/
+sudo chmod +x /usr/local/bin/ech-workers
+2. 创建systemd服务配置文件
+创建服务文件/etc/systemd/system/ech-workers.service,内容如下:
+
+[Unit]
+Description=ECH Workers Proxy Service
+After=network.target
+
+[Service]
+Type=simple
+User=root
+# 🤣🤣🤣🤣
+ExecStart=/usr/local/bin/ech-workers \
+ -l 0.0.0.0:30000 \
+ -f "xxxxxxxxxxx.workers.dev:443" \
+ -token "xxxxxxxx" \
+ -ip "xx.xx.xxx" \
+ -dns "dns.alidns.com/dns-query"
+Restart=on-failure # 仅在失败时重启,而不是一直重启
+RestartSec=10 # 重启间隔增加到10秒
+RestartPreventExitStatus=0 # 正常退出时不重启
+[Install]
+
+WantedBy=multi-user.target
+3. 重新加载systemd配置并启动服务
+bash
+# 重新加载systemd配置
+sudo systemctl daemon-reload
+# 启动服务
+sudo systemctl start ech-workers
+# 设置开机自启
+sudo systemctl enable ech-workers
+# 检查服务状态
+sudo systemctl status ech-workers
+
+## 🍏 iOS 构建
+
+### 构建未签名 IPA
+```bash
+# 安装依赖
+go install golang.org/x/mobile/cmd/gomobile@latest
+gomobile init
+
+# 构建 iOS 应用
+chmod +x scripts/build-ios.sh
+./scripts/build-ios.sh
+
diff --git a/ios/bridge/bridge.go b/ios/bridge/bridge.go
new file mode 100644
index 0000000..96c375c
--- /dev/null
+++ b/ios/bridge/bridge.go
@@ -0,0 +1,108 @@
+// +build ios
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "time"
+
+ "golang.org/x/mobile/app"
+ "golang.org/x/mobile/event/key"
+ "golang.org/x/mobile/event/lifecycle"
+ "golang.org/x/mobile/event/paint"
+ "golang.org/x/mobile/event/size"
+ "golang.org/x/mobile/event/touch"
+ "golang.org/x/mobile/gl"
+)
+
+// SOCKS5Server iOS SOCKS5 服务器实现
+type SOCKS5Server struct {
+ config *Config
+ running bool
+}
+
+// NewSOCKS5Server 创建新的 SOCKS5 服务器
+func NewSOCKS5Server(config *Config) *SOCKS5Server {
+ return &SOCKS5Server{
+ config: config,
+ running: false,
+ }
+}
+
+// Start 启动 SOCKS5 代理
+func (s *SOCKS5Server) Start() error {
+ if s.running {
+ return fmt.Errorf("server already running")
+ }
+
+ log.Printf("Starting SOCKS5 server on %s", s.config.ListenAddr)
+ s.running = true
+
+ // iOS 特定的 SOCKS5 实现
+ go s.runIOSProxy()
+
+ return nil
+}
+
+// Stop 停止 SOCKS5 代理
+func (s *SOCKS5Server) Stop() {
+ s.running = false
+ log.Println("SOCKS5 server stopped")
+}
+
+// runIOSProxy iOS 平台的代理实现
+func (s *SOCKS5Server) runIOSProxy() {
+ // iOS 特定的网络处理
+ // 这里需要实现 SOCKS5 协议处理
+}
+
+// Export iOS 接口函数
+//export StartSOCKS5Proxy
+func StartSOCKS5Proxy(listenAddr, workerURL, token string) int {
+ config := &Config{
+ ListenAddr: listenAddr,
+ WorkerURL: workerURL,
+ Token: token,
+ }
+
+ server := NewSOCKS5Server(config)
+ if err := server.Start(); err != nil {
+ return -1
+ }
+
+ return 0
+}
+
+//export StopSOCKS5Proxy
+func StopSOCKS5Proxy() {
+ // 停止代理实现
+}
+
+//export IsSOCKS5ProxyRunning
+func IsSOCKS5ProxyRunning() bool {
+ // 检查代理状态
+ return false
+}
+
+// iOS 应用主函数
+func main() {
+ app.Main(func(a app.App) {
+ var sz size.Event
+ for e := range a.Events() {
+ switch e := a.Filter(e).(type) {
+ case lifecycle.Event:
+ // 处理生命周期事件
+ case size.Event:
+ sz = e
+ case paint.Event:
+ // 绘制界面
+ a.EndPaint(e)
+ case touch.Event:
+ // 处理触摸事件
+ case key.Event:
+ // 处理键盘事件
+ }
+ }
+ })
+}
diff --git a/ios/bridge/go.mod b/ios/bridge/go.mod
new file mode 100644
index 0000000..cfc6622
--- /dev/null
+++ b/ios/bridge/go.mod
@@ -0,0 +1,13 @@
+module ech-workers-ios
+
+go 1.21
+
+replace github.com/hhsw2015/ech_workers => ../..
+
+require (
+ github.com/hhsw2015/ech_workers v0.0.0
+ golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57
+ golang.org/x/net v0.17.0
+)
+
+require golang.org/x/text v0.13.0 // indirect
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..0d7c854
--- /dev/null
+++ b/main.go
@@ -0,0 +1,106 @@
+// 添加构建标签
+//go:build !ios
+// +build !ios
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
+ "syscall"
+)
+
+func main() {
+ // 原有参数...
+ var (
+ listenAddr = flag.String("l", "127.0.0.1:30000", "监听地址")
+ serverAddr = flag.String("f", "", "服务端地址")
+ token = flag.String("token", "", "身份验证令牌")
+ socks5 = flag.Bool("socks5", false, "启用 SOCKS5 协议")
+ // ... 其他参数
+ )
+
+ flag.Parse()
+
+ // 如果启用了 SOCKS5,使用 SOCKS5 模式
+ if *socks5 {
+ startSOCKS5Proxy(*listenAddr, *serverAddr, *token)
+ } else {
+ // 原有逻辑
+ startHTTPProxy(*listenAddr, *serverAddr, *token)
+ }
+}
+
+// startSOCKS5Proxy 启动 SOCKS5 代理
+func startSOCKS5Proxy(listenAddr, serverAddr, token string) {
+ fmt.Println("Starting SOCKS5 proxy on", listenAddr)
+
+ config := &Config{
+ ListenAddr: listenAddr,
+ WorkerURL: serverAddr,
+ Token: token,
+ }
+
+ server := NewSOCKS5Server(config)
+ if err := server.Start(); err != nil {
+ log.Fatal("Failed to start SOCKS5 proxy:", err)
+ }
+
+ // 等待退出信号
+ sigCh := make(chan os.Signal, 1)
+ signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
+ <-sigCh
+
+ server.Stop()
+ fmt.Println("SOCKS5 proxy stopped")
+}
+
+// Config 配置结构体
+type Config struct {
+ ListenAddr string
+ WorkerURL string
+ Token string
+ SocksProxy string
+ PreferredIP string
+ DNSServer string
+ ECHDomain string
+}
+
+// SOCKS5Server SOCKS5 服务器
+type SOCKS5Server struct {
+ config *Config
+ running bool
+}
+
+// NewSOCKS5Server 创建 SOCKS5 服务器
+func NewSOCKS5Server(config *Config) *SOCKS5Server {
+ return &SOCKS5Server{
+ config: config,
+ running: false,
+ }
+}
+
+// Start 启动服务器
+func (s *SOCKS5Server) Start() error {
+ if s.running {
+ return fmt.Errorf("server already running")
+ }
+
+ // 实现 SOCKS5 服务器逻辑
+ log.Printf("SOCKS5 proxy started on %s", s.config.ListenAddr)
+ s.running = true
+
+ // 这里实现具体的 SOCKS5 代理逻辑
+ // 需要处理 SOCKS5 协议认证、连接转发等
+
+ return nil
+}
+
+// Stop 停止服务器
+func (s *SOCKS5Server) Stop() {
+ s.running = false
+ log.Println("SOCKS5 proxy stopped")
+}
diff --git a/mobile.go b/mobile.go
new file mode 100644
index 0000000..5db9a94
--- /dev/null
+++ b/mobile.go
@@ -0,0 +1,58 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "net/url"
+ "time"
+
+ // 导入原项目的包
+ ech "github.com/hhsw2015/ech_workers"
+)
+
+// Client 是一个移动端使用的客户端
+type Client struct {
+ cancel context.CancelFunc
+}
+
+// Start 启动代理服务,参数为:
+// listenAddr: 监听地址,例如 "127.0.0.1:30000"
+// workerURL: Cloudflare Worker地址,例如 "your-worker.workers.dev:443"
+// token: 身份验证令牌
+// socksAddr: SOCKS代理地址,例如 "192.168.1.100:1080",如果为空则不使用SOCKS
+// 返回一个错误
+func (c *Client) Start(listenAddr, workerURL, token, socksAddr string) error {
+ // 如果socksAddr不为空,设置SOCKS代理
+ if socksAddr != "" {
+ // 设置SOCKS代理环境变量,原项目可能需要通过环境变量或参数设置
+ // 这里假设原项目支持通过参数设置SOCKS代理
+ // 实际上,原项目可能不支持,所以需要修改原项目以支持SOCKS代理
+ // 我们假设原项目有一个SetSOCKSProxy函数
+ // 如果没有,我们需要修改原项目
+ }
+
+ // 原项目可能是一个阻塞的函数,我们需要在goroutine中运行
+ ctx, cancel := context.WithCancel(context.Background())
+ c.cancel = cancel
+
+ go func() {
+ // 调用原项目的启动函数,这里假设原项目有一个Run函数
+ // 注意:原项目可能需要参数,我们需要将其适配
+ err := ech.Run(ctx, listenAddr, workerURL, token)
+ if err != nil {
+ log.Printf("ech.Run error: %v", err)
+ }
+ }()
+
+ // 等待一段时间确保服务启动
+ time.Sleep(2 * time.Second)
+ return nil
+}
+
+// Stop 停止代理服务
+func (c *Client) Stop() {
+ if c.cancel != nil {
+ c.cancel()
+ }
+}
diff --git a/scripts/build-ios.sh b/scripts/build-ios.sh
new file mode 100644
index 0000000..728d414
--- /dev/null
+++ b/scripts/build-ios.sh
@@ -0,0 +1,209 @@
+#!/bin/bash
+# iOS 构建脚本
+
+set -e
+
+echo "🚀 开始构建 iOS SOCKS5 代理应用"
+echo "========================================"
+
+# 检查依赖
+check_dependencies() {
+ echo "🔍 检查依赖..."
+
+ # 检查 Go
+ if ! command -v go &> /dev/null; then
+ echo "❌ Go 未安装"
+ exit 1
+ fi
+ echo "✅ Go $(go version)"
+
+ # 检查 gomobile
+ if ! command -v gomobile &> /dev/null; then
+ echo "📦 安装 gomobile..."
+ go install golang.org/x/mobile/cmd/gomobile@latest
+ gomobile init
+ fi
+ echo "✅ gomobile 已安装"
+
+ # 检查 Xcode
+ if [ ! -d "/Applications/Xcode.app" ]; then
+ echo "❌ Xcode 未安装"
+ exit 1
+ fi
+ echo "✅ Xcode 已安装"
+}
+
+# 清理工作区
+clean_workspace() {
+ echo "🧹 清理工作区..."
+ rm -rf ios/bridge/EchWorkers.xcframework
+ rm -rf Payload
+ rm -rf *.ipa
+}
+
+# 构建 iOS 框架
+build_framework() {
+ echo "🛠️ 构建 iOS 框架..."
+
+ cd ios/bridge
+
+ # 下载依赖
+ go mod download
+
+ # 编译为 iOS 框架
+ gomobile bind -target=ios \
+ -ldflags="-w -s" \
+ -o EchWorkers.xcframework \
+ .
+
+ echo "✅ iOS 框架构建完成"
+
+ # 回到项目根目录
+ cd ../..
+}
+
+# 打包 IPA
+package_ipa() {
+ echo "📦 打包未签名 IPA..."
+
+ # 创建应用目录结构
+ mkdir -p Payload/ECHWorkers.app
+
+ # 创建 Info.plist
+ cat > Payload/ECHWorkers.app/Info.plist << EOF
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ECH SOCKS5 Proxy
+ CFBundleExecutable
+ ECHWorkers
+ CFBundleIdentifier
+ com.ech.workers.ios
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ECHWorkers
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+
+
+EOF
+
+ # 创建可执行文件占位符
+ touch Payload/ECHWorkers.app/ECHWorkers
+ chmod +x Payload/ECHWorkers.app/ECHWorkers
+
+ # 压缩为 IPA
+ zip -qr ech-workers-ios-unsigned.ipa Payload
+
+ echo "✅ IPA 打包完成: ech-workers-ios-unsigned.ipa"
+}
+
+# 创建安装说明
+create_readme() {
+ echo "📝 创建安装说明..."
+
+ cat > INSTALL-iOS.md << 'EOF'
+# iOS SOCKS5 代理应用安装指南
+
+## 应用功能
+- ✅ SOCKS5 代理服务器
+- ✅ Cloudflare Workers 中转
+- ✅ 本地端口转发
+- ✅ 简单的配置界面
+
+## 安装方法
+
+### 方法一:使用 AltStore (推荐)
+1. 在电脑上安装 AltServer: https://altstore.io
+2. 连接 iOS 设备到电脑
+3. 使用 AltServer 安装 AltStore 到手机
+4. 通过 AltStore 安装此 IPA
+
+### 方法二:使用 TrollStore (需要越狱)
+1. 安装 TrollStore: https://github.com/opa334/TrollStore
+2. 通过 TrollStore 安装此 IPA
+
+### 方法三:企业签名
+1. 使用 iOS App Signer 重新签名
+2. 使用企业证书分发
+
+## 使用方法
+1. 安装应用
+2. 在应用内配置:
+ - Server URL: 您的 Cloudflare Worker 地址
+ - Token: 身份验证令牌
+ - Port: 本地监听端口 (默认 1080)
+3. 启动代理
+4. 在系统设置中配置 SOCKS5 代理:
+ - 设置 → Wi-Fi → 当前网络 → 配置代理 → 手动
+ - 服务器: 127.0.0.1
+ - 端口: 1080
+
+## 注意事项
+- 未签名应用有7天有效期限制
+- 需要保持应用在后台运行
+- 某些网络可能限制本地回环地址
+EOF
+
+ echo "✅ 安装说明创建完成: INSTALL-iOS.md"
+}
+
+# 主流程
+main() {
+ check_dependencies
+ clean_workspace
+ build_framework
+ package_ipa
+ create_readme
+
+ echo ""
+ echo "🎉 iOS SOCKS5 代理应用构建完成!"
+ echo ""
+ echo "📦 生成的文件:"
+ echo " - ech-workers-ios-unsigned.ipa (未签名应用包)"
+ echo " - ios/bridge/EchWorkers.xcframework (iOS 框架)"
+ echo " - INSTALL-iOS.md (安装指南)"
+ echo ""
+ echo "📱 安装方法:"
+ echo " 使用 AltStore 或 TrollStore 安装到 iOS 设备"
+}
+
+# 执行主流程
+main "$@"