mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	实现自动SYN Flood防护
This commit is contained in:
		@@ -84,6 +84,7 @@ func (this *PolicyAction) RunGet(params struct {
 | 
			
		||||
	if len(firewallPolicy.Mode) == 0 {
 | 
			
		||||
		firewallPolicy.Mode = firewallconfigs.FirewallModeDefend
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["firewallPolicy"] = maps.Map{
 | 
			
		||||
		"id":               firewallPolicy.Id,
 | 
			
		||||
		"name":             firewallPolicy.Name,
 | 
			
		||||
@@ -94,6 +95,7 @@ func (this *PolicyAction) RunGet(params struct {
 | 
			
		||||
		"groups":           internalGroups,
 | 
			
		||||
		"blockOptions":     firewallPolicy.BlockOptions,
 | 
			
		||||
		"useLocalFirewall": firewallPolicy.UseLocalFirewall,
 | 
			
		||||
		"synFlood":         firewallPolicy.SYNFlood,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 正在使用此策略的集群
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,16 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["modes"] = firewallconfigs.FindAllFirewallModes()
 | 
			
		||||
 | 
			
		||||
	// syn flood
 | 
			
		||||
	if firewallPolicy.SYNFlood == nil {
 | 
			
		||||
		firewallPolicy.SYNFlood = &firewallconfigs.SYNFloodConfig{
 | 
			
		||||
			IsOn:           false,
 | 
			
		||||
			MinAttempts:    10,
 | 
			
		||||
			TimeoutSeconds: 600,
 | 
			
		||||
			IgnoreLocal:    true,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["firewallPolicy"] = maps.Map{
 | 
			
		||||
		"id":               firewallPolicy.Id,
 | 
			
		||||
		"name":             firewallPolicy.Name,
 | 
			
		||||
@@ -56,6 +66,7 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
		"mode":             firewallPolicy.Mode,
 | 
			
		||||
		"blockOptions":     firewallPolicy.BlockOptions,
 | 
			
		||||
		"useLocalFirewall": firewallPolicy.UseLocalFirewall,
 | 
			
		||||
		"synFloodConfig":   firewallPolicy.SYNFlood,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 预置分组
 | 
			
		||||
@@ -89,6 +100,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
	IsOn             bool
 | 
			
		||||
	Mode             string
 | 
			
		||||
	UseLocalFirewall bool
 | 
			
		||||
	SynFloodJSON     []byte
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
@@ -115,6 +127,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
		BlockOptionsJSON:     params.BlockOptionsJSON,
 | 
			
		||||
		Mode:                 params.Mode,
 | 
			
		||||
		UseLocalFirewall:     params.UseLocalFirewall,
 | 
			
		||||
		SynFloodJSON:         params.SynFloodJSON,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import (
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Data("teaMenu", "servers").
 | 
			
		||||
			Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
			Prefix("/servers").
 | 
			
		||||
 
 | 
			
		||||
@@ -133,6 +133,16 @@ func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// node
 | 
			
		||||
		var sourceNodeMap = maps.Map{"id": 0}
 | 
			
		||||
		if item.SourceNode != nil && item.SourceNode.NodeCluster != nil {
 | 
			
		||||
			sourceNodeMap = maps.Map{
 | 
			
		||||
				"id":        item.SourceNode.Id,
 | 
			
		||||
				"name":      item.SourceNode.Name,
 | 
			
		||||
				"clusterId": item.SourceNode.NodeCluster.Id,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		itemMaps = append(itemMaps, maps.Map{
 | 
			
		||||
			"id":             item.Id,
 | 
			
		||||
			"ipFrom":         item.IpFrom,
 | 
			
		||||
@@ -149,6 +159,7 @@ func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
			"sourceGroup":    sourceGroupMap,
 | 
			
		||||
			"sourceSet":      sourceSetMap,
 | 
			
		||||
			"sourceServer":   sourceServerMap,
 | 
			
		||||
			"sourceNode":     sourceNodeMap,
 | 
			
		||||
			"list":           listMap,
 | 
			
		||||
			"policy":         policyMap,
 | 
			
		||||
		})
 | 
			
		||||
 
 | 
			
		||||
@@ -172,6 +172,9 @@ Vue.component("ip-list-table", {
 | 
			
		||||
						<a :href="'/servers/components/waf/group?firewallPolicyId=' +  item.sourcePolicy.id + '&type=inbound&groupId=' + item.sourceGroup.id" v-if="item.sourcePolicy.serverId == 0"><span class="small "><i class="icon shield"></i>{{item.sourcePolicy.name}} » {{item.sourceGroup.name}} » {{item.sourceSet.name}}</span></a>
 | 
			
		||||
						<a :href="'/servers/server/settings/waf/group?serverId=' + item.sourcePolicy.serverId + '&firewallPolicyId=' + item.sourcePolicy.id + '&type=inbound&groupId=' + item.sourceGroup.id" v-if="item.sourcePolicy.serverId > 0"><span class="small "><i class="icon shield"></i> {{item.sourcePolicy.name}} » {{item.sourceGroup.name}} » {{item.sourceSet.name}}</span></a>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div v-if="item.sourceNode != null && item.sourceNode.id > 0" style="margin-top: 0.4em">
 | 
			
		||||
						<a :href="'/clusters/cluster/node?clusterId=' + item.sourceNode.clusterId + '&nodeId=' + item.sourceNode.id"><span class="small"><i class="icon cloud"></i>{{item.sourceNode.name}}</span></a>
 | 
			
		||||
					</div>
 | 
			
		||||
				</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<a href="" @click.prevent="viewLogs(item.id)">日志</a>  
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,92 @@
 | 
			
		||||
Vue.component("firewall-syn-flood-config-box", {
 | 
			
		||||
	props: ["v-syn-flood-config"],
 | 
			
		||||
	data: function () {
 | 
			
		||||
		let config = this.vSynFloodConfig
 | 
			
		||||
		if (config == null) {
 | 
			
		||||
			config = {
 | 
			
		||||
				isOn: false,
 | 
			
		||||
				minAttempts: 10,
 | 
			
		||||
				timeoutSeconds: 600,
 | 
			
		||||
				ignoreLocal: true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return {
 | 
			
		||||
			config: config,
 | 
			
		||||
			isEditing: false,
 | 
			
		||||
			minAttempts: config.minAttempts,
 | 
			
		||||
			timeoutSeconds: config.timeoutSeconds
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		edit: function () {
 | 
			
		||||
			this.isEditing = !this.isEditing
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	watch: {
 | 
			
		||||
		minAttempts: function (v) {
 | 
			
		||||
			let count = parseInt(v)
 | 
			
		||||
			if (isNaN(count)) {
 | 
			
		||||
				count = 10
 | 
			
		||||
			}
 | 
			
		||||
			if (count < 3) {
 | 
			
		||||
				count = 3
 | 
			
		||||
			}
 | 
			
		||||
			this.config.minAttempts = count
 | 
			
		||||
		},
 | 
			
		||||
		timeoutSeconds: function (v) {
 | 
			
		||||
			let seconds = parseInt(v)
 | 
			
		||||
			if (isNaN(seconds)) {
 | 
			
		||||
				seconds = 10
 | 
			
		||||
			}
 | 
			
		||||
			if (seconds < 60) {
 | 
			
		||||
				seconds = 60
 | 
			
		||||
			}
 | 
			
		||||
			this.config.timeoutSeconds = seconds
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	<input type="hidden" name="synFloodJSON" :value="JSON.stringify(config)"/>
 | 
			
		||||
	<a href="" @click.prevent="edit">
 | 
			
		||||
		<span v-if="config.isOn">
 | 
			
		||||
			已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时间:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
 | 
			
		||||
		</span>
 | 
			
		||||
		<span v-else>未启用</span>
 | 
			
		||||
		<i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i>
 | 
			
		||||
	</a>
 | 
			
		||||
	
 | 
			
		||||
	<table class="ui table selectable" v-show="isEditing">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">是否启用</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<checkbox v-model="config.isOn"></checkbox>
 | 
			
		||||
				<p class="comment">启用后,WAF将会尝试自动检测并阻止SYN Flood攻击。此功能需要节点已安装并启用Firewalld。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>空连接次数</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui input right labeled">
 | 
			
		||||
					<input type="text" v-model="minAttempts" style="width: 5em" maxlength="4"/>
 | 
			
		||||
					<span class="ui label">次/分钟</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<p class="comment">超过此数字的"空连接"将被视为SYN Flood攻击,为了防止误判,此数值默认不小于3。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>封禁时间</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui input right labeled">
 | 
			
		||||
					<input type="text" v-model="timeoutSeconds" style="width: 5em" maxlength="4"/>
 | 
			
		||||
					<span class="ui label">秒</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>忽略局域网访问</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<checkbox v-model="config.ignoreLocal"></checkbox>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
</div>`
 | 
			
		||||
})
 | 
			
		||||
@@ -4,7 +4,8 @@ Vue.component("http-firewall-block-options", {
 | 
			
		||||
		return {
 | 
			
		||||
			blockOptions: this.vBlockOptions,
 | 
			
		||||
			statusCode: this.vBlockOptions.statusCode,
 | 
			
		||||
			timeout: this.vBlockOptions.timeout
 | 
			
		||||
			timeout: this.vBlockOptions.timeout,
 | 
			
		||||
			isEditing: false
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	watch: {
 | 
			
		||||
@@ -25,9 +26,15 @@ Vue.component("http-firewall-block-options", {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		edit: function () {
 | 
			
		||||
			this.isEditing = !this.isEditing
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
<input type="hidden" name="blockOptionsJSON" :value="JSON.stringify(blockOptions)"/>
 | 
			
		||||
	<table class="ui table">
 | 
			
		||||
	<input type="hidden" name="blockOptionsJSON" :value="JSON.stringify(blockOptions)"/>
 | 
			
		||||
	<a href="" @click.prevent="edit">状态码:{{statusCode}} / 提示内容:<span v-if="blockOptions.body != null && blockOptions.body.length > 0">[{{blockOptions.body.length}}字符]</span><span v-else class="disabled">[无]</span>  / 超时时间:{{timeout}}秒 <i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
 | 
			
		||||
	<table class="ui table" v-show="isEditing">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">状态码</td>
 | 
			
		||||
			<td>
 | 
			
		||||
 
 | 
			
		||||
@@ -59,6 +59,39 @@
 | 
			
		||||
            <p class="comment" v-if="firewallPolicy.useLocalFirewall">可以在合适的时候自动使用系统自带防火墙进行防御。</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>SYN Flood防御</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="firewallPolicy.synFlood == null || !firewallPolicy.synFlood.isOn" class="disabled">未启用</span>
 | 
			
		||||
            <table class="ui table selectable" v-if="firewallPolicy.synFlood != null && firewallPolicy.synFlood.isOn">
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td class="title">是否启用</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                       <span class="green">启用</span>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>空连接次数</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        {{firewallPolicy.synFlood.minAttempts}}次/分钟
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>封禁时间</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        {{firewallPolicy.synFlood.timeoutSeconds}}秒
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>忽略局域网访问</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <span v-if="firewallPolicy.synFlood.ignoreLocal" class="green">Y</span>
 | 
			
		||||
                        <span class="disabled" v-else>N</span>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </table>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>描述</td>
 | 
			
		||||
        <td>
 | 
			
		||||
 
 | 
			
		||||
@@ -43,26 +43,32 @@
 | 
			
		||||
                    <checkbox name="useLocalFirewall" v-model="firewallPolicy.useLocalFirewall"></checkbox>
 | 
			
		||||
                    <p class="comment">开启后,可以在合适的时候自动使用系统自带防火墙进行防御。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>SYN Flood防御</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <firewall-syn-flood-config-box :v-syn-flood-config="firewallPolicy.synFloodConfig"></firewall-syn-flood-config-box>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>描述</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<textarea name="description" rows="3" v-model="firewallPolicy.description"></textarea>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>是否启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" name="isOn" value="1" v-model="firewallPolicy.isOn"/>
 | 
			
		||||
						<label></label>
 | 
			
		||||
					</div>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>描述</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <textarea name="description" rows="3" v-model="firewallPolicy.description"></textarea>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>是否启用</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div class="ui checkbox">
 | 
			
		||||
                            <input type="checkbox" name="isOn" value="1" v-model="firewallPolicy.isOn"/>
 | 
			
		||||
                            <label></label>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
			</tbody>
 | 
			
		||||
		</table>
 | 
			
		||||
		<submit-btn></submit-btn>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user