2020-10-08 15:06:42 +08:00
|
|
|
package nodes
|
|
|
|
|
|
|
|
|
|
import (
|
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"
|
2020-11-09 10:45:44 +08:00
|
|
|
"github.com/iwind/TeaGo/lists"
|
2020-11-02 15:49:30 +08:00
|
|
|
"github.com/iwind/TeaGo/types"
|
2020-10-08 15:06:42 +08:00
|
|
|
"net/http"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 调用WAF
|
|
|
|
|
func (this *HTTPRequest) doWAFRequest() (blocked bool) {
|
2021-01-03 20:18:47 +08:00
|
|
|
// 当前服务的独立设置
|
|
|
|
|
if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn {
|
2021-01-21 10:45:55 +08:00
|
|
|
blocked, breakChecking := this.checkWAFRequest(this.web.FirewallPolicy)
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 公用的防火墙设置
|
|
|
|
|
if sharedNodeConfig.HTTPFirewallPolicy != nil {
|
2021-01-21 10:45:55 +08:00
|
|
|
blocked, breakChecking := this.checkWAFRequest(sharedNodeConfig.HTTPFirewallPolicy)
|
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
|
|
|
|
2021-01-21 10:45:55 +08:00
|
|
|
func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFirewallPolicy) (blocked bool, breakChecking bool) {
|
2020-11-09 10:45:44 +08:00
|
|
|
// 检查配置是否为空
|
2020-12-17 17:36:10 +08:00
|
|
|
if firewallPolicy == nil || !firewallPolicy.IsOn || firewallPolicy.Inbound == nil || !firewallPolicy.Inbound.IsOn {
|
2020-11-09 10:45:44 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查IP白名单
|
2021-02-02 19:32:19 +08:00
|
|
|
remoteAddrs := this.requestRemoteAddrs()
|
2020-12-17 17:36:10 +08:00
|
|
|
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 {
|
|
|
|
|
found, _ := list.ContainsIPStrings(remoteAddrs)
|
|
|
|
|
if found {
|
|
|
|
|
breakChecking = true
|
|
|
|
|
return
|
|
|
|
|
}
|
2021-02-26 16:33:58 +08:00
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查IP黑名单
|
2021-06-23 13:14:37 +08:00
|
|
|
for _, ref := range inbound.AllDenyListRefs() {
|
|
|
|
|
if ref.IsOn && ref.ListId > 0 {
|
|
|
|
|
list := iplibrary.SharedIPListManager.FindList(ref.ListId)
|
|
|
|
|
if list != nil {
|
|
|
|
|
found, item := 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-02-26 16:33:58 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
// TODO 需要记录日志信息
|
2020-11-09 11:02:29 +08:00
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
|
|
|
|
this.writer.Close()
|
2021-02-26 16:33:58 +08:00
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
// 停止日志
|
|
|
|
|
this.disableLog = true
|
2021-02-26 16:33:58 +08:00
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
return true, false
|
|
|
|
|
}
|
2021-02-26 16:33:58 +08:00
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查地区封禁
|
|
|
|
|
if iplibrary.SharedLibrary != nil {
|
2020-12-17 17:36:10 +08:00
|
|
|
if firewallPolicy.Inbound.Region != nil && firewallPolicy.Inbound.Region.IsOn {
|
|
|
|
|
regionConfig := firewallPolicy.Inbound.Region
|
2020-11-09 10:45:44 +08:00
|
|
|
if regionConfig.IsNotEmpty() {
|
2021-02-02 19:32:19 +08:00
|
|
|
for _, remoteAddr := range remoteAddrs {
|
|
|
|
|
result, err := iplibrary.SharedLibrary.Lookup(remoteAddr)
|
|
|
|
|
if err != nil {
|
2021-06-06 23:42:11 +08:00
|
|
|
remotelogs.Error("HTTP_REQUEST_WAF", "iplibrary lookup failed: "+err.Error())
|
2021-02-02 19:32:19 +08:00
|
|
|
} else if result != nil {
|
|
|
|
|
// 检查国家级别封禁
|
|
|
|
|
if len(regionConfig.DenyCountryIds) > 0 && len(result.Country) > 0 {
|
|
|
|
|
countryId := iplibrary.SharedCountryManager.Lookup(result.Country)
|
|
|
|
|
if countryId > 0 && lists.ContainsInt64(regionConfig.DenyCountryIds, countryId) {
|
|
|
|
|
// TODO 可以配置对封禁的处理方式等
|
|
|
|
|
// TODO 需要记录日志信息
|
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
|
|
|
|
this.writer.Close()
|
|
|
|
|
|
|
|
|
|
// 停止日志
|
|
|
|
|
this.disableLog = true
|
|
|
|
|
|
|
|
|
|
return true, false
|
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
}
|
|
|
|
|
|
2021-02-02 19:32:19 +08:00
|
|
|
// 检查省份封禁
|
|
|
|
|
if len(regionConfig.DenyProvinceIds) > 0 && len(result.Province) > 0 {
|
|
|
|
|
provinceId := iplibrary.SharedProvinceManager.Lookup(result.Province)
|
|
|
|
|
if provinceId > 0 && lists.ContainsInt64(regionConfig.DenyProvinceIds, provinceId) {
|
|
|
|
|
// TODO 可以配置对封禁的处理方式等
|
|
|
|
|
// TODO 需要记录日志信息
|
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
|
|
|
|
this.writer.Close()
|
2020-11-09 11:02:29 +08:00
|
|
|
|
2021-02-02 19:32:19 +08:00
|
|
|
// 停止日志
|
|
|
|
|
this.disableLog = true
|
2020-11-09 11:02:29 +08:00
|
|
|
|
2021-02-02 19:32:19 +08:00
|
|
|
return true, false
|
|
|
|
|
}
|
2020-11-09 10:45:44 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-09 11:02:29 +08:00
|
|
|
// 规则测试
|
2020-12-17 17:36:10 +08:00
|
|
|
w := sharedWAFManager.FindWAF(firewallPolicy.Id)
|
2020-10-08 15:06:42 +08:00
|
|
|
if w == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-11-02 15:49:30 +08:00
|
|
|
goNext, ruleGroup, ruleSet, err := w.MatchRequest(this.RawReq, this.writer)
|
2020-10-08 15:06:42 +08:00
|
|
|
if err != nil {
|
2021-06-06 23:42:11 +08:00
|
|
|
remotelogs.Error("HTTP_REQUEST_WAF", this.rawURI+": "+err.Error())
|
2020-10-08 15:06:42 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ruleSet != nil {
|
|
|
|
|
if ruleSet.Action != waf.ActionAllow {
|
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-13 11:04:38 +08:00
|
|
|
if ruleSet.Action == waf.ActionBlock {
|
|
|
|
|
this.isAttack = true
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-26 18:42:46 +08:00
|
|
|
// 添加统计
|
|
|
|
|
stats.SharedHTTPRequestStatManager.AddFirewallRuleGroupId(this.Server.Id, this.firewallRuleGroupId, ruleSet.Action)
|
2020-10-08 15:06:42 +08:00
|
|
|
}
|
2020-11-02 15:49:30 +08:00
|
|
|
|
|
|
|
|
this.logAttrs["waf.action"] = ruleSet.Action
|
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) {
|
2021-06-21 15:29:07 +08:00
|
|
|
// 当前服务的独立设置
|
|
|
|
|
if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn {
|
|
|
|
|
blocked := this.checkWAFResponse(this.web.FirewallPolicy, resp)
|
|
|
|
|
if blocked {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 公用的防火墙设置
|
|
|
|
|
if sharedNodeConfig.HTTPFirewallPolicy != nil {
|
|
|
|
|
blocked := this.checkWAFResponse(sharedNodeConfig.HTTPFirewallPolicy, resp)
|
|
|
|
|
if blocked {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *HTTPRequest) checkWAFResponse(firewallPolicy *firewallconfigs.HTTPFirewallPolicy, resp *http.Response) (blocked bool) {
|
2020-12-17 17:36:10 +08:00
|
|
|
if firewallPolicy == nil || !firewallPolicy.IsOn || !firewallPolicy.Outbound.IsOn {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
w := sharedWAFManager.FindWAF(firewallPolicy.Id)
|
2020-10-08 15:06:42 +08:00
|
|
|
if w == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-02 15:49:30 +08:00
|
|
|
goNext, ruleGroup, ruleSet, err := w.MatchResponse(this.RawReq, resp, this.writer)
|
2020-10-08 15:06:42 +08:00
|
|
|
if err != nil {
|
2021-06-06 23:42:11 +08:00
|
|
|
remotelogs.Error("HTTP_REQUEST_WAF", this.rawURI+": "+err.Error())
|
2020-10-08 15:06:42 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ruleSet != nil {
|
|
|
|
|
if ruleSet.Action != waf.ActionAllow {
|
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-13 11:04:38 +08:00
|
|
|
if ruleSet.Action == waf.ActionBlock {
|
|
|
|
|
this.isAttack = true
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-26 18:42:46 +08:00
|
|
|
// 添加统计
|
|
|
|
|
stats.SharedHTTPRequestStatManager.AddFirewallRuleGroupId(this.Server.Id, this.firewallRuleGroupId, ruleSet.Action)
|
2020-10-08 15:06:42 +08:00
|
|
|
}
|
2020-11-02 15:49:30 +08:00
|
|
|
|
|
|
|
|
this.logAttrs["waf.action"] = ruleSet.Action
|
2020-10-08 15:06:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return !goNext
|
|
|
|
|
}
|