您好,登錄后才能下訂單哦!
本篇內容主要講解“如何通過ngx_lua模塊實現CC攻擊的防護”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何通過ngx_lua模塊實現CC攻擊的防護”吧!
CC攻擊(ChallengeCollapsar)是常見網站應用層攻擊的一種,目的是消耗服務器資源,降低業務響應效率;極端情況會讓站點無法正常提供服務。
a.系統
CentOSLinux release 7.5.1804 (Core);
b.資源存放目錄
mkdir/root/ngx_lua
c.要求
各種編譯安裝相關依賴和報錯請google解決;
d.NGX_LUA官文
https://github.com/openresty/lua-nginx-module#installation
e.準備
cd/root/ngx_lua
wgethttp://www.lua.org/ftp/lua-5.3.4.tar.gz
tarzxf lua-5.3.4.tar.gz
cdlua-5.3.4
makelinux test
cd..
wgethttp://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz
tarzxvf LuaJIT-2.1.0-beta3.tar.gz
cdLuaJIT-2.1.0-beta3
#指定安裝目錄
makePREFIX=/usr/local/luajit2
makeinstall PREFIX=/usr/local/luajit2
cd..
wgethttps://github.com/simplresty/ngx_devel_kit/archive/v0.3.1rc1.tar.gz
tarzxvf v0.3.1rc1.tar.gz
wgethttps://github.com/openresty/lua-nginx-module/archive/v0.10.13.tar.gz
tarzxvf v0.10.13.tar.gz
wget-O "lua-resty-redis-master.zip"https://codeload.github.com/openresty/lua-resty-redis/zip/master
unziplua-resty-redis-master.zip
cdlua-resty-redis-master
makeinstall PREFIX=/usr/local/lua-redis
cd..
wgethttp://download.redis.io/releases/redis-4.0.9.tar.gz
tarzxvf redis-4.0.9.tar.gz
cdredis-4.0.9
#復制配置文件模板
cpredis.conf /etc/
#編譯安裝
makePREFIX=/usr/local/redis
makeinstall PREFIX=/usr/local/redis
#嘗試運行,可以考慮打包為后臺服務或托管給supervisor,本文略;
cd/usr/local/redis/bin
./redis-server/etc/redis.conf
#添加NGINX 用戶
useradd-s /sbin/nologin www
#下載、解壓并進入目錄
wgethttp://nginx.org/download/nginx-1.13.12.tar.gz
tarzxvf nginx-1.13.12.tar.gz
cdnginx-1.13.12
#增加環境變量
exportLUAJIT_LIB=/usr/local/luajit2/lib
exportLUAJIT_INC=/usr/local/luajit2/include/luajit-2.1
#編譯安裝
./configure--user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module--with-http_gzip_static_module --with-http_sub_module --with-ld-opt="-Wl,-rpath,/usr/local/luajit2/lib"--add-dynamic-module=/root/ngx_lua/ngx_devel_kit-0.3.1rc1--add-dynamic-module=/root/ngx_lua/lua-nginx-module-0.10.13
make&& make test
#編輯主配置文件使其支持NGX_LUA
vim/usr/local/nginx/conf/nginx.conf
#指定為其創建的用戶
userwww www;
#指定進程數及將進程綁定至CPU核心;
worker_processes auto;
worker_cpu_affinityauto;
pid logs/nginx.pid;
#打開文件數
worker_rlimit_nofile 65535;
#此處加載LUA相關模塊
load_modulemodules/ndk_http_module.so;
load_modulemodules/ngx_http_lua_module.so;
events{
useepoll;
worker_connections 65535;
accept_mutexoff;
multi_accepton;
}
http{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 64k;
large_client_header_buffers4 32k;
client_max_body_size 512m;
#lua redis 依賴包
lua_package_path"/usr/local/lua-redis/lib/lua/?.lua;;";
sendfile on;
keepalive_timeout 60;
server_tokens off;
log_formataccess '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent"$http_referer" '
'"$http_user_agent""$http_x_forwarded_for"';
includeconf.d/*.conf;
}
:wq
nginx-t && nginx
mkdir/usr/local/nginx/conf/lua
vim/usr/local/nginx/conf/lua/content.lua
--獲取請求的HEADER
localheaders = ngx.req.get_headers()
--依次通過x_real_ip,x_forwarded_for,remote_addr獲取客戶端IP
localclientip = headers["X-Real-IP"]
ifclientip == nil then
clientip =headers["x_forwarded_for"]
end
ifclientip == nil then
clientip = ngx.var.remote_addr
end
--指定響應內容
ngx.say("YourIp Adress is ",clientip,", WelCome!")
:wq
a.新建配置文件
vim/usr/local/nginx/conf/conf.d/luatest.conf
server
{
#指定監聽端口及主機名
listen80;
server_namewww.knownsec.com;
#建立測試地址
location/lua_test
{
#指定響應的默認MIME類型
default_type"text/html";
#通過lua響應內容
content_by_lua_fileconf/lua/index.lua;
}
error_log /home/log/ngx/error.log;
access_log /home/log/ngx/access access;
}
:wq
b.測試并重載配置
nginx-t
nginx-s reload
curl--resolve www.knownsec.com:80:192.168.0.196 http://www.knownsec.com/lua_test
YourIp Adress is 192.168.0.196, WelCome!
a.NGINX的請求處理過程一共劃分為11個階段,分別是:post-read、server-rewrite、find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log.(參考:https://github.com/nginx/nginx/blob/master/src/http/ngx_http_core_module.h)
b.在nginx官方文檔(參考:https://www.nginx.com/resources/wiki/modules/lua/)中,可處理階段均有相應的lua指令;就本文的目的而言,訪問限速控制處于access階段,所以需要使用的指令為access_by_lua;
c.為了方便調試和管理,可以使用access_by_lua_file指令直接加載指定路徑下的lua文件來對access過程進行處理;
a.令牌桶算法可控制請求的數量,并允許突發大量請求的情況。
b.當用戶請求Nginx時,判斷該location是否需要限制流量;
c.若需要,則檢查當前IP是否已有令牌桶,若無則使用setex往redis中放入令牌桶,并指定的令牌數量及“桶”過期時間;設定單位時間內允許訪問次數,比如1分鐘允許10次,則令牌數量為9(當前請求算作首次消耗),過期時間60s
d.若已有令牌桶,并且令牌數量大于0,則使用decr使其值減1(消耗令牌)并放行;
e.若令牌數量為0,則攔截;
vim/usr/local/lua-redis/lib/lua/LimitRate.lua
--加載REDIS模塊
localr_md = require "resty.redis"
--獲取當前請求的HEADER
localheaders = ngx.req.get_headers()
--指定REDIS的地址和端口
localredis_ip = "127.0.0.1"
localredis_port = "9600"
--建立redis實例
localredis = r_md:new()
--指定單位時間
localqtrange = 60
--允許訪問的次數
localqcount = 10
--嘗試根據HTTP頭遂級獲取IP
localclientip = headers["X-Real-IP"]
ifclientip == nil then
clientip =headers["x_forwarded_for"]
end
ifclientip == nil then
clientip = ngx.var.remote_addr
end
--釋放redis連接的函數
localfunction redis_close(red)
--釋放連接,使用set_keepalive指令將當前連接放入當前進程的連接池中待用,需要指定連接池的大小及其中各個連接的空閑超時時間;
localpool_max_idle_time = 10000 --毫秒
localpool_size = 100 --連接池大小
localok, err = red:set_keepalive(pool_max_idle_time, pool_size)
ifnot ok then
ngx_log(ngx_ERR,"set redis keepalive error : ", err)
end
end
--指定所有REDIS操作的超時時間,其中包含了連接超時
redis:set_timeout(1000)
建立連接,若異常則釋放連接;
localok, wrong = redis:connect(redis_ip,redis_port)
ifnot ok then
redis_close(redis)
end
--建立限速類
LimitIpRate= {}
--限速方法,令牌桶限速邏輯實現
functionLimitIpRate:is_limited()
--嘗試獲取當前IP的令牌桶,令牌桶命名為“x.x.x.x|pool”
localres, err = redis:get(clientip.."|pool")
ifnot res then
ngx.log(ngx.ERR,"luaerror: ",err)
end
--如果res不為空并且類型為string,則代表獲取到了對應的令牌桶
iftype(res) == "string" then
--可用令牌數量為0則攔截
iftonumber(res) == 0 then
ngx.exit(ngx.HTTP_FORBIDDEN)
--反之放行并讓令牌數量減少1
else
add,err= redis:decr(clientip.."|pool")
ifnot add then
ngx.log(ngx.ERR,"luaerror: ",err)
end
end
--如果res不為空并且類型為userdata,則代表redis中沒有對應令牌桶
elseiftype(res) == "userdata" then
--往redis中放入指定名稱、過期時間、值的鍵值對
ini,err = redis:setex(clientip.."|pool", qtrange, (qcount-1))
ifnot ini then
ngx.log(ngx.ERR,"luaerror: ",err)
end
end
end
--調用限速方法
LimitIpRate.is_limited()
:wq
a.編輯配置文件,加入指令
vim/usr/local/nginx/conf/conf.d/luatest.conf
server
{
#指定監聽端口及主機名
listen80;
server_namewww.knownsec.com;
#建立測試地址
location/lua_test
{
#指定響應的默認MIME類型
default_type"text/html";
#通過lua對access進行過濾
access_by_lua_file"conf/lua/LimitRate.lua";
#通過lua返回響應內容
content_by_lua_fileconf/lua/index.lua;
}
error_log /home/log/ngx/error.log;
access_log /home/log/ngx/access access;
}
:wq
b.測試并重載配置
nginx-t
nginx-s reload
fori in {1..12}; do curl -s --resolve www.knownsec.com:80:192.168.0.196http://www.knownsec.com/lua_test -o /dev/null -w %{http_code};echo ;done
200
200
200
200
200
200
200
200
200
200
403
403
到此,相信大家對“如何通過ngx_lua模塊實現CC攻擊的防護”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。