1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 08:19:15 +08:00

feat: 增加网站防火墙相关

This commit is contained in:
zhengkunwang223 2022-11-30 21:40:05 +08:00 committed by zhengkunwang223
parent 5b63dc42a2
commit 1bd5a180b3
27 changed files with 590 additions and 92 deletions

View File

@ -1,4 +1,4 @@
user nginx;
#user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
@ -36,5 +36,11 @@ http {
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
include /etc/nginx/conf.d/*.conf;
lua_code_cache on;
lua_shared_dict limit 10m;
lua_package_path "/www/common/waf/?.lua;/usr/local/openresty/lualib/?.lua;";
init_by_lua_file /www/common/waf/init.lua;
include /usr/local/openresty/nginx/conf/conf.d/*.conf;
}

View File

@ -1,16 +1,12 @@
version: '3'
services:
nginx1.23.1:
container_name: nginx1.23.1
image: nginx:1.23.1
openresty1.21.4:
image: openresty/openresty:1.21.4.1-3-alpine
restart: always
network_mode: host
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./conf/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf
- ./log:/var/log/nginx
- ./conf/conf.d:/etc/nginx/conf.d/
- ./ssl:/etc/nginx/ssl
- ./www:/www/root/
- ./conf/conf.d:/usr/local/openresty/nginx/conf/conf.d/
- ./www:/www
- ./root:/usr/share/nginx/html

View File

@ -0,0 +1,374 @@
local match = string.match
local ngxmatch=ngx.re.match
local unescape=ngx.unescape_uri
local get_headers = ngx.req.get_headers
local cjson = require "cjson"
local content_length=tonumber(ngx.req.get_headers()['content-length'])
local method=ngx.req.get_method()
local function optionIsOn(options)
return options == "on" or options == "On" or options == "ON"
end
local logpath = ngx.var.logdir
local rulepath = ngx.var.RulePath
local UrlDeny = optionIsOn(ngx.var.UrlDeny)
local PostCheck = optionIsOn(ngx.var.postMatch)
local CookieCheck = optionIsOn(ngx.var.cookieMatch)
local WhiteCheck = optionIsOn(ngx.var.whiteModule)
local attacklog = optionIsOn(ngx.var.attacklog)
local CCDeny = optionIsOn(ngx.var.CCDeny)
local Redirect=optionIsOn(ngx.var.Redirect)
local function getClientIp()
IP = ngx.var.remote_addr
if IP == nil then
IP = "unknown"
end
return IP
end
local function write(logfile,msg)
local fd = io.open(logfile,"ab")
if fd == nil then return end
fd:write(msg)
fd:flush()
fd:close()
end
local function log(method,url,data,ruletag)
if attacklog then
local realIp = getClientIp()
local ua = ngx.var.http_user_agent
local servername=ngx.var.server_name
local time=ngx.localtime()
local line = nil
if ua then
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" \""..ua.."\" \""..ruletag.."\"\n"
else
line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
end
local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
write(filename,line)
end
end
------------------------------------规则读取函数-------------------------------------------------------------------
local function read_rule(var)
file = io.open(rulepath..'/'..var,"r")
if file==nil then
return
end
t = {}
for line in file:lines() do
table.insert(t,line)
end
file:close()
return(t)
end
local function read_json(var)
file = io.open(rulepath..'/'..var,"r")
if file==nil then
return
end
str = file:read("*a")
file:close()
list = cjson.decode(str)
return list
end
local function read_str(var)
file = io.open(rulepath..'/'..var,"r")
if file==nil then
return
end
local str = file:read("*a")
file:close()
return str
end
local urlrules=read_rule('url')
local argsrules=read_rule('args')
local uarules=read_rule('user-agent')
local wturlrules=read_rule('whiteurl')
local postrules=read_rule('post')
local ckrules=read_rule('cookie')
local ccrate=read_str('ccrate')
local ipWhitelist=read_json('ipWhitelist')
local ipBlocklist=read_json('ipBlocklist')
local black_fileExt = read_json('blackfileExt')
local html=read_str('html')
local function say_html()
if Redirect then
ngx.header.content_type = "text/html"
ngx.status = ngx.HTTP_FORBIDDEN
ngx.say(html)
ngx.exit(ngx.status)
end
end
local function whiteurl()
if WhiteCheck then
if wturlrules ~=nil then
for _,rule in pairs(wturlrules) do
if ngxmatch(ngx.var.uri,rule,"isjo") then
return true
end
end
end
end
return false
end
local function fileExtCheck(ext)
local items = Set(black_fileExt)
ext=string.lower(ext)
if ext then
for rule in pairs(items) do
if ngx.re.match(ext,rule,"isjo") then
log('POST',ngx.var.request_uri,"-","file attack with ext "..ext)
say_html()
end
end
end
return false
end
function Set (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
local function args()
if argsrules then
for _,rule in pairs(argsrules) do
local uriArgs = ngx.req.get_uri_args()
for key, val in pairs(uriArgs) do
if type(val)=='table' then
local t={}
for k,v in pairs(val) do
if v == true then
v=""
end
table.insert(t,v)
end
data=table.concat(t, " ")
else
data=val
end
if data and type(data) ~= "boolean" and rule ~="" and ngxmatch(unescape(data),rule,"isjo") then
log('GET',ngx.var.request_uri,"-",rule)
say_html()
return true
end
end
end
end
return false
end
local function url()
if UrlDeny then
for _,rule in pairs(urlrules) do
if rule ~="" and ngxmatch(ngx.var.request_uri,rule,"isjo") then
log('GET',ngx.var.request_uri,"-",rule)
say_html()
return true
end
end
end
return false
end
function ua()
local ua = ngx.var.http_user_agent
if ua ~= nil then
for _,rule in pairs(uarules) do
if rule ~="" and ngxmatch(ua,rule,"isjo") then
log('UA',ngx.var.request_uri,"-",rule)
say_html()
return true
end
end
end
return false
end
function body(data)
for _,rule in pairs(postrules) do
if rule ~="" and data~="" and ngxmatch(unescape(data),rule,"isjo") then
log('POST',ngx.var.request_uri,data,rule)
say_html()
return true
end
end
return false
end
local function cookie()
local ck = ngx.var.http_cookie
if CookieCheck and ck then
for _,rule in pairs(ckrules) do
if rule ~="" and ngxmatch(ck,rule,"isjo") then
log('Cookie',ngx.var.request_uri,"-",rule)
say_html()
return true
end
end
end
return false
end
local function denycc()
if CCDeny and ccrate then
local uri=ngx.var.uri
CCcount=tonumber(string.match(ccrate,'(.*)/'))
CCseconds=tonumber(string.match(ccrate,'/(.*)'))
local uri = getClientIp()..uri
local limit = ngx.shared.limit
local req,_=limit:get(uri)
if req then
if req > CCcount then
ngx.exit(503)
return true
else
limit:incr(token,1)
end
else
limit:set(uri,1,CCseconds)
end
end
return false
end
local function get_boundary()
local header = get_headers()["content-type"]
if not header then
return nil
end
if type(header) == "table" then
header = header[1]
end
local m = match(header, ";%s*boundary=\"([^\"]+)\"")
if m then
return m
end
return match(header, ";%s*boundary=([^\",;]+)")
end
local function whiteip()
if next(ipWhitelist) ~= nil then
for _,ip in pairs(ipWhitelist) do
if getClientIp()==ip then
return true
end
end
end
return false
end
local function blockip()
if next(ipBlocklist) ~= nil then
for _,ip in pairs(ipBlocklist) do
if getClientIp()==ip then
ngx.exit(403)
return true
end
end
end
return false
end
if whiteip() then
elseif blockip() then
elseif denycc() then
elseif ngx.var.http_Acunetix_Aspect then
ngx.exit(444)
elseif ngx.var.http_X_Scan_Memo then
ngx.exit(444)
elseif whiteurl() then
elseif ua() then
elseif url() then
elseif args() then
elseif cookie() then
elseif PostCheck then
if method=="POST" then
local boundary = get_boundary()
if boundary then
local len = string.len
local sock, err = ngx.req.socket()
if not sock then
return
end
ngx.req.init_body(128 * 1024)
sock:settimeout(0)
local content_length = nil
content_length=tonumber(ngx.req.get_headers()['content-length'])
local chunk_size = 4096
if content_length < chunk_size then
chunk_size = content_length
end
local size = 0
while size < content_length do
local data, err, partial = sock:receive(chunk_size)
data = data or partial
if not data then
return
end
ngx.req.append_body(data)
if body(data) then
return true
end
size = size + len(data)
local m = ngxmatch(data,[[Content-Disposition: form-data;(.+)filename="(.+)\\.(.*)"]],'ijo')
if m then
fileExtCheck(m[3])
filetranslate = true
else
if ngxmatch(data,"Content-Disposition:",'isjo') then
filetranslate = false
end
if filetranslate==false then
if body(data) then
return true
end
end
end
local less = content_length - size
if less < chunk_size then
chunk_size = less
end
end
ngx.req.finish_body()
else
ngx.req.read_body()
local args = ngx.req.get_post_args()
if not args then
return
end
for key, val in pairs(args) do
if type(val) == "table" then
if type(val[1]) == "boolean" then
return
end
data=table.concat(val, ", ")
else
data=val
end
if data and type(data) ~= "boolean" and body(data) then
body(key)
end
end
end
end
else
return
end

View File

@ -0,0 +1 @@
ngx.log(ngx.INFO,"init success")

View File

@ -0,0 +1,22 @@
\.\./
\:\$
\$\{
select.+(from|limit)
(?:(union(.*?)select))
having|rongjitest
sleep\((\s*)(\d*)(\s*)\)
benchmark\((.*)\,(.*)\)
base64_decode\(
(?:from\W+information_schema\W)
(?:(?:current_)user|database|schema|connection_id)\s*\(
(?:etc\/\W*passwd)
into(\s+)+(?:dump|out)file\s*
group\s+by.+\(
xwork.MethodAccessor
(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
xwork\.MethodAccessor
(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
java\.lang
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
(onmouseover|onerror|onload)\=

View File

@ -0,0 +1 @@
["php","jsp"]

View File

@ -0,0 +1 @@
100/60

View File

@ -0,0 +1,20 @@
\.\./
\:\$
\$\{
select.+(from|limit)
(?:(union(.*?)select))
having|rongjitest
sleep\((\s*)(\d*)(\s*)\)
benchmark\((.*)\,(.*)\)
base64_decode\(
(?:from\W+information_schema\W)
(?:(?:current_)user|database|schema|connection_id)\s*\(
(?:etc\/\W*passwd)
into(\s+)+(?:dump|out)file\s*
group\s+by.+\(
xwork.MethodAccessor
(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
xwork\.MethodAccessor
(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
java\.lang
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[

View File

@ -0,0 +1,30 @@
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>网站防火墙</title>
<style>
p {
line-height:20px;
}
ul{ list-style-type:none;}
li{ list-style-type:none;}
</style>
</head>
<body style=" padding:0; margin:0; font:14px/1.5 Microsoft Yahei, 宋体,sans-serif; color:#555;">
<div style="margin: 0 auto; width:1000px; padding-top:70px; overflow:hidden;">
<div style="width:600px; float:left;">
<div style=" height:40px; line-height:40px; color:#fff; font-size:16px; overflow:hidden; background:#6bb3f6; padding-left:20px;">网站防火墙 </div>
<div style="border:1px dashed #cdcece; border-top:none; font-size:14px; background:#fff; color:#555; line-height:24px; height:220px; padding:20px 20px 0 20px; overflow-y:auto;background:#f3f7f9;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#fc4f03;">您的请求带有不合法参数,已被网站管理员设置拦截!</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">可能原因:您提交的内容包含危险的攻击请求</p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:1; text-indent:0px;">如何解决:</p>
<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1检查提交内容</li>
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2如网站托管请联系空间提供商</li>
<li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3普通网站访客请联系网站管理员</li></ul>
</div>
</div>
</div>
</body></html>

View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1,19 @@
select.+(from|limit)
(?:(union(.*?)select))
having|rongjitest
sleep\((\s*)(\d*)(\s*)\)
benchmark\((.*)\,(.*)\)
base64_decode\(
(?:from\W+information_schema\W)
(?:(?:current_)user|database|schema|connection_id)\s*\(
(?:etc\/\W*passwd)
into(\s+)+(?:dump|out)file\s*
group\s+by.+\(
xwork.MethodAccessor
(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(
xwork\.MethodAccessor
(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\/
java\.lang
\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\[
\<(iframe|script|body|img|layer|div|meta|style|base|object|input)
(onmouseover|onerror|onload)\=

View File

@ -0,0 +1,6 @@
\.(svn|htaccess|bash_history)
\.(bak|inc|old|mdb|sql|backup|java|class)$
(vhost|bbs|host|wwwroot|www|site|root|hytop|flashfxp).*\.rar
(phpmyadmin|jmx-console|jmxinvokerservlet)
java\.lang
/(attachments|upimg|images|css|uploadfiles|html|uploads|templets|static|template|data|inc|forumdata|upload|includes|cache|avatar)/(\\w+).(php|jsp)

View File

@ -0,0 +1 @@
(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)

View File

@ -0,0 +1 @@
^/123/$

View File

@ -4,7 +4,6 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
"github.com/1Panel-dev/1Panel/backend/utils/nginx/parser"
"os"
"path"
@ -49,9 +48,6 @@ func getHttpConfigByKeys(keys []string) ([]dto.NginxParam, error) {
Name: dir.GetName(),
Params: dir.GetParameters(),
}
if isRepeatKey(key) {
nginxParam.SecondKey = dir.GetParameters()[0]
}
res = append(res, nginxParam)
}
if len(dirs) == 0 {
@ -73,15 +69,7 @@ func updateHttpNginxConfig(params []dto.NginxParam) error {
config := nginxConfig.Config
http := config.FindHttp()
for _, p := range params {
newDir := components.Directive{
Name: p.Name,
Parameters: p.Params,
}
if isRepeatKey(p.Name) {
http.UpdateDirectiveBySecondKey(p.Name, p.SecondKey, newDir)
} else {
http.UpdateDirectives(p.Name, newDir)
}
http.UpdateDirective(p.Name, p.Params)
}
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return err

View File

@ -347,7 +347,7 @@ func (w WebsiteService) UpdateNginxConfigByScope(req dto.NginxConfigReq) error {
return err
}
if req.Operate == dto.ConfigDel {
return deleteNginxConfig(website, keys)
return deleteNginxConfig(website, constant.NginxScopeServer, keys)
}
return updateNginxConfig(website, getNginxParams(req.Params, keys), req.Scope)
@ -468,7 +468,7 @@ func (w WebsiteService) OpWebsiteHTTPS(req dto.WebsiteHTTPSOp) (dto.WebsiteHTTPS
return dto.WebsiteHTTPS{}, err
}
if err := deleteNginxConfig(website, getKeysFromStaticFile(dto.SSL)); err != nil {
if err := deleteNginxConfig(website, constant.NginxScopeServer, getKeysFromStaticFile(dto.SSL)); err != nil {
return dto.WebsiteHTTPS{}, err
}
}

View File

@ -44,15 +44,12 @@ func getDomain(domainStr string, websiteID uint) (model.WebSiteDomain, error) {
}
func createStaticHtml(website *model.WebSite) error {
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
nginxInstall, err := getAppInstallByKey("nginx")
if err != nil {
return err
}
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
if err != nil {
return err
}
indexFolder := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "www", website.Alias)
indexFolder := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "www", "sites", website.Alias)
indexPath := path.Join(indexFolder, "index.html")
indexContent := string(nginx_conf.Index)
fileOp := files.NewFileOp()
@ -72,14 +69,38 @@ func createStaticHtml(website *model.WebSite) error {
return nil
}
func createWebsiteFolder(nginxInstall model.AppInstall, website *model.WebSite) error {
nginxFolder := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name)
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
fileOp := files.NewFileOp()
if !fileOp.Stat(siteFolder) {
if err := fileOp.CreateDir(siteFolder, 0755); err != nil {
return err
}
if err := fileOp.CreateDir(path.Join(siteFolder, "log"), 0755); err != nil {
return err
}
if err := fileOp.CreateFile(path.Join(siteFolder, "log", "access.log")); err != nil {
return err
}
if err := fileOp.CreateDir(path.Join(siteFolder, "waf", "rules"), 0755); err != nil {
return err
}
if err := fileOp.CreateDir(path.Join(siteFolder, "data"), 0755); err != nil {
return err
}
}
return fileOp.CopyDir(path.Join(nginxFolder, "www", "common", "waf", "rules"), path.Join(siteFolder, "waf", "rules"))
}
func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) error {
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
nginxInstall, err := getAppInstallByKey("nginx")
if err != nil {
return err
}
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
if err != nil {
if err := createWebsiteFolder(nginxInstall, website); err != nil {
return err
}
@ -98,6 +119,14 @@ func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) e
server.UpdateListen(strconv.Itoa(domain.Port), false)
}
server.UpdateServerName(serverNames)
siteFolder := path.Join("/www", "sites", website.Alias)
commonFolder := path.Join("/www", "common")
server.UpdateDirective("access_log", []string{path.Join(siteFolder, "log", "access.log")})
server.UpdateDirective("access_by_lua_file", []string{path.Join(commonFolder, "waf", "access.lua")})
server.UpdateDirective("set", []string{"$RulePath", path.Join(siteFolder, "waf", "rules")})
server.UpdateDirective("set", []string{"$logdir", path.Join(siteFolder, "waf", "log")})
if website.Type == "deployment" {
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
if err != nil {
@ -106,7 +135,7 @@ func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) e
proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort)
server.UpdateRootProxy([]string{proxy})
} else {
server.UpdateRoot(path.Join("/www/root", website.Alias))
server.UpdateRoot(path.Join("/www/sites", website.Alias))
server.UpdateRootLocation()
}
@ -114,15 +143,16 @@ func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) e
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return err
}
if err := opNginx(nginxInstall.ContainerName, "check"); err != nil {
if err := opNginx(nginxInstall.ContainerName, constant.NginxCheck); err != nil {
return err
}
return opNginx(nginxInstall.ContainerName, "reload")
return opNginx(nginxInstall.ContainerName, constant.NginxReload)
}
func opNginx(containerName, operate string) error {
nginxCmd := fmt.Sprintf("docker exec -i %s %s", containerName, "nginx -s reload")
if operate == "check" {
if operate == constant.NginxCheck {
nginxCmd = fmt.Sprintf("docker exec -i %s %s", containerName, "nginx -t")
}
if out, err := cmd.Exec(nginxCmd); err != nil {
@ -160,12 +190,12 @@ func delNginxConfig(website model.WebSite) error {
func nginxCheckAndReload(oldContent string, filePath string, containerName string) error {
if err := opNginx(containerName, "check"); err != nil {
if err := opNginx(containerName, constant.NginxCheck); err != nil {
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
return err
}
if err := opNginx(containerName, "reload"); err != nil {
if err := opNginx(containerName, constant.NginxReload); err != nil {
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
return err
}
@ -253,9 +283,6 @@ func getNginxConfigByKeys(website model.WebSite, keys []string) ([]dto.NginxPara
Name: dir.GetName(),
Params: dir.GetParameters(),
}
if isRepeatKey(key) {
nginxParam.SecondKey = dir.GetParameters()[0]
}
res = append(res, nginxParam)
}
}
@ -271,15 +298,7 @@ func updateNginxConfig(website model.WebSite, params []dto.NginxParam, scope dto
updateConfig(config, scope)
server := config.FindServers()[0]
for _, p := range params {
newDir := components.Directive{
Name: p.Name,
Parameters: p.Params,
}
if isRepeatKey(p.Name) {
server.UpdateDirectiveBySecondKey(p.Name, p.SecondKey, newDir)
} else {
server.UpdateDirectives(p.Name, newDir)
}
server.UpdateDirective(p.Name, p.Params)
}
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return err
@ -298,15 +317,7 @@ func updateConfig(config *components.Config, scope dto.NginxKey) {
}
for _, dir := range newConfig.GetDirectives() {
newDir := components.Directive{
Name: dir.GetName(),
Parameters: dir.GetParameters(),
}
if isRepeatKey(dir.GetName()) {
config.UpdateDirectiveBySecondKey(dir.GetName(), dir.GetParameters()[0], newDir)
} else {
config.UpdateDirectives(dir.GetName(), newDir)
}
config.UpdateDirective(dir.GetName(), dir.GetParameters())
}
}
@ -339,15 +350,24 @@ func getKeysFromStaticFile(scope dto.NginxKey) []string {
return res
}
func deleteNginxConfig(website model.WebSite, keys []string) error {
func deleteNginxConfig(website model.WebSite, scope string, keys []string) error {
nginxConfig, err := getNginxConfig(website.Alias)
if err != nil {
return err
}
config := nginxConfig.Config
config.RemoveDirectives(keys)
server := config.FindServers()[0]
server.RemoveDirectives(keys)
if scope == constant.NginxScopeHttp {
http := config.FindHttp()
for _, key := range keys {
http.RemoveDirective(key, []string{})
}
}
if scope == constant.NginxScopeServer {
server := config.FindServers()[0]
for _, key := range keys {
server.RemoveDirective(key, []string{})
}
}
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return err
}
@ -452,9 +472,6 @@ func handleParamMap(paramMap map[string]string, keys []string) []dto.NginxParam
Name: k,
Params: getParamArray(k, v),
}
if isRepeatKey(k) {
param.SecondKey = param.Params[0]
}
nginxParams = append(nginxParams, param)
}
}
@ -478,14 +495,6 @@ func getNginxParams(params interface{}, keys []string) []dto.NginxParam {
return nginxParams
}
func isRepeatKey(key string) bool {
if _, ok := dto.RepeatKeys[key]; ok {
return true
}
return false
}
func toMapStr(m map[string]interface{}) map[string]string {
ret := make(map[string]string, len(m))
for k, v := range m {

11
backend/constant/nginx.go Normal file
View File

@ -0,0 +1,11 @@
package constant
const (
NginxScopeServer = "server"
NginxScopeHttp = "http"
)
const (
NginxReload = "reload"
NginxCheck = "check"
)

View File

@ -119,9 +119,9 @@ func (b *Block) RemoveDirective(key string, params []string) {
var newDirectives []IDirective
for _, dir := range directives {
if dir.GetName() == key {
if IsRepeatKey(key) {
if IsRepeatKey(key) && len(params) > 0 {
oldParams := dir.GetParameters()
if len(oldParams) > 0 && oldParams[0] == params[0] {
if oldParams[0] == params[0] {
continue
}
} else {

View File

@ -102,9 +102,9 @@ func (h *Http) RemoveDirective(key string, params []string) {
var newDirectives []IDirective
for _, dir := range directives {
if dir.GetName() == key {
if IsRepeatKey(key) {
if IsRepeatKey(key) && len(params) > 0 {
oldParams := dir.GetParameters()
if len(oldParams) > 0 && oldParams[0] == params[0] {
if oldParams[0] == params[0] {
continue
}
} else {

View File

@ -73,7 +73,7 @@ func (s *Server) UpdateDirective(key string, params []string) {
if key == "" || len(params) == 0 {
return
}
directives := s.GetDirectives()
directives := s.Directives
index := -1
for i, dir := range directives {
if dir.GetName() == key {
@ -100,13 +100,13 @@ func (s *Server) UpdateDirective(key string, params []string) {
}
func (s *Server) RemoveDirective(key string, params []string) {
directives := s.GetDirectives()
directives := s.Directives
var newDirectives []IDirective
for _, dir := range directives {
if dir.GetName() == key {
if IsRepeatKey(key) {
if IsRepeatKey(key) && len(params) > 0 {
oldParams := dir.GetParameters()
if len(oldParams) > 0 && oldParams[0] == params[0] {
if oldParams[0] == params[0] {
continue
}
} else {

View File

@ -112,9 +112,9 @@ func (us *Upstream) RemoveDirective(key string, params []string) {
var newDirectives []IDirective
for _, dir := range directives {
if dir.GetName() == key {
if IsRepeatKey(key) {
if IsRepeatKey(key) && len(params) > 0 {
oldParams := dir.GetParameters()
if len(oldParams) > 0 && oldParams[0] == params[0] {
if oldParams[0] == params[0] {
continue
}
} else {

View File

@ -12,5 +12,17 @@ server {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
access_log /var/log/nginx/nginx-log.log;
access_log /www/sites/domain/log/access.log;
access_by_lua_file /www/common/waf/access.lua;
set $RulePath /www/sites/domain/waf/rules;
set $logdir /www/sites/domain/waf/log;
set $CCDeny on;
set $attacklog on;
set $whiteModule on;
set $getMatch on;
set $cookieMatch on;
set $postMatch on;
set $Redirect on;
}

View File

@ -4,7 +4,6 @@ export namespace Nginx {
}
export interface NginxParam {
name: string;
secondKey: string;
params: string[];
}

View File

@ -107,7 +107,6 @@ export namespace WebSite {
export interface NginxParam {
name: string;
secondKey: string;
params: string[];
}

View File

@ -68,10 +68,10 @@ const search = (req: WebSite.NginxConfigReq) => {
enable.value = true;
for (const param of res.data) {
if (param.name === 'limit_conn') {
if (param.secondKey === 'perserver') {
if (param.params[0] === 'perserver') {
form.perserver = Number(param.params[1]);
}
if (param.secondKey === 'perip') {
if (param.params[0] === 'perip') {
form.perip = Number(param.params[1]);
}
}