4.2.0-rc.0

This commit is contained in:
wjqserver
2025-07-22 16:37:59 +08:00
parent 95dd34a456
commit d2d9ad1db7
12 changed files with 139 additions and 15 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@ demo.toml
*.log
*.bak
list.json
iplist.json
repos
pages
*_test

View File

@@ -1,5 +1,11 @@
# 更新日志
4.2.0-rc.0 - 2025-07-22
---
- PRE-RELEASE: v4.2.0-rc.0是v4.2.0预发布版本,请勿在生产环境中使用;
- CHANGE: 支持根据IP(CDIR)进行白名单与屏蔽
- CHANGE: 深化json/v2改革, 预备go1.25 json/v2
4.1.7 - 2025-07-20
---
- CHANGE: 更新相关依赖

View File

@@ -1 +1 @@
4.1.7-rc.0
4.2.0-rc.0

View File

@@ -7,7 +7,7 @@ import (
"strings"
"sync"
"encoding/json"
"github.com/go-json-experiment/json"
)
type Blacklist struct {

60
auth/ipfilter.go Normal file
View File

@@ -0,0 +1,60 @@
package auth
import (
"fmt"
"ghproxy/config"
"os"
"github.com/go-json-experiment/json"
"github.com/go-json-experiment/json/jsontext"
)
func ReadIPFilterList(cfg *config.Config) (whitelist []string, blacklist []string, err error) {
if cfg.IPFilter.IPFilterFile == "" {
return nil, nil, nil
}
// 检查文件是否存在, 不存在则创建空json
if _, err := os.Stat(cfg.IPFilter.IPFilterFile); os.IsNotExist(err) {
if err := CreateEmptyIPFilterFile(cfg.IPFilter.IPFilterFile); err != nil {
return nil, nil, fmt.Errorf("failed to create empty IP filter file: %w", err)
}
}
data, err := os.ReadFile(cfg.IPFilter.IPFilterFile)
if err != nil {
return nil, nil, fmt.Errorf("failed to read IP filter file: %w", err)
}
var ipFilterData struct {
AllowList []string `json:"allow"`
BlockList []string `json:"block"`
}
if err := json.Unmarshal(data, &ipFilterData); err != nil {
return nil, nil, fmt.Errorf("invalid IP filter file format: %w", err)
}
return ipFilterData.AllowList, ipFilterData.BlockList, nil
}
// 创建空列表json
func CreateEmptyIPFilterFile(filePath string) error {
emptyData := struct {
AllowList []string `json:"allow"`
BlockList []string `json:"block"`
}{
AllowList: []string{},
BlockList: []string{},
}
jsonData, err := json.Marshal(emptyData, jsontext.Multiline(true), jsontext.WithIndent(" "))
if err != nil {
return fmt.Errorf("failed to marshal empty IP filter data: %w", err)
}
err = os.WriteFile(filePath, jsonData, 0644)
if err != nil {
return fmt.Errorf("failed to write empty IP filter file: %w", err)
}
return nil
}

View File

@@ -1,12 +1,13 @@
package auth
import (
"encoding/json"
"fmt"
"ghproxy/config"
"os"
"strings"
"sync"
"github.com/go-json-experiment/json"
)
// Whitelist 用于存储白名单信息

View File

@@ -7,18 +7,19 @@ import (
)
type Config struct {
Server ServerConfig
Httpc HttpcConfig
GitClone GitCloneConfig
Shell ShellConfig
Pages PagesConfig
Log LogConfig
Auth AuthConfig
Blacklist BlacklistConfig
Whitelist WhitelistConfig
RateLimit RateLimitConfig
Outbound OutboundConfig
Docker DockerConfig
Server ServerConfig `toml:"server"`
Httpc HttpcConfig `toml:"httpc"`
GitClone GitCloneConfig `toml:"gitclone"`
Shell ShellConfig `toml:"shell"`
Pages PagesConfig `toml:"pages"`
Log LogConfig `toml:"log"`
Auth AuthConfig `toml:"auth"`
Blacklist BlacklistConfig `toml:"blacklist"`
Whitelist WhitelistConfig `toml:"whitelist"`
IPFilter IPFilterConfig `toml:"ipFilter"`
RateLimit RateLimitConfig `toml:"rateLimit"`
Outbound OutboundConfig `toml:"outbound"`
Docker DockerConfig `toml:"docker"`
}
/*
@@ -128,6 +129,13 @@ type WhitelistConfig struct {
WhitelistFile string `toml:"whitelistFile"`
}
type IPFilterConfig struct {
Enabled bool `toml:"enabled"`
EnableAllowList bool `toml:"enableAllowList"`
EnableBlockList bool `toml:"enableBlockList"`
IPFilterFile string
}
/*
[rateLimit]
enabled = false
@@ -273,6 +281,12 @@ func DefaultConfig() *Config {
Enabled: false,
WhitelistFile: "/data/ghproxy/config/whitelist.json",
},
IPFilter: IPFilterConfig{
Enabled: false,
IPFilterFile: "/data/ghproxy/config/ipfilter.json",
EnableAllowList: false,
EnableBlockList: false,
},
RateLimit: RateLimitConfig{
Enabled: false,
RatePerMinute: 100,

View File

@@ -49,6 +49,12 @@ enabled = false
enabled = false
whitelistFile = "/data/ghproxy/config/whitelist.json"
[ipFilter]
enabled = false
enableAllowList = false
enableBlockList = false
ipFilterFile = "/data/ghproxy/config/ipfilter.json"
[rateLimit]
enabled = false
ratePerMinute = 180

11
config/ipfilter.json Normal file
View File

@@ -0,0 +1,11 @@
{
"allow": [
"127.0.0.1",
"192.168.1.0/24",
"::1"
],
"block": [
"10.0.0.0/8",
"192.168.1.0/24"
]
}

1
go.mod
View File

@@ -13,6 +13,7 @@ require (
github.com/WJQSERVER-STUDIO/go-utils/limitreader v0.0.2
github.com/fenthope/bauth v0.0.1
github.com/fenthope/ikumi v0.0.2
github.com/fenthope/ipfilter v0.0.1
github.com/fenthope/reco v0.0.3
github.com/fenthope/record v0.0.3
github.com/hashicorp/golang-lru/v2 v2.0.7

2
go.sum
View File

@@ -10,6 +10,8 @@ github.com/fenthope/bauth v0.0.1 h1:+4UIQshGx3mYD4L3f2S4MLZOi5PWU7fU5GK3wsZvwzE=
github.com/fenthope/bauth v0.0.1/go.mod h1:1fveTpgfR1p+WXQ8MXm9BfBCeNYi55j23jxCOGOvBSA=
github.com/fenthope/ikumi v0.0.2 h1:5oaSTf/Msp7M2O3o/X20omKWEQbFhX4KV0CVF21oCdk=
github.com/fenthope/ikumi v0.0.2/go.mod h1:IYbxzOGndZv/yRrbVMyV6dxh06X2wXCbfxrTRM1IruU=
github.com/fenthope/ipfilter v0.0.1 h1:HrYAyixCMvsDAz36GRyFfyCNtrgYwzrhMcY0XV7fGcM=
github.com/fenthope/ipfilter v0.0.1/go.mod h1:QfY0GrpG0D82HROgdH4c9eog4js42ghLIfl/iM4MvvY=
github.com/fenthope/reco v0.0.3 h1:RmnQ0D9a8PWtwOODawitTe4BztTnS9wYwrDbipISNq4=
github.com/fenthope/reco v0.0.3/go.mod h1:mDkGLHte5udWTIcjQTxrABRcf56SSdxBOCLgrRDwI/Y=
github.com/fenthope/record v0.0.3 h1:v5urgs5LAkLMlljAT/MjW8fWuRHXPnAraTem5ui7rm4=

22
main.go
View File

@@ -21,6 +21,7 @@ import (
"ghproxy/weakcache"
"github.com/fenthope/ikumi"
"github.com/fenthope/ipfilter"
"github.com/fenthope/reco"
"github.com/fenthope/record"
"github.com/infinite-iroha/touka"
@@ -366,6 +367,27 @@ func main() {
Burst: cfg.RateLimit.Burst,
}))
}
if cfg.IPFilter.Enabled {
var err error
ipAllowList, ipBlockList, err := auth.ReadIPFilterList(cfg)
if err != nil {
fmt.Printf("Failed to read IP filter list: %v\n", err)
os.Exit(1)
}
ipBlockFilter, err := ipfilter.NewIPFilter(ipfilter.IPFilterConfig{
EnableAllowList: cfg.IPFilter.EnableAllowList,
EnableBlockList: cfg.IPFilter.EnableBlockList,
AllowList: ipAllowList,
BlockList: ipBlockList,
})
if err != nil {
fmt.Printf("Failed to initialize IP filter: %v\n", err)
os.Exit(1)
} else {
r.Use(ipBlockFilter)
}
}
setupApi(cfg, r, version)
setupPages(cfg, r)
r.SetRedirectTrailingSlash(false)