Lua Support
Nauthilus has Lua 5.1 support in all areas of the service. To understand the interfaces, you must first get an idea of what happens with an incoming authentication request.
Authentication workflow
An incoming authentication request first enters the brute_force check. After that it continues with the features pipeline. After that has past, it continues to process the request in a password backend. When the final result for the request was obtained, it passes filters.
Filters may change the backend result in one or the other way (accepting a formely rejected message or vice versa). This is especially useful for other remote services that can influence the authentication process.
After all this has finished, it is possible to do some post actions, which are run independent of all other steps in the whole pipeline and therefore can not influence the final result anymore.
In the following sequence diagram you can see the processing of the request in more detail.
Additional things to know
When starting the server, it is possible to call an init script, which may be used to register prometheus elements, start connection tracker or define custom redis pools. The latter is interesting, if you prefer using other redis servers for all your custom Lua scripts.
While runtime...
When an incoming authentication request is started, a Lua context is created.
All parts of a request share that common request context. Lua scripts can set arbitrary data in the context and read/delete things from there.
Lua scripts can modify the final log line by adding key-value pairs from each script.
Configuration
For the configuration, please have a look for the configuration file document.
Lua components
Each component does provide a set of global functions, constants, ... and requires a well-defined response from each request.
Every Lua script that has been configured is pre-compiled and kept in memory for future use. To make script changes, you must reload the service.
Lua libraries
Nauthilus does not automatically preload Lua modules. Therefor, a dynamic loader has been written, which must be run before requireing a module.
Example:
dynamic_loader("foo")
local foo = require("foo")
A module is preloaded for a single Lua state, which is shared accross all scripts that make use of it. Let's say, there have been defined three filter scripts and 5 post-action scripts, then each class (filter and post-action) share the same Lua state and receive the same preloaded modules.
Modules are never preloaded twice.
This is the list of modules that are currently available:
| Loader name | Description |
|---|---|
| nauthilus_mail | E-Mail functions |
| nauthilus_password | Password compare and validation functions |
| nauthilus_redis | Redis related functions |
| nauthilus_misc | Country code and sleep functions |
| nauthilus_context | Global Lua context accross all States in Nauthilus |
| nauthilus_ldap | LDAP related functions |
| nauthilus_backend | Backend related functions |
| nauthilus_http_request | HTTP request header functions |
| nauthilus_http_response | HTTP response functions (headers, status, body; Filters/Features MUST NOT send a body) |
| nauthilus_gluacrypto | gluacrpyto project on Github |
| nauthilus_gll_plugin | gopher-lua-libs project on Github |
| nauthilus_gll_argparse | gopher-lua-libs project on Github |
| nauthilus_gll_base64 | gopher-lua-libs project on Github |
| nauthilus_gll_cert_util | gopher-lua-libs project on Github |
| nauthilus_gll_chef | gopher-lua-libs project on Github |
| nauthilus_gll_cloudwatch | gopher-lua-libs project on Github |
| nauthilus_gll_cmd | gopher-lua-libs project on Github |
| nauthilus_gll_crypto | gopher-lua-libs project on Github |
| nauthilus_gll_db | gopher-lua-libs project on Github |
| nauthilus_gll_filepath | gopher-lua-libs project on Github |
| nauthilus_gll_goos | gopher-lua-libs project on Github |
| nauthilus_gll_http | gopher-lua-libs project on Github |
| nauthilus_gll_humanize | gopher-lua-libs project on Github |
| nauthilus_gll_inspect | gopher-lua-libs project on Github |
| nauthilus_gll_ioutil | gopher-lua-libs project on Github |
| nauthilus_gll_json | gopher-lua-libs project on Github |
| nauthilus_gll_log | gopher-lua-libs project on Github |
| nauthilus_gll_pb | gopher-lua-libs project on Github |
| nauthilus_gll_pprof | gopher-lua-libs project on Github |
| nauthilus_gll_prometheus | gopher-lua-libs project on Github |
| nauthilus_gll_regexp | gopher-lua-libs project on Github |
| nauthilus_gll_runtime | gopher-lua-libs project on Github |
| nauthilus_gll_shellescape | gopher-lua-libs project on Github |
| nauthilus_gll_stats | gopher-lua-libs project on Github |
| nauthilus_gll_storage | gopher-lua-libs project on Github |
| nauthilus_gll_strings | gopher-lua-libs project on Github |
| nauthilus_gll_tac | gopher-lua-libs project on Github |
| nauthilus_gll_tcp | gopher-lua-libs project on Github |
| nauthilus_gll_telegram | gopher-lua-libs project on Github |
| nauthilus_gll_template | gopher-lua-libs project on Github |
| nauthilus_gll_time | gopher-lua-libs project on Github |
| nauthilus_gll_xmlpath | gopher-lua-libs project on Github |
| nauthilus_gll_yaml | gopher-lua-libs project on Github |
| nauthilus_gll_zabbix | gopher-lua-libs project on Github |
Example:
dynamic_loader("nauthilus_redis")
local nauthilus_redis = require("nauthilus_redis")
dynamic_loader("nauthilus_context")
local nauthilus_builtin_context = require("nauthilus_context")
dynamic_loader("nauthilus_gluacrypto")
local crypto = require("crypto")
dynamic_loader("nauthilus_gll_db")
local db = require("db")
dynamic_loader("nauthilus_gll_time")
local time = require("time")
Actions
Whenever a brute froce attack is recognized, actions may be called. The request will wait until all requests have finished. Actions are processed by a central action worker. No results are returned to the regular request, so actions in general do their own logging!
Also, features may call actions if they were triggered. The request is waiting to finish all actions by the worker process.