mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2025-12-06 14:59:18 +08:00
@@ -40,6 +40,7 @@ type APIGroup struct {
|
||||
WafPrivateInfoApi
|
||||
WafCacheRuleApi
|
||||
WafTunnelApi
|
||||
WafVpConfigApi
|
||||
}
|
||||
|
||||
var APIGroupAPP = new(APIGroup)
|
||||
|
||||
44
api/waf_vpconfig_api.go
Normal file
44
api/waf_vpconfig_api.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"SamWaf/global"
|
||||
"SamWaf/model/common/response"
|
||||
"SamWaf/model/request"
|
||||
response2 "SamWaf/model/response"
|
||||
"SamWaf/wafconfig"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type WafVpConfigApi struct {
|
||||
}
|
||||
|
||||
// UpdateIpWhitelistApi 更新IP白名单配置
|
||||
func (w *WafVpConfigApi) UpdateIpWhitelistApi(c *gin.Context) {
|
||||
var req request.WafVpConfigIpWhitelistUpdateReq
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err == nil {
|
||||
|
||||
// 调用配置文件更新函数
|
||||
err = wafconfig.UpdateIpWhitelist(req.IpWhitelist)
|
||||
if err != nil {
|
||||
response.FailWithMessage("更新IP白名单失败: "+err.Error(), c)
|
||||
} else {
|
||||
response.OkWithMessage("更新IP白名单成功", c)
|
||||
}
|
||||
} else {
|
||||
response.FailWithMessage("解析请求失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
// GetIpWhitelistApi 获取IP白名单配置
|
||||
func (w *WafVpConfigApi) GetIpWhitelistApi(c *gin.Context) {
|
||||
// 直接从全局变量获取IP白名单
|
||||
ipWhitelist := global.GWAF_IP_WHITELIST
|
||||
|
||||
// 构造响应数据
|
||||
resp := response2.WafVpConfigIpWhitelistGetResp{
|
||||
IpWhitelist: ipWhitelist,
|
||||
}
|
||||
|
||||
response.OkWithDetailed(resp, "获取IP白名单成功", c)
|
||||
}
|
||||
@@ -65,6 +65,9 @@ var (
|
||||
GWAF_CUSTOM_SERVER_NAME string // 当前服务器自定义名称
|
||||
GWAF_TENANT_ID string = "SamWafCom" // 当前租户ID
|
||||
|
||||
//管理端访问控制
|
||||
GWAF_IP_WHITELIST string = "0.0.0.0/0,::/0" //IP白名单 后台默认放行所有
|
||||
|
||||
//zlog 日志相关信息
|
||||
GWAF_LOG_OUTPUT_FORMAT string = "console" //zlog输出格式 控制台格式console,json格式
|
||||
GWAF_RELEASE string = "false" // 当前是否为发行版
|
||||
|
||||
51
middleware/ip_whitelist_middleware.go
Normal file
51
middleware/ip_whitelist_middleware.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"SamWaf/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IPWhitelist IP白名单中间件
|
||||
func IPWhitelist() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
clientIP := c.ClientIP()
|
||||
allowed := false
|
||||
|
||||
allowedIPs := strings.Split(global.GWAF_IP_WHITELIST, ",")
|
||||
if global.GWAF_IP_WHITELIST == "0.0.0.0/0,::/0" {
|
||||
allowed = true
|
||||
} else if len(allowedIPs) == 0 {
|
||||
allowed = true
|
||||
} else {
|
||||
for _, ip := range allowedIPs {
|
||||
if ip == "0.0.0.0/0" || ip == "::/0" {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
if isIPMatch(clientIP, ip) {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !allowed {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
|
||||
"message": "Access denied",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// 支持 CIDR 范围匹配,例如 "192.168.0.0/16"
|
||||
func isIPMatch(clientIP, allowed string) bool {
|
||||
if _, ipNet, err := net.ParseCIDR(allowed); err == nil {
|
||||
return ipNet.Contains(net.ParseIP(clientIP))
|
||||
}
|
||||
return clientIP == allowed
|
||||
}
|
||||
6
model/request/waf_vpconfig_req.go
Normal file
6
model/request/waf_vpconfig_req.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package request
|
||||
|
||||
// WafVpConfigIpWhitelistUpdateReq IP白名单更新请求
|
||||
type WafVpConfigIpWhitelistUpdateReq struct {
|
||||
IpWhitelist string `json:"ip_whitelist"` // IP白名单,多个IP用逗号分隔
|
||||
}
|
||||
6
model/response/waf_vpconfig_resp.go
Normal file
6
model/response/waf_vpconfig_resp.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package response
|
||||
|
||||
// WafVpConfigIpWhitelistGetResp IP白名单获取响应
|
||||
type WafVpConfigIpWhitelistGetResp struct {
|
||||
IpWhitelist string `json:"ip_whitelist"` // IP白名单,多个IP用逗号分隔
|
||||
}
|
||||
@@ -38,6 +38,7 @@ type ApiGroup struct {
|
||||
WafPrivateInfoRouter
|
||||
WafCacheRuleRouter
|
||||
WafTunnelRouter
|
||||
WafVpConfigRouter
|
||||
}
|
||||
type PublicApiGroup struct {
|
||||
LoginRouter
|
||||
|
||||
16
router/waf_vpconfig_router.go
Normal file
16
router/waf_vpconfig_router.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"SamWaf/api"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type WafVpConfigRouter struct {
|
||||
}
|
||||
|
||||
func (receiver *WafVpConfigRouter) InitWafVpConfigRouter(group *gin.RouterGroup) {
|
||||
wafVpConfigApi := api.APIGroupAPP.WafVpConfigApi
|
||||
router := group.Group("")
|
||||
router.POST("/samwaf/vipconfig/updateIpWhitelist", wafVpConfigApi.UpdateIpWhitelistApi)
|
||||
router.GET("/samwaf/vipconfig/getIpWhitelist", wafVpConfigApi.GetIpWhitelistApi)
|
||||
}
|
||||
@@ -102,6 +102,13 @@ func LoadAndInitConfig() {
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
//配置和提取白名单
|
||||
if config.IsSet("security.ip_whitelist") {
|
||||
global.GWAF_IP_WHITELIST = config.GetString("security.ip_whitelist")
|
||||
} else {
|
||||
config.Set("security.ip_whitelist", global.GWAF_IP_WHITELIST)
|
||||
configChanged = true
|
||||
}
|
||||
// 只有在配置发生变化时才写入文件
|
||||
if configChanged {
|
||||
err := config.WriteConfig()
|
||||
@@ -115,3 +122,55 @@ func LoadAndInitConfig() {
|
||||
fmt.Printf("%s\tINFO\tuser_code:%s ,soft_id:%s\n",
|
||||
currentTime, global.GWAF_USER_CODE, global.GWAF_TENANT_ID)
|
||||
}
|
||||
|
||||
// UpdateIpWhitelist 更新IP白名单配置
|
||||
func UpdateIpWhitelist(ipWhitelist string) error {
|
||||
// 格式化当前时间为指定格式
|
||||
currentTime := time.Now().Format("2006-01-02 15:04:05.000")
|
||||
|
||||
// 判断配置目录是否存在
|
||||
configDir := utils.GetCurrentDir() + "/conf/"
|
||||
if _, err := os.Stat(configDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(configDir, os.ModePerm); err != nil {
|
||||
fmt.Printf("%s\tERROR\t创建config目录失败:%v\n", currentTime, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
config := viper.New()
|
||||
config.AddConfigPath(configDir) // 文件所在目录
|
||||
config.SetConfigName("config") // 文件名
|
||||
config.SetConfigType("yml") // 文件类型
|
||||
|
||||
// 读取配置文件
|
||||
if err := config.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
fmt.Printf("%s\tWARN\t找不到配置文件..\n", currentTime)
|
||||
config.Set("local_port", global.GWAF_LOCAL_SERVER_PORT)
|
||||
err = config.SafeWriteConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("%s\tERROR\t配置文件出错..\n", currentTime)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 更新IP白名单配置
|
||||
config.Set("security.ip_whitelist", ipWhitelist)
|
||||
|
||||
// 更新全局变量
|
||||
global.GWAF_IP_WHITELIST = ipWhitelist
|
||||
|
||||
// 写入配置文件
|
||||
err := config.WriteConfig()
|
||||
if err != nil {
|
||||
fmt.Printf("%s\tERROR\twrite config failed:%v\n", currentTime, err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%s\tINFO\tIP whitelist config updated\n", currentTime)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ type WafWebManager struct {
|
||||
func (web *WafWebManager) initRouter(r *gin.Engine) {
|
||||
|
||||
PublicRouterGroup := r.Group("")
|
||||
PublicRouterGroup.Use(middleware.SecApi())
|
||||
PublicRouterGroup.Use(middleware.SecApi(), middleware.IPWhitelist())
|
||||
router.PublicApiGroupApp.InitLoginRouter(PublicRouterGroup)
|
||||
router.PublicApiGroupApp.InitCenterRouter(PublicRouterGroup) //注册中心接收接口
|
||||
|
||||
RouterGroup := r.Group("")
|
||||
RouterGroup.Use(middleware.Auth(), middleware.CenterApi(), middleware.SecApi(), middleware.GinGlobalExceptionMiddleWare()) //TODO 中心管控 特定
|
||||
RouterGroup.Use(middleware.Auth(), middleware.CenterApi(), middleware.SecApi(), middleware.GinGlobalExceptionMiddleWare(), middleware.IPWhitelist()) //TODO 中心管控 特定
|
||||
{
|
||||
router.ApiGroupApp.InitHostRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitLogRouter(RouterGroup)
|
||||
@@ -72,6 +72,7 @@ func (web *WafWebManager) initRouter(r *gin.Engine) {
|
||||
router.ApiGroupApp.InitWafPrivateInfoRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafCacheRuleRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafTunnelRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafVpConfigRouter(RouterGroup)
|
||||
}
|
||||
|
||||
if global.GWAF_RELEASE == "true" {
|
||||
@@ -130,6 +131,9 @@ func (web *WafWebManager) StartLocalServer() error {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
gin.DefaultWriter = io.Discard
|
||||
}
|
||||
if global.GWAF_IP_WHITELIST == "0.0.0.0/0,::/0" {
|
||||
zlog.Warn("管理端未配置 IP 白名单,默认允许所有 IP4(0.0.0.0/0) IPv6 ::/0 访问")
|
||||
}
|
||||
r := gin.Default()
|
||||
r.Use(web.cors()) //解决跨域
|
||||
web.initRouter(r)
|
||||
|
||||
Reference in New Issue
Block a user