diff --git a/.github/ISSUE_TEMPLATE/features_request.md b/.github/ISSUE_TEMPLATE/features_request.md new file mode 100644 index 0000000..603c02f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/features_request.md @@ -0,0 +1,20 @@ +--- +name: Features request +about: 提出新功能建议 +title: "[Features]" +labels: enhancement +assignees: '' + +--- + +### 功能描述 + +请简要描述您希望增加的功能。 + +### 功能原因 + +请说明您为什么需要这个功能。 + +### 功能实现 + +请详细描述您期望的功能实现。 \ No newline at end of file diff --git a/.github/workflows/build-nocache.yml b/.github/workflows/build-nocache.yml deleted file mode 100644 index 8f84886..0000000 --- a/.github/workflows/build-nocache.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Build NoCache Docker Image - -on: - workflow_dispatch: - push: - branches: - - 'main' - paths: - - 'VERSION' - -jobs: - docker: - runs-on: ubuntu-latest - env: - IMAGE_NAME: wjqserver/ghproxy # 定义镜像名称变量 - DOCKERFILE: docker/dockerfile/nocache/Dockerfile # 定义 Dockerfile 路径变量 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Load VERSION - run: | - if [ -f VERSION ]; then - echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV - else - echo "VERSION file not found!" && exit 1 - fi - - name: Wait for Compile - run: sleep 300s - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: 构建镜像 - uses: docker/build-push-action@v6 - with: - file: ./${{ env.DOCKERFILE }} - platforms: linux/amd64,linux/arm64 - push: true - tags: | - ${{ env.IMAGE_NAME }}:${{ env.VERSION }}-nocache - ${{ env.IMAGE_NAME }}:nocache diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b23b64..52c96f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,31 +21,35 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Load VERSION + - name: 加载版本号 run: | if [ -f VERSION ]; then echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV else echo "VERSION file not found!" && exit 1 fi - - name: Set up Go + - name: 安装 Go uses: actions/setup-go@v3 with: go-version: ${{ env.GO_VERSION }} - - name: Install UPX + - name: 安装 UPX run: | sudo apt-get update sudo apt-get install -y upx - - name: Build + - name: 编译 env: GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} run: | - CGO_ENABLED=0 go build -ldflags="-s -w" -o ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} ./main.go + CGO_ENABLED=0 go build -ldflags "-s -w -X main.version=${{ env.VERSION }}" -o ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} ./main.go upx -9 ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} - - name: Package + - name: 打包 run: | - tar -czvf ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}}.tar.gz ./${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} + mkdir ghproxyd + cp ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} ./ghproxyd/ + mv ./ghproxyd/${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} ./ghproxyd/${{ env.OUTPUT_BINARY }} + cp LICENSE ./ghproxyd/ + tar -czf ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}}.tar.gz -C ghproxyd . - name: Upload to GitHub Artifacts uses: actions/upload-artifact@v3 with: @@ -57,7 +61,7 @@ jobs: uses: ncipollo/release-action@v1 with: name: ${{ env.VERSION }} - artifacts: ./${{ env.OUTPUT_BINARY }}* + artifacts: ./${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}}.tar.gz token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ env.VERSION }} allowUpdates: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cae8bb..292085f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # 更新日志 +v1.7.0 +--- +- ADD: 加入`rate`模块,实现内置速率限制 +- CHANGE: 优化`blacklist`与`whitelist`模块的匹配算法,提升性能;由原先的完整匹配改为切片匹配,提升匹配效率 +- ADD: 加入`version`相关表示与API接口 +- ADD: 加入`rate`相关API接口 +- CHANGE: 优化前端界面,优化部分样式 +- CHANGE: 更新相关依赖库 +- CHANGE: 对编译打包进行改进,此后不再提供独立可执行文件,请改为拉取`tar.gz`压缩包 + 24w21d --- - PRE-RELEASE: 此版本是v1.7.0的预发布版本,请勿在生产环境中使用 @@ -8,7 +18,7 @@ - ADD: 前端新增 `重定向` 按钮,用于重定向到代理后的链接 - CHANGE: 优化输出代码块,使样式更加美观 - CHANGE: 更新相关依赖库 -- CHANGE: 对黑名单模块进行实验性功能优化,提升性能 +- CHANGE: 对黑名单模块进行实验性功能优化,提升性能(改进匹配算法,在切片后优先匹配user,减少无效匹配) 24w21c --- diff --git a/auth/blacklist.go b/auth/blacklist.go index f293ffc..3aac712 100644 --- a/auth/blacklist.go +++ b/auth/blacklist.go @@ -32,7 +32,6 @@ func LoadBlacklist(cfg *config.Config) { } } -// fullrepo: "owner/repo" or "owner/*" func CheckBlacklist(repouser string, user string, repo string) bool { return forRangeCheckBlacklist(blacklist.Blacklist, repouser, user) } @@ -46,28 +45,16 @@ func sliceRepoName_Blacklist(fullrepo string) (string, string) { } func forRangeCheckBlacklist(blist []string, fullrepo string, user string) bool { - // 先匹配user,再匹配user/*,最后匹配完整repo for _, blocked := range blist { - // 切片 users, _ := sliceRepoName_Blacklist(blocked) - logw("users:%s, blocked:%s", users, blocked) - // 匹配 user if user == users { - // 匹配 user/* if strings.HasSuffix(blocked, "/*") { return true } - // 匹配完整repo if fullrepo == blocked { return true } } } - - /* for _, blocked := range blist { - if blocked == fullrepo || (strings.HasSuffix(blocked, "/*") && strings.HasPrefix(repoUser, blocked[:len(blocked)-2])) { - return true - } - } */ return false } diff --git a/auth/whitelist.go b/auth/whitelist.go index 340be52..000b016 100644 --- a/auth/whitelist.go +++ b/auth/whitelist.go @@ -31,8 +31,8 @@ func LoadWhitelist(cfg *config.Config) { } } -func CheckWhitelist(fullrepo string) bool { - return forRangeCheckWhitelist(whitelist.Whitelist, fullrepo) +func CheckWhitelist(fullrepo string, user string, repo string) bool { + return forRangeCheckWhitelist(whitelist.Whitelist, fullrepo, user) } func sliceRepoName_Whitelist(fullrepo string) (string, string) { @@ -43,11 +43,16 @@ func sliceRepoName_Whitelist(fullrepo string) (string, string) { return s[0], s[1] } -func forRangeCheckWhitelist(wlist []string, fullrepo string) bool { - repoUser, _ := sliceRepoName_Whitelist(fullrepo) - for _, blocked := range wlist { - if blocked == fullrepo || (strings.HasSuffix(blocked, "/*") && strings.HasPrefix(repoUser, blocked[:len(blocked)-2])) { - return true +func forRangeCheckWhitelist(wlist []string, fullrepo string, user string) bool { + for _, passd := range wlist { + users, _ := sliceRepoName_Whitelist(passd) + if users == user { + if strings.HasSuffix(passd, "/*") { + return true + } + if fullrepo == passd { + return true + } } } return false diff --git a/config/config.toml b/config/config.toml index 8481dc1..2592dae 100644 --- a/config/config.toml +++ b/config/config.toml @@ -28,5 +28,5 @@ whitelistFile = "/data/ghproxy/config/whitelist.json" [rateLimit] enabled = false -ratePerMinute = 100 -burst = 10 +ratePerMinute = 180 +burst = 5 diff --git a/deploy/config.toml b/deploy/config.toml index ad7ff2e..4ad6468 100644 --- a/deploy/config.toml +++ b/deploy/config.toml @@ -25,3 +25,8 @@ enabled = false [whitelist] enabled = false whitelistFile = "/usr/local/ghproxy/config/whitelist.json" + +[rateLimit] +enabled = false +ratePerMinute = 180 +burst = 5 diff --git a/deploy/install.sh b/deploy/install.sh index 4ff84ae..c6ef3d1 100644 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -96,7 +96,9 @@ VERSION=$(curl -s https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/mai wget -q -O ${ghproxy_dir}/VERSION https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/VERSION # 下载ghproxy -wget -q -O ${ghproxy_dir}/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH +wget -q -O ${ghproxy_dir}/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH.tar.gz +install tar +tar -zxvf ${ghproxy_dir}/ghproxy-linux-$ARCH.tar.gz -C ${ghproxy_dir} chmod +x ${ghproxy_dir}/ghproxy # 下载pages diff --git a/docker/dockerfile/nocache/Dockerfile b/docker/dockerfile/nocache/Dockerfile index 31680a6..578d5d6 100644 --- a/docker/dockerfile/nocache/Dockerfile +++ b/docker/dockerfile/nocache/Dockerfile @@ -13,7 +13,7 @@ RUN mkdir -p /data/${APPLICATION}/config RUN mkdir -p /data/${APPLICATION}/log # 安装依赖 -RUN apk add --no-cache curl wget +RUN apk add --no-cache curl wget tar # 前端 RUN wget -O /data/www/index.html https://raw.githubusercontent.com/${USER}/${REPO}/main/pages/index.html @@ -21,7 +21,9 @@ RUN wget -O /data/www/favicon.ico https://raw.githubusercontent.com/${USER}/${RE # 后端 RUN VERSION=$(curl -s https://raw.githubusercontent.com/${USER}/${REPO}/main/VERSION) && \ - wget -O /data/${APPLICATION}/${APPLICATION} https://github.com/${USER}/${REPO}/releases/download/$VERSION/${APPLICATION}-${TARGETOS}-${TARGETARCH} + wget -O /data/${APPLICATION}/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz https://github.com/${USER}/${REPO}/releases/download/$VERSION/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz && \ + tar -zxvf /data/${APPLICATION}/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz -C /data/${APPLICATION} && \ + rm -rf /data/${APPLICATION}/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz RUN wget -O /usr/local/bin/init.sh https://raw.githubusercontent.com/${USER}/${REPO}/main/docker/dockerfile/nocache/init.sh # 拉取配置 diff --git a/docker/dockerfile/release/Dockerfile b/docker/dockerfile/release/Dockerfile index 9f50ae2..e668161 100644 --- a/docker/dockerfile/release/Dockerfile +++ b/docker/dockerfile/release/Dockerfile @@ -13,7 +13,7 @@ RUN mkdir -p /data/${APPLICATION}/config RUN mkdir -p /data/${APPLICATION}/log # 安装依赖 -RUN apk add --no-cache curl wget +RUN apk add --no-cache curl wget tar # 前端 RUN wget -O /data/www/index.html https://raw.githubusercontent.com/${USER}/${REPO}/main/pages/index.html @@ -21,7 +21,9 @@ RUN wget -O /data/www/favicon.ico https://raw.githubusercontent.com/${USER}/${RE # 后端 RUN VERSION=$(curl -s https://raw.githubusercontent.com/${USER}/${REPO}/main/VERSION) && \ - wget -O /data/${APPLICATION}/${APPLICATION} https://github.com/${USER}/${REPO}/releases/download/$VERSION/${APPLICATION}-${TARGETOS}-${TARGETARCH} + wget -O /data/${APPLICATION}/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz https://github.com/${USER}/${REPO}/releases/download/$VERSION/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz && \ + tar -zxvf /data/${APPLICATION}/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz -C /data/${APPLICATION} && \ + rm -rf /data/${APPLICATION}/${APPLICATION}-${TARGETOS}-${TARGETARCH}.tar.gz RUN wget -O /usr/local/bin/init.sh https://raw.githubusercontent.com/${USER}/${REPO}/main/docker/dockerfile/release/init.sh # 拉取配置 diff --git a/proxy/proxy.go b/proxy/proxy.go index 352d7c7..74b8008 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -37,6 +37,7 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter) gin.HandlerFu return func(c *gin.Context) { // 限制访问频率 if cfg.RateLimit.Enabled { + logInfo("Rate_Limit Enabled") if !limiter.Allow() { c.JSON(http.StatusTooManyRequests, gin.H{"error": "Too Many Requests"}) logWarning("%s %s %s %s %s 429-TooManyRequests", c.ClientIP(), c.Request.Method, c.Request.URL.RequestURI(), c.Request.Header.Get("User-Agent"), c.Request.Proto) @@ -64,7 +65,7 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter) gin.HandlerFu // 白名单检查 if cfg.Whitelist.Enabled { - whitelist := auth.CheckWhitelist(repouser) + whitelist := auth.CheckWhitelist(repouser, username, repo) if !whitelist { logErrMsg := fmt.Sprintf("%s %s %s %s %s Whitelist Blocked repo: %s", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, repouser) errMsg := fmt.Sprintf("Whitelist Blocked repo: %s", repouser)