plugins - support log_default() hook, same as log() but for default server
This commit is contained in:
parent
c563731e86
commit
e21a35017a
@ -1,6 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.4.2 -
|
||||||
|
|
||||||
|
- Fix static config (SERVER_NAME not empty) support when using autoconf/swarm/k8s
|
||||||
|
- Fix config files overwrite when using Docker autoconf
|
||||||
|
- Add log_default() plugin hook
|
||||||
|
- Force NGINX version dependencies in Linux packages DEB/RPM
|
||||||
|
- Add Discord to supported plugins
|
||||||
|
|
||||||
## v1.4.1 - 2022/16/06
|
## v1.4.1 - 2022/16/06
|
||||||
|
|
||||||
- Fix sending local IPs to BunkerNet when DISABLE_DEFAULT_SERVER=yes
|
- Fix sending local IPs to BunkerNet when DISABLE_DEFAULT_SERVER=yes
|
||||||
- Fix certbot bug when AUTOCONF_MODE=yes
|
- Fix certbot bug when AUTOCONF_MODE=yes
|
||||||
- Fix certbot bug when MULTISITE=no
|
- Fix certbot bug when MULTISITE=no
|
||||||
|
|||||||
@ -246,6 +246,7 @@ Here is the list of "official" plugins that we maintain (see the [bunkerweb-plug
|
|||||||
| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: |
|
| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: |
|
||||||
| **ClamAV** | 0.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
|
| **ClamAV** | 0.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
|
||||||
| **CrowdSec** | 0.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
|
| **CrowdSec** | 0.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
|
||||||
|
| **Discord** | 0.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) |
|
||||||
| **VirusTotal** | 0.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
|
| **VirusTotal** | 0.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
|
||||||
|
|
||||||
You will find more information in the [plugins section](https://docs.bunkerweb.io/latest/plugins) of the documentation.
|
You will find more information in the [plugins section](https://docs.bunkerweb.io/latest/plugins) of the documentation.
|
||||||
@ -280,7 +281,7 @@ This project is licensed under the terms of the [GNU Affero General Public Licen
|
|||||||
|
|
||||||
# Contribute
|
# Contribute
|
||||||
|
|
||||||
If you would like to contribute to the plugins you can read the [contributing guidelines](https://github.com/bunkerity/bunkerweb/tree/master/LICENSE.md) to get started.
|
If you would like to contribute to the plugins you can read the [contributing guidelines](https://github.com/bunkerity/bunkerweb/tree/master/CONTRIBUTING.md) to get started.
|
||||||
|
|
||||||
# Security policy
|
# Security policy
|
||||||
|
|
||||||
|
|||||||
@ -12,4 +12,50 @@ server {
|
|||||||
|
|
||||||
# include custom default-server configurations
|
# include custom default-server configurations
|
||||||
include /opt/bunkerweb/configs/default-server-http/*.conf;
|
include /opt/bunkerweb/configs/default-server-http/*.conf;
|
||||||
|
|
||||||
|
log_by_lua_block {
|
||||||
|
|
||||||
|
local utils = require "utils"
|
||||||
|
local logger = require "logger"
|
||||||
|
local datastore = require "datastore"
|
||||||
|
local plugins = require "plugins"
|
||||||
|
|
||||||
|
logger.log(ngx.INFO, "LOG", "Log phase started")
|
||||||
|
|
||||||
|
-- List all plugins
|
||||||
|
local list, err = plugins:list()
|
||||||
|
if not list then
|
||||||
|
logger.log(ngx.ERR, "LOG", "Can't list loaded plugins : " .. err)
|
||||||
|
list = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call log_default method of plugins
|
||||||
|
for i, plugin in ipairs(list) do
|
||||||
|
local ret, plugin_lua = pcall(require, plugin.id .. "/" .. plugin.id)
|
||||||
|
if ret then
|
||||||
|
local plugin_obj = plugin_lua.new()
|
||||||
|
if plugin_obj.log_default ~= nil then
|
||||||
|
logger.log(ngx.INFO, "LOG", "Executing log_default() of " .. plugin.id)
|
||||||
|
local ok, err = plugin_obj:log_default()
|
||||||
|
if not ok then
|
||||||
|
logger.log(ngx.ERR, "LOG", "Error while calling log_default() on plugin " .. plugin.id .. " : " .. err)
|
||||||
|
else
|
||||||
|
logger.log(ngx.INFO, "LOG", "Return value from " .. plugin.id .. ".log_default() is : " .. err)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
logger.log(ngx.INFO, "LOG", "log_default() method not found in " .. plugin.id .. ", skipped execution")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Display reason at info level
|
||||||
|
local reason = utils.get_reason()
|
||||||
|
if reason then
|
||||||
|
logger.log(ngx.INFO, "LOG", "Client was denied with reason : " .. reason)
|
||||||
|
end
|
||||||
|
|
||||||
|
logger.log(ngx.INFO, "LOG", "Log phase ended")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,12 +141,14 @@ function _M:report(ip, reason, method, url, headers)
|
|||||||
return self:request("POST", "/report", data)
|
return self:request("POST", "/report", data)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _M:log()
|
function _M:log(bypass_use_bunkernet)
|
||||||
|
if bypass_use_bunkernet then
|
||||||
-- Check if BunkerNet is activated
|
-- Check if BunkerNet is activated
|
||||||
local use_bunkernet = utils.get_variable("USE_BUNKERNET")
|
local use_bunkernet = utils.get_variable("USE_BUNKERNET")
|
||||||
if use_bunkernet ~= "yes" then
|
if use_bunkernet ~= "yes" then
|
||||||
return true, "bunkernet not activated"
|
return true, "bunkernet not activated"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
-- Check if BunkerNet ID is generated
|
-- Check if BunkerNet ID is generated
|
||||||
if not self.id then
|
if not self.id then
|
||||||
return true, "bunkernet ID is not generated"
|
return true, "bunkernet ID is not generated"
|
||||||
@ -193,6 +195,27 @@ function _M:log()
|
|||||||
return true, "created report timer"
|
return true, "created report timer"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _M:log_default()
|
||||||
|
-- Check if bunkernet is activated
|
||||||
|
local check, err = utils.has_variable("USE_BUNKERNET", "yes")
|
||||||
|
if check == nil then
|
||||||
|
return false, "error while checking variable USE_BUNKERNET (" .. err .. ")"
|
||||||
|
end
|
||||||
|
if not check then
|
||||||
|
return true, "bunkernet not enabled"
|
||||||
|
end
|
||||||
|
-- Check if default server is disabled
|
||||||
|
local check, err = utils.get_variable("DISABLE_DEFAULT_SERVER", false)
|
||||||
|
if check == nil then
|
||||||
|
return false, "error while getting variable DISABLE_DEFAULT_SERVER (" .. err .. ")"
|
||||||
|
end
|
||||||
|
if check ~= "yes" then
|
||||||
|
return true, "default server not disabled"
|
||||||
|
end
|
||||||
|
-- Call log method
|
||||||
|
return self:log(true)
|
||||||
|
end
|
||||||
|
|
||||||
function _M:access()
|
function _M:access()
|
||||||
local use_bunkernet = utils.get_variable("USE_BUNKERNET")
|
local use_bunkernet = utils.get_variable("USE_BUNKERNET")
|
||||||
if use_bunkernet ~= "yes" then
|
if use_bunkernet ~= "yes" then
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
log_by_lua_block {
|
|
||||||
local bunkernet = require "bunkernet.bunkernet"
|
|
||||||
local utils = require "utils"
|
|
||||||
local datastore = require "datastore"
|
|
||||||
local logger = require "logger"
|
|
||||||
local disable_default_server = utils.get_variable("DISABLE_DEFAULT_SERVER", false)
|
|
||||||
local use_bunkernet = utils.has_variable("USE_BUNKERNET", "yes")
|
|
||||||
|
|
||||||
if disable_default_server == "yes" and use_bunkernet then
|
|
||||||
-- Instantiate bunkernet
|
|
||||||
local bnet, err = bunkernet.new()
|
|
||||||
if not bnet then
|
|
||||||
ngx.log(ngx.ERR, "BUNKERNET", "can't instantiate bunkernet " .. err)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Check if BunkerNet ID is generated
|
|
||||||
if not bnet.id then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Check if IP has been blocked
|
|
||||||
if ngx.status ~= ngx.HTTP_CLOSE then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Check if IP is global
|
|
||||||
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
|
|
||||||
if is_global == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not is_global then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Only report if it hasn't been reported for the same reason recently
|
|
||||||
local reported = datastore:get("plugin_bunkernet_cache_" .. ngx.var.remote_addr .. "default")
|
|
||||||
if reported then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- report callback called in a light thread
|
|
||||||
local function report_callback(premature, obj, ip, reason, method, url, headers)
|
|
||||||
local ok, err, status, data = obj:report(ip, reason, method, url, headers)
|
|
||||||
if not ok then
|
|
||||||
logger.log(ngx.ERR, "BUNKERNET", "Can't report IP : " .. err)
|
|
||||||
elseif status ~= 200 then
|
|
||||||
logger.log(ngx.ERR, "BUNKERNET", "Error from remote server : " .. tostring(status))
|
|
||||||
else
|
|
||||||
logger.log(ngx.NOTICE, "BUNKERNET", "Successfully reported IP " .. ip .. " (reason : " .. reason .. ")")
|
|
||||||
local ok, err = datastore:set("plugin_bunkernet_cache_" .. ip .. reason, true, 3600)
|
|
||||||
if not ok then
|
|
||||||
logger.log(ngx.ERR, "BUNKERNET", "Can't store cached report : " .. err)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Set a timer at the end of log()
|
|
||||||
local hdr, err = ngx.timer.at(0, report_callback, bnet, ngx.var.remote_addr, "default", ngx.var.request_method, ngx.var.request_uri, ngx.req.get_headers())
|
|
||||||
if not hdr then
|
|
||||||
logger.log(ngx.ERR, "BUNKERNET", "can't create report timer : " .. err)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
}
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
{% if DISABLE_DEFAULT_SERVER == "yes" +%}
|
{% if DISABLE_DEFAULT_SERVER == "yes" +%}
|
||||||
location / {
|
location / {
|
||||||
|
set $reason "default";
|
||||||
return 444;
|
return 444;
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -10,6 +10,7 @@ Here is the list of "official" plugins that we maintain (see the [bunkerweb-plug
|
|||||||
| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: |
|
| :------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: |
|
||||||
| **ClamAV** | 0.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
|
| **ClamAV** | 0.1 | Automatically scans uploaded files with the ClamAV antivirus engine and denies the request when a file is detected as malicious. | [bunkerweb-plugins/clamav](https://github.com/bunkerity/bunkerweb-plugins/tree/main/clamav) |
|
||||||
| **CrowdSec** | 0.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
|
| **CrowdSec** | 0.1 | CrowdSec bouncer for BunkerWeb. | [bunkerweb-plugins/crowdsec](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) |
|
||||||
|
| **Discord** | 0.1 | Send security notifications to a Discord channel using a Webhook. | [bunkerweb-plugins/discord](https://github.com/bunkerity/bunkerweb-plugins/tree/main/discord) |
|
||||||
| **VirusTotal** | 0.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
|
| **VirusTotal** | 0.1 | Automatically scans uploaded files with the VirusTotal API and denies the request when a file is detected as malicious. | [bunkerweb-plugins/virustotal](https://github.com/bunkerity/bunkerweb-plugins/tree/main/virustotal) |
|
||||||
|
|
||||||
## How to use a plugin
|
## How to use a plugin
|
||||||
@ -242,16 +243,22 @@ function _M:log()
|
|||||||
return true, "success"
|
return true, "success"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _M:log_default()
|
||||||
|
logger.log(ngx.NOTICE, "MYPLUGIN", "log_default called")
|
||||||
|
return true, "success"
|
||||||
|
end
|
||||||
|
|
||||||
return _M
|
return _M
|
||||||
```
|
```
|
||||||
|
|
||||||
The 3 functions `init`, `access`, and `log` are automatically called during specific contexts. Here are the details of each function :
|
The declared functions are automatically called during specific contexts. Here are the details of each function :
|
||||||
|
|
||||||
| Function | Context | Description | Return value |
|
| Function | Context | Description | Return value |
|
||||||
| :------: | :--------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| :------: | :--------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `init` | [init_by_lua](https://github.com/openresty/lua-nginx-module#init_by_lua) | Called when NGINX just started or received a reload order. the typical use case is to prepare any data that will be used by your plugin. | `ret`, `err`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li></ul> |
|
| `init` | [init_by_lua](https://github.com/openresty/lua-nginx-module#init_by_lua) | Called when NGINX just started or received a reload order. the typical use case is to prepare any data that will be used by your plugin. | `ret`, `err`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li></ul> |
|
||||||
| `access` | [access_by_lua](https://github.com/openresty/lua-nginx-module#access_by_lua) | Called on each request received by the server. The typical use case is to do the security checks here and deny the request if needed. | `ret`, `err`, `return`, `status`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li><li>`return` (boolean) : true if you want to stop the access phase and send a status to the client</li><li>`status` (number) : the return value to set if `return` is set to true</li></ul> |
|
| `access` | [access_by_lua](https://github.com/openresty/lua-nginx-module#access_by_lua) | Called on each request received by the server. The typical use case is to do the security checks here and deny the request if needed. | `ret`, `err`, `return`, `status`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li><li>`return` (boolean) : true if you want to stop the access phase and send a status to the client</li><li>`status` (number) : the return value to set if `return` is set to true</li></ul> |
|
||||||
| `log` | [log_by_lua](https://github.com/openresty/lua-nginx-module#log_by_lua) | Called when a request has finished (and before it gets logged to the access logs). The typical use case is to make stats or compute counters for example. | `ret`, `err`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li></ul> |
|
| `log` | [log_by_lua](https://github.com/openresty/lua-nginx-module#log_by_lua) | Called when a request has finished (and before it gets logged to the access logs). The typical use case is to make stats or compute counters for example. | `ret`, `err`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li></ul> |
|
||||||
|
| `log_default` | [log_by_lua](https://github.com/openresty/lua-nginx-module#log_by_lua) | Same as `log` but only called on the default server. | `ret`, `err`<ul><li>`ret` (boolean) : true if no error else false</li><li>`err` (string) : success or error message</li></ul> |
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user