This commit is contained in:
WJQSERVER 2024-11-04 18:38:12 +08:00
parent b1e3a9c1bd
commit f1ff3e9d27
12 changed files with 75 additions and 88 deletions

View file

@ -0,0 +1,20 @@
---
name: Features request
about: 提出新功能建议
title: "[Features]"
labels: enhancement
assignees: ''
---
### 功能描述
请简要描述您希望增加的功能。
### 功能原因
请说明您为什么需要这个功能。
### 功能实现
请详细描述您期望的功能实现。

View file

@ -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

View file

@ -21,31 +21,35 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Load VERSION - name: 加载版本号
run: | run: |
if [ -f VERSION ]; then if [ -f VERSION ]; then
echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV
else else
echo "VERSION file not found!" && exit 1 echo "VERSION file not found!" && exit 1
fi fi
- name: Set up Go - name: 安装 Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
- name: Install UPX - name: 安装 UPX
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y upx sudo apt-get install -y upx
- name: Build - name: 编译
env: env:
GOOS: ${{ matrix.goos }} GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }} GOARCH: ${{ matrix.goarch }}
run: | 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}} upx -9 ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}}
- name: Package - name: 打包
run: | 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 - name: Upload to GitHub Artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
@ -57,7 +61,7 @@ jobs:
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
name: ${{ env.VERSION }} name: ${{ env.VERSION }}
artifacts: ./${{ env.OUTPUT_BINARY }}* artifacts: ./${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}}.tar.gz
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ env.VERSION }} tag: ${{ env.VERSION }}
allowUpdates: true allowUpdates: true

View file

@ -1,5 +1,15 @@
# 更新日志 # 更新日志
v1.7.0
---
- ADD: 加入`rate`模块,实现内置速率限制
- CHANGE: 优化`blacklist``whitelist`模块的匹配算法,提升性能;由原先的完整匹配改为切片匹配,提升匹配效率
- ADD: 加入`version`相关表示与API接口
- ADD: 加入`rate`相关API接口
- CHANGE: 优化前端界面,优化部分样式
- CHANGE: 更新相关依赖库
- CHANGE: 对编译打包进行改进,此后不再提供独立可执行文件,请改为拉取`tar.gz`压缩包
24w21d 24w21d
--- ---
- PRE-RELEASE: 此版本是v1.7.0的预发布版本,请勿在生产环境中使用 - PRE-RELEASE: 此版本是v1.7.0的预发布版本,请勿在生产环境中使用
@ -8,7 +18,7 @@
- ADD: 前端新增 `重定向` 按钮,用于重定向到代理后的链接 - ADD: 前端新增 `重定向` 按钮,用于重定向到代理后的链接
- CHANGE: 优化输出代码块,使样式更加美观 - CHANGE: 优化输出代码块,使样式更加美观
- CHANGE: 更新相关依赖库 - CHANGE: 更新相关依赖库
- CHANGE: 对黑名单模块进行实验性功能优化,提升性能 - CHANGE: 对黑名单模块进行实验性功能优化,提升性能(改进匹配算法,在切片后优先匹配user,减少无效匹配)
24w21c 24w21c
--- ---

View file

