优化WAF动作

This commit is contained in:
刘祥超
2021-07-18 15:52:50 +08:00
parent 9c231a2b8c
commit 63884bc836
6 changed files with 112 additions and 73 deletions

View File

@@ -49,7 +49,7 @@ Vue.component("http-access-log-box", {
}
},
template: `<div :style="{'color': (accessLog.status >= 400) ? '#dc143c' : ''}" ref="box">
<span v-if="accessLog.region != null && accessLog.region.length > 0" class="grey">[{{accessLog.region}}]</span> <keyword :v-word="vKeyword">{{accessLog.remoteAddr}}</keyword> [{{accessLog.timeLocal}}] <em>&quot;<keyword :v-word="vKeyword">{{accessLog.requestMethod}}</keyword> {{accessLog.scheme}}://<keyword :v-word="vKeyword">{{accessLog.host}}</keyword><keyword :v-word="vKeyword">{{accessLog.requestURI}}</keyword> <a :href="accessLog.scheme + '://' + accessLog.host + accessLog.requestURI" target="_blank" title="新窗口打开" class="disabled"><i class="external icon tiny"></i> </a> {{accessLog.proto}}&quot; </em> <keyword :v-word="vKeyword">{{accessLog.status}}</keyword> <code-label v-if="accessLog.attrs != null && accessLog.attrs['cache.status'] == 'HIT'">cache hit</code-label> <code-label v-if="accessLog.attrs != null && accessLog.attrs['waf.action'] != null && accessLog.attrs['waf.action'].length > 0">waf {{accessLog.attrs['waf.action']}}</code-label> - 耗时:{{formatCost(accessLog.requestTime)}} ms <span v-if="accessLog.humanTime != null && accessLog.humanTime.length > 0" class="grey small">&nbsp; ({{accessLog.humanTime}})</span>
<span v-if="accessLog.region != null && accessLog.region.length > 0" class="grey">[{{accessLog.region}}]</span> <keyword :v-word="vKeyword">{{accessLog.remoteAddr}}</keyword> [{{accessLog.timeLocal}}] <em>&quot;<keyword :v-word="vKeyword">{{accessLog.requestMethod}}</keyword> {{accessLog.scheme}}://<keyword :v-word="vKeyword">{{accessLog.host}}</keyword><keyword :v-word="vKeyword">{{accessLog.requestURI}}</keyword> <a :href="accessLog.scheme + '://' + accessLog.host + accessLog.requestURI" target="_blank" title="新窗口打开" class="disabled"><i class="external icon tiny"></i> </a> {{accessLog.proto}}&quot; </em> <keyword :v-word="vKeyword">{{accessLog.status}}</keyword> <code-label v-if="accessLog.attrs != null && accessLog.attrs['cache.status'] == 'HIT'">cache hit</code-label> <code-label v-if="accessLog.firewallActions != null && accessLog.firewallActions.length > 0">waf {{accessLog.firewallActions}}</code-label> <span v-if="accessLog.tags != null && accessLog.tags.length > 0">- <code-label v-for="tag in accessLog.tags">{{tag}}</code-label></span> - 耗时:{{formatCost(accessLog.requestTime)}} ms <span v-if="accessLog.humanTime != null && accessLog.humanTime.length > 0" class="grey small">&nbsp; ({{accessLog.humanTime}})</span>
&nbsp; <a href="" @click.prevent="showLog" title="查看详情"><i class="icon expand"></i></a>
</div>`
})

View File

