1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@ demo.toml
|
||||
*.log
|
||||
*.bak
|
||||
list.json
|
||||
iplist.json
|
||||
repos
|
||||
pages
|
||||
*_test
|
||||
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,5 +1,16 @@
|
||||
# 更新日志
|
||||
|
||||
4.2.0 - 2025-07-22
|
||||
---
|
||||
- CHANGE: 支持根据IP(CDIR)进行白名单与屏蔽
|
||||
- CHANGE: 进一步推进`json/v2`支持
|
||||
|
||||
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: 更新相关依赖
|
||||
|
||||
@@ -1 +1 @@
|
||||
4.1.7-rc.0
|
||||
4.2.0-rc.0
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
[相关文章](https://blog.wjqserver.com/categories/my-program/)
|
||||
|
||||
代理相关推广: [Thordata](https://www.thordata.com/?ls=github&lk=WJQserver),市面上最具性价比的代理服务商,便宜好用,来自全球195个国家城市的6000万IP,轮换住宅/原生ISP/无限量仅从$0.65/GB 起,新用户$1=5GB .联系客户可获得免费测试.
|
||||
|
||||
### 使用示例
|
||||
|
||||
```bash
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"encoding/json"
|
||||
"github.com/go-json-experiment/json"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"ghproxy/config"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/go-json-experiment/json"
|
||||
)
|
||||
|
||||
// Whitelist 用于存储白名单信息
|
||||
|
||||
@@ -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 `toml:"ipFilterFile"`
|
||||
}
|
||||
|
||||
/*
|
||||
[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,
|
||||
|
||||
@@ -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
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"
|
||||
]
|
||||
}
|
||||
3
go.mod
3
go.mod
@@ -13,8 +13,10 @@ 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/go-json-experiment/json v0.0.0-20250714165856-be8212f5270d
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/infinite-iroha/touka v0.3.1
|
||||
github.com/wjqserver/modembed v0.0.1
|
||||
@@ -22,6 +24,5 @@ require (
|
||||
|
||||
require (
|
||||
github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.6 // indirect
|
||||
github.com/go-json-experiment/json v0.0.0-20250714165856-be8212f5270d // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
)
|
||||
|
||||
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/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=
|
||||
|
||||
24
main.go
24
main.go
@@ -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,29 @@ 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)
|
||||
logger.Errorf("Failed to read IP filter list: %v", 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)
|
||||
logger.Errorf("Failed to initialize IP filter: %v", err)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
r.Use(ipBlockFilter)
|
||||
}
|
||||
}
|
||||
setupApi(cfg, r, version)
|
||||
setupPages(cfg, r)
|
||||
r.SetRedirectTrailingSlash(false)
|
||||
|
||||
Reference in New Issue
Block a user