You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2022/07/07 16:55:42 UTC
[trafficserver] branch 9.2.x updated: Update lua plugin examples (#8646)
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.2.x by this push:
new e58c55bff Update lua plugin examples (#8646)
e58c55bff is described below
commit e58c55bffb154b8e16d9de3412a3a66c7563cbdc
Author: Kit Chan <ki...@apache.org>
AuthorDate: Mon Feb 7 17:26:58 2022 -0800
Update lua plugin examples (#8646)
* Clean up example directory for lua plugin
* Update information on connect_redis.lua
* Update information on connect_geoip.lua
* Update connect_geoip.lua installation instructions
* Add maxmind example
* Update information on modsecurity example
(cherry picked from commit 048e6e845e8087cd90b63bcb9579383c6fd75b11)
---
example/plugins/lua-api/connect_geoip.lua | 20 ++-
example/plugins/lua-api/connect_maxmind.lua | 45 +++++++
example/plugins/lua-api/connect_redis.lua | 31 ++++-
example/plugins/lua-api/modsecurity/README.md | 8 +-
example/plugins/lua-api/modsecurity/example.conf | 4 +-
plugins/lua/business/mediaslice.lua | 155 -----------------------
plugins/lua/{business => example}/sethost.lua | 0
7 files changed, 90 insertions(+), 173 deletions(-)
diff --git a/example/plugins/lua-api/connect_geoip.lua b/example/plugins/lua-api/connect_geoip.lua
index 1277e2057..cdb5c74fe 100644
--- a/example/plugins/lua-api/connect_geoip.lua
+++ b/example/plugins/lua-api/connect_geoip.lua
@@ -14,17 +14,23 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
-
-- This example depends on "luajit-geoip".
--- It illustrates how to connect to GeoIP and use it to look up country of an IP address.
+-- It illustrates how to connect to GeoIP and uses it to look up country of an IP address.
-- It can be used in plugin.config with the lua plugin.
-- Setup Instructions
--- 1) install GeoIP - 1.6.12
--- 2) install GeoIP legacy country database - https://dev.maxmind.com/geoip/legacy/install/country/
--- 3) install luajit-geoip (https://github.com/leafo/luajit-geoip)
--- or just copy geoip/init.lua from the repo to /usr/local/share/lua/5.1/geoip/init.lua
--- 4) You may need to make change so luajit-geoip does ffi.load() on /usr/local/lib/libGeoIP.so
+-- 1. install legacy GeoIP library 1.6.12 (https://github.com/maxmind/geoip-api-c)
+-- a. wget https://github.com/maxmind/geoip-api-c/releases/download/v1.6.12/GeoIP-1.6.12.tar.gz
+-- b. tar zxvf GeoIP-1.6.12.tar.gz
+-- c. cd GeoIP-1.6.12
+-- d. ./configure; make; make install
+-- 2. Find and install GeoIP legacy country database to /usr/local/share/GeoIP/GeoIP.dat
+-- 3. install luajit-geoip v2.1.0 (https://github.com/leafo/luajit-geoip)
+-- a. wget https://github.com/leafo/luajit-geoip/archive/refs/tags/v2.1.0.tar.gz
+-- b. tar zxvf v2.1.0.tar.gz
+-- c. mkdir -p /usr/local/share/lua/5.1/geoip
+-- d. cp luajit-geoip-2.1.0/geoip.lua /usr/local/share/lua/5.1/geoip.lua
+-- e. cp luajit-geoip-2.1.0/geoip/*.lua /usr/local/share/lua/5.1/geoip/
ts.add_package_path('/usr/local/share/lua/5.1/?.lua')
diff --git a/example/plugins/lua-api/connect_maxmind.lua b/example/plugins/lua-api/connect_maxmind.lua
new file mode 100644
index 000000000..28d8a8fb1
--- /dev/null
+++ b/example/plugins/lua-api/connect_maxmind.lua
@@ -0,0 +1,45 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- This example depends on "libmaxminddb".
+-- It illustrates how to connect to MaxMind DB and uses it to look up country of an IP address.
+-- It can be used in plugin.config with the lua plugin.
+
+-- Setup Instructions
+-- 1. install libmaxminddb 1.6.0 (https://github.com/maxmind/libmaxminddb)
+-- a. wget https://github.com/maxmind/libmaxminddb/releases/download/1.6.0/libmaxminddb-1.6.0.tar.gz
+-- b. tar zxvf libmaxminddb-1.6.0.tar.gz
+-- c. cd libmaxminddb-1.6.0
+-- d. ./configure; make; make install
+-- 2) Get GeoLite2 country database from https://dev.maxmind.com/geoip/geolite2-free-geolocation-data and put it in /usr/share/GeoIP/GeoLite2-Country.mmdb
+-- 3. install luajit-geoip v2.1.0 (https://github.com/leafo/luajit-geoip)
+-- a. wget https://github.com/leafo/luajit-geoip/archive/refs/tags/v2.1.0.tar.gz
+-- b. tar zxvf v2.1.0.tar.gz
+-- c. mkdir -p /usr/local/share/lua/5.1/geoip
+-- d. cp luajit-geoip-2.1.0/geoip.lua /usr/local/share/lua/5.1/geoip.lua
+-- e. cp luajit-geoip-2.1.0/geoip/*.lua /usr/local/share/lua/5.1/geoip/
+
+ts.add_package_path('/usr/local/share/lua/5.1/?.lua')
+
+local geoip = require 'geoip.mmdb'
+
+function do_global_send_response()
+ local mmdb = geoip.load_database("/usr/share/GeoIP/GeoLite2-Country.mmdb")
+
+ local result = mmdb:lookup("8.8.8.8")
+
+ ts.client_response.header['X-Maxmind-Info'] = result.country.iso_code
+end
diff --git a/example/plugins/lua-api/connect_redis.lua b/example/plugins/lua-api/connect_redis.lua
index dddb2af3d..4e004d913 100644
--- a/example/plugins/lua-api/connect_redis.lua
+++ b/example/plugins/lua-api/connect_redis.lua
@@ -19,10 +19,31 @@
-- It illustrates how to connect to redis and retrieve a key value.
-- It can be used in plugin.config with the lua plugin.
--- unix domain socket has better performance and so we should set up local redis to use that
--- Note the sock must be readable/writable by nobody since ATS runs as that user
--- Sample instructions for setting up redis 2.8.4 and putting a key in
--- 1. edit /etc/redis/redis.conf to set "port 0", "unixsocket /var/run/redis/redis.sock" and "unixsocketperm 755"
+-- Compile luasocket with luajit library and installation:
+-- 1. wget https://github.com/diegonehab/luasocket/archive/v3.0-rc1.tar.gz
+-- 2. tar zxf v3.0-rc1.tar.gz
+-- 3. cd luasocket-3.0-rc1
+-- 4. sed -i "s/LDFLAGS_linux=-O -shared -fpic -o/LDFLAGS_linux=-O -shared -fpic -L\/usr\/lib -lluajit-5.1 -o/" src/makefile
+-- 5. ln -sf /usr/lib/libluajit-5.1.so.2.1.0 /usr/lib/libluajit-5.1.so
+-- 6. mkdir -p /usr/include/lua
+-- 7. ln -sf /usr/include/luajit-2.1 /usr/include/lua/5.1
+-- 8. make
+-- 9. make install-unix
+
+-- redis-lua installation:
+-- 1. wget https://github.com/nrk/redis-lua/archive/v2.0.4.tar.gz
+-- 2. tar zxf v2.0.4.tar.gz
+-- 3. mkdir -p /usr/local/share/lua/5.1
+-- 4. cp redis-lua-2.0.4/src/redis.lua /usr/local/share/lua/5.1/redis.lua
+
+-- Redis setup instructions:
+-- Unix domain socket has better performance and so we should set up local redis to use that.
+-- Note the sock must be readable/writable by nobody since ATS runs as that user.
+-- Sample instructions for setting up redis and putting a key in
+-- 1. edit /etc/redis/redis.conf (or copy from redis configuration file). Make the following changes
+-- a. "port 0"
+-- b. "unixsocket /var/run/redis/redis.sock"
+-- c. "unixsocketperm 755"
-- 2. sudo chown nobody /var/run/redis
-- 3. sudo chgrp nogroup /var/run/redis
-- 4. sudo chown nobody /var/log/redis
@@ -30,7 +51,7 @@
-- 6. sudo -u nobody redis-server /etc/redis/redis.conf
-- 7. sudo -u nobody redis-cli -s /var/run/redis/redis.sock set mykey helloworld
-ts.add_package_cpath("/usr/local/lib/lua/5.1/socket/?.so;/usr/local/lib/lua/5.1/mime/?.so")
+ts.add_package_cpath("/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/socket/?.so;/usr/local/lib/lua/5.1/mime/?.so")
ts.add_package_path("/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/socket/?.lua")
local redis = require "redis"
diff --git a/example/plugins/lua-api/modsecurity/README.md b/example/plugins/lua-api/modsecurity/README.md
index 7cc9b2afb..71798ee88 100644
--- a/example/plugins/lua-api/modsecurity/README.md
+++ b/example/plugins/lua-api/modsecurity/README.md
@@ -3,10 +3,10 @@ Integrating ATS with ModSecurity V3 using LuaJIT and FFI
Open source WAF for [Apache Traffic Server](http://trafficserver.apache.org/).
-Requirement
+Tested with the following
====
- - ModSecurity v3.0.4
- - ATS 8.0.8
+ - ModSecurity v3.0.6
+ - ATS 9.1.1
How to Use
====
@@ -63,7 +63,7 @@ SecDebugLogLevel 9
TODOs/Limitations
====
- No support for `REQUEST_BODY` examination (We need to buffer the request body for examination first before we send to origin.)
- - No support for `RESPONSE BODY` examination (We need to uncompress the contents first if they are gzipped. And that will be expensive operation for proxy)
+ - No support for `RESPONSE_BODY` examination (We need to uncompress the contents first if they are gzipped. And that will be expensive operation for proxy). See https://github.com/SpiderLabs/ModSecurity/issues/2494 for reference
- How does this work with the lua engine inside ModSecurity V3?
- Unit Test using busted framework
- More functional testing needed
diff --git a/example/plugins/lua-api/modsecurity/example.conf b/example/plugins/lua-api/modsecurity/example.conf
index c7df943ad..36eb7818c 100644
--- a/example/plugins/lua-api/modsecurity/example.conf
+++ b/example/plugins/lua-api/modsecurity/example.conf
@@ -23,6 +23,6 @@ SecDebugLog /tmp/debug.log
SecDebugLogLevel 9
SecRule ARGS:testparam "@contains test2" "id:1234,deny,status:403"
-SecRule ARGS:testparam "@contains test1" "id:1235,redirect:https://www.yahoo.com/"
+SecRule ARGS:testparam "@contains test1" "id:1235,status:301,redirect:https://www.yahoo.com/"
SecRule RESPONSE_HEADERS:test "@contains 1" "id:1236,phase:3,deny,status:403"
-SecRule RESPONSE_HEADERS:test "@contains 2" "id:1237,phase:3,redirect:https://www.yahoo.com/"
+SecRule RESPONSE_HEADERS:test "@contains 2" "id:1237,phase:3,status:301,redirect:https://www.yahoo.com/"
diff --git a/plugins/lua/business/mediaslice.lua b/plugins/lua/business/mediaslice.lua
deleted file mode 100644
index c118445a6..000000000
--- a/plugins/lua/business/mediaslice.lua
+++ /dev/null
@@ -1,155 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements. See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership. The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License. You may obtain a copy of the License at
---
--- http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-
-function media_transform(data, eos)
- done = 0
- slen = string.len(data)
-
- if ts.ctx['fit'] > 0 then
- if ts.ctx['fit'] + slen >= ts.ctx['len'] then
- need = ts.ctx['len'] - ts.ctx['fit']
- done = 1
- else
- need = slen
- end
-
- ts.ctx['fit'] = ts.ctx['fit'] + need
- ts.ctx['passed'] = ts.ctx['passed'] + slen
- return data:sub(1, need), done
-
- elseif ts.ctx['passed'] + slen >= ts.ctx['offset'] then
- spos = ts.ctx['offset'] - ts.ctx['passed'] + 1
- need = ts.ctx['passed'] + slen - ts.ctx['offset']
- if need >= ts.ctx['len'] then
- need = ts.ctx['len']
- done = 1
- end
-
- epos = spos + need - 1
-
- ts.ctx['fit'] = ts.ctx['fit'] + need
- ts.ctx['passed'] = ts.ctx['passed'] + slen
-
- return data:sub(spos, epos), done
- else
- ts.ctx['passed'] = ts.ctx['passed'] + slen
- return nil, eos
- end
-
-end
-
-
-function read_response()
- http_status = ts.server_response.header.get_status()
- ts.debug(string.format('server_response status = %d', http_status))
- if http_status ~= 200 then
- return
- end
-
- ts.http.resp_cache_transformed(0)
- ts.http.resp_cache_untransformed(1)
-
- if ts.ctx['transform_add'] == 1 then
- return
- end
-
- ts.hook(TS_LUA_RESPONSE_TRANSFORM, media_transform)
- ts.ctx['fit'] = 0
- ts.ctx['passed'] = 0
-end
-
-
-function cache_lookup()
- status = ts.http.get_cache_lookup_status()
- ts.debug(string.format('cache lookup status: %d', status))
- if status ~= TS_LUA_CACHE_LOOKUP_HIT_FRESH and status ~= TS_LUA_CACHE_LOOKUP_HIT_STALE then
- return
- end
-
- http_status = ts.cached_response.header.get_status()
- ts.debug(string.format('cached_response http status: %d', http_status))
- if http_status ~= 200 then
- return
- end
-
- ts.http.resp_cache_transformed(0)
- ts.hook(TS_LUA_RESPONSE_TRANSFORM, media_transform)
-
- ts.ctx['transform_add'] = 1
- ts.ctx['fit'] = 0
- ts.ctx['passed'] = 0
-end
-
-
-function do_remap()
-
- url = ts.client_request.get_url()
- ts.debug(string.format('src_url = %s', url))
-
- param_s = string.find(url, '?')
- start_s, start_e, start_val = string.find(url, 'start=(%d+)', param_s)
-
- if start_s ~= nil then
- end_s, end_e, end_val = string.find(url, 'end=(%d+)', start_e)
- offset_s, offset_e, offset_val = string.find(url, 'offset=(%d+)', end_e)
- len_s, len_e, len_val = string.find(url, 'len=(%d+)', offset_e)
- in_query = true
- else
- start_s, start_e, start_val = string.find(url, "/start_(%d+)")
- end_s, end_e, end_val = string.find(url, "/end_(%d+)", start_e)
- offset_s, offset_e, offset_val = string.find(url, "/offset_(%d+)", end_e)
- len_s, len_e, len_val = string.find(url, "/len_(%d+)", offset_e)
- end
-
- start_val = tonumber(start_val)
- end_val = tonumber(end_val)
- offset_val = tonumber(offset_val)
- len_val = tonumber(len_val)
-
- if start_val == nil or end_val == nil or offset_val == nil or len_val == nil then
- ts.http.set_resp(400, "params invalid\n")
- return 0
- end
-
- if start_val < 0 or end_val < start_val or offset_val < 0 or len_val <= 0 then
- ts.http.set_resp(400, "params invalid\n")
- return 0
- end
-
- if in_query then
- slash = url:len() - url:reverse():find("/") + 1
- cache_url = string.format('%sstart_%d/end_%d/%s', string.sub(url, 1, slash), start_val, end_val, string.sub(url, slash+1, param_s-1))
- else
- cache_url = string.format('%s%s', string.sub(url, 1, end_e), string.sub(url, len_e))
- end
-
- ts.debug(string.format('cache_url = %s', cache_url))
-
- ts.http.set_cache_url(cache_url)
- ts.client_request.header['Range'] = nil
-
- ts.ctx['start'] = start_val
- ts.ctx['end'] = end_val
- ts.ctx['offset'] = offset_val
- ts.ctx['len'] = len_val
-
- ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
- ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
-
- return 0
-end
-
diff --git a/plugins/lua/business/sethost.lua b/plugins/lua/example/sethost.lua
similarity index 100%
rename from plugins/lua/business/sethost.lua
rename to plugins/lua/example/sethost.lua