实现基础的DDoS防护

This commit is contained in:
GoEdgeLab
2022-05-18 21:02:53 +08:00
parent 7c32617d08
commit 97868be17d
12 changed files with 521 additions and 93 deletions

2
go.sum
View File

@@ -242,6 +242,8 @@ github.com/iwind/TeaGo v0.0.0-20220322141208-22f88d04004d h1:e8fkTKras/RXQWECApM
github.com/iwind/TeaGo v0.0.0-20220322141208-22f88d04004d/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220408064305-92be81dc2f7c h1:ugjYZ74FJGWlfDKKraNgMyDTeS4vbXHe89JGUVQIJMo=
github.com/iwind/TeaGo v0.0.0-20220408064305-92be81dc2f7c/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570 h1:zqz2FiMMkSHXWO1EsTRJDPTwX9xQ4uuyD5GAE4JGlhM=
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3 h1:aBSonas7vFcgTj9u96/bWGILGv1ZbUSTLiOzcI1ZT6c=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=

View File

@@ -9,6 +9,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -180,7 +181,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
}
// UpdateCluster 修改集群
func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, nodeTCPMaxConnections int32, autoOpenPorts bool) error {
func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool) error {
if clusterId <= 0 {
return errors.New("invalid clusterId")
}
@@ -195,11 +196,6 @@ func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name stri
nodeMaxThreads = 0
}
op.NodeMaxThreads = nodeMaxThreads
if nodeTCPMaxConnections < 0 {
nodeTCPMaxConnections = 0
}
op.NodeTCPMaxConnections = nodeTCPMaxConnections
op.AutoOpenPorts = autoOpenPorts
err := this.Save(tx, op)
@@ -922,7 +918,7 @@ func (this *NodeClusterDAO) FindClusterBasicInfo(tx *dbs.Tx, clusterId int64, ca
cluster, err := this.Query(tx).
Pk(clusterId).
State(NodeClusterStateEnabled).
Result("timeZone", "nodeMaxThreads", "nodeTCPMaxConnections", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "isOn").
Result("id", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "isOn", "ddosProtection").
Find()
if err != nil || cluster == nil {
return nil, err
@@ -992,6 +988,45 @@ func (this *NodeClusterDAO) FindClusterWebPPolicy(tx *dbs.Tx, clusterId int64, c
return policy, nil
}
// FindClusterDDoSProtection 获取集群的DDoS设置
func (this *NodeClusterDAO) FindClusterDDoSProtection(tx *dbs.Tx, clusterId int64) (*ddosconfigs.ProtectionConfig, error) {
one, err := this.Query(tx).
Result("ddosProtection").
Pk(clusterId).
Find()
if one == nil || err != nil {
return nil, err
}
return one.(*NodeCluster).DecodeDDoSProtection(), nil
}
// UpdateClusterDDoSProtection 设置集群的DDOS设置
func (this *NodeClusterDAO) UpdateClusterDDoSProtection(tx *dbs.Tx, clusterId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
if clusterId <= 0 {
return ErrNotFound
}
var op = NewNodeClusterOperator()
op.Id = clusterId
if ddosProtection == nil {
op.DdosProtection = "{}"
} else {
ddosProtectionJSON, err := json.Marshal(ddosProtection)
if err != nil {
return err
}
op.DdosProtection = ddosProtectionJSON
}
err := this.Save(tx, op)
if err != nil {
return err
}
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, NodeTaskTypeDDosProtectionChanged)
}
// NotifyUpdate 通知更新
func (this *NodeClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, NodeTaskTypeConfigChanged)

View File

@@ -4,69 +4,69 @@ import "github.com/iwind/TeaGo/dbs"
// NodeCluster 节点集群
type NodeCluster struct {
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
IsOn bool `field:"isOn"` // 是否启用
Name string `field:"name"` // 名称
UseAllAPINodes uint8 `field:"useAllAPINodes"` // 是否使用所有API节点
ApiNodes dbs.JSON `field:"apiNodes"` // 使用的API节点
InstallDir string `field:"installDir"` // 安装目录
Order uint32 `field:"order"` // 排序
CreatedAt uint64 `field:"createdAt"` // 创建时间
GrantId uint32 `field:"grantId"` // 默认认证方式
State uint8 `field:"state"` // 状态
AutoRegister uint8 `field:"autoRegister"` // 是否开启自动注册
UniqueId string `field:"uniqueId"` // 唯一ID
Secret string `field:"secret"` // 密钥
HealthCheck dbs.JSON `field:"healthCheck"` // 健康检查
DnsName string `field:"dnsName"` // DNS名称
DnsDomainId uint32 `field:"dnsDomainId"` // 域名ID
Dns dbs.JSON `field:"dns"` // DNS配置
Toa dbs.JSON `field:"toa"` // TOA配置
CachePolicyId uint32 `field:"cachePolicyId"` // 缓存策略ID
HttpFirewallPolicyId uint32 `field:"httpFirewallPolicyId"` // WAF策略ID
AccessLog dbs.JSON `field:"accessLog"` // 访问日志设置
SystemServices dbs.JSON `field:"systemServices"` // 系统服务设置
TimeZone string `field:"timeZone"` // 时区
NodeMaxThreads uint32 `field:"nodeMaxThreads"` // 节点最大线程数
NodeTCPMaxConnections uint32 `field:"nodeTCPMaxConnections"` // TCP最大连接数
AutoOpenPorts uint8 `field:"autoOpenPorts"` // 是否自动尝试开放端口
IsPinned bool `field:"isPinned"` // 是否置顶
Webp dbs.JSON `field:"webp"` // WebP设置
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
IsOn bool `field:"isOn"` // 是否启用
Name string `field:"name"` // 名称
UseAllAPINodes uint8 `field:"useAllAPINodes"` // 是否使用所有API节点
ApiNodes dbs.JSON `field:"apiNodes"` // 使用的API节点
InstallDir string `field:"installDir"` // 安装目录
Order uint32 `field:"order"` // 排序
CreatedAt uint64 `field:"createdAt"` // 创建时间
GrantId uint32 `field:"grantId"` // 默认认证方式
State uint8 `field:"state"` // 状态
AutoRegister uint8 `field:"autoRegister"` // 是否开启自动注册
UniqueId string `field:"uniqueId"` // 唯一ID
Secret string `field:"secret"` // 密钥
HealthCheck dbs.JSON `field:"healthCheck"` // 健康检查
DnsName string `field:"dnsName"` // DNS名称
DnsDomainId uint32 `field:"dnsDomainId"` // 域名ID
Dns dbs.JSON `field:"dns"` // DNS配置
Toa dbs.JSON `field:"toa"` // TOA配置
CachePolicyId uint32 `field:"cachePolicyId"` // 缓存策略ID
HttpFirewallPolicyId uint32 `field:"httpFirewallPolicyId"` // WAF策略ID
AccessLog dbs.JSON `field:"accessLog"` // 访问日志设置
SystemServices dbs.JSON `field:"systemServices"` // 系统服务设置
TimeZone string `field:"timeZone"` // 时区
NodeMaxThreads uint32 `field:"nodeMaxThreads"` // 节点最大线程数
DdosProtection dbs.JSON `field:"ddosProtection"` // DDOS端口
AutoOpenPorts uint8 `field:"autoOpenPorts"` // 是否自动尝试开放端口
IsPinned bool `field:"isPinned"` // 是否置顶
Webp dbs.JSON `field:"webp"` // WebP设置
}
type NodeClusterOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
IsOn interface{} // 是否启用
Name interface{} // 名称
UseAllAPINodes interface{} // 是否使用所有API节点
ApiNodes interface{} // 使用的API节点
InstallDir interface{} // 安装目录
Order interface{} // 排序
CreatedAt interface{} // 创建时间
GrantId interface{} // 默认认证方式
State interface{} // 状态
AutoRegister interface{} // 是否开启自动注册
UniqueId interface{} // 唯一ID
Secret interface{} // 密钥
HealthCheck interface{} // 健康检查
DnsName interface{} // DNS名称
DnsDomainId interface{} // 域名ID
Dns interface{} // DNS配置
Toa interface{} // TOA配置
CachePolicyId interface{} // 缓存策略ID
HttpFirewallPolicyId interface{} // WAF策略ID
AccessLog interface{} // 访问日志设置
SystemServices interface{} // 系统服务设置
TimeZone interface{} // 时区
NodeMaxThreads interface{} // 节点最大线程数
NodeTCPMaxConnections interface{} // TCP最大连接数
AutoOpenPorts interface{} // 是否自动尝试开放端口
IsPinned interface{} // 是否置顶
Webp interface{} // WebP设置
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
IsOn interface{} // 是否启用
Name interface{} // 名称
UseAllAPINodes interface{} // 是否使用所有API节点
ApiNodes interface{} // 使用的API节点
InstallDir interface{} // 安装目录
Order interface{} // 排序
CreatedAt interface{} // 创建时间
GrantId interface{} // 默认认证方式
State interface{} // 状态
AutoRegister interface{} // 是否开启自动注册
UniqueId interface{} // 唯一ID
Secret interface{} // 密钥
HealthCheck interface{} // 健康检查
DnsName interface{} // DNS名称
DnsDomainId interface{} // 域名ID
Dns interface{} // DNS配置
Toa interface{} // TOA配置
CachePolicyId interface{} // 缓存策略ID
HttpFirewallPolicyId interface{} // WAF策略ID
AccessLog interface{} // 访问日志设置
SystemServices interface{} // 系统服务设置
TimeZone interface{} // 时区
NodeMaxThreads interface{} // 节点最大线程数
DdosProtection interface{} // DDOS端口
AutoOpenPorts interface{} // 是否自动尝试开放端口
IsPinned interface{} // 是否置顶
Webp interface{} // WebP设置
}
func NewNodeClusterOperator() *NodeClusterOperator {

View File

@@ -3,6 +3,7 @@ package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
)
// DecodeDNSConfig 解析DNS配置
@@ -21,3 +22,26 @@ func (this *NodeCluster) DecodeDNSConfig() (*dnsconfigs.ClusterDNSConfig, error)
}
return dnsConfig, nil
}
// DecodeDDoSProtection 解析DDOS Protection设置
func (this *NodeCluster) DecodeDDoSProtection() *ddosconfigs.ProtectionConfig {
if IsNull(this.DdosProtection) {
return nil
}
var result = &ddosconfigs.ProtectionConfig{}
err := json.Unmarshal(this.DdosProtection, &result)
if err != nil {
// ignore err
}
return result
}
// HasDDoSProtection 检查是否有DDOS设置
func (this *NodeCluster) HasDDoSProtection() bool {
var config = this.DecodeDDoSProtection()
if config != nil {
return config.IsOn()
}
return false
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
_ "github.com/go-sql-driver/mysql"
@@ -973,6 +974,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
clusterIds = append(clusterIds, node.DecodeSecondaryClusterIds()...)
var clusterIndex = 0
config.WebPImagePolicies = map[int64]*nodeconfigs.WebPImagePolicy{}
var allowIPMaps = map[string]bool{}
for _, clusterId := range clusterIds {
nodeCluster, err := SharedNodeClusterDAO.FindClusterBasicInfo(tx, clusterId, cacheMap)
if err != nil {
@@ -982,6 +984,21 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
continue
}
// 节点IP地址
nodeIPAddresses, err := SharedNodeIPAddressDAO.FindAllAccessibleIPAddressesWithClusterId(tx, nodeconfigs.NodeRoleNode, clusterId, cacheMap)
if err != nil {
return nil, err
}
for _, address := range nodeIPAddresses {
var ip = address.Ip
_, ok := allowIPMaps[ip]
if !ok {
allowIPMaps[ip] = true
config.AllowedIPs = append(config.AllowedIPs, ip)
}
}
// 防火墙
var httpFirewallPolicyId = int64(nodeCluster.HttpFirewallPolicyId)
if httpFirewallPolicyId > 0 {
firewallPolicy, err := SharedHTTPFirewallPolicyDAO.ComposeFirewallPolicy(tx, httpFirewallPolicyId, cacheMap)
@@ -1016,7 +1033,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
// 最大线程数、TCP连接数
if clusterIndex == 0 {
config.MaxThreads = int(nodeCluster.NodeMaxThreads)
config.TCPMaxConnections = int(nodeCluster.NodeTCPMaxConnections)
config.DDOSProtection = nodeCluster.DecodeDDoSProtection()
config.AutoOpenPorts = nodeCluster.AutoOpenPorts == 1
}
@@ -1148,6 +1165,16 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
}
config.OCSPVersion = ocspVersion
// DDOS Protection
var ddosProtection = node.DecodeDDoSProtection()
if ddosProtection != nil {
if config.DDOSProtection == nil {
config.DDOSProtection = ddosProtection
} else {
config.DDOSProtection.Merge(ddosProtection)
}
}
// 初始化扩展配置
err = this.composeExtConfig(tx, config, clusterIds, cacheMap)
if err != nil {
@@ -1794,6 +1821,53 @@ func (this *NodeDAO) FindParentNodeConfigs(tx *dbs.Tx, nodeId int64, groupId int
return
}
// FindNodeDDoSProtection 获取节点的DDOS设置
func (this *NodeDAO) FindNodeDDoSProtection(tx *dbs.Tx, nodeId int64) (*ddosconfigs.ProtectionConfig, error) {
one, err := this.Query(tx).
Result("ddosProtection").
Pk(nodeId).
Find()
if one == nil || err != nil {
return nil, err
}
return one.(*Node).DecodeDDoSProtection(), nil
}
// UpdateNodeDDoSProtection 设置集群的DDOS设置
func (this *NodeDAO) UpdateNodeDDoSProtection(tx *dbs.Tx, nodeId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
if nodeId <= 0 {
return ErrNotFound
}
var op = NewNodeOperator()
op.Id = nodeId
if ddosProtection == nil {
op.DdosProtection = "{}"
} else {
ddosProtectionJSON, err := json.Marshal(ddosProtection)
if err != nil {
return err
}
op.DdosProtection = ddosProtectionJSON
}
err := this.Save(tx, op)
if err != nil {
return err
}
clusterId, err := this.FindNodeClusterId(tx, nodeId)
if err != nil {
return err
}
if clusterId > 0 {
return SharedNodeTaskDAO.CreateNodeTask(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, 0, NodeTaskTypeDDosProtectionChanged, 0)
}
return nil
}
// NotifyUpdate 通知节点相关更新
func (this *NodeDAO) NotifyUpdate(tx *dbs.Tx, nodeId int64) error {
// 这里只需要通知单个集群即可,因为节点是公用的,更新一个就相当于更新了所有

View File

@@ -5,6 +5,7 @@ import (
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
@@ -375,7 +376,15 @@ func (this *NodeIPAddressDAO) ListEnabledIPAddresses(tx *dbs.Tx, role string, no
}
// FindAllAccessibleIPAddressesWithClusterId 列出所有的正在启用的IP地址
func (this *NodeIPAddressDAO) FindAllAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeIPAddress, err error) {
func (this *NodeIPAddressDAO) FindAllAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64, cacheMap *utils.CacheMap) (result []*NodeIPAddress, err error) {
var cacheKey = this.Table + ":FindAllAccessibleIPAddressesWithClusterId:" + role + ":" + types.String(clusterId)
if cacheMap != nil {
cache, ok := cacheMap.Get(cacheKey)
if ok {
return cache.([]*NodeIPAddress), nil
}
}
_, err = this.Query(tx).
State(NodeIPAddressStateEnabled).
Attr("role", role).
@@ -385,6 +394,14 @@ func (this *NodeIPAddressDAO) FindAllAccessibleIPAddressesWithClusterId(tx *dbs.
Param("clusterId", clusterId).
Slice(&result).
FindAll()
if err != nil {
return
}
if cacheMap != nil {
cacheMap.Put(cacheKey, result)
}
return
}

View File

@@ -31,6 +31,8 @@ type Node struct {
State uint8 `field:"state"` // 状态
ConnectedAPINodes dbs.JSON `field:"connectedAPINodes"` // 当前连接的API节点
MaxCPU uint32 `field:"maxCPU"` // 可以使用的最多CPU
MaxThreads uint32 `field:"maxThreads"` // 最大线程数
DdosProtection dbs.JSON `field:"ddosProtection"` // DDOS配置
DnsRoutes dbs.JSON `field:"dnsRoutes"` // DNS线路设置
MaxCacheDiskCapacity dbs.JSON `field:"maxCacheDiskCapacity"` // 硬盘缓存容量
MaxCacheMemoryCapacity dbs.JSON `field:"maxCacheMemoryCapacity"` // 内存缓存容量
@@ -66,6 +68,8 @@ type NodeOperator struct {
State interface{} // 状态
ConnectedAPINodes interface{} // 当前连接的API节点
MaxCPU interface{} // 可以使用的最多CPU
MaxThreads interface{} // 最大线程数
DdosProtection interface{} // DDOS配置
DnsRoutes interface{} // DNS线路设置
MaxCacheDiskCapacity interface{} // 硬盘缓存容量
MaxCacheMemoryCapacity interface{} // 内存缓存容量

View File

@@ -3,6 +3,8 @@ package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"sort"
"time"
)
@@ -97,6 +99,7 @@ func (this *Node) DecodeSecondaryClusterIds() []int64 {
return result
}
// AllClusterIds 获取所属集群IDs
func (this *Node) AllClusterIds() []int64 {
var result = []int64{}
@@ -108,3 +111,60 @@ func (this *Node) AllClusterIds() []int64 {
return result
}
// DecodeDDoSProtection 解析DDoS Protection设置
func (this *Node) DecodeDDoSProtection() *ddosconfigs.ProtectionConfig {
if IsNull(this.DdosProtection) {
return nil
}
var result = &ddosconfigs.ProtectionConfig{}
err := json.Unmarshal(this.DdosProtection, &result)
if err != nil {
// ignore err
}
return result
}
// HasDDoSProtection 检查是否有DDOS设置
func (this *Node) HasDDoSProtection() bool {
var config = this.DecodeDDoSProtection()
if config != nil {
return !config.IsPriorEmpty()
}
return false
}
func (this *Node) DecodeMaxCacheDiskCapacity() *shared.SizeCapacity {
if this.MaxCacheDiskCapacity.IsNull() {
return nil
}
// ignore error
capacity, _ := shared.DecodeSizeCapacityJSON(this.MaxCacheDiskCapacity)
return capacity
}
func (this *Node) DecodeMaxCacheMemoryCapacity() *shared.SizeCapacity {
if this.MaxCacheMemoryCapacity.IsNull() {
return nil
}
// ignore error
capacity, _ := shared.DecodeSizeCapacityJSON(this.MaxCacheMemoryCapacity)
return capacity
}
// DecodeDNSResolver 解析DNS解析主机配置
func (this *Node) DecodeDNSResolver() *nodeconfigs.DNSResolverConfig {
if this.DnsResolver.IsNull() {
return nil
}
var resolverConfig = nodeconfigs.DefaultDNSResolverConfig()
err := json.Unmarshal(this.DnsResolver, resolverConfig)
if err != nil {
// ignore error
}
return resolverConfig
}

View File

@@ -14,11 +14,12 @@ import (
type NodeTaskType = string
const (
NodeTaskTypeConfigChanged NodeTaskType = "configChanged"
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged"
NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged"
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged"
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged"
NodeTaskTypeConfigChanged NodeTaskType = "configChanged" // 节点整体配置变化
NodeTaskTypeDDosProtectionChanged NodeTaskType = "ddosProtectionChanged" // 节点DDoS配置变更
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged"
NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged"
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged"
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged"
// NS相关

View File

@@ -71,7 +71,7 @@ func TestAliDNSProvider_AddRecord(t *testing.T) {
Name: "test",
Type: dnstypes.RecordTypeA,
Value: "192.168.1.100",
Route: "unicom",
Route: "aliyun_r_cn-beijing",
})
if err != nil {
t.Fatal(err)
@@ -103,7 +103,7 @@ func testAliDNSProvider() (ProviderInterface, error) {
if err != nil {
return nil, err
}
one, err := db.FindOne("SELECT * FROM edgeDNSProviders WHERE type='alidns' ORDER BY id DESC")
one, err := db.FindOne("SELECT * FROM edgeDNSProviders WHERE type='alidns' AND state=1 ORDER BY id DESC")
if err != nil {
return nil, err
}

View File

@@ -16,6 +16,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/andybalholm/brotli"
"github.com/iwind/TeaGo/dbs"
@@ -767,6 +768,7 @@ func (this *NodeService) FindCurrentNodeConfig(ctx context.Context, req *pb.Find
NodeJSON: data,
DataSize: int64(len(data)),
IsCompressed: isCompressed,
Timestamp: time.Now().Unix(),
}, nil
}
@@ -1789,3 +1791,161 @@ func (this *NodeService) UpdateNodeDNSResolver(ctx context.Context, req *pb.Upda
return this.Success()
}
// FindNodeDDoSProtection 获取集群的DDoS设置
func (this *NodeService) FindNodeDDoSProtection(ctx context.Context, req *pb.FindNodeDDoSProtectionRequest) (*pb.FindNodeDDoSProtectionResponse, error) {
var nodeId = req.NodeId
var isFromNode = false
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
// 检查是否来自节点
currentNodeId, err2 := this.ValidateNode(ctx)
if err2 != nil {
return nil, err
}
if nodeId > 0 && currentNodeId != nodeId {
return nil, errors.New("invalid 'nodeId'")
}
nodeId = currentNodeId
isFromNode = true
}
var tx *dbs.Tx
ddosProtection, err := models.SharedNodeDAO.FindNodeDDoSProtection(tx, nodeId)
if err != nil {
return nil, err
}
if ddosProtection == nil {
ddosProtection = ddosconfigs.DefaultProtectionConfig()
}
// 组合父级节点配置
// 只有从节点读取配置时才需要组合
if isFromNode {
clusterId, err := models.SharedNodeDAO.FindNodeClusterId(tx, nodeId)
if err != nil {
return nil, err
}
if clusterId > 0 {
clusterDDoSProtection, err := models.SharedNodeClusterDAO.FindClusterDDoSProtection(tx, clusterId)
if err != nil {
return nil, err
}
if clusterDDoSProtection == nil {
clusterDDoSProtection = ddosconfigs.DefaultProtectionConfig()
}
clusterDDoSProtection.Merge(ddosProtection)
ddosProtection = clusterDDoSProtection
}
}
ddosProtectionJSON, err := json.Marshal(ddosProtection)
if err != nil {
return nil, err
}
var result = &pb.FindNodeDDoSProtectionResponse{
DdosProtectionJSON: ddosProtectionJSON,
}
return result, nil
}
// UpdateNodeDDoSProtection 修改集群的DDOS设置
func (this *NodeService) UpdateNodeDDoSProtection(ctx context.Context, req *pb.UpdateNodeDDoSProtectionRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var ddosProtection = &ddosconfigs.ProtectionConfig{}
err = json.Unmarshal(req.DdosProtectionJSON, ddosProtection)
if err != nil {
return nil, err
}
var tx *dbs.Tx
err = models.SharedNodeDAO.UpdateNodeDDoSProtection(tx, req.NodeId, ddosProtection)
if err != nil {
return nil, err
}
return this.Success()
}
// FindEnabledNodeConfigInfo 取得节点的配置概要信息
func (this *NodeService) FindEnabledNodeConfigInfo(ctx context.Context, req *pb.FindEnabledNodeConfigInfoRequest) (*pb.FindEnabledNodeConfigInfoResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
var result = &pb.FindEnabledNodeConfigInfoResponse{}
node, err := models.SharedNodeDAO.FindEnabledNode(tx, req.NodeId)
if err != nil {
return nil, err
}
if node == nil {
// 总是返回非空
return result, nil
}
// dns
if len(node.DNSRouteCodes()) > 0 {
result.HasDNSInfo = true
}
// cache
if len(node.CacheDiskDir) > 0 {
result.HasCacheInfo = true
} else {
var diskCapacity = node.DecodeMaxCacheDiskCapacity()
var memoryCapacity = node.DecodeMaxCacheMemoryCapacity()
if (diskCapacity != nil && diskCapacity.IsNotEmpty()) || (memoryCapacity != nil && memoryCapacity.IsNotEmpty()) {
result.HasCacheInfo = true
}
}
// thresholds
countThresholds, err := models.SharedNodeThresholdDAO.CountAllEnabledThresholds(tx, nodeconfigs.NodeRoleNode, 0, req.NodeId)
if err != nil {
return nil, err
}
result.HasThresholds = countThresholds > 0
// ssh
nodeLogin, err := models.SharedNodeLoginDAO.FindEnabledNodeLoginWithNodeId(tx, nodeconfigs.NodeRoleNode, req.NodeId)
if err != nil {
return nil, err
}
if nodeLogin != nil {
sshParams, err := nodeLogin.DecodeSSHParams()
if err != nil {
return nil, err
}
if sshParams != nil {
result.HasSSH = len(sshParams.Host) > 0 || sshParams.Port > 0
}
}
// systemSettings
if node.MaxCPU > 0 {
result.HasSystemSettings = true
} else {
// dns resolver
var dnsResolverConfig = node.DecodeDNSResolver()
if dnsResolverConfig != nil {
result.HasSystemSettings = dnsResolverConfig.Type != nodeconfigs.DNSResolverTypeDefault
}
}
// ddos protection
result.HasDDoSProtection = node.HasDDoSProtection()
return result, nil
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
@@ -83,7 +84,7 @@ func (this *NodeClusterService) UpdateNodeCluster(ctx context.Context, req *pb.U
tx := this.NullTx()
err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.NodeTCPMaxConnections, req.AutoOpenPorts)
err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts)
if err != nil {
return nil, err
}
@@ -148,22 +149,21 @@ func (this *NodeClusterService) FindEnabledNodeCluster(ctx context.Context, req
}
return &pb.FindEnabledNodeClusterResponse{NodeCluster: &pb.NodeCluster{
Id: int64(cluster.Id),
Name: cluster.Name,
CreatedAt: int64(cluster.CreatedAt),
InstallDir: cluster.InstallDir,
NodeGrantId: int64(cluster.GrantId),
UniqueId: cluster.UniqueId,
Secret: cluster.Secret,
HttpCachePolicyId: int64(cluster.CachePolicyId),
HttpFirewallPolicyId: int64(cluster.HttpFirewallPolicyId),
DnsName: cluster.DnsName,
DnsDomainId: int64(cluster.DnsDomainId),
IsOn: cluster.IsOn,
TimeZone: cluster.TimeZone,
NodeMaxThreads: int32(cluster.NodeMaxThreads),
NodeTCPMaxConnections: int32(cluster.NodeTCPMaxConnections),
AutoOpenPorts: cluster.AutoOpenPorts == 1,
Id: int64(cluster.Id),
Name: cluster.Name,
CreatedAt: int64(cluster.CreatedAt),
InstallDir: cluster.InstallDir,
NodeGrantId: int64(cluster.GrantId),
UniqueId: cluster.UniqueId,
Secret: cluster.Secret,
HttpCachePolicyId: int64(cluster.CachePolicyId),
HttpFirewallPolicyId: int64(cluster.HttpFirewallPolicyId),
DnsName: cluster.DnsName,
DnsDomainId: int64(cluster.DnsDomainId),
IsOn: cluster.IsOn,
TimeZone: cluster.TimeZone,
NodeMaxThreads: int32(cluster.NodeMaxThreads),
AutoOpenPorts: cluster.AutoOpenPorts == 1,
}}, nil
}
@@ -1054,6 +1054,9 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
}
}
// ddos
result.HasDDoSProtection = cluster.HasDDoSProtection()
return result, nil
}
@@ -1114,3 +1117,51 @@ func (this *NodeClusterService) UpdateNodeClusterWebPPolicy(ctx context.Context,
}
return this.Success()
}
// FindNodeClusterDDoSProtection 获取集群的DDOS设置
func (this *NodeClusterService) FindNodeClusterDDoSProtection(ctx context.Context, req *pb.FindNodeClusterDDoSProtectionRequest) (*pb.FindNodeClusterDDoSProtectionResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx *dbs.Tx
ddosProtection, err := models.SharedNodeClusterDAO.FindClusterDDoSProtection(tx, req.NodeClusterId)
if err != nil {
return nil, err
}
if ddosProtection == nil {
ddosProtection = ddosconfigs.DefaultProtectionConfig()
}
ddosProtectionJSON, err := json.Marshal(ddosProtection)
if err != nil {
return nil, err
}
var result = &pb.FindNodeClusterDDoSProtectionResponse{
DdosProtectionJSON: ddosProtectionJSON,
}
return result, nil
}
// UpdateNodeClusterDDoSProtection 修改集群的DDOS设置
func (this *NodeClusterService) UpdateNodeClusterDDoSProtection(ctx context.Context, req *pb.UpdateNodeClusterDDoSProtectionRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var ddosProtection = &ddosconfigs.ProtectionConfig{}
err = json.Unmarshal(req.DdosProtectionJSON, ddosProtection)
if err != nil {
return nil, err
}
var tx *dbs.Tx
err = models.SharedNodeClusterDAO.UpdateClusterDDoSProtection(tx, req.NodeClusterId, ddosProtection)
if err != nil {
return nil, err
}
return this.Success()
}