General Information:
Distribution: Ubuntu 18.04
Fail2Ban v0.10.2
Hello,
I'm using now a WAF to secure my owncloud instance.
The Sophos UTM needs 2 parts; first creating the host object (attacker) and second update the reverse proxy object. The RESTful API works from my own script, but not triggered by my custom action file. Step one creating the object works well; variable <ip>
is only needed here.
But the second part crashes, because of my variable definition block:
2020-11-23 16:15:12,158 fail2ban.actions [28653]: NOTICE [owncloud] Ban 80.187.101.140
2020-11-23 16:15:12,175 fail2ban.utils [28653]: Level 39 7f612c005a90 -- exec: UTM2B=80.187.101.140;
UTM=${UTM2B//./};
REF="REF_NetHos";
REF_ID="${UTM:0:10}";
DN="$REF$REF_ID";
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \
--header 'Authorization: Basic access_token' -d '{"address":"80.187.101.140","address6":"","comment":"","duids":[],"hostnames":[],"interface":"","macs":[],"name":"80.187.101.140","resolved":false,"resolved6":false,"reverse_dns":false}' \
'https://host.domain/api/objects/network/host/' > /dev/null
curl -X PATCH --header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Restd-Err-Ack: all' \
--header 'X-Restd-Lock-Override: yes' \
--header 'Authorization: Basic access_token' -d \
'{"access_control":"1","allowed_networks":["REF_NetworkAny"],"auth_profile":"","backend":["REF_RevBacWEBHost"],"be_path":"","comment":"","denied_networks":["'"$DN"'"],"hot_standby":false,"name":"ProxyN","path":"/subtree","status":true,"stickysession_id":"ROUTEID","stickysession_status":false,"websocket_passthrough":true}' \
'https://my.fw/api/objects/reverse_proxy/location/REF_RevLocProxyN'
2020-11-23 16:15:12,175 fail2ban.utils [28653]: ERROR 7f612c005a90 -- stderr: '/bin/sh: 2: Bad substitution'
2020-11-23 16:15:12,175 fail2ban.utils [28653]: ERROR 7f612c005a90 -- returned 2
actionban = UTM2B=<ip>;
UTM=${UTM2B//./};
REF="REF_NetHos";
REF_ID="${UTM:0:10}";
DN="$REF$REF_ID";
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \
--header 'Authorization: Basic access_token' -d '{"address":"<ip>","address6":"","comment":"","duids":[],"hostnames":[],"interface":"","macs":[],"name":"<ip>","resolved":false,"resolved6":false,"reverse_dns":false}' \
'https://my.fw/api/objects/network/host/' > /dev/null
curl -X PATCH --header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Restd-Err-Ack: all' \
--header 'X-Restd-Lock-Override: yes' \
--header 'Authorization: Basic access_token' -d \
'{"access_control":"1","allowed_networks":["REF_NetworkAny"],"auth_profile":"","backend":["REF_RevBacWEBHost"],"be_path":"","comment":"","denied_networks":["'"$DN"'"],"hot_standby":false,"name":"ProxyN","path":"/subtree","status":true,"stickysession_id":"ROUTEID","stickysession_status":false,"websocket_passthrough":true}' \
'https://my.fw/api/objects/reverse_proxy/location/REF_RevLocProxyN' > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 492 100 307 100 185 291 175 0:00:01 0:00:01 --:--:-- 466
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 841 100 504 100 337 7411 4955 --:--:-- --:--:-- --:--:-- 12367
80.187.101.140
80187101140
REF_NetHos
8018710114
REF_NetHos8018710114
actionban inside add_host.sh
just add echo $VAR to the end for debugging
Could you please help me and shed some light into this - How do I have to declare variables ? What am I doing wrong?
I really appreciate any help you can provide.
The RESTful API works from my own script, but not triggered by my custom action file.
I assume you used bash for your script? (because ${UTM2B//./}
is a bashism).
As you can see fail2ban using sh (default shell for user running fail2ban on your system), so it would not work per design.
Try this example:
$ sh -c 'UTM2B=192.0.2.1; UTM=${UTM2B//./};'
sh: 1: Bad substitution
Either you should rewrite the action without unsupported constructs in sh
shell, or you write it to the script using shebang for bash and then calling your script from action (so the script is executed in bash instead of sh).
Thank you for your fast feedback.
I followed your suggestion rewrite to shell did the trick!
Are there any possibility to get a variable with all banned IPs
Are there any possibility to get a variable with all banned IPs
?
It could be possible (but in which format)...
And I'm also wondering for which purposes it should be good.
One can also use fail2ban-client get <JAIL> banned
(see 54b2208690e3c2fff00fbd9b197984d880e29a02, released with newest version).
Well, I'm testing my construction :D It is not bad at all, but some silly thing is that the WAF
can only handle host objects to block and not host groups. So each time f2b detects a new ip, my script must send all in the banned list! If not, that’s at the moment the case, only the newest ip is banned. :( My client is outdated but I could work with
fail2ban-client status owncloud |grep Banned
Done! Now a protocol is written that knows all blocked IP addresses,
In case of someone else is playing around this will be added there and the script use all of these to update the access_control list from the proxy with only one call “curl patch” - So nobody goes through my fingers anymore: D
Btw. Maybe you identify this immediately why it was not possible to use;
Just to format the value to my needs:
No Issues in sh shell: sh -c 'VAR=${VAR1%?};'
but in fail2ban: fail2ban-server[4540]: Failed during configuration: Error in action definition 'UTM9': '%' must be followed by '%' or '(', found: '%?};\ncurl -X POST --header \'Content-Type: application
Thanks for this absolutely brilliant software!
Maybe you identify this immediately ...
Failed during configuration: Error in action definition 'UTM9': '%' must be followed by '%' or ...
Sure, as the error message (and documentation) says, the % char in (python) config files is a special character, e. g. used for substitution of variables and parameters, like %(var)s
, etc.
So simply escape this (with additional %), like:
- VAR=${VAR1%?};
+ VAR=${VAR1%%?};
it will be interpolated by read of config to the single %-char.
Most helpful comment
Sure, as the error message (and documentation) says, the % char in (python) config files is a special character, e. g. used for substitution of variables and parameters, like
%(var)s
, etc.So simply escape this (with additional %), like:
it will be interpolated by read of config to the single %-char.