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