@@ -62,7 +62,7 @@ Vue.component("http-firewall-actions-box", {
ipListLevels: [],
// 动作参数
blockLife: "",
blockTimeout: "",
captchaLife: "",
get302Life: "",
post307Life: "",
@@ -89,12 +89,12 @@ Vue.component("http-firewall-actions-box", {
})
this.actionOptions = {}
},
blockLife: function (v) {
blockTimeout: function (v) {
v = parseInt(v)
if (isNaN(v)) {
this.actionOptions["life"] = 0
this.actionOptions["timeout"] = 0
} else {
this.actionOptions["life"] = v
this.actionOptions["timeout"] = v
}
},
captchaLife: function (v) {
@@ -121,7 +121,7 @@ Vue.component("http-firewall-actions-box", {
this.actionOptions["life"] = v
}
},
recordIPType: function () {
recordIPType: function (v) {
this.recordIPListId = 0
},
recordIPTimeout: function (v) {
@@ -168,7 +168,7 @@ Vue.component("http-firewall-actions-box", {
this.actionOptions = {}
// 动作参数
this.blockLife = ""
this.blockTimeout = ""
this.captchaLife = ""
this.get302Life = ""
this.post307Life = ""
@@ -192,8 +192,13 @@ Vue.component("http-firewall-actions-box", {
this.action = this.vActions.$find(function (k, v) {
return v.code == that.actionCode
})
// 滚到界面底部
this.scroll()
},
remove: function (index) {
this.isAdding = false
this.editingIndex = -1
this.configs.$remove(index)
},
update: function (index, config) {
@@ -211,9 +216,9 @@ Vue.component("http-firewall-actions-box", {
switch (config.code) {
case "block":
this.blockLife = ""
if (config.options.life != null || config.options.life > 0) {
this.blockLife = config.options.life.toString()
this.blockTimeout = ""
if (config.options.timeout != null || config.options.timeout > 0) {
this.blockTimeout = config.options.timeout.toString()
}
break
case "allow":
@@ -247,8 +252,13 @@ Vue.component("http-firewall-actions-box", {
if (config.options.timeout > 0) {
this.recordIPTimeout = config.options.timeout.toString()
}
this.recordIPListId = config.options.ipListId
this.recordIPListName = config.options.ipListName
let that = this
// VUE需要在函数执行完之后才会调用watch函数这样会导致设置的值被覆盖所以这里使用setTimeout
setTimeout(function () {
that.recordIPListId = config.options.ipListId
that.recordIPListName = config.options.ipListName
})
}
break
case "tag":
@@ -274,18 +284,25 @@ Vue.component("http-firewall-actions-box", {
return v.id == config.options.groupId
})
this.goSetId = config.options.setId
if (this.goGroup != null) {
let set = this.goGroup.sets.$find(function (k, v) {
// VUE需要在函数执行完之后才会调用watch函数这样会导致设置的值被覆盖所以这里使用setTimeout
let that = this
setTimeout(function () {
that.goSetId = config.options.setId
if (that.goGroup != null) {
let set = that.goGroup.sets.$find(function (k, v) {
return v.id == config.options.setId
})
if (set != null) {
this.goSetName = set.name
that.goSetName = set.name
}
}
})
}
break
}
// 滚到界面底部
this.scroll()
},
cancel: function () {
this.isAdding = false
@@ -335,7 +352,7 @@ Vue.component("http-firewall-actions-box", {
return
}
this.actionOptions = {
groupId: groupId,
groupId: groupId.toString(),
groupName: this.goGroupName
}
} else if (this.actionCode == "go_set") { // go_set
@@ -358,9 +375,9 @@ Vue.component("http-firewall-actions-box", {
return
}
this.actionOptions = {
groupId: groupId,
groupId: groupId.toString(),
groupName: this.goGroupName,
setId: setId,
setId: setId.toString(),
setName: this.goSetName
}
}
@@ -419,6 +436,14 @@ Vue.component("http-firewall-actions-box", {
callback()
})
document.head.appendChild(jsFile)
},
scroll: function () {
setTimeout(function () {
let mainDiv = document.getElementsByClassName("main")
if (mainDiv.length > 0) {
mainDiv[0].scrollTo(0, 1000)
}
}, 10)
}
},
template: `<div>
@@ -427,6 +452,18 @@ Vue.component("http-firewall-actions-box", {
<div v-for="(config, index) in configs" :data-index="index" :key="config.id" class="ui label small basic" :class="{blue: index == editingIndex}" style="margin-bottom: 0.4em">
{{config.name}} ({{config.code.toUpperCase()}})
<!-- block -->
<span v-if="config.code == 'block' && config.options.timeout > 0">:有效期{{config.options.timeout}}秒</span>
<!-- captcha -->
<span v-if="config.code == 'captcha' && config.options.life > 0">:有效期{{config.options.life}}秒</span>
<!-- get 302 -->
<span v-if="config.code == 'get_302' && config.options.life > 0">:有效期{{config.options.life}}秒</span>
<!-- post 307 -->
<span v-if="config.code == 'post_307' && config.options.life > 0">:有效期{{config.options.life}}秒</span>
<!-- record_ip -->
<span v-if="config.code == 'record_ip'">{{config.options.ipListName}}</span>
@@ -461,7 +498,7 @@ Vue.component("http-firewall-actions-box", {
<td>封锁时间</td>
<td>
<div class="ui input right labeled">
<input type="text" style="width: 5em" maxlength="10" v-model="blockLife" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
<input type="text" style="width: 5em" maxlength="10" v-model="blockTimeout" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
<span class="ui label">秒</span>
</div>
</td>
@@ -475,7 +512,7 @@ Vue.component("http-firewall-actions-box", {
<input type="text" style="width: 5em" maxlength="10" v-model="captchaLife" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
<span class="ui label">秒</span>
</div>
<p class="comment">验证通过后在这个时间内不再验证。</p>
<p class="comment">验证通过后在这个时间内不再验证默认600秒。</p>
</td>
</tr>
@@ -514,7 +551,7 @@ Vue.component("http-firewall-actions-box", {
</td>
</tr>
<tr v-if="actionCode == 'record_ip'">
<td>选择IP名单</td>
<td>选择IP名单 *</td>
<td>
<div v-if="recordIPListId > 0" class="ui label basic small">{{recordIPListName}} <a href="" @click.prevent="removeRecordIPList"><i class="icon remove small"></i></a></div>
<button type="button" class="ui button tiny" @click.prevent="selectRecordIPList">+</button>
@@ -533,7 +570,7 @@ Vue.component("http-firewall-actions-box", {
<td>超时时间</td>
<td>
<div class="ui input right labeled">
<input type="text" style="width: 5em" maxlength="10" v-model="recordIPTimeout" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
<input type="text" style="width: 6em" maxlength="10" v-model="recordIPTimeout" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
<span class="ui label">秒</span>
</div>
<p class="comment">0表示不超时。</p>
@@ -585,5 +622,6 @@ Vue.component("http-firewall-actions-box", {
<div v-if="!isAdding">
<button class="ui button tiny" type="button" @click.prevent="add">+</button>
</div>
<p class="comment">系统总是会先执行记录日志、标签等不会修改请求的动作,再执行阻止、验证码等可能改变请求的动作。</p>
</div>`
})

View File

@@ -12,7 +12,7 @@
</td>
</tr>
<tr>
<td>规则</td>
<td>规则 *</td>
<td>
<http-firewall-rules-box :v-rules="rules" :v-type="type"></http-firewall-rules-box>
</td>

View File

@@ -1,14 +1,14 @@
{$layout}
{$template "waf_menu"}
{$template "waf_menu"}
<second-menu style="margin-top:-1em">
<second-menu style="margin-top:-1em">
<a href="" class="item" @click.prevent="createGroup(type)">[添加分组]</a>
</second-menu>
</second-menu>
<p class="comment" v-if="groups.length == 0">暂时还没有规则分组。</p>
<p class="comment" v-if="groups.length == 0">暂时还没有规则分组。</p>
<table class="ui table selectable celled" v-if="groups.length > 0" id="sortable-table">
<table class="ui table selectable celled" v-if="groups.length > 0" id="sortable-table">
<thead>
<tr>
<th style="width:3em"></th>
@@ -39,6 +39,6 @@
</td>
</tr>
</tbody>
</table>
</table>
<p class="comment" v-if="groups.length > 0">所有规则匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。</p>
<p class="comment" v-if="groups.length > 0">所有规则匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。</p>

View File

@@ -12,7 +12,7 @@
</td>
</tr>
<tr>
<td>规则</td>
<td>规则 *</td>
<td>
<http-firewall-rules-box :v-rules="rules" :v-type="type"></http-firewall-rules-box>
</td>

View File

@@ -33,7 +33,7 @@
<th style="width:3em"></th>
<th nowrap="">规则集名称</th>
<th nowrap="">规则</th>
<th nowrap="" class="center">关系</th>
<th nowrap="" class="center one wide">关系</th>
<th nowrap="">动作</th>
<th class="three op">操作</th>
</tr>
@@ -52,11 +52,12 @@
</div>
<span class="ui disabled" v-if="set.rules.length == 0">暂时还没有规则</span>
</td>
<td class="center">{{set.connector.toUpperCase()}}</td>
<td nowrap=""><span :class="{red:set.action == 'BLOCK' || set.action == 'CAPTCHA', green:set.action != 'BLOCK' && set.action != 'CAPTCHA'}">{{set.actionName}}[{{set.action.toUpperCase()}}]</span>
<div v-if="set.actionLinks != null && set.actionLinks.length > 0" style="margin-top:0.3em">
<span class="disabled">-&gt;</span> <span v-for="link in set.actionLinks"><a :href="link.url"><span class="disabled">[{{link.name}}]</span></a> &nbsp;</span>
</div>
<td class="center">
<span v-if="set.connector.toUpperCase() == 'OR'"></span><span v-else></span>
<span class="small grey">({{set.connector.toUpperCase()}})</span>
</td>
<td nowrap="">
<http-firewall-actions-view :v-actions="set.actions"></http-firewall-actions-view>
</td>
<td>
<a href="" @click.prevent="updateSet(set.id)">修改</a> &nbsp; <a href="" @click.prevent="updateSetOn(set.id, false)" v-if="set.isOn">停用</a><a href="" @click.prevent="updateSetOn(set.id, true)" v-if="!set.isOn">启用</a> &nbsp; <a href="" @click.prevent="deleteSet(set.id)">删除</a>