Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion bfe_basic/common.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 The BFE Authors.
// Copyright (c) 2019 - 2025 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -15,6 +15,10 @@
package bfe_basic

import (
"io/ioutil"
"strconv"
"strings"

"github.com/bfenetworks/bfe/bfe_http"
"github.com/bfenetworks/bfe/bfe_route/bfe_cluster"
)
Expand Down Expand Up @@ -80,6 +84,22 @@ func CreateInternalResp(request *Request, code int) *bfe_http.Response {
return res
}

func CreateSpecifiedContentResp(request *Request, responseCode int, contentType string, content string) *bfe_http.Response {
resp := new(bfe_http.Response)
resp.StatusCode = responseCode

resp.Header = make(bfe_http.Header)
resp.Header.Set("Server", "bfe")

if len(contentType) != 0 {
resp.Header.Set("Content-Type", contentType)
}
resp.Header.Set("Content-Length", strconv.Itoa(len(content)))
resp.Body = ioutil.NopCloser(strings.NewReader(content))

return resp
}

// ServerDataConfInterface is an interface used for lookup config for each request
type ServerDataConfInterface interface {
ClusterTableLookup(clusterName string) (*bfe_cluster.BfeCluster, error)
Expand Down
61 changes: 61 additions & 0 deletions bfe_basic/waf_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) 2025 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// basic waf info

package bfe_basic

const (
REQ_CHECK_ONLY = "CheckOnly"
REQ_NO_CHECK = "NoCheck"
REQ_FORBIDDEN = "Forbidden"
REQ_OK = "WaitResponse.Pass.Ok"
REQ_TIMEOUT = "WaitResponse.Pass.Timeout"
REQ_OTHER = "WaitResponse.Pass.Other"
NET_ERR = "Net.Error" // net error between go-bfe and waf-server
)

const (
WAF_NO_CHECK = 0 // no check for request
WAF_CHECKONLY = 1 // check only; from mod_waf_client, not used now
WAF_FORBIDDEN = 2 // check and forbidden
WAF_PASS = 3 // check and pass
WAF_DEGRADE = 4 // check, but pass with degraded
WAF_TIMEOUT = 5 // check, but pass with timeout
WAF_ERROR = 6 // check and pass with error happened
)

const (
REQ_CTX_WAF_INFO = "waf_client.waf_info"
)

// support old waf info struct
type WafInfo struct {
WafSpentTime int64 // in ms.
WafStatus int // waf status, see bfe proto file for detail
WafRuleName string // not used
}

func GetWafInfo(req *Request) *WafInfo {
var info *WafInfo

val := req.GetContext(REQ_CTX_WAF_INFO)
if val != nil {
info = val.(*WafInfo)
} else {
info = new(WafInfo)
req.SetContext(REQ_CTX_WAF_INFO, info)
}
return info
}
6 changes: 5 additions & 1 deletion bfe_modules/bfe_modules.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 The BFE Authors.
// Copyright (c) 2019 - 2025 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -42,6 +42,7 @@ import (
"github.com/bfenetworks/bfe/bfe_modules/mod_tcp_keepalive"
"github.com/bfenetworks/bfe/bfe_modules/mod_trace"
"github.com/bfenetworks/bfe/bfe_modules/mod_trust_clientip"
"github.com/bfenetworks/bfe/bfe_modules/mod_unified_waf"
"github.com/bfenetworks/bfe/bfe_modules/mod_userid"
"github.com/bfenetworks/bfe/bfe_modules/mod_waf"
"github.com/bfenetworks/bfe/bfe_modules/mod_wasmplugin"
Expand Down Expand Up @@ -135,6 +136,9 @@ var moduleList = []bfe_module.BfeModule{

// mod_wasm
mod_wasmplugin.NewModuleWasm(),

// mod_unified_waf
mod_unified_waf.NewModuleWaf(),
}

// init modules list
Expand Down
100 changes: 100 additions & 0 deletions bfe_modules/mod_unified_waf/conf_load.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) 2025 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mod_unified_waf

