Finish ip block
parent
41a6d8cec9
commit
b56499f7e2
|
@ -0,0 +1,14 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="pillow" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7.10 (/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7)" project-jdk-type="Python SDK" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/ngx_lua_waf.iml" filepath="$PROJECT_DIR$/.idea/ngx_lua_waf.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="TestRunnerService">
|
||||
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,183 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="2eef964a-b574-48e0-859a-c282c4760328" name="Default" comment="">
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/README.md" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/entry.lua" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/init.lua" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/wafconf/args" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/wafconf/cookie" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/wafconf/post" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/wafconf/url" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/wafconf/user_agent" afterPath="" />
|
||||
<change type="DELETED" beforePath="$PROJECT_DIR$/wafconf/white_url" afterPath="" />
|
||||
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/config.lua" afterPath="$PROJECT_DIR$/config.lua" />
|
||||
</list>
|
||||
<ignored path="ngx_lua_waf.iws" />
|
||||
<ignored path=".idea/workspace.xml" />
|
||||
<ignored path=".idea/dataSources.local.xml" />
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="TRACKING_ENABLED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
|
||||
<component name="CreatePatchCommitExecutor">
|
||||
<option name="PATCH_PATH" value="" />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="ngx_lua_waf" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/init.lua" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
|
||||
<component name="JsGulpfileManager">
|
||||
<detection-done>true</detection-done>
|
||||
<sorting>DEFINITION_ORDER</sorting>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="x" value="49" />
|
||||
<option name="y" value="23" />
|
||||
<option name="width" value="1260" />
|
||||
<option name="height" value="709" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||
<flattenPackages />
|
||||
<showMembers />
|
||||
<showModules />
|
||||
<showLibraryContents />
|
||||
<hideEmptyPackages />
|
||||
<abbreviatePackageNames />
|
||||
<autoscrollToSource />
|
||||
<autoscrollFromSource />
|
||||
<sortByType />
|
||||
<manualOrder />
|
||||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="ngx_lua_waf" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="ngx_lua_waf" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="ngx_lua_waf" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="Scope" />
|
||||
<pane id="Scratches" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../lua-resty-waf" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
</component>
|
||||
<component name="ShelveChangesManager" show_recycled="false">
|
||||
<option name="remove_strategy" value="false" />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="2eef964a-b574-48e0-859a-c282c4760328" name="Default" comment="" />
|
||||
<created>1474616676553</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1474616676553</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="49" y="23" width="1260" height="709" extended-state="0" />
|
||||
<editor active="false" />
|
||||
<layout>
|
||||
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.24958949" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="LuaJ" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager />
|
||||
<watches-manager />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/logger.lua">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="0">
|
||||
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/entry.lua">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="304">
|
||||
<caret line="16" column="0" selection-start-line="16" selection-start-column="0" selection-end-line="16" selection-end-column="0" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/init.lua">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="247">
|
||||
<caret line="212" column="24" selection-start-line="212" selection-start-column="24" selection-end-line="212" selection-end-column="24" />
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
43
config.lua
43
config.lua
|
@ -1,23 +1,26 @@
|
|||
debug = false
|
||||
-- rule_path = "/data/server/nginx/conf/waf/wafconf/"
|
||||
-- url_check = false
|
||||
-- url_write_check = false
|
||||
-- args_check = false
|
||||
-- ua_check = false
|
||||
-- ua_write_check = false
|
||||
-- cookie_check = false
|
||||
-- post_check = false
|
||||
--
|
||||
-- Created by IntelliJ IDEA.
|
||||
-- User: guang
|
||||
-- Date: 16/9/23
|
||||
-- Time: 下午4:28
|
||||
-- To change this template use File | Settings | File Templates.
|
||||
--
|
||||
|
||||
-- black_file_ext = {"php", "jsp"}
|
||||
-- attack_log = false
|
||||
-- attach_log_dir = "/data/logs/waf/"
|
||||
local _M = {}
|
||||
_M.version = '0.1.0'
|
||||
|
||||
-- redirect = false
|
||||
-- redirect_url = "http://www.baidu.com"
|
||||
ip_check = false
|
||||
ip_white_list = {} -- {'192.168.1.*', '127.0.0.1'}
|
||||
ip_black_list = {} -- {'0.0.0.0', '106.2.34.29'}
|
||||
|
||||
cc_deny = false
|
||||
cc_rate = "100/60"
|
||||
cc_deny_seconds = "600"
|
||||
_M.defaults = {
|
||||
debug = true,
|
||||
active = false,
|
||||
cc_deny = true,
|
||||
cc_rate = "100/600",
|
||||
cc_deny_seconds = 600,
|
||||
cc_deny_code = 404,
|
||||
log_path = "/tmp/nginx_waf.log",
|
||||
ip_check= true,
|
||||
ip_white_list = nil,
|
||||
ip_black_list = nil,
|
||||
}
|
||||
|
||||
return _M
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
--
|
||||
-- Created by IntelliJ IDEA.
|
||||
-- User: guang
|
||||
-- Date: 16/9/22
|
||||
-- Time: 下午7:13
|
||||
-- To change this template use File | Settings | File Templates.
|
||||
--
|
||||
|
||||
|
||||
local _M = {}
|
||||
_M.version = '0.1.0'
|
||||
log_inited = {}
|
||||
|
||||
local get_headers = ngx.req.get_headers
|
||||
local config = require "config"
|
||||
local mt = {__index=_M }
|
||||
|
||||
local function get_client_ip()
|
||||
local ip = get_headers()["X-Real-IP"]
|
||||
if ip == nil then
|
||||
ip = ngx.var.remote_addr
|
||||
end
|
||||
|
||||
if ip == nil then
|
||||
ip = "unkown"
|
||||
end
|
||||
return ip
|
||||
end
|
||||
|
||||
function _M.table_copy(orig_table)
|
||||
local copy = {}
|
||||
|
||||
for k, v in pairs(orig_table) do
|
||||
if type(v) ~= "table" then
|
||||
copy[k] = v
|
||||
else
|
||||
copy[k] = _M.table_copy(v)
|
||||
end
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
function _M.new(self, name)
|
||||
local t = {}
|
||||
t["name"] = name
|
||||
t["config"] = _M.table_copy(config.defaults)
|
||||
return setmetatable(t, mt)
|
||||
end
|
||||
|
||||
function _M.set_option(self, key, value)
|
||||
self["config"][key] = value
|
||||
end
|
||||
|
||||
function _M.deny_cc(self)
|
||||
local uri = ngx.var.uri
|
||||
local max_visit = tonumber(string.match(self.config.cc_rate, '(.*)/'))
|
||||
local count_period = tonumber(string.match(self.config.cc_rate, '/(.*)'))
|
||||
local ip = get_client_ip()
|
||||
|
||||
local token = ip..":"..uri
|
||||
local limit = ngx.shared.limit
|
||||
local req, _ = limit:get(token)
|
||||
|
||||
if req then
|
||||
if req > max_visit then
|
||||
ngx.exit(self.config.cc_deny_code)
|
||||
return true
|
||||
elseif req == max_visit then
|
||||
self:log("[Block] " .. token)
|
||||
limit:incr(token, 1)
|
||||
else
|
||||
limit:incr(token, 1)
|
||||
end
|
||||
else
|
||||
limit:set(token, 1, count_period)
|
||||
end
|
||||
end
|
||||
|
||||
function _M.log(self, msg)
|
||||
if log_inited[self.config.log_path] == nil then
|
||||
log_inited[self.config.log_path] = io.open(self.config.log_path, 'ab')
|
||||
end
|
||||
self.fd = log_inited[self.config.log_path]
|
||||
|
||||
self.fd:write(msg .. '\n')
|
||||
self.fd:flush()
|
||||
end
|
||||
|
||||
function _M.run(self)
|
||||
ngx.log(ngx.WARN, 'Start running waf')
|
||||
if self.config.cc_deny and self:deny_cc() then
|
||||
end
|
||||
end
|
||||
|
||||
return _M
|
|
@ -0,0 +1,207 @@
|
|||
local ipairs, tonumber, tostring, type = ipairs, tonumber, tostring, type
|
||||
local bit = require("bit")
|
||||
local tobit = bit.tobit
|
||||
local lshift = bit.lshift
|
||||
local band = bit.band
|
||||
local bor = bit.bor
|
||||
local xor = bit.bxor
|
||||
local byte = string.byte
|
||||
local str_find = string.find
|
||||
local str_sub = string.sub
|
||||
|
||||
local lrucache = nil
|
||||
|
||||
local _M = {
|
||||
_VERSION = '0.02',
|
||||
}
|
||||
|
||||
local mt = { __index = _M }
|
||||
|
||||
|
||||
-- Precompute binary subnet masks...
|
||||
local bin_masks = {}
|
||||
for i=1,32 do
|
||||
bin_masks[tostring(i)] = lshift(tobit((2^i)-1), 32-i)
|
||||
end
|
||||
-- ... and their inverted counterparts
|
||||
local bin_inverted_masks = {}
|
||||
for i=1,32 do
|
||||
local i = tostring(i)
|
||||
bin_inverted_masks[i] = xor(bin_masks[i], bin_masks["32"])
|
||||
end
|
||||
|
||||
local log_err
|
||||
if ngx then
|
||||
log_err = function(...)
|
||||
ngx.log(ngx.ERR, ...)
|
||||
end
|
||||
else
|
||||
log_err = function(...)
|
||||
print(...)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function enable_lrucache(size)
|
||||
local size = size or 4000 -- Cache the last 4000 IPs (~1MB memory) by default
|
||||
local lrucache_obj, err = require("resty.lrucache").new(4000)
|
||||
if not lrucache_obj then
|
||||
return nil, "failed to create the cache: " .. (err or "unknown")
|
||||
end
|
||||
lrucache = lrucache_obj
|
||||
return true
|
||||
end
|
||||
_M.enable_lrucache = enable_lrucache
|
||||
|
||||
|
||||
local function split_octets(input)
|
||||
local pos = 0
|
||||
local prev = 0
|
||||
local octs = {}
|
||||
|
||||
for i=1, 4 do
|
||||
pos = str_find(input, ".", prev, true)
|
||||
if pos then
|
||||
if i == 4 then
|
||||
-- Should not have a match after 4 octets
|
||||
return nil, "Invalid IP"
|
||||
end
|
||||
octs[i] = str_sub(input, prev, pos-1)
|
||||
elseif i == 4 then
|
||||
-- Last octet, get everything to the end
|
||||
octs[i] = str_sub(input, prev, -1)
|
||||
break
|
||||
else
|
||||
return nil, "Invalid IP"
|
||||
end
|
||||
prev = pos +1
|
||||
end
|
||||
|
||||
return octs
|
||||
end
|
||||
|
||||
|
||||
local function ip2bin(ip)
|
||||
if lrucache then
|
||||
local get = lrucache:get(ip)
|
||||
if get then
|
||||
return get[1], get[2]
|
||||
end
|
||||
end
|
||||
|
||||
if type(ip) ~= "string" then
|
||||
return nil, "IP must be a string"
|
||||
end
|
||||
|
||||
local octets = split_octets(ip)
|
||||
if not octets or #octets ~= 4 then
|
||||
return nil, "Invalid IP"
|
||||
end
|
||||
|
||||
-- Return the binary representation of an IP and a table of binary octets
|
||||
local bin_octets = {}
|
||||
local bin_ip = 0
|
||||
|
||||
for i,octet in ipairs(octets) do
|
||||
local bin_octet = tonumber(octet)
|
||||
if not bin_octet or bin_octet > 255 then
|
||||
return nil, "Invalid octet: "..tostring(octet)
|
||||
end
|
||||
bin_octet = tobit(bin_octet)
|
||||
bin_octets[i] = bin_octet
|
||||
bin_ip = bor(lshift(bin_octet, 8*(4-i) ), bin_ip)
|
||||
end
|
||||
|
||||
if lrucache then
|
||||
lrucache:set(ip, {bin_ip, bin_octets})
|
||||
end
|
||||
return bin_ip, bin_octets
|
||||
end
|
||||
_M.ip2bin = ip2bin
|
||||
|
||||
|
||||
local function split_cidr(input)
|
||||
local pos = str_find(input, "/", 0, true)
|
||||
if not pos then
|
||||
return {input}
|
||||
end
|
||||
return {str_sub(input, 1, pos-1), str_sub(input, pos+1, -1)}
|
||||
end
|
||||
|
||||
|
||||
local function parse_cidr(cidr)
|
||||
local mask_split = split_cidr(cidr, '/')
|
||||
local net = mask_split[1]
|
||||
local mask = mask_split[2] or "32"
|
||||
local mask_num = tonumber(mask)
|
||||
if not mask_num or (mask_num > 32 or mask_num < 1) then
|
||||
return nil, "Invalid prefix: /"..tostring(mask)
|
||||
end
|
||||
|
||||
local bin_net, err = ip2bin(net) -- Convert IP to binary
|
||||
if not bin_net then
|
||||
return nil, err
|
||||
end
|
||||
local bin_mask = bin_masks[mask] -- Get masks
|
||||
local bin_inv_mask = bin_inverted_masks[mask]
|
||||
|
||||
local lower = band(bin_net, bin_mask) -- Network address
|
||||
local upper = bor(lower, bin_inv_mask) -- Broadcast address
|
||||
return lower, upper
|
||||
end
|
||||
_M.parse_cidr = parse_cidr
|
||||
|
||||
|
||||
local function parse_cidrs(cidrs)
|
||||
local out = {}
|
||||
local i = 1
|
||||
for _,cidr in ipairs(cidrs) do
|
||||
local lower, upper = parse_cidr(cidr)
|
||||
if not lower then
|
||||
log_err("Error parsing '", cidr, "': ", upper)
|
||||
else
|
||||
out[i] = {lower, upper}
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
_M.parse_cidrs = parse_cidrs
|
||||
|
||||
|
||||
local function ip_in_cidrs(ip, cidrs)
|
||||
local bin_ip, bin_octets = ip2bin(ip)
|
||||
if not bin_ip then
|
||||
return nil, bin_octets
|
||||
end
|
||||
|
||||
for _,cidr in ipairs(cidrs) do
|
||||
if bin_ip >= cidr[1] and bin_ip <= cidr[2] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
_M.ip_in_cidrs = ip_in_cidrs
|
||||
|
||||
|
||||
local function binip_in_cidrs(bin_ip_ngx, cidrs)
|
||||
if 4 ~= #bin_ip_ngx then
|
||||
return false, "invalid IP address"
|
||||
end
|
||||
|
||||
local bin_ip = 0
|
||||
for i=1,4 do
|
||||
bin_ip = bor(lshift(bin_ip, 8), tobit(byte(bin_ip_ngx, i)))
|
||||
end
|
||||
|
||||
for _,cidr in ipairs(cidrs) do
|
||||
if bin_ip >= cidr[1] and bin_ip <= cidr[2] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
_M.binip_in_cidrs = binip_in_cidrs
|
||||
|
||||
return _M
|
|
@ -0,0 +1,23 @@
|
|||
debug = false
|
||||
-- rule_path = "/data/server/nginx/conf/waf/wafconf/"
|
||||
-- url_check = false
|
||||
-- url_write_check = false
|
||||
-- args_check = false
|
||||
-- ua_check = false
|
||||
-- ua_write_check = false
|
||||
-- cookie_check = false
|
||||
-- post_check = false
|
||||
|
||||
-- black_file_ext = {"php", "jsp"}
|
||||
-- attack_log = false
|
||||
-- attach_log_dir = "/data/logs/waf/"
|
||||
|
||||
-- redirect = false
|
||||
-- redirect_url = "http://www.baidu.com"
|
||||
ip_check = false
|
||||
ip_white_list = {} -- {'192.168.1.*', '127.0.0.1'}
|
||||
ip_black_list = {} -- {'0.0.0.0', '106.2.34.29'}
|
||||
|
||||
cc_deny = false
|
||||
cc_rate = "100/60"
|
||||
cc_deny_seconds = "600"
|
|
@ -9,8 +9,6 @@ ip_check = true
|
|||
ip_white_list = {}
|
||||
ip_black_list = {}
|
||||
|
||||
--------- Init project ----------------
|
||||
require 'init'
|
||||
--------- Access control limit --------
|
||||
if ip_check and (whiteIP(ip_white_list, debug) or blackIP(ip_black_list, debug)) then
|
||||
elseif cc_deny and denyCC(cc_rate, cc_deny_seconds, debug) then
|
|
@ -0,0 +1,41 @@
|
|||
--
|
||||
-- Created by IntelliJ IDEA.
|
||||
-- User: guang
|
||||
-- Date: 16/9/22
|
||||
-- Time: 下午5:59
|
||||
-- To change this template use File | Settings | File Templates.
|
||||
--
|
||||
|
||||
local _M = {}
|
||||
_M.version = '0.1.1'
|
||||
|
||||
local util = require "resty.waf.util"
|
||||
|
||||
local mt = {__index=_M}
|
||||
|
||||
function hello()
|
||||
print("hello world")
|
||||
end
|
||||
|
||||
local config = {'hello', 'world' }
|
||||
|
||||
local _a = {}
|
||||
|
||||
|
||||
function _M:new()
|
||||
return setmetatable({}, mt)
|
||||
end
|
||||
|
||||
function _M:name()
|
||||
local name = {'guang', 'hong', 'wei' }
|
||||
name_new = util.table_copy(name)
|
||||
print(table.concat(name_new, ','))
|
||||
end
|
||||
|
||||
function _M.get_version()
|
||||
local name = _M.name()
|
||||
print(name)
|
||||
end
|
||||
|
||||
return _a
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
--
|
||||
-- Created by IntelliJ IDEA.
|
||||
-- User: guang
|
||||
-- Date: 16/9/22
|
||||
-- Time: 下午6:25
|
||||
-- To change this template use File | Settings | File Templates.
|
||||
--
|
||||
|
||||
|
||||
local lua_waf = require "core"
|
||||
local iputils = require "iputils"
|
||||
|
||||
local waf = lua_waf:new("test")
|
||||
local waf2 = lua_waf:new("jj")
|
||||
|
||||
for k, v in pairs(waf["config"]) do
|
||||
print(k, v)
|
||||
end
|
||||
|
||||
waf:set_option("active", true)
|
||||
|
||||
for k, v in pairs(waf["config"]) do
|
||||
print(k, v)
|
||||
end
|
||||
print(waf.config.active)
|
||||
|
||||
-- waf:deny_cc()
|
||||
-- waf2:deny_cc()
|
||||
waf:log("hello world")
|
||||
waf2:log("world")
|
||||
print(iputils.ip2bin("192.168.1.1"))
|
Loading…
Reference in New Issue