mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	优化WAF策略默认设置
* 增加JSCookie动作选项 * 拦截动作增加“失败全局封禁”选项 * 人机识别动作增加“失败全局封禁”选项 * IP名单中的“服务”文字改为“网站”
This commit is contained in:
		@@ -97,6 +97,7 @@ func (this *PolicyAction) RunGet(params struct {
 | 
				
			|||||||
		"blockOptions":             firewallPolicy.BlockOptions,
 | 
							"blockOptions":             firewallPolicy.BlockOptions,
 | 
				
			||||||
		"pageOptions":              firewallPolicy.PageOptions,
 | 
							"pageOptions":              firewallPolicy.PageOptions,
 | 
				
			||||||
		"captchaOptions":           firewallPolicy.CaptchaOptions,
 | 
							"captchaOptions":           firewallPolicy.CaptchaOptions,
 | 
				
			||||||
 | 
							"jsCookieOptions":          firewallPolicy.JSCookieOptions,
 | 
				
			||||||
		"useLocalFirewall":         firewallPolicy.UseLocalFirewall,
 | 
							"useLocalFirewall":         firewallPolicy.UseLocalFirewall,
 | 
				
			||||||
		"synFlood":                 firewallPolicy.SYNFlood,
 | 
							"synFlood":                 firewallPolicy.SYNFlood,
 | 
				
			||||||
		"log":                      firewallPolicy.Log,
 | 
							"log":                      firewallPolicy.Log,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ import (
 | 
				
			|||||||
	"github.com/iwind/TeaGo/actions"
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
	"github.com/iwind/TeaGo/maps"
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
	"github.com/iwind/TeaGo/types"
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdateAction struct {
 | 
					type UpdateAction struct {
 | 
				
			||||||
@@ -36,17 +35,17 @@ func (this *UpdateAction) RunGet(params struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// block options
 | 
						// block options
 | 
				
			||||||
	if firewallPolicy.BlockOptions == nil {
 | 
						if firewallPolicy.BlockOptions == nil {
 | 
				
			||||||
		firewallPolicy.BlockOptions = &firewallconfigs.HTTPFirewallBlockAction{
 | 
							firewallPolicy.BlockOptions = firewallconfigs.NewHTTPFirewallBlockAction()
 | 
				
			||||||
			StatusCode: http.StatusForbidden,
 | 
					 | 
				
			||||||
			Body:       "Blocked By WAF",
 | 
					 | 
				
			||||||
			URL:        "",
 | 
					 | 
				
			||||||
			Timeout:    60,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// page options
 | 
						// page options
 | 
				
			||||||
	if firewallPolicy.PageOptions == nil {
 | 
						if firewallPolicy.PageOptions == nil {
 | 
				
			||||||
		firewallPolicy.PageOptions = firewallconfigs.DefaultHTTPFirewallPageAction()
 | 
							firewallPolicy.PageOptions = firewallconfigs.NewHTTPFirewallPageAction()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// jscookie options
 | 
				
			||||||
 | 
						if firewallPolicy.JSCookieOptions == nil {
 | 
				
			||||||
 | 
							firewallPolicy.JSCookieOptions = firewallconfigs.NewHTTPFirewallJavascriptCookieAction()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// mode
 | 
						// mode
 | 
				
			||||||
@@ -79,6 +78,7 @@ func (this *UpdateAction) RunGet(params struct {
 | 
				
			|||||||
		"blockOptions":       firewallPolicy.BlockOptions,
 | 
							"blockOptions":       firewallPolicy.BlockOptions,
 | 
				
			||||||
		"pageOptions":        firewallPolicy.PageOptions,
 | 
							"pageOptions":        firewallPolicy.PageOptions,
 | 
				
			||||||
		"captchaOptions":     firewallPolicy.CaptchaOptions,
 | 
							"captchaOptions":     firewallPolicy.CaptchaOptions,
 | 
				
			||||||
 | 
							"jsCookieOptions":    firewallPolicy.JSCookieOptions,
 | 
				
			||||||
		"useLocalFirewall":   firewallPolicy.UseLocalFirewall,
 | 
							"useLocalFirewall":   firewallPolicy.UseLocalFirewall,
 | 
				
			||||||
		"synFloodConfig":     firewallPolicy.SYNFlood,
 | 
							"synFloodConfig":     firewallPolicy.SYNFlood,
 | 
				
			||||||
		"log":                firewallPolicy.Log,
 | 
							"log":                firewallPolicy.Log,
 | 
				
			||||||
@@ -116,6 +116,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
	BlockOptionsJSON    []byte
 | 
						BlockOptionsJSON    []byte
 | 
				
			||||||
	PageOptionsJSON     []byte
 | 
						PageOptionsJSON     []byte
 | 
				
			||||||
	CaptchaOptionsJSON  []byte
 | 
						CaptchaOptionsJSON  []byte
 | 
				
			||||||
 | 
						JsCookieOptionsJSON []byte
 | 
				
			||||||
	Description         string
 | 
						Description         string
 | 
				
			||||||
	IsOn                bool
 | 
						IsOn                bool
 | 
				
			||||||
	Mode                string
 | 
						Mode                string
 | 
				
			||||||
@@ -136,7 +137,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
		Require("请输入策略名称")
 | 
							Require("请输入策略名称")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 校验拦截选项JSON
 | 
						// 校验拦截选项JSON
 | 
				
			||||||
	var blockOptions = &firewallconfigs.HTTPFirewallBlockAction{}
 | 
						var blockOptions = firewallconfigs.NewHTTPFirewallBlockAction()
 | 
				
			||||||
	err := json.Unmarshal(params.BlockOptionsJSON, blockOptions)
 | 
						err := json.Unmarshal(params.BlockOptionsJSON, blockOptions)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.Fail("拦截动作参数校验失败:" + err.Error())
 | 
							this.Fail("拦截动作参数校验失败:" + err.Error())
 | 
				
			||||||
@@ -144,7 +145,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 校验显示页面选项JSON
 | 
						// 校验显示页面选项JSON
 | 
				
			||||||
	var pageOptions = &firewallconfigs.HTTPFirewallPageAction{}
 | 
						var pageOptions = firewallconfigs.NewHTTPFirewallPageAction()
 | 
				
			||||||
	err = json.Unmarshal(params.PageOptionsJSON, pageOptions)
 | 
						err = json.Unmarshal(params.PageOptionsJSON, pageOptions)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.Fail("校验显示页面动作配置失败:" + err.Error())
 | 
							this.Fail("校验显示页面动作配置失败:" + err.Error())
 | 
				
			||||||
@@ -156,7 +157,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 校验验证码选项JSON
 | 
						// 校验验证码选项JSON
 | 
				
			||||||
	var captchaOptions = &firewallconfigs.HTTPFirewallCaptchaAction{}
 | 
						var captchaOptions = firewallconfigs.NewHTTPFirewallCaptchaAction()
 | 
				
			||||||
	err = json.Unmarshal(params.CaptchaOptionsJSON, captchaOptions)
 | 
						err = json.Unmarshal(params.CaptchaOptionsJSON, captchaOptions)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.Fail("验证码动作参数校验失败:" + err.Error())
 | 
							this.Fail("验证码动作参数校验失败:" + err.Error())
 | 
				
			||||||
@@ -180,6 +181,16 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 校验JSCookie选项JSON
 | 
				
			||||||
 | 
						var jsCookieOptions = firewallconfigs.NewHTTPFirewallJavascriptCookieAction()
 | 
				
			||||||
 | 
						if len(params.JsCookieOptionsJSON) > 0 {
 | 
				
			||||||
 | 
							err = json.Unmarshal(params.JsCookieOptionsJSON, jsCookieOptions)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								this.Fail("JSCookie动作参数校验失败:" + err.Error())
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 最大内容尺寸
 | 
						// 最大内容尺寸
 | 
				
			||||||
	if params.MaxRequestBodySize < 0 {
 | 
						if params.MaxRequestBodySize < 0 {
 | 
				
			||||||
		params.MaxRequestBodySize = 0
 | 
							params.MaxRequestBodySize = 0
 | 
				
			||||||
@@ -194,6 +205,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
		BlockOptionsJSON:     params.BlockOptionsJSON,
 | 
							BlockOptionsJSON:     params.BlockOptionsJSON,
 | 
				
			||||||
		PageOptionsJSON:      params.PageOptionsJSON,
 | 
							PageOptionsJSON:      params.PageOptionsJSON,
 | 
				
			||||||
		CaptchaOptionsJSON:   params.CaptchaOptionsJSON,
 | 
							CaptchaOptionsJSON:   params.CaptchaOptionsJSON,
 | 
				
			||||||
 | 
							JsCookieOptionsJSON:  params.JsCookieOptionsJSON,
 | 
				
			||||||
		Mode:                 params.Mode,
 | 
							Mode:                 params.Mode,
 | 
				
			||||||
		UseLocalFirewall:     params.UseLocalFirewall,
 | 
							UseLocalFirewall:     params.UseLocalFirewall,
 | 
				
			||||||
		SynFloodJSON:         params.SynFloodJSON,
 | 
							SynFloodJSON:         params.SynFloodJSON,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if firewallPolicy != nil {
 | 
						if firewallPolicy != nil {
 | 
				
			||||||
		// captcha action
 | 
							// captcha action
 | 
				
			||||||
		var captchaOptions = firewallconfigs.DefaultHTTPFirewallCaptchaAction()
 | 
							var captchaOptions = firewallconfigs.NewHTTPFirewallCaptchaAction()
 | 
				
			||||||
		if len(firewallPolicy.CaptchaOptionsJSON) > 0 {
 | 
							if len(firewallPolicy.CaptchaOptionsJSON) > 0 {
 | 
				
			||||||
			err = json.Unmarshal(firewallPolicy.CaptchaOptionsJSON, captchaOptions)
 | 
								err = json.Unmarshal(firewallPolicy.CaptchaOptionsJSON, captchaOptions)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,7 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if firewallPolicy != nil {
 | 
						if firewallPolicy != nil {
 | 
				
			||||||
		// captcha action
 | 
							// captcha action
 | 
				
			||||||
		var captchaOptions = firewallconfigs.DefaultHTTPFirewallCaptchaAction()
 | 
							var captchaOptions = firewallconfigs.NewHTTPFirewallCaptchaAction()
 | 
				
			||||||
		if len(firewallPolicy.CaptchaOptionsJSON) > 0 {
 | 
							if len(firewallPolicy.CaptchaOptionsJSON) > 0 {
 | 
				
			||||||
			err = json.Unmarshal(firewallPolicy.CaptchaOptionsJSON, captchaOptions)
 | 
								err = json.Unmarshal(firewallPolicy.CaptchaOptionsJSON, captchaOptions)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,8 +175,8 @@ Vue.component("ip-list-table", {
 | 
				
			|||||||
								
 | 
													
 | 
				
			||||||
								<span v-if="item.policy.id > 0">
 | 
													<span v-if="item.policy.id > 0">
 | 
				
			||||||
									<span v-if="item.policy.server != null">
 | 
														<span v-if="item.policy.server != null">
 | 
				
			||||||
										<a :href="'/servers/server/settings/waf/ipadmin/allowList?serverId=' + item.policy.server.id + '&firewallPolicyId=' + item.policy.id" v-if="item.list.type == 'white'">[服务:{{item.policy.server.name}}]</a>
 | 
															<a :href="'/servers/server/settings/waf/ipadmin/allowList?serverId=' + item.policy.server.id + '&firewallPolicyId=' + item.policy.id" v-if="item.list.type == 'white'">[网站:{{item.policy.server.name}}]</a>
 | 
				
			||||||
										<a :href="'/servers/server/settings/waf/ipadmin/denyList?serverId=' + item.policy.server.id + '&firewallPolicyId=' + item.policy.id" v-if="item.list.type == 'black'">[服务:{{item.policy.server.name}}]</a>
 | 
															<a :href="'/servers/server/settings/waf/ipadmin/denyList?serverId=' + item.policy.server.id + '&firewallPolicyId=' + item.policy.id" v-if="item.list.type == 'black'">[网站:{{item.policy.server.name}}]</a>
 | 
				
			||||||
									</span>
 | 
														</span>
 | 
				
			||||||
									<span v-else>
 | 
														<span v-else>
 | 
				
			||||||
										<a :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + item.policy.id +  '&type=' + item.list.type">[策略:{{item.policy.name}}]</a>
 | 
															<a :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + item.policy.id +  '&type=' + item.list.type">[策略:{{item.policy.name}}]</a>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ Vue.component("http-firewall-block-options-viewer", {
 | 
				
			|||||||
	<span v-if="options == null">默认设置</span>
 | 
						<span v-if="options == null">默认设置</span>
 | 
				
			||||||
	<div v-else>
 | 
						<div v-else>
 | 
				
			||||||
		状态码:{{options.statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span>  / 超时时间:{{options.timeout}}秒 <span v-if="options.timeoutMax > options.timeout">/ 最大封禁时长:{{options.timeoutMax}}秒</span>
 | 
							状态码:{{options.statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span>  / 超时时间:{{options.timeout}}秒 <span v-if="options.timeoutMax > options.timeout">/ 最大封禁时长:{{options.timeoutMax}}秒</span>
 | 
				
			||||||
 | 
							<span v-if="options.failBlockScopeAll"> / 尝试全局封禁</span>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>	
 | 
					</div>	
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ Vue.component("http-firewall-block-options", {
 | 
				
			|||||||
	props: ["v-block-options"],
 | 
						props: ["v-block-options"],
 | 
				
			||||||
	data: function () {
 | 
						data: function () {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			blockOptions: this.vBlockOptions,
 | 
								options: this.vBlockOptions,
 | 
				
			||||||
			statusCode: this.vBlockOptions.statusCode,
 | 
								statusCode: this.vBlockOptions.statusCode,
 | 
				
			||||||
			timeout: this.vBlockOptions.timeout,
 | 
								timeout: this.vBlockOptions.timeout,
 | 
				
			||||||
			timeoutMax: this.vBlockOptions.timeoutMax,
 | 
								timeoutMax: this.vBlockOptions.timeoutMax,
 | 
				
			||||||
@@ -13,25 +13,25 @@ Vue.component("http-firewall-block-options", {
 | 
				
			|||||||
		statusCode: function (v) {
 | 
							statusCode: function (v) {
 | 
				
			||||||
			let statusCode = parseInt(v)
 | 
								let statusCode = parseInt(v)
 | 
				
			||||||
			if (isNaN(statusCode)) {
 | 
								if (isNaN(statusCode)) {
 | 
				
			||||||
				this.blockOptions.statusCode = 403
 | 
									this.options.statusCode = 403
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				this.blockOptions.statusCode = statusCode
 | 
									this.options.statusCode = statusCode
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		timeout: function (v) {
 | 
							timeout: function (v) {
 | 
				
			||||||
			let timeout = parseInt(v)
 | 
								let timeout = parseInt(v)
 | 
				
			||||||
			if (isNaN(timeout)) {
 | 
								if (isNaN(timeout)) {
 | 
				
			||||||
				this.blockOptions.timeout = 0
 | 
									this.options.timeout = 0
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				this.blockOptions.timeout = timeout
 | 
									this.options.timeout = timeout
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		timeoutMax: function (v) {
 | 
							timeoutMax: function (v) {
 | 
				
			||||||
			let timeoutMax = parseInt(v)
 | 
								let timeoutMax = parseInt(v)
 | 
				
			||||||
			if (isNaN(timeoutMax)) {
 | 
								if (isNaN(timeoutMax)) {
 | 
				
			||||||
				this.blockOptions.timeoutMax = 0
 | 
									this.options.timeoutMax = 0
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				this.blockOptions.timeoutMax = timeoutMax
 | 
									this.options.timeoutMax = timeoutMax
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
@@ -41,9 +41,10 @@ Vue.component("http-firewall-block-options", {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	template: `<div>
 | 
						template: `<div>
 | 
				
			||||||
	<input type="hidden" name="blockOptionsJSON" :value="JSON.stringify(blockOptions)"/>
 | 
						<input type="hidden" name="blockOptionsJSON" :value="JSON.stringify(options)"/>
 | 
				
			||||||
	<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> <span v-if="timeout > 0"> / 封禁时长:{{timeout}}秒</span>
 | 
						<a href="" @click.prevent="edit">状态码:{{statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span> <span v-if="timeout > 0"> / 封禁时长:{{timeout}}秒</span>
 | 
				
			||||||
	 <span v-if="timeoutMax > timeout"> / 最大封禁时长:{{timeoutMax}}秒</span>
 | 
						 <span v-if="timeoutMax > timeout"> / 最大封禁时长:{{timeoutMax}}秒</span>
 | 
				
			||||||
 | 
						 <span v-if="options.failBlockScopeAll"> / 尝试全局封禁</span>
 | 
				
			||||||
	 <i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
 | 
						 <i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
 | 
				
			||||||
	<table class="ui table" v-show="isEditing">
 | 
						<table class="ui table" v-show="isEditing">
 | 
				
			||||||
		<tr>
 | 
							<tr>
 | 
				
			||||||
@@ -55,7 +56,7 @@ Vue.component("http-firewall-block-options", {
 | 
				
			|||||||
		<tr>
 | 
							<tr>
 | 
				
			||||||
			<td>提示内容</td>
 | 
								<td>提示内容</td>
 | 
				
			||||||
			<td>
 | 
								<td>
 | 
				
			||||||
				<textarea rows="3" v-model="blockOptions.body"></textarea>
 | 
									<textarea rows="3" v-model="options.body"></textarea>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
		<tr>
 | 
							<tr>
 | 
				
			||||||
@@ -78,6 +79,13 @@ Vue.component("http-firewall-block-options", {
 | 
				
			|||||||
				<p class="comment">如果最大封禁时长大于封禁时长({{timeout}}秒),那么表示每次封禁的时候,将会在这两个时长数字之间随机选取一个数字作为最终的封禁时长。</p>
 | 
									<p class="comment">如果最大封禁时长大于封禁时长({{timeout}}秒),那么表示每次封禁的时候,将会在这两个时长数字之间随机选取一个数字作为最终的封禁时长。</p>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>失败全局封禁</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<checkbox v-model="options.failBlockScopeAll"></checkbox>
 | 
				
			||||||
 | 
									<p class="comment">选中后,表示允许系统尝试全局封禁某个IP,以提升封禁性能。</p>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
	</table>
 | 
						</table>
 | 
				
			||||||
</div>	
 | 
					</div>	
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,7 +119,7 @@ Vue.component("http-firewall-captcha-options", {
 | 
				
			|||||||
				summaryList.push("失败拦截" + this.options.failBlockTimeout + "秒")
 | 
									summaryList.push("失败拦截" + this.options.failBlockTimeout + "秒")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (this.options.failBlockScopeAll) {
 | 
								if (this.options.failBlockScopeAll) {
 | 
				
			||||||
				summaryList.push("全局封禁")
 | 
									summaryList.push("尝试全局封禁")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let that = this
 | 
								let that = this
 | 
				
			||||||
@@ -199,7 +199,7 @@ Vue.component("http-firewall-captcha-options", {
 | 
				
			|||||||
					<td>失败全局封禁</td>
 | 
										<td>失败全局封禁</td>
 | 
				
			||||||
					<td>
 | 
										<td>
 | 
				
			||||||
						<checkbox v-model="options.failBlockScopeAll"></checkbox>
 | 
											<checkbox v-model="options.failBlockScopeAll"></checkbox>
 | 
				
			||||||
						<p class="comment">是否在失败时全局封禁,默认为只封禁对单个网站的访问。</p>
 | 
											<p class="comment">选中后,表示允许系统尝试全局封禁某个IP,以提升封禁性能。</p>
 | 
				
			||||||
					</td>
 | 
										</td>
 | 
				
			||||||
				</tr>
 | 
									</tr>
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					Vue.component("http-firewall-js-cookie-options-viewer", {
 | 
				
			||||||
 | 
						props: ["v-js-cookie-options"],
 | 
				
			||||||
 | 
						mounted: function () {
 | 
				
			||||||
 | 
							this.updateSummary()
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						data: function () {
 | 
				
			||||||
 | 
							let options = this.vJsCookieOptions
 | 
				
			||||||
 | 
							if (options == null) {
 | 
				
			||||||
 | 
								options = {
 | 
				
			||||||
 | 
									life: 0,
 | 
				
			||||||
 | 
									maxFails: 0,
 | 
				
			||||||
 | 
									failBlockTimeout: 0,
 | 
				
			||||||
 | 
									failBlockScopeAll: false,
 | 
				
			||||||
 | 
									scope: ""
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								options: options,
 | 
				
			||||||
 | 
								summary: ""
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							updateSummary: function () {
 | 
				
			||||||
 | 
								let summaryList = []
 | 
				
			||||||
 | 
								if (this.options.life > 0) {
 | 
				
			||||||
 | 
									summaryList.push("有效时间" + this.options.life + "秒")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.options.maxFails > 0) {
 | 
				
			||||||
 | 
									summaryList.push("最多失败" + this.options.maxFails + "次")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.options.failBlockTimeout > 0) {
 | 
				
			||||||
 | 
									summaryList.push("失败拦截" + this.options.failBlockTimeout + "秒")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.options.failBlockScopeAll) {
 | 
				
			||||||
 | 
									summaryList.push("尝试全局封禁")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (summaryList.length == 0) {
 | 
				
			||||||
 | 
									this.summary = "默认配置"
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									this.summary = summaryList.join(" / ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						template: `<div>{{summary}}</div>
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -0,0 +1,130 @@
 | 
				
			|||||||
 | 
					Vue.component("http-firewall-js-cookie-options", {
 | 
				
			||||||
 | 
						props: ["v-js-cookie-options"],
 | 
				
			||||||
 | 
						mounted: function () {
 | 
				
			||||||
 | 
							this.updateSummary()
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						data: function () {
 | 
				
			||||||
 | 
							let options = this.vJsCookieOptions
 | 
				
			||||||
 | 
							if (options == null) {
 | 
				
			||||||
 | 
								options = {
 | 
				
			||||||
 | 
									life: 0,
 | 
				
			||||||
 | 
									maxFails: 0,
 | 
				
			||||||
 | 
									failBlockTimeout: 0,
 | 
				
			||||||
 | 
									failBlockScopeAll: false,
 | 
				
			||||||
 | 
									scope: "service"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								options: options,
 | 
				
			||||||
 | 
								isEditing: false,
 | 
				
			||||||
 | 
								summary: ""
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						watch: {
 | 
				
			||||||
 | 
							"options.life": function (v) {
 | 
				
			||||||
 | 
								let i = parseInt(v, 10)
 | 
				
			||||||
 | 
								if (isNaN(i)) {
 | 
				
			||||||
 | 
									i = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								this.options.life = i
 | 
				
			||||||
 | 
								this.updateSummary()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"options.maxFails": function (v) {
 | 
				
			||||||
 | 
								let i = parseInt(v, 10)
 | 
				
			||||||
 | 
								if (isNaN(i)) {
 | 
				
			||||||
 | 
									i = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								this.options.maxFails = i
 | 
				
			||||||
 | 
								this.updateSummary()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"options.failBlockTimeout": function (v) {
 | 
				
			||||||
 | 
								let i = parseInt(v, 10)
 | 
				
			||||||
 | 
								if (isNaN(i)) {
 | 
				
			||||||
 | 
									i = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								this.options.failBlockTimeout = i
 | 
				
			||||||
 | 
								this.updateSummary()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"options.failBlockScopeAll": function (v) {
 | 
				
			||||||
 | 
								this.updateSummary()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							edit: function () {
 | 
				
			||||||
 | 
								this.isEditing = !this.isEditing
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							updateSummary: function () {
 | 
				
			||||||
 | 
								let summaryList = []
 | 
				
			||||||
 | 
								if (this.options.life > 0) {
 | 
				
			||||||
 | 
									summaryList.push("有效时间" + this.options.life + "秒")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.options.maxFails > 0) {
 | 
				
			||||||
 | 
									summaryList.push("最多失败" + this.options.maxFails + "次")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.options.failBlockTimeout > 0) {
 | 
				
			||||||
 | 
									summaryList.push("失败拦截" + this.options.failBlockTimeout + "秒")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.options.failBlockScopeAll) {
 | 
				
			||||||
 | 
									summaryList.push("尝试全局封禁")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (summaryList.length == 0) {
 | 
				
			||||||
 | 
									this.summary = "默认配置"
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									this.summary = summaryList.join(" / ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							confirm: function () {
 | 
				
			||||||
 | 
								this.isEditing = false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						template: `<div>
 | 
				
			||||||
 | 
						<input type="hidden" name="jsCookieOptionsJSON" :value="JSON.stringify(options)"/>
 | 
				
			||||||
 | 
						<a href="" @click.prevent="edit">{{summary}} <i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
 | 
				
			||||||
 | 
						<div v-show="isEditing" style="margin-top: 0.5em">
 | 
				
			||||||
 | 
							<table class="ui table definition selectable">
 | 
				
			||||||
 | 
								<tbody>
 | 
				
			||||||
 | 
									<tr>
 | 
				
			||||||
 | 
										<td class="title">有效时间</td>
 | 
				
			||||||
 | 
										<td>
 | 
				
			||||||
 | 
											<div class="ui input right labeled">
 | 
				
			||||||
 | 
												<input type="text" style="width: 5em" maxlength="9" v-model="options.life" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
 | 
				
			||||||
 | 
												<span class="ui label">秒</span>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<p class="comment">验证通过后在这个时间内不再验证,默认3600秒。</p>
 | 
				
			||||||
 | 
										</td>
 | 
				
			||||||
 | 
									</tr>
 | 
				
			||||||
 | 
									<tr>
 | 
				
			||||||
 | 
										<td>最多失败次数</td>
 | 
				
			||||||
 | 
										<td>
 | 
				
			||||||
 | 
											<div class="ui input right labeled">
 | 
				
			||||||
 | 
												<input type="text" style="width: 5em" maxlength="9" v-model="options.maxFails" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
 | 
				
			||||||
 | 
												<span class="ui label">次</span>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<p class="comment"><span v-if="options.maxFails > 0 && options.maxFails < 5" class="red">建议填入一个不小于5的数字,以减少误判几率。</span>允许用户失败尝试的最多次数,超过这个次数将被自动加入黑名单。如果为空或者为0,表示不限制。</p>
 | 
				
			||||||
 | 
										</td>
 | 
				
			||||||
 | 
									</tr>
 | 
				
			||||||
 | 
									<tr>
 | 
				
			||||||
 | 
										<td>失败拦截时间</td>
 | 
				
			||||||
 | 
										<td>
 | 
				
			||||||
 | 
											<div class="ui input right labeled">
 | 
				
			||||||
 | 
												<input type="text" style="width: 5em" maxlength="9" v-model="options.failBlockTimeout" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
 | 
				
			||||||
 | 
												<span class="ui label">秒</span>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<p class="comment">在达到最多失败次数(大于0)时,自动拦截的时长;如果为0表示不自动拦截。</p>
 | 
				
			||||||
 | 
										</td>
 | 
				
			||||||
 | 
									</tr>
 | 
				
			||||||
 | 
									<tr>
 | 
				
			||||||
 | 
										<td>失败全局封禁</td>
 | 
				
			||||||
 | 
										<td>
 | 
				
			||||||
 | 
											<checkbox v-model="options.failBlockScopeAll"></checkbox>
 | 
				
			||||||
 | 
											<p class="comment">选中后,表示允许系统尝试全局封禁某个IP,以提升封禁性能。</p>
 | 
				
			||||||
 | 
										</td>
 | 
				
			||||||
 | 
									</tr>
 | 
				
			||||||
 | 
								</tbody>
 | 
				
			||||||
 | 
							</table>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -48,6 +48,12 @@
 | 
				
			|||||||
            <http-firewall-captcha-options-viewer :v-captcha-options="firewallPolicy.captchaOptions"></http-firewall-captcha-options-viewer>
 | 
					            <http-firewall-captcha-options-viewer :v-captcha-options="firewallPolicy.captchaOptions"></http-firewall-captcha-options-viewer>
 | 
				
			||||||
        </td>
 | 
					        </td>
 | 
				
			||||||
    </tr>
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>JSCookie动作配置</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <http-firewall-js-cookie-options-viewer :v-js-cookie-options="firewallPolicy.jsCookieOptions"></http-firewall-js-cookie-options-viewer>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
        <td>使用系统防火墙</td>
 | 
					        <td>使用系统防火墙</td>
 | 
				
			||||||
        <td>
 | 
					        <td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,6 +54,12 @@
 | 
				
			|||||||
                    <http-firewall-captcha-options :v-captcha-options="firewallPolicy.captchaOptions"></http-firewall-captcha-options>
 | 
					                    <http-firewall-captcha-options :v-captcha-options="firewallPolicy.captchaOptions"></http-firewall-captcha-options>
 | 
				
			||||||
                </td>
 | 
					                </td>
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>JSCookie动作配置</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <http-firewall-js-cookie-options :v-js-cookie-options="firewallPolicy.jsCookieOptions"></http-firewall-js-cookie-options>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
    </table>
 | 
					    </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user