import (
"errors"
"fmt"

"github.com/baidu/go-lib/log"
"github.com/bfenetworks/bfe/bfe_modules/mod_unified_waf/waf_impl"
gcfg "gopkg.in/gcfg.v1"
)

type ConfBasic struct {
WafProductName string
ConnPoolSize int
}

type ConfModWaf struct {
Basic ConfBasic

ConfigPath struct {
ModWafDataPath string // configure path for mod_unified_waf.data
ProductParamPath string // configure path for product_param.data
WafInstancesPath string // configure path for waf_instances.data
}

Log struct {
OpenDebug bool
}
}

func ConfLoad(path string, confRoot string) (*ConfModWaf, error) {
var err error
var cfg ConfModWaf

// read config from file
if err = gcfg.ReadFileInto(&cfg, path); err != nil {
return &cfg, err
}
// check conf of mod_waf_client
err = cfg.Check(confRoot)
if err != nil {
return &cfg, err
}

return &cfg, nil
}

// check also fix some configure value
func (cfg *ConfModWaf) Check(confRoot string) error {
if len(cfg.Basic.WafProductName) <= 0 {
cfg.Basic.WafProductName = NoneWafName
}

if len(cfg.Basic.WafProductName) > 0 {
twafName := cfg.Basic.WafProductName
if (twafName != NoneWafName) && !waf_impl.CheckWafSupport(twafName) {
err := fmt.Errorf("Basic.WafProductName:%s is illgal", cfg.Basic.WafProductName)
return err
}
}

if cfg.Basic.ConnPoolSize <= 0 {
log.Logger.Warn("Basic.ConnPoolSize is : %d, use DEFAULT_POOL_SIZE(%d)", cfg.Basic.ConnPoolSize, DEFAULT_POOL_SIZE)
cfg.Basic.ConnPoolSize = DEFAULT_POOL_SIZE
}

// check conf of ProductParamPath
if cfg.ConfigPath.ProductParamPath == "" {
log.Logger.Error("ConfigPath.ProductParamPath not set")
return errors.New("ConfigPath.ProductParamPath not set")
}

// check conf of ModWafDataPath
if cfg.ConfigPath.ModWafDataPath == "" {
log.Logger.Error("ConfigPath.ModWafDataPath not set")
return errors.New("ConfigPath.ModWafDataPath not set")
}

// check conf of WafInstancesPath
if cfg.ConfigPath.WafInstancesPath == "" {
log.Logger.Error("ConfigPath.WafInstancesPath not set")
return errors.New("ConfigPath.WafInstancesPath not set")
}

return nil
}
48 changes: 48 additions & 0 deletions bfe_modules/mod_unified_waf/conf_load_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2025 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mod_unified_waf

import (
"testing"
)

// config path is not empty, correct
func TestConfLoad_1(t *testing.T) {
confPath := "./testdata/mod_unified_waf.conf"
ModWafDataPath := "./testdata/mod_unified_waf.data"
productParamPath := "./testdata/product_param.data"
wafInstancesPath := "./testdata/waf_instances.data"
WafProductName := "BFEMockWaf"

conf, err := ConfLoad(confPath, "")
if err != nil {
t.Errorf("ConfLoad(): %v", err)
return
}

if conf.Basic.WafProductName != WafProductName {
t.Errorf("WafProductName should be %s not %s", WafProductName, conf.Basic.WafProductName)
}

if conf.ConfigPath.ModWafDataPath != ModWafDataPath {
t.Errorf("ModWafDataPath should be %s not %s", ModWafDataPath, conf.ConfigPath.ModWafDataPath)
}
if conf.ConfigPath.ProductParamPath != productParamPath {
t.Errorf("ProductParamPath should be %s not %s", productParamPath, conf.ConfigPath.ProductParamPath)
}
if conf.ConfigPath.WafInstancesPath != wafInstancesPath {
t.Errorf("AlbWafInstancesPath should be %s not %s", wafInstancesPath, conf.ConfigPath.WafInstancesPath)
}
}
Loading