{"id":15374238,"url":"https://github.com/moteus/lua-spylog","last_synced_at":"2025-10-05T04:42:16.819Z","repository":{"id":147045776,"uuid":"50663155","full_name":"moteus/lua-spylog","owner":"moteus","description":"Execute actions based on log records","archived":false,"fork":false,"pushed_at":"2018-02-24T11:19:45.000Z","size":198,"stargazers_count":14,"open_issues_count":6,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-15T15:11:39.674Z","etag":null,"topics":["ban-hosts","ban-management","ban-users","fail2ban","filter-messages","ids","intrusion-detection","intrusion-prevention","lua","monitoring","windows"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moteus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-01-29T13:11:59.000Z","updated_at":"2024-08-15T14:53:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"0516fda5-6e42-49e0-8ef7-79e2b3d1974f","html_url":"https://github.com/moteus/lua-spylog","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/moteus/lua-spylog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moteus%2Flua-spylog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moteus%2Flua-spylog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moteus%2Flua-spylog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moteus%2Flua-spylog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moteus","download_url":"https://codeload.github.com/moteus/lua-spylog/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moteus%2Flua-spylog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278411250,"owners_count":25982365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ban-hosts","ban-management","ban-users","fail2ban","filter-messages","ids","intrusion-detection","intrusion-prevention","lua","monitoring","windows"],"created_at":"2024-10-01T13:57:57.633Z","updated_at":"2025-10-05T04:42:16.813Z","avatar_url":"https://github.com/moteus.png","language":"Lua","readme":"# SpyLog\n\n## Execute actions based on log records\n\n[![SpyLog-x86-0.0.2.exe](https://img.shields.io/badge/0.0.2-x86-blue.svg)](https://github.com/moteus/lua-spylog/releases/download/v0.0.2/SpyLog-x86-0.0.2.exe)\n[![SpyLog-x64-0.0.2.exe](https://img.shields.io/badge/0.0.2-x64-blue.svg)](https://github.com/moteus/lua-spylog/releases/download/v0.0.2/SpyLog-x64-0.0.2.exe)\n\n-----------------------------------------------------------\n\nThe main goal of this project is provide [fail2ban](http://www.fail2ban.org) functionality to Windows.\n\n## Install/Start\nThe `lua-spylog` consist of three services.\n\n * filter - read logs from sources and extract date(optional) and IP and send them to `jail` service.\n * jail - read messages from `filter` service and support time couter. If some counter is reached to\n  `maxretry` then jail send message to `action` service.\n * action - read messages from `jail` service and support queue of actions to be done. When it recv new\n  message it push 2 new action to queue (ban and unban). Queue is persistent.\n\nAll services can be run as separate process or as thread in one multithreaded process.\nTo run spylog as Windows service you can use [LuaService](https://github.com/moteus/luaservice).\n\nFor Windows there exists installer which allows install SpyLog and all dependencies. You can download\nit form [Releases](https://github.com/moteus/lua-spylog/releases) page.\n\n## Configuration\n\n### Detect auth fail on FreeSWITCH system\n```Lua\n-- config/sources/freeswitch.lua\nSOURCE{\"freeswitch\",\n  \"esl:ClueCon@127.0.0.1:8021\",\n  level = 'WARNING';\n}\n```\n```Lua\n-- config/filters/freeswitch.lua\nFILTER{ \"freeswitch-auth-fail\";\n  enabled = true;\n  source  = \"freeswitch\";\n  failregex = {\n    \"^(%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d%.%d+) %[WARNING%] sofia_reg.c:%d+ SIP auth failure %([A-Z]+%) on sofia profile %'[^']+%' for %[.-%] from ip ([0-9.]+)%s*$\";\n    \"^(%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d%.%d+) %[WARNING%] sofia.c:%d+ IP ([0-9.]+) Rejected by acl \\\"[^\\\"]*\\\"%s*$\";\n  }\n};\n```\n```Lua\n-- config/jails/freeswitch.lua\nJAIL{\"voip-auth-fail\";\n  enabled  = true;\n  filter   = {\"freeswitch-auth-fail\"};\n  findtime = 600;\n  maxretry = 3;\n  bantime  = 3600 * 24;\n  action   = {\"mail\", \"growl\", \"ipsec\"};\n}\n```\n\n### Supported sources\n * Text log file\n * UDP raw server\n * SysLog UDP server (rfc3164 and rfc5424)\n * SNMP trap UDP server (allows handle Windows event logs)\n * EventLog (based on event trap) allows additional filters based on source names.\n * FreeSWITCH ESL TCP connection\n * TCP raw connection\n * Process stdout and/or stderr\n\n### Filters\n\n#### Named captures\nBy default filter names first capure as `date` and second one as `host`.\nIf there only one capture then `date` set as current timestamp and capture names as `host`.\nIt is possible to assign names to captures using `capture` array.\n```Lua\nFILTER{'nginx-404',\n  capture = {'host', 'date'}; -- we have to swap `date` and `host`\n  failregex = '^([0-9.]+) %- %- %[(.-)%].-GET.-HTTP.- 404';\n}\n```\nAlso it possible add any other captures. They will be send to jails as whell.\n\n#### Ignore regex\nFilters support `ignoreregex` field to exclude records which already matched by `failregex`\n\n#### Exclude IP\nFilters support `exclude` array which allows exclude some IP and networks.\n\n### Jails\nEach jail is just array of counters with some expire time.\n\n#### Counter types\nCurrently supports this counter types\n\n * `incremental` increment to one for each filter message\n * `accumulate` get increment value from filter message.\n   Can be used e.g. to calculate total calls duration in some VOIP system.\n * `fixed` just return value from filter message.\n   Can be used e.g. to monitor max call duration for calls in some VOIP system.\n\nBy default `increment` type uses.\n\n#### Counter control values\nEach counter do count for some value (like `counter[id] = counter[id] + value`).\nTo specify `id` field you can use `capture` field. By default it is `host`.\nTo specify `value` you can use `value` field. There no default value for this.\nE.g. in voip system it may be need monitor each account and block them .\n\n```Lua\nJAIL{\n  ...\n  counter  = {\n    type    = 'accumulate';\n    capture = 'account'; -- count total duration for each account\n    value   = 'duration'; -- what value use to increment.\n  };\n}\n```\n\n#### Capture filters\nIt is also possible add some additional filter to `filters` and `jails`.\n\nExample 1. Add `black` list for user names for RDP service.\n```Lua\nJAIL{\"rdp-bad-user-access\"; -- e.g. can ban after first attempt\n  -- apply this jail only for specific user list\n  cfilter  = {\"list\",\n    type    = \"allow\",\n    capture = \"user\",\n    nocase  = true,\n    filter  = { \"admin\", \"guest\", \"user\", \"root\"};\n  };\n}\n```\n\nExample 2. Counts attempts to call only to some specific area codes.\n```Lua\nJAIL{\n  -- count only calls to Cuba and Albania and exclude '192.168.123.22' host\n  cfilter = {\n    {'prefix',            -- filter type\n      type    = 'allow',  -- count if match\n      capture = 'number', -- capture name to filter\n      filter = {          -- filter rules\n        '53',  -- Cuba \n        '355', -- Albania\n      }\n    };\n\n    {'acl',              -- filter type\n      type    = 'deny',  -- count if not match\n      capture = 'host',  -- capture name to filter\n      filter  = {        -- filter rules\n        '192.168.123.22',\n      }\n    };\n  }\n}\n```\n\nExample 3. Apply jail to some countries only.\n```Lua\nJAIL{\"rdp-bad-country-access\"; -- e.g. can ban after first attempt\n  -- apply this jail for all counties except Russia and North America\n  cfilter  = {\"geoip\",\n    type    = \"deny\",\n    filter  = { 'ru', continent = {'na'} };\n  };\n}\n```\n\nEach capture filter should have name as first element, `capture` and `filter` fields.\nCurrently support `prefix`, `acl`, `regex`, `list` and `geoip` filters.\n`capture` field specify what value from capture should be used in this fileter.\n`filter` is set of rules had specific format for each type of filter.\n`prefix` filter should have `filter` field as array of prefixes of file name.\n`acl` filter should have `filter` field as array of IP and/or CIDR.\n`regex` filter should have `filter` field as string/array of strings.\n`list` filter should have `list` field as string/array of strings.\n\n\n## Dependencies\n - [bit32](https://luarocks.org/modules/siffiejoe/bit32)\n - [date](https://luarocks.org/modules/tieske/date)\n - [lluv](https://luarocks.org/modules/moteus/lluv)\n - [lluv-poll-zmq](https://luarocks.org/modules/moteus/lluv-poll-zmq)\n - [lpeg](https://luarocks.org/modules/gvvaughan/lpeg)\n - [Lrexlib-PCRE](https://luarocks.org/modules/rrt/lrexlib-pcre)\n - [lua-cjson](https://luarocks.org/modules/luarocks/lua-cjson)\n - [lua-llthreads2](https://luarocks.org/modules/moteus/lua-llthreads2)\n - [lua-log](https://luarocks.org/modules/moteus/lua-log)\n - [lua-path](https://luarocks.org/modules/moteus/lua-path)\n - [Lua-Sqlite3](https://luarocks.org/modules/moteus/sqlite3)\n - [LuaFileSystem](https://luarocks.org/modules/hisham/luafilesystem)\n - [luuid](https://luarocks.org/modules/luarocks/luuid)\n - [lzmq](https://luarocks.org/modules/moteus/lzmq)\n - [StackTracePlus](https://luarocks.org/modules/ignacio/stacktraceplus)\n - [LuaService](https://luarocks.org/modules/moteus/luaservice)\n - [environ](https://luarocks.org/modules/moteus/environ)\n\n### To support `mail` action\n - [lluv-ssl](https://luarocks.org/modules/moteus/lluv-ssl)\n - [sendmail](https://luarocks.org/modules/moteus/sendmail)\n - [try](https://luarocks.org/modules/moteus/try)\n\n### To support `growl` action\n - [gntp](https://luarocks.org/modules/moteus/gntp)\n - [openssl](https://luarocks.org/modules/zhaozg/openssl)\n\n### To support `esl` source type\n - [lluv-esl](https://luarocks.org/modules/moteus/lluv-esl)\n\n### To support `prefix` capture filter\n - [prefix_tree](https://luarocks.org/modules/moteus/prefix_tree)\n\n### To support `geoip` capture filter\n - [mmdblua](https://luarocks.org/modules/daurnimator/mmdblua)\n - [compat53](https://luarocks.org/modules/siffiejoe/compat53)\n - [lua-lru](https://luarocks.org/modules/starius/lua-lru) (optional)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoteus%2Flua-spylog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoteus%2Flua-spylog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoteus%2Flua-spylog/lists"}