WAF动作增加显示HTML内容

This commit is contained in:
刘祥超
2021-02-26 16:32:16 +08:00
parent 643a0dd17e
commit e42256dd61
7 changed files with 12 additions and 215 deletions

View File

@@ -8,6 +8,7 @@ const (
FirewallActionTypeIPTables FirewallActionType = "iptables"
FirewallActionTypeScript FirewallActionType = "script"
FirewallActionTypeHTTPAPI FirewallActionType = "httpAPI"
FirewallActionTypeHTML FirewallActionType = "html"
)
type FirewallActionTypeDefinition struct {
@@ -43,6 +44,11 @@ func FindAllFirewallActionTypes() []*FirewallActionTypeDefinition {
Code: FirewallActionTypeHTTPAPI,
Description: "使用自定义的HTTP API执行IP操作。",
},
{
Name: "显示HTML内容",
Code: FirewallActionTypeHTML,
Description: "显示一段自定义的HTML网页内容",
},
}
}
@@ -86,6 +92,7 @@ type FirewallActionScriptConfig struct {
// TODO 添加需要阻止的端口列表
}
// HTTP API配置
type FirewallActionHTTPAPIConfig struct {
URL string `json:"url"` // URL路径
TimeoutSeconds int `json:"timeoutSeconds"` // 超时时间 TODO 暂时不实现
@@ -93,3 +100,8 @@ type FirewallActionHTTPAPIConfig struct {
// TODO 添加需要阻止的端口列表
}
// HTML配置
type FirewallActionHTMLConfig struct {
Content string `json:"content"` // 完整的HTML内容
}

View File

@@ -1,101 +0,0 @@
package ipconfigs
import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"io"
"net/http"
"net/url"
"strings"
)
// TODO 支持自定义Header
type HTTPAction struct {
URL string `yaml:"url" json:"url"` // URL
Method string `yaml:"method" json:"method"` // 请求方法
ParamName string `yaml:"paramName" json:"paramsName"` // 参数名
Params map[string]string `yaml:"params" json:"params"` // 附加参数,在请求的时候一起提交
Timeout *shared.TimeDuration `yaml:"timeout" json:"timeout"` // 超时时间
Tries int `yaml:"tries" json:"tries"` // 失败尝试次数
}
func (this *HTTPAction) Node() string {
return "api"
}
func (this *HTTPAction) Run(itemConfig *IPItemConfig) error {
if itemConfig == nil {
return errors.New("invalid ip item")
}
itemJSON, err := json.Marshal(itemConfig)
if err != nil {
return err
}
method := this.Method
if len(method) == 0 {
method = http.MethodGet
}
var body io.Reader = nil
defaultParamName := "ip"
apiURL := this.URL
v := url.Values{}
for paramName, paramValue := range this.Params {
v[paramName] = []string{paramValue}
}
if len(this.ParamName) == 0 {
v[defaultParamName] = []string{string(itemJSON)}
} else {
v[this.ParamName] = []string{string(itemJSON)}
}
if method != http.MethodGet {
body = strings.NewReader(v.Encode())
} else {
if strings.Contains(apiURL, "?") {
apiURL += "&"
} else {
apiURL += "?"
}
apiURL += v.Encode()
}
req, err := http.NewRequest(method, apiURL, body)
if err != nil {
return err
}
if method == http.MethodPost {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
client := &http.Client{}
if this.Timeout != nil {
timeout := this.Timeout.Duration()
if timeout > 0 {
client.Timeout = timeout
}
}
defer func() {
client.CloseIdleConnections()
}()
tries := this.Tries
if tries <= 0 {
tries = 1
}
for i := 0; i < tries; i++ {
resp, err := client.Do(req)
if err == nil {
_ = resp.Body.Close()
return nil
} else if i == tries-1 {
return err
}
}
return nil
}

View File

@@ -1,24 +0,0 @@
package ipconfigs
import (
"net/http"
"testing"
"time"
)
func TestHTTPAction_Run(t *testing.T) {
action := &HTTPAction{
URL: "http://127.0.0.1:1234/get?hello=world",
Method: http.MethodGet,
Params: map[string]string{"a": "b"},
ParamName: "IP",
}
err := action.Run(&IPItemConfig{
IPFrom: "192.168.1.100",
ExpiredAt: time.Now().Unix() + 3600,
})
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}

View File

@@ -1,9 +0,0 @@
package ipconfigs
type ActionInterface interface {
// 运行节点
Node() string
// 执行对IP信息的处理
Run(itemConfig *IPItemConfig) error
}

View File

@@ -1,60 +0,0 @@
package ipconfigs
import (
"os/exec"
"strconv"
"time"
)
type IPSetAction struct {
Exe string `yaml:"exe" json:"exe"` // 可执行文件位置
SetName string `yaml:"setName" json:"setName"` // 集合名称,多个集合使用同一个名称
}
func (this *IPSetAction) Node() string {
return "node"
}
func (this *IPSetAction) Run(itemConfig *IPItemConfig) error {
exe := this.Exe
if len(exe) == 0 {
path, err := exec.LookPath("ipset")
if err != nil {
return err
}
exe = path
}
var timeout int64 = 0
if itemConfig.ExpiredAt > 0 {
timeout = itemConfig.ExpiredAt - time.Now().Unix()
if timeout <= 0 {
return nil
}
}
ip := itemConfig.IPFrom
if len(itemConfig.IPTo) > 0 {
ip += "-" + itemConfig.IPTo
}
switch itemConfig.Action {
case IPItemActionAdd:
cmd := exec.Command(exe, "add", this.SetName, ip, "timeout", strconv.FormatInt(timeout, 10))
_ = cmd.Run()
case IPItemActionUpdate:
{
cmd := exec.Command(exe, "del", this.SetName, ip, "timeout", strconv.FormatInt(timeout, 10))
_ = cmd.Run()
}
{
cmd := exec.Command(exe, "add", this.SetName, ip, "timeout", strconv.FormatInt(timeout, 10))
_ = cmd.Run()
}
case IPItemActionDelete:
cmd := exec.Command(exe, "del", this.SetName, ip, "timeout", strconv.FormatInt(timeout, 10))
_ = cmd.Run()
}
return nil
}

View File

@@ -1,12 +0,0 @@
package ipconfigs
import "testing"
func TestIPSetAction_Run(t *testing.T) {
action := &IPSetAction{}
err := action.Run(&IPItemConfig{})
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}

View File

@@ -1,9 +0,0 @@
package ipconfigs
type IPListAction = string
const (
IPListActionHTTP IPListAction = "http" // HTTP
IPListActionIPSet IPListAction = "ipset" // ipset
)