diff --git a/apps/nginx/versions/1.23.1/conf/nginx.conf b/apps/nginx/versions/1.23.1/conf/nginx.conf index 8a03e229f..b9c3624b3 100644 --- a/apps/nginx/versions/1.23.1/conf/nginx.conf +++ b/apps/nginx/versions/1.23.1/conf/nginx.conf @@ -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; } \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/docker-compose.yml b/apps/nginx/versions/1.23.1/docker-compose.yml index ac972f049..88116ebfc 100644 --- a/apps/nginx/versions/1.23.1/docker-compose.yml +++ b/apps/nginx/versions/1.23.1/docker-compose.yml @@ -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 - - diff --git a/apps/nginx/versions/1.23.1/www/common/waf/access.lua b/apps/nginx/versions/1.23.1/www/common/waf/access.lua new file mode 100644 index 000000000..37f4b1641 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/access.lua @@ -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 diff --git a/apps/nginx/versions/1.23.1/www/common/waf/init.lua b/apps/nginx/versions/1.23.1/www/common/waf/init.lua new file mode 100644 index 000000000..84f342c3f --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/init.lua @@ -0,0 +1 @@ +ngx.log(ngx.INFO,"init success") \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/args b/apps/nginx/versions/1.23.1/www/common/waf/rules/args new file mode 100644 index 000000000..d5bf8e807 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/args @@ -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)\= diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/blackfileExt b/apps/nginx/versions/1.23.1/www/common/waf/rules/blackfileExt new file mode 100644 index 000000000..4bfec715e --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/blackfileExt @@ -0,0 +1 @@ +["php","jsp"] \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/ccrate b/apps/nginx/versions/1.23.1/www/common/waf/rules/ccrate new file mode 100644 index 000000000..2286d9b85 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/ccrate @@ -0,0 +1 @@ +100/60 \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/cookie b/apps/nginx/versions/1.23.1/www/common/waf/rules/cookie new file mode 100644 index 000000000..30554cacd --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/cookie @@ -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)\[ diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/html b/apps/nginx/versions/1.23.1/www/common/waf/rules/html new file mode 100644 index 000000000..fc44e2312 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/html @@ -0,0 +1,30 @@ + + +网站防火墙 + + + + + +
+ + +
+
网站防火墙
+
+

您的请求带有不合法参数,已被网站管理员设置拦截!

+

可能原因:您提交的内容包含危险的攻击请求

+

如何解决:

+
  • 1)检查提交内容;
  • +
  • 2)如网站托管,请联系空间提供商;
  • +
  • 3)普通网站访客,请联系网站管理员;
+
+
+
+ \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/ipBlocklist b/apps/nginx/versions/1.23.1/www/common/waf/rules/ipBlocklist new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/ipBlocklist @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/ipWhitelist b/apps/nginx/versions/1.23.1/www/common/waf/rules/ipWhitelist new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/ipWhitelist @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/post b/apps/nginx/versions/1.23.1/www/common/waf/rules/post new file mode 100644 index 000000000..87d094656 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/post @@ -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)\= diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/url b/apps/nginx/versions/1.23.1/www/common/waf/rules/url new file mode 100644 index 000000000..31130d347 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/url @@ -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) diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/user-agent b/apps/nginx/versions/1.23.1/www/common/waf/rules/user-agent new file mode 100644 index 000000000..f929be2a1 --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/user-agent @@ -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/) diff --git a/apps/nginx/versions/1.23.1/www/common/waf/rules/whiteurl b/apps/nginx/versions/1.23.1/www/common/waf/rules/whiteurl new file mode 100644 index 000000000..4e3c6543a --- /dev/null +++ b/apps/nginx/versions/1.23.1/www/common/waf/rules/whiteurl @@ -0,0 +1 @@ +^/123/$ diff --git a/backend/app/service/nginx_utils.go b/backend/app/service/nginx_utils.go index 7d10527bc..8d47a78cb 100644 --- a/backend/app/service/nginx_utils.go +++ b/backend/app/service/nginx_utils.go @@ -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 diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 931e5e51a..e10a612fd 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -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 } } diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index b1ef97337..742bd3b5d 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -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 { diff --git a/backend/constant/nginx.go b/backend/constant/nginx.go new file mode 100644 index 000000000..2439db01b --- /dev/null +++ b/backend/constant/nginx.go @@ -0,0 +1,11 @@ +package constant + +const ( + NginxScopeServer = "server" + NginxScopeHttp = "http" +) + +const ( + NginxReload = "reload" + NginxCheck = "check" +) diff --git a/backend/utils/nginx/components/block.go b/backend/utils/nginx/components/block.go index ad53d8a2e..0d3141a46 100644 --- a/backend/utils/nginx/components/block.go +++ b/backend/utils/nginx/components/block.go @@ -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 { diff --git a/backend/utils/nginx/components/http.go b/backend/utils/nginx/components/http.go index 69bed41bd..0fcb293bc 100644 --- a/backend/utils/nginx/components/http.go +++ b/backend/utils/nginx/components/http.go @@ -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 { diff --git a/backend/utils/nginx/components/server.go b/backend/utils/nginx/components/server.go index 747e2b708..cdb3b89ec 100644 --- a/backend/utils/nginx/components/server.go +++ b/backend/utils/nginx/components/server.go @@ -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 { diff --git a/backend/utils/nginx/components/upstream.go b/backend/utils/nginx/components/upstream.go index 83bd2c8b4..e73488204 100644 --- a/backend/utils/nginx/components/upstream.go +++ b/backend/utils/nginx/components/upstream.go @@ -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 { diff --git a/cmd/server/nginx_conf/website_default.conf b/cmd/server/nginx_conf/website_default.conf index f7da3940c..ebbb1ce28 100644 --- a/cmd/server/nginx_conf/website_default.conf +++ b/cmd/server/nginx_conf/website_default.conf @@ -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; } diff --git a/frontend/src/api/interface/nginx.ts b/frontend/src/api/interface/nginx.ts index 409161f1c..d2502f3f4 100644 --- a/frontend/src/api/interface/nginx.ts +++ b/frontend/src/api/interface/nginx.ts @@ -4,7 +4,6 @@ export namespace Nginx { } export interface NginxParam { name: string; - secondKey: string; params: string[]; } diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 7c79ae80b..eee86afa9 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -107,7 +107,6 @@ export namespace WebSite { export interface NginxParam { name: string; - secondKey: string; params: string[]; } diff --git a/frontend/src/views/website/website/config/basic/limit-conn/index.vue b/frontend/src/views/website/website/config/basic/limit-conn/index.vue index c7a2d3046..404a02cc1 100644 --- a/frontend/src/views/website/website/config/basic/limit-conn/index.vue +++ b/frontend/src/views/website/website/config/basic/limit-conn/index.vue @@ -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]); } }