2020-10-08 15:06:42 +08:00
|
|
|
|
package nodes
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2021-07-18 15:51:49 +08:00
|
|
|
|
"bytes"
|
2022-08-21 20:37:49 +08:00
|
|
|
|
iplib "github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
2021-01-03 20:18:47 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
2020-11-09 10:45:44 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/iplibrary"
|
2020-12-17 17:36:10 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
2021-01-26 18:42:46 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/stats"
|
2020-10-08 15:06:42 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/waf"
|
2021-12-06 10:11:22 +08:00
|
|
|
|
"github.com/iwind/TeaGo/Tea"
|
2020-11-02 15:49:30 +08:00
|
|
|
|
"github.com/iwind/TeaGo/types"
|
2021-07-18 15:51:49 +08:00
|
|
|
|
"io"
|
2020-10-08 15:06:42 +08:00
|
|
|
|
"net/http"
|
2023-07-14 16:03:58 +08:00
|
|
|
|
"time"
|
2020-10-08 15:06:42 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 调用WAF
|
|
|
|
|
|
func (this *HTTPRequest) doWAFRequest() (blocked bool) {
|
2022-01-02 22:45:37 +08:00
|
|
|
|
if this.web.FirewallRef == nil || !this.web.FirewallRef.IsOn {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-06 10:11:22 +08:00
|
|
|
|
var remoteAddr = this.requestRemoteAddr(true)
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否为白名单直连
|
2022-04-04 12:06:53 +08:00
|
|
|
|
if !Tea.IsTesting() && this.nodeConfig.IPIsAutoAllowed(remoteAddr) {
|
2021-12-06 10:11:22 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-29 09:19:45 +08:00
|
|
|
|
// 当前连接是否已关闭
|
2021-12-01 20:55:19 +08:00
|
|
|
|
if this.isConnClosed() {
|
|
|
|
|
|
this.disableLog = true
|
|
|
|
|
|
return true
|
2021-09-29 09:19:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-11-17 16:16:09 +08:00
|
|
|
|
// 是否在全局名单中
|
2023-03-31 21:37:15 +08:00
|
|
|
|
canGoNext, isInAllowedList, _ := iplibrary.AllowIP(remoteAddr, this.ReqServer.Id)
|
2022-03-06 19:40:26 +08:00
|
|
|
|
if !canGoNext {
|
2021-11-17 16:16:09 +08:00
|
|
|
|
this.disableLog = true
|
2022-01-01 20:15:39 +08:00
|
|
|
|
this.Close()
|
2021-11-17 16:16:09 +08:00
|
|
|
|
return true
|
|
|
|
|
|
}
|
2022-03-06 19:40:26 +08:00
|
|
|
|
if isInAllowedList {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
2021-11-17 16:16:09 +08:00
|
|
|
|
|
2021-10-19 09:21:58 +08:00
|
|
|
|
// 检查是否在临时黑名单中
|
2022-01-01 20:15:39 +08:00
|
|
|
|
if waf.SharedIPBlackList.Contains(waf.IPTypeAll, firewallconfigs.FirewallScopeService, this.ReqServer.Id, remoteAddr) || waf.SharedIPBlackList.Contains(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, remoteAddr) {
|
2021-10-19 09:21:58 +08:00
|
|
|
|
this.disableLog = true
|
2022-01-01 20:15:39 +08:00
|
|
|
|
this.Close()
|
2021-10-19 09:21:58 +08:00
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-16 17:05:37 +08:00
|
|
|
|
var forceLog = false
|
|
|
|
|
|
var forceLogRequestBody = false
|
2022-07-16 18:47:59 +08:00
|
|
|
|
var forceLogRegionDenying = false
|
2022-07-16 17:05:37 +08:00
|
|
|
|
if this.ReqServer.HTTPFirewallPolicy != nil &&
|
|
|
|
|
|
this.ReqServer.HTTPFirewallPolicy.IsOn &&
|
|
|
|
|
|
this.ReqServer.HTTPFirewallPolicy.Log != nil &&
|
|
|
|
|
|
this.ReqServer.HTTPFirewallPolicy.Log.IsOn {
|
|
|
|
|
|
forceLog = true
|
|
|
|
|
|
forceLogRequestBody = this.ReqServer.HTTPFirewallPolicy.Log.RequestBody
|
2022-07-16 18:47:59 +08:00
|
|
|
|
forceLogRegionDenying = this.ReqServer.HTTPFirewallPolicy.Log.RegionDenying
|
2022-07-16 17:05:37 +08:00
|
|
|
|
}
|
2022-04-21 19:44:19 +08:00
|
|
|
|
|
2021-01-03 20:18:47 +08:00
|
|
|
|
// 当前服务的独立设置
|
|
|
|
|
|
if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn {
|
2023-03-01 16:46:43 +08:00
|
|
|
|
blocked, breakChecking := this.checkWAFRequest(this.web.FirewallPolicy, forceLog, forceLogRequestBody, forceLogRegionDenying, false)
|
2021-01-03 20:18:47 +08:00
|
|
|
|
if blocked {
|
2021-01-21 10:45:55 +08:00
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
if breakChecking {
|
|
|
|
|
|
return false
|
2021-01-03 20:18:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 公用的防火墙设置
|
2022-01-01 20:15:39 +08:00
|
|
|
|
if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.IsOn {
|
2023-03-01 16:46:43 +08:00
|
|
|
|
blocked, breakChecking := this.checkWAFRequest(this.ReqServer.HTTPFirewallPolicy, forceLog, forceLogRequestBody, forceLogRegionDenying, this.web.FirewallRef.IgnoreGlobalRules)
|
2021-01-03 20:18:47 +08:00
|
|
|
|
if blocked {
|
2021-01-21 10:45:55 +08:00
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
if breakChecking {
|
|
|
|
|
|
return false
|
2021-01-03 20:18:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2020-12-17 17:36:10 +08:00
|
|
|
|
|
2023-03-01 16:46:43 +08:00
|
|
|
|
func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFirewallPolicy, forceLog bool, logRequestBody bool, logDenying bool, ignoreRules bool) (blocked bool, breakChecking bool) {
|
2020-11-09 10:45:44 +08:00
|
|
|
|
// 检查配置是否为空
|
2021-10-07 13:51:26 +08:00
|
|
|
|
if firewallPolicy == nil || !firewallPolicy.IsOn || firewallPolicy.Inbound == nil || !firewallPolicy.Inbound.IsOn || firewallPolicy.Mode == firewallconfigs.FirewallModeBypass {
|
2020-11-09 10:45:44 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查IP白名单
|
2022-07-16 18:47:59 +08:00
|
|
|
|
var remoteAddrs []string
|
|
|
|
|
|
if len(this.remoteAddr) > 0 {
|
|
|
|
|
|
remoteAddrs = []string{this.remoteAddr}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
remoteAddrs = this.requestRemoteAddrs()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var inbound = firewallPolicy.Inbound
|
2021-06-23 13:14:37 +08:00
|
|
|
|
if inbound == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
for _, ref := range inbound.AllAllowListRefs() {
|
|
|
|
|
|
if ref.IsOn && ref.ListId > 0 {
|
|
|
|
|
|
list := iplibrary.SharedIPListManager.FindList(ref.ListId)
|
|
|
|
|
|
if list != nil {
|
2021-10-04 17:42:38 +08:00
|
|
|
|
_, found := list.ContainsIPStrings(remoteAddrs)
|
2021-06-23 13:14:37 +08:00
|
|
|
|
if found {
|
|
|
|
|
|
breakChecking = true
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2021-02-26 16:33:58 +08:00
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查IP黑名单
|
2021-10-04 18:22:51 +08:00
|
|
|
|
if firewallPolicy.Mode == firewallconfigs.FirewallModeDefend {
|
|
|
|
|
|
for _, ref := range inbound.AllDenyListRefs() {
|
|
|
|
|
|
if ref.IsOn && ref.ListId > 0 {
|
|
|
|
|
|
list := iplibrary.SharedIPListManager.FindList(ref.ListId)
|
|
|
|
|
|
if list != nil {
|
|
|
|
|
|
item, found := list.ContainsIPStrings(remoteAddrs)
|
|
|
|
|
|
if found {
|
|
|
|
|
|
// 触发事件
|
|
|
|
|
|
if item != nil && len(item.EventLevel) > 0 {
|
|
|
|
|
|
actions := iplibrary.SharedActionManager.FindEventActions(item.EventLevel)
|
|
|
|
|
|
for _, action := range actions {
|
|
|
|
|
|
goNext, err := action.DoHTTP(this.RawReq, this.RawWriter)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
remotelogs.Error("HTTP_REQUEST_WAF", "do action '"+err.Error()+"' failed: "+err.Error())
|
|
|
|
|
|
return true, false
|
|
|
|
|
|
}
|
|
|
|
|
|
if !goNext {
|
|
|
|
|
|
this.disableLog = true
|
|
|
|
|
|
return true, false
|
|
|
|
|
|
}
|
2021-06-23 13:14:37 +08:00
|
|
|
|
}
|
2021-02-26 16:33:58 +08:00
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
|
2021-10-04 18:22:51 +08:00
|
|
|
|
// TODO 需要记录日志信息
|
2020-11-09 11:02:29 +08:00
|
|
|
|
|
2021-10-04 18:22:51 +08:00
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
|
|
|
|
|
this.writer.Close()
|
2021-02-26 16:33:58 +08:00
|
|
|
|
|
2021-10-04 18:22:51 +08:00
|
|
|
|
// 停止日志
|
|
|
|
|
|
this.disableLog = true
|
2021-02-26 16:33:58 +08:00
|
|
|
|
|
2021-10-04 18:22:51 +08:00
|
|
|
|
return true, false
|
|
|
|
|
|
}
|
2021-06-23 13:14:37 +08:00
|
|
|
|
}
|
2021-02-26 16:33:58 +08:00
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查地区封禁
|
2021-10-04 18:22:51 +08:00
|
|
|
|
if firewallPolicy.Mode == firewallconfigs.FirewallModeDefend {
|
2022-08-21 20:37:49 +08:00
|
|
|
|
if firewallPolicy.Inbound.Region != nil && firewallPolicy.Inbound.Region.IsOn {
|
2023-05-25 12:02:40 +08:00
|
|
|
|
var regionConfig = firewallPolicy.Inbound.Region
|
2022-08-21 20:37:49 +08:00
|
|
|
|
if regionConfig.IsNotEmpty() {
|
|
|
|
|
|
for _, remoteAddr := range remoteAddrs {
|
|
|
|
|
|
var result = iplib.LookupIP(remoteAddr)
|
|
|
|
|
|
if result != nil && result.IsOk() {
|
2023-05-25 12:02:40 +08:00
|
|
|
|
var currentURL = this.URL()
|
|
|
|
|
|
if regionConfig.MatchCountryURL(currentURL) {
|
|
|
|
|
|
// 检查国家/地区级别封禁
|
2023-07-07 10:11:49 +08:00
|
|
|
|
if !regionConfig.IsAllowedCountry(result.CountryId(), result.ProvinceId()) {
|
2023-05-25 12:02:40 +08:00
|
|
|
|
this.firewallPolicyId = firewallPolicy.Id
|
|
|
|
|
|
|
2023-07-14 11:02:20 +08:00
|
|
|
|
if len(regionConfig.CountryHTML) > 0 {
|
2023-08-10 09:50:02 +08:00
|
|
|
|
var formattedHTML = this.Format(regionConfig.CountryHTML)
|
2023-07-14 11:02:20 +08:00
|
|
|
|
this.writer.Header().Set("Content-Type", "text/html; charset=utf-8")
|
2023-08-10 09:50:02 +08:00
|
|
|
|
this.writer.Header().Set("Content-Length", types.String(len(formattedHTML)))
|
2023-07-14 11:02:20 +08:00
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
2023-08-10 09:50:02 +08:00
|
|
|
|
_, _ = this.writer.Write([]byte(formattedHTML))
|
2023-07-14 11:02:20 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.writeCode(http.StatusForbidden, "The region has been denied.", "当前区域禁止访问")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-14 16:03:58 +08:00
|
|
|
|
// 延时返回,避免攻击
|
|
|
|
|
|
time.Sleep(1 * time.Second)
|
2023-05-25 12:02:40 +08:00
|
|
|
|
|
|
|
|
|
|
// 停止日志
|
|
|
|
|
|
if !logDenying {
|
|
|
|
|
|
this.disableLog = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.tags = append(this.tags, "denyCountry")
|
|
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
|
2023-05-25 12:02:40 +08:00
|
|
|
|
return true, false
|
|
|
|
|
|
}
|
2022-08-21 20:37:49 +08:00
|
|
|
|
}
|
2022-07-16 18:47:59 +08:00
|
|
|
|
|
2023-05-25 12:02:40 +08:00
|
|
|
|
if regionConfig.MatchProvinceURL(currentURL) {
|
|
|
|
|
|
// 检查省份封禁
|
2023-07-07 10:11:49 +08:00
|
|
|
|
if !regionConfig.IsAllowedProvince(result.CountryId(), result.ProvinceId()) {
|
2023-05-25 12:02:40 +08:00
|
|
|
|
this.firewallPolicyId = firewallPolicy.Id
|
2020-11-09 11:02:29 +08:00
|
|
|
|
|
2023-07-14 11:02:20 +08:00
|
|
|
|
if len(regionConfig.ProvinceHTML) > 0 {
|
2023-08-10 09:50:02 +08:00
|
|
|
|
var formattedHTML = this.Format(regionConfig.ProvinceHTML)
|
2023-07-14 11:02:20 +08:00
|
|
|
|
this.writer.Header().Set("Content-Type", "text/html; charset=utf-8")
|
2023-08-10 09:50:02 +08:00
|
|
|
|
this.writer.Header().Set("Content-Length", types.String(len(formattedHTML)))
|
2023-07-14 11:02:20 +08:00
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
2023-08-10 09:50:02 +08:00
|
|
|
|
_, _ = this.writer.Write([]byte(formattedHTML))
|
2023-07-14 11:02:20 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.writeCode(http.StatusForbidden, "The region has been denied.", "当前区域禁止访问")
|
|
|
|
|
|
}
|
2023-07-14 16:03:58 +08:00
|
|
|
|
|
|
|
|
|
|
// 延时返回,避免攻击
|
|
|
|
|
|
time.Sleep(1 * time.Second)
|
2020-11-09 11:02:29 +08:00
|
|
|
|
|
2023-05-25 12:02:40 +08:00
|
|
|
|
// 停止日志
|
|
|
|
|
|
if !logDenying {
|
|
|
|
|
|
this.disableLog = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.tags = append(this.tags, "denyProvince")
|
|
|
|
|
|
}
|
2022-08-21 20:37:49 +08:00
|
|
|
|
|
2023-05-25 12:02:40 +08:00
|
|
|
|
return true, false
|
|
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-01 16:46:43 +08:00
|
|
|
|
// 是否执行规则
|
|
|
|
|
|
if ignoreRules {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-09 11:02:29 +08:00
|
|
|
|
// 规则测试
|
2023-03-01 16:46:43 +08:00
|
|
|
|
var w = waf.SharedWAFManager.FindWAF(firewallPolicy.Id)
|
2020-10-08 15:06:42 +08:00
|
|
|
|
if w == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2021-07-18 15:51:49 +08:00
|
|
|
|
|
2022-07-16 17:05:37 +08:00
|
|
|
|
goNext, hasRequestBody, ruleGroup, ruleSet, err := w.MatchRequest(this, this.writer)
|
2022-09-28 16:46:05 +08:00
|
|
|
|
if forceLog && logRequestBody && hasRequestBody && ruleSet != nil && ruleSet.HasAttackActions() {
|
2022-07-16 17:05:37 +08:00
|
|
|
|
this.wafHasRequestBody = true
|
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
|
if err != nil {
|
2021-12-04 19:28:02 +08:00
|
|
|
|
if !this.canIgnore(err) {
|
|
|
|
|
|
remotelogs.Error("HTTP_REQUEST_WAF", this.rawURI+": "+err.Error())
|
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ruleSet != nil {
|
2022-04-21 19:44:19 +08:00
|
|
|
|
if forceLog {
|
2022-04-21 19:02:17 +08:00
|
|
|
|
this.forceLog = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
if ruleSet.HasSpecialActions() {
|
2020-12-17 17:36:10 +08:00
|
|
|
|
this.firewallPolicyId = firewallPolicy.Id
|
2020-11-02 15:49:30 +08:00
|
|
|
|
this.firewallRuleGroupId = types.Int64(ruleGroup.Id)
|
|
|
|
|
|
this.firewallRuleSetId = types.Int64(ruleSet.Id)
|
2021-01-26 18:42:46 +08:00
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
if ruleSet.HasAttackActions() {
|
2021-07-13 11:04:38 +08:00
|
|
|
|
this.isAttack = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-26 18:42:46 +08:00
|
|
|
|
// 添加统计
|
2022-01-01 20:15:39 +08:00
|
|
|
|
stats.SharedHTTPRequestStatManager.AddFirewallRuleGroupId(this.ReqServer.Id, this.firewallRuleGroupId, ruleSet.Actions)
|
2020-10-08 15:06:42 +08:00
|
|
|
|
}
|
2020-11-02 15:49:30 +08:00
|
|
|
|
|
2021-10-06 08:56:38 +08:00
|
|
|
|
this.firewallActions = append(ruleSet.ActionCodes(), firewallPolicy.Mode)
|
2020-10-08 15:06:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-21 10:45:55 +08:00
|
|
|
|
return !goNext, false
|
2020-10-08 15:06:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// call response waf
|
|
|
|
|
|
func (this *HTTPRequest) doWAFResponse(resp *http.Response) (blocked bool) {
|
2022-01-02 22:45:37 +08:00
|
|
|
|
if this.web.FirewallRef == nil || !this.web.FirewallRef.IsOn {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-21 15:29:07 +08:00
|
|
|
|
// 当前服务的独立设置
|
2022-07-16 17:05:37 +08:00
|
|
|
|
var forceLog = false
|
|
|
|
|
|
var forceLogRequestBody = false
|
|
|
|
|
|
if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.IsOn && this.ReqServer.HTTPFirewallPolicy.Log != nil && this.ReqServer.HTTPFirewallPolicy.Log.IsOn {
|
|
|
|
|
|
forceLog = true
|
|
|
|
|
|
forceLogRequestBody = this.ReqServer.HTTPFirewallPolicy.Log.RequestBody
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-21 15:29:07 +08:00
|
|
|
|
if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn {
|
2023-03-01 16:46:43 +08:00
|
|
|
|
blocked := this.checkWAFResponse(this.web.FirewallPolicy, resp, forceLog, forceLogRequestBody, false)
|
2021-06-21 15:29:07 +08:00
|
|
|
|
if blocked {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 公用的防火墙设置
|
2022-01-01 20:15:39 +08:00
|
|
|
|
if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.IsOn {
|
2023-03-01 16:46:43 +08:00
|
|
|
|
blocked := this.checkWAFResponse(this.ReqServer.HTTPFirewallPolicy, resp, forceLog, forceLogRequestBody, this.web.FirewallRef.IgnoreGlobalRules)
|
2021-06-21 15:29:07 +08:00
|
|
|
|
if blocked {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-01 16:46:43 +08:00
|
|
|
|
func (this *HTTPRequest) checkWAFResponse(firewallPolicy *firewallconfigs.HTTPFirewallPolicy, resp *http.Response, forceLog bool, logRequestBody bool, ignoreRules bool) (blocked bool) {
|
2021-10-07 13:51:26 +08:00
|
|
|
|
if firewallPolicy == nil || !firewallPolicy.IsOn || !firewallPolicy.Outbound.IsOn || firewallPolicy.Mode == firewallconfigs.FirewallModeBypass {
|
2020-12-17 17:36:10 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-01 16:46:43 +08:00
|
|
|
|
// 是否执行规则
|
|
|
|
|
|
if ignoreRules {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var w = waf.SharedWAFManager.FindWAF(firewallPolicy.Id)
|
2020-10-08 15:06:42 +08:00
|
|
|
|
if w == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-16 17:05:37 +08:00
|
|
|
|
goNext, hasRequestBody, ruleGroup, ruleSet, err := w.MatchResponse(this, resp, this.writer)
|
2022-09-28 16:46:05 +08:00
|
|
|
|
if forceLog && logRequestBody && hasRequestBody && ruleSet != nil && ruleSet.HasAttackActions() {
|
2022-07-16 17:05:37 +08:00
|
|
|
|
this.wafHasRequestBody = true
|
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
|
if err != nil {
|
2021-12-04 19:28:02 +08:00
|
|
|
|
if !this.canIgnore(err) {
|
|
|
|
|
|
remotelogs.Error("HTTP_REQUEST_WAF", this.rawURI+": "+err.Error())
|
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ruleSet != nil {
|
2022-04-21 19:44:19 +08:00
|
|
|
|
if forceLog {
|
2022-04-21 19:02:17 +08:00
|
|
|
|
this.forceLog = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
if ruleSet.HasSpecialActions() {
|
2020-12-17 17:36:10 +08:00
|
|
|
|
this.firewallPolicyId = firewallPolicy.Id
|
2020-11-02 15:49:30 +08:00
|
|
|
|
this.firewallRuleGroupId = types.Int64(ruleGroup.Id)
|
|
|
|
|
|
this.firewallRuleSetId = types.Int64(ruleSet.Id)
|
2021-01-26 18:42:46 +08:00
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
if ruleSet.HasAttackActions() {
|
2021-07-13 11:04:38 +08:00
|
|
|
|
this.isAttack = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-26 18:42:46 +08:00
|
|
|
|
// 添加统计
|
2022-01-01 20:15:39 +08:00
|
|
|
|
stats.SharedHTTPRequestStatManager.AddFirewallRuleGroupId(this.ReqServer.Id, this.firewallRuleGroupId, ruleSet.Actions)
|
2020-10-08 15:06:42 +08:00
|
|
|
|
}
|
2020-11-02 15:49:30 +08:00
|
|
|
|
|
2021-10-06 08:56:38 +08:00
|
|
|
|
this.firewallActions = append(ruleSet.ActionCodes(), firewallPolicy.Mode)
|
2020-10-08 15:06:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return !goNext
|
|
|
|
|
|
}
|
2021-07-18 15:51:49 +08:00
|
|
|
|
|
|
|
|
|
|
// WAFRaw 原始请求
|
|
|
|
|
|
func (this *HTTPRequest) WAFRaw() *http.Request {
|
|
|
|
|
|
return this.RawReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WAFRemoteIP 客户端IP
|
|
|
|
|
|
func (this *HTTPRequest) WAFRemoteIP() string {
|
2021-10-06 11:40:48 +08:00
|
|
|
|
return this.requestRemoteAddr(true)
|
2021-07-18 15:51:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WAFGetCacheBody 获取缓存中的Body
|
|
|
|
|
|
func (this *HTTPRequest) WAFGetCacheBody() []byte {
|
2021-12-07 15:12:15 +08:00
|
|
|
|
return this.requestBodyData
|
2021-07-18 15:51:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WAFSetCacheBody 设置Body
|
|
|
|
|
|
func (this *HTTPRequest) WAFSetCacheBody(body []byte) {
|
2021-12-07 15:12:15 +08:00
|
|
|
|
this.requestBodyData = body
|
2021-07-18 15:51:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WAFReadBody 读取Body
|
|
|
|
|
|
func (this *HTTPRequest) WAFReadBody(max int64) (data []byte, err error) {
|
|
|
|
|
|
if this.RawReq.ContentLength > 0 {
|
2022-08-04 11:34:06 +08:00
|
|
|
|
data, err = io.ReadAll(io.LimitReader(this.RawReq.Body, max))
|
2021-07-18 15:51:49 +08:00
|
|
|
|
}
|
2021-12-04 19:28:02 +08:00
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WAFRestoreBody 恢复Body
|
|
|
|
|
|
func (this *HTTPRequest) WAFRestoreBody(data []byte) {
|
|
|
|
|
|
if len(data) > 0 {
|
2022-08-04 11:34:06 +08:00
|
|
|
|
this.RawReq.Body = io.NopCloser(io.MultiReader(bytes.NewBuffer(data), this.RawReq.Body))
|
2021-07-18 15:51:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// WAFServerId 服务ID
|
|
|
|
|
|
func (this *HTTPRequest) WAFServerId() int64 {
|
2022-01-01 20:15:39 +08:00
|
|
|
|
return this.ReqServer.Id
|
2021-07-18 15:51:49 +08:00
|
|
|
|
}
|
2021-09-29 11:06:00 +08:00
|
|
|
|
|
|
|
|
|
|
// WAFClose 关闭连接
|
|
|
|
|
|
func (this *HTTPRequest) WAFClose() {
|
2022-01-01 20:15:39 +08:00
|
|
|
|
this.Close()
|
2022-09-02 15:20:58 +08:00
|
|
|
|
|
|
|
|
|
|
// 这里不要强关IP所有连接,避免因为单个服务而影响所有
|
2021-09-29 11:06:00 +08:00
|
|
|
|
}
|
2021-12-01 17:43:08 +08:00
|
|
|
|
|
|
|
|
|
|
func (this *HTTPRequest) WAFOnAction(action interface{}) (goNext bool) {
|
|
|
|
|
|
if action == nil {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
instance, ok := action.(waf.ActionInterface)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch instance.Code() {
|
|
|
|
|
|
case waf.ActionTag:
|
|
|
|
|
|
this.tags = append(this.tags, action.(*waf.TagAction).Tags...)
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
2023-03-08 16:59:44 +08:00
|
|
|
|
|
|
|
|
|
|
func (this *HTTPRequest) WAFFingerprint() []byte {
|
2023-03-10 10:41:16 +08:00
|
|
|
|
// 目前只有HTTPS请求才有指纹
|
|
|
|
|
|
if !this.IsHTTPS {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-08 16:59:44 +08:00
|
|
|
|
var requestConn = this.RawReq.Context().Value(HTTPConnContextKey)
|
|
|
|
|
|
if requestConn == nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
clientConn, ok := requestConn.(ClientConnInterface)
|
|
|
|
|
|
if ok {
|
|
|
|
|
|
return clientConn.Fingerprint()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2023-03-16 10:38:40 +08:00
|
|
|
|
|
2023-08-02 17:00:16 +08:00
|
|
|
|
func (this *HTTPRequest) WAFMaxRequestSize() int64 {
|
|
|
|
|
|
var maxRequestSize = firewallconfigs.DefaultMaxRequestBodySize
|
|
|
|
|
|
if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.MaxRequestBodySize > 0 {
|
|
|
|
|
|
maxRequestSize = this.ReqServer.HTTPFirewallPolicy.MaxRequestBodySize
|
|
|
|
|
|
}
|
|
|
|
|
|
return maxRequestSize
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-16 10:38:40 +08:00
|
|
|
|
// DisableAccessLog 在当前请求中不使用访问日志
|
|
|
|
|
|
func (this *HTTPRequest) DisableAccessLog() {
|
|
|
|
|
|
this.disableLog = true
|
|
|
|
|
|
}
|