4.2.0-rc.0
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@ demo.toml
|
|||||||
*.log
|
*.log
|
||||||
*.bak
|
*.bak
|
||||||
list.json
|
list.json
|
||||||
|
iplist.json
|
||||||
repos
|
repos
|
||||||
pages
|
pages
|
||||||
*_test
|
*_test
|
||||||
@@ -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
|
4.1.7 - 2025-07-20
|
||||||
---
|
---
|
||||||
- CHANGE: 更新相关依赖
|
- CHANGE: 更新相关依赖
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
4.1.7-rc.0
|
4.2.0-rc.0
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"encoding/json"
|
"github.com/go-json-experiment/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Blacklist struct {
|
type Blacklist struct {
|
||||||
|
|||||||
60
auth/ipfilter.go
Normal file
60
auth/ipfilter.go
Normal 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
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"ghproxy/config"
|
"ghproxy/config"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/go-json-experiment/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Whitelist 用于存储白名单信息
|
// Whitelist 用于存储白名单信息
|
||||||
|
|||||||
@@ -7,18 +7,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Server ServerConfig
|
Server ServerConfig `toml:"server"`
|
||||||
Httpc HttpcConfig
|
Httpc HttpcConfig `toml:"httpc"`
|
||||||
GitClone GitCloneConfig
|
GitClone GitCloneConfig `toml:"gitclone"`
|
||||||
Shell ShellConfig
|
Shell ShellConfig `toml:"shell"`
|
||||||
Pages PagesConfig
|
Pages PagesConfig `toml:"pages"`
|
||||||
Log LogConfig
|
Log LogConfig `toml:"log"`
|
||||||
Auth AuthConfig
|
Auth AuthConfig `toml:"auth"`
|
||||||
Blacklist BlacklistConfig
|
Blacklist BlacklistConfig `toml:"blacklist"`
|
||||||
Whitelist WhitelistConfig
|
Whitelist WhitelistConfig `toml:"whitelist"`
|
||||||
RateLimit RateLimitConfig
|
IPFilter IPFilterConfig `toml:"ipFilter"`
|
||||||
Outbound OutboundConfig
|
RateLimit RateLimitConfig `toml:"rateLimit"`
|
||||||
Docker DockerConfig
|
Outbound OutboundConfig `toml:"outbound"`
|
||||||
|
Docker DockerConfig `toml:"docker"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -128,6 +129,13 @@ type WhitelistConfig struct {
|
|||||||
WhitelistFile string `toml:"whitelistFile"`
|
WhitelistFile string `toml:"whitelistFile"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IPFilterConfig struct {
|
||||||
|
Enabled bool `toml:"enabled"`
|
||||||
|
EnableAllowList bool `toml:"enableAllowList"`
|
||||||
|
EnableBlockList bool `toml:"enableBlockList"`
|
||||||
|
IPFilterFile string
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[rateLimit]
|
[rateLimit]
|
||||||
enabled = false
|
enabled = false
|
||||||
@@ -273,6 +281,12 @@ func DefaultConfig() *Config {
|
|||||||
Enabled: false,
|
Enabled: false,
|
||||||
WhitelistFile: "/data/ghproxy/config/whitelist.json",
|
WhitelistFile: "/data/ghproxy/config/whitelist.json",
|
||||||
},
|
},
|
||||||
|
IPFilter: IPFilterConfig{
|
||||||
|
Enabled: false,
|
||||||
|
IPFilterFile: "/data/ghproxy/config/ipfilter.json",
|
||||||
|
EnableAllowList: false,
|
||||||
|
EnableBlockList: false,
|
||||||
|
},
|
||||||
RateLimit: RateLimitConfig{
|
RateLimit: RateLimitConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
RatePerMinute: 100,
|
RatePerMinute: 100,
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ enabled = false
|
|||||||
enabled = false
|
enabled = false
|
||||||
whitelistFile = "/data/ghproxy/config/whitelist.json"
|
whitelistFile = "/data/ghproxy/config/whitelist.json"
|
||||||
|
|
||||||
|
[ipFilter]
|
||||||
|
enabled = false
|
||||||
|
enableAllowList = false
|
||||||
|
enableBlockList = false
|
||||||
|
ipFilterFile = "/data/ghproxy/config/ipfilter.json"
|
||||||
|
|
||||||
[rateLimit]
|
[rateLimit]
|
||||||
enabled = false
|
enabled = false
|
||||||
ratePerMinute = 180
|
ratePerMinute = 180
|
||||||
|
|||||||
11
config/ipfilter.json
Normal file
11
config/ipfilter.json
Normal 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
1
go.mod
@@ -13,6 +13,7 @@ require (
|
|||||||
github.com/WJQSERVER-STUDIO/go-utils/limitreader v0.0.2
|
github.com/WJQSERVER-STUDIO/go-utils/limitreader v0.0.2
|
||||||
github.com/fenthope/bauth v0.0.1
|
github.com/fenthope/bauth v0.0.1
|
||||||
github.com/fenthope/ikumi v0.0.2
|
github.com/fenthope/ikumi v0.0.2
|
||||||
|
github.com/fenthope/ipfilter v0.0.1
|
||||||
github.com/fenthope/reco v0.0.3
|
github.com/fenthope/reco v0.0.3
|
||||||
github.com/fenthope/record v0.0.3
|
github.com/fenthope/record v0.0.3
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -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/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 h1:5oaSTf/Msp7M2O3o/X20omKWEQbFhX4KV0CVF21oCdk=
|
||||||
github.com/fenthope/ikumi v0.0.2/go.mod h1:IYbxzOGndZv/yRrbVMyV6dxh06X2wXCbfxrTRM1IruU=
|
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 h1:RmnQ0D9a8PWtwOODawitTe4BztTnS9wYwrDbipISNq4=
|
||||||
github.com/fenthope/reco v0.0.3/go.mod h1:mDkGLHte5udWTIcjQTxrABRcf56SSdxBOCLgrRDwI/Y=
|
github.com/fenthope/reco v0.0.3/go.mod h1:mDkGLHte5udWTIcjQTxrABRcf56SSdxBOCLgrRDwI/Y=
|
||||||
github.com/fenthope/record v0.0.3 h1:v5urgs5LAkLMlljAT/MjW8fWuRHXPnAraTem5ui7rm4=
|
github.com/fenthope/record v0.0.3 h1:v5urgs5LAkLMlljAT/MjW8fWuRHXPnAraTem5ui7rm4=
|
||||||
|
|||||||
22
main.go
22
main.go
@@ -21,6 +21,7 @@ import (
|
|||||||
"ghproxy/weakcache"
|
"ghproxy/weakcache"
|
||||||
|
|
||||||
"github.com/fenthope/ikumi"
|
"github.com/fenthope/ikumi"
|
||||||
|
"github.com/fenthope/ipfilter"
|
||||||
"github.com/fenthope/reco"
|
"github.com/fenthope/reco"
|
||||||
"github.com/fenthope/record"
|
"github.com/fenthope/record"
|
||||||
"github.com/infinite-iroha/touka"
|
"github.com/infinite-iroha/touka"
|
||||||
@@ -366,6 +367,27 @@ func main() {
|
|||||||
Burst: cfg.RateLimit.Burst,
|
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)
|
setupApi(cfg, r, version)
|
||||||
setupPages(cfg, r)
|
setupPages(cfg, r)
|
||||||
r.SetRedirectTrailingSlash(false)
|
r.SetRedirectTrailingSlash(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user