@ -32,7 +32,6 @@ func LoadBlacklist(cfg *config.Config) {
} }
} }
// fullrepo: "owner/repo" or "owner/*"
func CheckBlacklist(repouser string, user string, repo string) bool { func CheckBlacklist(repouser string, user string, repo string) bool {
return forRangeCheckBlacklist(blacklist.Blacklist, repouser, user) 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 { func forRangeCheckBlacklist(blist []string, fullrepo string, user string) bool {
// 先匹配user,再匹配user/*,最后匹配完整repo
for _, blocked := range blist { for _, blocked := range blist {
// 切片
users, _ := sliceRepoName_Blacklist(blocked) users, _ := sliceRepoName_Blacklist(blocked)
logw("users:%s, blocked:%s", users, blocked)
// 匹配 user
if user == users { if user == users {
// 匹配 user/*
if strings.HasSuffix(blocked, "/*") { if strings.HasSuffix(blocked, "/*") {
return true return true
} }
// 匹配完整repo
if fullrepo == blocked { if fullrepo == blocked {
return true return true
} }
} }
} }
/* for _, blocked := range blist {
if blocked == fullrepo || (strings.HasSuffix(blocked, "/*") && strings.HasPrefix(repoUser, blocked[:len(blocked)-2])) {
return true
}
} */
return false return false
} }

View file

@ -31,8 +31,8 @@ func LoadWhitelist(cfg *config.Config) {
} }
} }
func CheckWhitelist(fullrepo string) bool { func CheckWhitelist(fullrepo string, user string, repo string) bool {
return forRangeCheckWhitelist(whitelist.Whitelist, fullrepo) return forRangeCheckWhitelist(whitelist.Whitelist, fullrepo, user)
} }
func sliceRepoName_Whitelist(fullrepo string) (string, string) { func sliceRepoName_Whitelist(fullrepo string) (string, string) {
@ -43,11 +43,16 @@ func sliceRepoName_Whitelist(fullrepo string) (string, string) {
return s[0], s[1] return s[0], s[1]
} }
func forRangeCheckWhitelist(wlist []string, fullrepo string) bool { func forRangeCheckWhitelist(wlist []string, fullrepo string, user string) bool {
repoUser, _ := sliceRepoName_Whitelist(fullrepo) for _, passd := range wlist {
for _, blocked := range wlist { users, _ := sliceRepoName_Whitelist(passd)
if blocked == fullrepo || (strings.HasSuffix(blocked, "/*") && strings.HasPrefix(repoUser, blocked[:len(blocked)-2])) { if users == user {
return true if strings.HasSuffix(passd, "/*") {
return true
}
if fullrepo == passd {
return true
}
} }
} }
return false return false

View file

@ -28,5 +28,5 @@ whitelistFile = "/data/ghproxy/config/whitelist.json"
[rateLimit] [rateLimit]
enabled = false enabled = false
ratePerMinute = 100 ratePerMinute = 180
burst = 10 burst = 5

View file

@ -25,3 +25,8 @@ enabled = false
[whitelist] [whitelist]
enabled = false enabled = false
whitelistFile = "/usr/local/ghproxy/config/whitelist.json" whitelistFile = "/usr/local/ghproxy/config/whitelist.json"
[rateLimit]
enabled = false
ratePerMinute = 180
burst = 5

View file

@ -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 wget -q -O ${ghproxy_dir}/VERSION https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/VERSION
# 下载ghproxy # 下载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 chmod +x ${ghproxy_dir}/ghproxy
# 下载pages # 下载pages

View file

@ -13,7 +13,7 @@ RUN mkdir -p /data/${APPLICATION}/config
RUN mkdir -p /data/${APPLICATION}/log 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 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) && \ 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 RUN wget -O /usr/local/bin/init.sh https://raw.githubusercontent.com/${USER}/${REPO}/main/docker/dockerfile/nocache/init.sh
# 拉取配置 # 拉取配置

View file

@ -13,7 +13,7 @@ RUN mkdir -p /data/${APPLICATION}/config
RUN mkdir -p /data/${APPLICATION}/log 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 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) && \ 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 RUN wget -O /usr/local/bin/init.sh https://raw.githubusercontent.com/${USER}/${REPO}/main/docker/dockerfile/release/init.sh
# 拉取配置 # 拉取配置

View file

@ -37,6 +37,7 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter) gin.HandlerFu
return func(c *gin.Context) { return func(c *gin.Context) {
// 限制访问频率 // 限制访问频率
if cfg.RateLimit.Enabled { if cfg.RateLimit.Enabled {
logInfo("Rate_Limit Enabled")
if !limiter.Allow() { if !limiter.Allow() {
c.JSON(http.StatusTooManyRequests, gin.H{"error": "Too Many Requests"}) 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) 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 { if cfg.Whitelist.Enabled {
whitelist := auth.CheckWhitelist(repouser) whitelist := auth.CheckWhitelist(repouser, username, repo)
if !whitelist { 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) 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) errMsg := fmt.Sprintf("Whitelist Blocked repo: %s", repouser)