Skip to content

Commit

Permalink
feat(waf): 增加全局设置 (1Panel-dev#4088)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengkunwang223 authored Mar 6, 2024
1 parent fe717d9 commit 21f24f2
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 33 deletions.
4 changes: 4 additions & 0 deletions backend/i18n/lang/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,7 @@ CutWebsiteLogSuccess: "{{ .name }} website log cut successfully, backup path {{
#toolbox
ErrNotExistUser: "The current user does not exist. Please modify and retry!"
ErrBanAction: "Setting failed, the current {{ .name }} service is unavailable, please check and try again!"

#waf
ErrScope: "Modification of this configuration is not supported"
ErrStateChange: "State modification failed"
4 changes: 4 additions & 0 deletions backend/i18n/lang/zh-Hant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,7 @@ CutWebsiteLogSuccess: "{{ .name }} 網站日誌切割成功,備份路徑 {{ .p
#toolbox
ErrNotExistUser: "當前使用者不存在,請修改後重試!"
ErrBanAction: "設置失敗,當前 {{ .name }} 服務不可用,請檢查後重試!"

#waf
ErrScope: "不支援修改此配置"
ErrStateChange: "狀態修改失敗"
6 changes: 5 additions & 1 deletion backend/i18n/lang/zh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,8 @@ CutWebsiteLogSuccess: "{{ .name }} 网站日志切割成功,备份路径 {{ .p

#toolbox
ErrNotExistUser: "当前用户不存在,请修改后重试!"
ErrBanAction: "设置失败,当前 {{ .name }} 服务不可用,请检查后重试!"
ErrBanAction: "设置失败,当前 {{ .name }} 服务不可用,请检查后重试!"

#waf
ErrScope: "不支持修改此配置"
ErrStateChange: "状态修改失败"
56 changes: 56 additions & 0 deletions frontend/src/components/config-card/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<el-card class="config-card">
<div class="config-header">
<span>{{ header }}</span>
<slot name="header-r" />
</div>
<el-text type="info">{{ description }}</el-text>
<div class="config-content">
<slot name="content-r" />
</div>
<div class="config-form">
<slot name="content-form" />
</div>
</el-card>
</template>

<script setup lang="ts">
defineOptions({ name: 'ConfigCard' });
defineProps({
header: String,
description: String,
});
</script>

<style lang="scss" scoped>
.config-card {
cursor: pointer;
margin: 10px;
.config-header {
margin-bottom: 18px;
display: flex;
justify-content: space-between;
align-items: center;
span {
font-weight: normal;
font-size: 18px;
}
}
.config-content {
display: flex;
justify-content: flex-end;
}
.config-form {
margin-top: 20px;
}
}
.config-card {
border: var(--panel-border) !important;
&:hover {
cursor: pointer;
border: 1px solid var(--el-color-primary) !important;
}
}
</style>
41 changes: 40 additions & 1 deletion frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2157,7 +2157,7 @@ const message = {
request: 'request',
count4xx: '4xx quantity',
count5xx: '5xx quantity',
todayStatus: 'Today status',
todayStatus: 'Today Status',
reqMap: 'Request map (30 days)',
resource: 'source',
count: 'Quantity',
Expand All @@ -2167,6 +2167,45 @@ const message = {
interceptCount: 'Interception number',
requestTrends: 'Request Trends (7 days)',
interceptTrends: 'Intercept Trends (7 days)',
whiteList: 'whitelist',
blackList: 'blacklist',
ipBlackListHelper: 'IPs in the blacklist cannot access the website',
ipWhiteListHelper: 'IPs in the whitelist are not restricted by any rules',
uaBlackListHelper: 'Requests carrying User-Agent in the blacklist will be intercepted',
uaWhiteListHelper: 'Requests carrying User-Agent in the whitelist are not restricted by any rules',
urlBlackListHelper: 'Requests for URLs in the blacklist will be intercepted',
urlWhiteListHelper: 'Requests for URLs in the whitelist are not restricted by any rules',
ccHelper:
'If any website has been requested more than {1} times in {0} seconds, this IP will be blocked for {2} seconds',
blockTime: 'Block time',
attackHelper:
'The cumulative interception exceeds {1} times within {0} seconds, block this IP for {2} seconds',
notFoundHelper:
'The cumulative request returned 404 more than {1} times within {0} seconds, block this IP for {2} seconds',
frequencyLimit: 'frequency limit',
regionLimit: 'region limit',
defaultRule: 'Default rule',
accessFrequencyLmit: 'Access frequency limit',
attackLimit: 'Attack frequency limit',
notFoundLimit: '404 frequency limit',
urlLimit: 'URL frequency limit',
urlLimitHelper: 'Set access frequency for a single URL',
sqliDefense: 'SQL injection defense',
sqliHelper: 'Identify SQL injection in requests and intercept',
xssHelper: 'Identify XSS in the request and intercept it',
xssDefense: 'XSS Defense',
uaDefense: 'Malicious User-Agent Rule',
uaHelper: 'Contains common malicious crawler rules',
argsDefense: 'Malicious parameter rules',
argsHelper: 'Prohibit malicious parameters in requests',
cookieDefense: 'Malicious Cookie Rule',
cookieHelper: 'Prohibit malicious cookies from being carried in requests',
headerDefense: 'Malicious Header Rule',
headerHelper: 'Prohibit requests from containing malicious headers',
httpRule: 'HTTP request method rules',
httpHelper: 'Restrict the request method type of the website',
geoRule: 'Regional access restrictions',
geoHelper: 'Restrict access to your website from certain regions',
},
monitor: {
name: 'Website Monitoring',
Expand Down
36 changes: 36 additions & 0 deletions frontend/src/lang/modules/tw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,42 @@ const message = {
interceptCount: '攔截數',
requestTrends: '請求趨勢7)',
interceptTrends: '攔截趨勢7)',
whiteList: '白名單',
blackList: '黑名單',
ipBlackListHelper: '黑名單中的 IP 無法存取網站',
ipWhiteListHelper: '白名單中的 IP 不受任何規則限制',
uaBlackListHelper: '攜帶黑名單中的 User-Agent 的請求將被攔截',
uaWhiteListHelper: '攜帶白名單中的 User-Agent 的請求不受任何規則限制',
urlBlackListHelper: '請求黑名單中的 URL 將被攔截',
urlWhiteListHelper: '請求白名單中的 URL 請求不受任何規則限制',
ccHelper: '{0} 秒內累積請求任意網站超過 {1} 封鎖此 IP {2} ',
blockTime: '封鎖時間',
attackHelper: '{0} 秒內累計攔截超過 {1} 封鎖此 IP {2} ',
notFoundHelper: '{0} 秒內累計請求回傳 404 超過 {1} 封鎖此 IP {2} ',
frequencyLimit: '頻率限制',
regionLimit: '地區限制',
defaultRule: '預設規則',
accessFrequencyLmit: '存取頻率限制',
attackLimit: '攻擊頻率限制',
notFoundLimit: '404 頻率限制',
urlLimit: 'URL 頻率限制',
urlLimitHelper: '為單一 URL 設定存取頻率',
sqliDefense: 'SQL 注入防禦',
sqliHelper: '辨識請求中的 SQL 注入並攔截',
xssHelper: '辨識請求中的 XSS 並攔截',
xssDefense: 'XSS 防禦',
uaDefense: '惡 User-Agent 規則',
uaHelper: '包含常見的惡意爬蟲規則',
argsDefense: '惡意參數規則',
argsHelper: '在禁止請求中攜帶惡意參數',
cookieDefense: '惡 Cookie 規則',
cookieHelper: '禁止請求中攜帶惡意 Cookie',
headerDefense: '惡 Header 規則',
headerHelper: '禁止請求中攜帶惡意 Header',
httpRule: 'HTTP 請求方法規則',
httpHelper: '限制網站的請求方法類型',
geoRule: '地區存取限制',
geoHelper: '限制某些地區造訪你的網站',
},
monitor: {
name: '網站監控',
Expand Down
36 changes: 36 additions & 0 deletions frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,42 @@ const message = {
interceptCount: '拦截数',
requestTrends: '请求趋势7)',
interceptTrends: '拦截趋势7)',
whiteList: '白名单',
blackList: '黑名单',
ipBlackListHelper: '黑名单中的 IP 无法访问网站',
ipWhiteListHelper: '白名单中的 IP 不受任何规则限制',
uaBlackListHelper: '携带黑名单中的 User-Agent 的请求将被拦截',
uaWhiteListHelper: '携带白名单中的 User-Agent 的请求不受任何规则限制',
urlBlackListHelper: '请求黑名单中的 URL 将被拦截',
urlWhiteListHelper: '请求白名单中的 URL 请求不受任何规则限制',
ccHelper: '{0} 秒内累计请求任意网站超过 {1} 封锁此 IP {2} ',
blockTime: '封禁时间',
attackHelper: '{0} 秒内累计拦截超过 {1} 封锁此 IP {2} ',
notFoundHelper: '{0} 秒内累计请求返回 404 超过 {1} 封锁此 IP {2} ',
frequencyLimit: '频率限制',
regionLimit: '地区限制',
defaultRule: '默认规则',
accessFrequencyLmit: '访问频率限制',
attackLimit: '攻击频率限制',
notFoundLimit: '404 频率限制',
urlLimit: 'URL 频率限制',
urlLimitHelper: '为单个 URL 设置访问频率',
sqliDefense: 'SQL 注入防御',
sqliHelper: '识别请求中的 SQL 注入并拦截',
xssHelper: '识别请求中的 XSS 并拦截',
xssDefense: 'XSS 防御',
uaDefense: '恶 User-Agent 规则',
uaHelper: '包含常见的恶意爬虫规则',
argsDefense: '恶意参数规则',
argsHelper: '禁止请求中携带恶意参数',
cookieDefense: '恶 Cookie 规则',
cookieHelper: '禁止请求中携带恶意 Cookie',
headerDefense: '恶 Header 规则',
headerHelper: '禁止请求中携带恶意 Header',
httpRule: 'HTTP 请求方法规则',
httpHelper: '限制网站的请求方法类型',
geoRule: '地区访问限制',
geoHelper: '限制某些地区访问你的网站',
},
monitor: {
name: '网站监控',
Expand Down
2 changes: 1 addition & 1 deletion plugins/openresty/waf/conf/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
"action": "deny",
"code": 403,
"type": "fileExtCheck",
"extList": [
"rules": [
"php",
"jsp",
"asp",
Expand Down
2 changes: 1 addition & 1 deletion plugins/openresty/waf/lib/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ function _M.post_check()
local match = ngx_re_match(m[0], 'Content-Disposition: form-data; (.+)filename="(.+)\\.(.*)"', 'ijo')
if match then
local extension = match[3]
for _, ext in ipairs(rule.extList) do
for _, ext in ipairs(rule.rules) do
if extension == ext then
exec_action(rule)
end
Expand Down
28 changes: 28 additions & 0 deletions plugins/openresty/waf/lib/utils.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local geoip = require "geoip"
local sub_str = string.sub
local pairs = pairs
local insert_table = table.insert
Expand All @@ -6,6 +7,7 @@ local ipairs = ipairs
local type = type
local find_str = string.find
local gmatch_str = string.gmatch
local cjson = require "cjson"

local _M = {}

Expand Down Expand Up @@ -114,6 +116,32 @@ function _M.get_real_ip()
return "unknown"
end

function _M.get_geo_ip(ip)
if _M.is_intranet_address(ip) then
return {
country = { ["zh"] = "内网", ["en"] = "intranet" },
province = { ["zh"] = "内网", ["en"] = "intranet" },
city = { ["zh"] = "内网", ["en"] = "intranet" },
longitude = 0,
latitude = 0,
iso = "local"
}
else
geoip.init()
local geo_res = geoip.lookup(ip)
local msg = "访问 IP " .. ip
if geo_res.country then
msg = msg .. " 国家 " .. cjson.encode(geo_res.country)
end
if geo_res.province then
msg = msg .. " 省份 " .. cjson.encode(geo_res.province)
end
ngx.log(ngx.ERR, msg)
return geo_res

end
end

function _M.get_header(headerKey)
return ngx.req.get_headers(20000)[headerKey]
end
Expand Down
10 changes: 10 additions & 0 deletions plugins/openresty/waf/log_and_traffic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ if config.is_waf_on() then
count_not_found()
local is_attack = ngx.ctx.is_attack

if not ngx.ctx.ip then
ngx.ctx.ip = utils.get_real_ip()
ngx.ctx.geoip = utils.get_geo_ip(ngx.ctx.ip)
local ua = utils.get_header("user-agent")
if not ua then
ua = ""
end
end


local wafdb = utils.get_wafdb(config.waf_db_path)
if wafdb ~= nil then
count_req_status(wafdb,is_attack)
Expand Down
32 changes: 3 additions & 29 deletions plugins/openresty/waf/waf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,7 @@ local function get_website_key()
return s_name
end

local function get_geo_ip(ip)
if utils.is_intranet_address(ip) then
return {
country = { ["zh"] = "内网", ["en"] = "intranet" },
province = { ["zh"] = "内网", ["en"] = "intranet" },
city = { ["zh"] = "内网", ["en"] = "intranet" },
longitude = 0,
latitude = 0,
iso = "local"
}
else
return geoip.lookup(ip)
end
end


local function init()
local ip = utils.get_real_ip()
Expand All @@ -64,21 +51,10 @@ local function init()
if not ua then
ua = ""
end

geoip.init()

ngx.ctx.ua = ua
ngx.ctx.geoip = get_geo_ip(ip)

local msg = "访问 IP " .. ip
if ngx.ctx.geoip.country then
msg = msg .. " 国家 " .. cjson.encode(ngx.ctx.geoip.country)
end
if ngx.ctx.geoip.province then
msg = msg .. " 省份 " .. cjson.encode(ngx.ctx.geoip.province)
end
ngx.log(ngx.ERR, msg)

ngx.ctx.geoip = utils.get_geo_ip(ip)

ngx.ctx.website_key = get_website_key()
ngx.ctx.method = ngx.req.get_method()
ngx.ctx.content_type = utils.get_header("content-type")
Expand Down Expand Up @@ -144,8 +120,6 @@ local function waf_api()
end
end

ngx.log(ngx.ERR,"access waf")

if config.is_waf_on() then
init()
waf_api()
Expand Down

0 comments on commit 21f24f2

Please sign in to comment.