[SOLVED] Fail2ban email - custom

Does anyone know if it is possible for fail2ban to send out email alerts when a peer goes unreachable instead of when an ip gets banned?

me thinks you need to provide a bit more information on what you are trying to do. fail2ban takes action based on log file entries, so i guess, in theory, you could hack it around to send an email if it found “unreachable” in the log file…

:grin:

This is exactly what I thought of doing this morning when I noticed that one of my trunks failed…

I don’t know why it does that but once in a while Asterisk decides that one of its trunk is unreachable and it has to be restarted to work again…

Anybody knows why? It sounds like an Asterisk bug to me…

When I noticed the problem I, of course, restarted Asterisk and started googling around and found a few matches (including one on this forum, Notification when trunk is down, which is unfortunately incomplete and I am no Python guru…).

One of those matches suggested using https://sourceforge.net/projects/swatch/ and when I saw the similarity between it and fail2ban I realized fail2ban could most likely be used to do this.

I have not yet tried to make a fail2ban rule for this but my guess is that it would definitely be doable…

Good luck and have a nice day!

Nick

ps: The trunk that failed is the one that provides 911 service!

we switched away from trunk registration years ago and use ip authentication with all our itsp’s. the trunks don’t go offline, no need to worry about things like user id/passwords - more secure

Fail2ban is probably the wrong tool for the job, it’s regex’s are optimized to extract IP addresses from log files, and conditionally add them to iptables.

But similar behavior can be achieved very simply from bash

tail -F /var/log/asterisk/full|while read i;do if [[ $i =~ “UNREACHABLE” ]];then echo $i|mail [email protected] ;fi;done &

make your version of “unreachable” be a regex that matches exactly what you get when your trunk disappears, add that line to /etc/rc.local , you can easily reboot/restart/reload asterisk automatically if you want, and the emails you are getting are not in anyway spurious, for example

tail -F /var/log/asterisk/full|while read i;do if [[ $i =~ “unreachable” ]];then echo $i|mail [email protected] ;amportal -a r ;fi;done &

but no it is not an asterisk bug it is almost certainly a badly constructed network setup

(I hope that’s not considered inappropriate “code” or this post will probably disappear soon :wink: )

1 Like

Dicko - I think you are spot on. Using fail2ban’s regex and filters you have to have a host in order for the regex to be used by the system and an unreachable message does not include any host. Only lists sip peer.

would your base code be a perpetual watch or would I need to run it each time I wanted to search for unreachable?

thanks for your help!

Something that doesn’t require anything besides restarting Asterisk sounds like an Asterisk bug to me…

Maybe at a certain point something happened network-wise but the network recuperated a long time ago and not Asterisk…

Have a nice day,

Nicolas

When the network repairs itself then the UNREACHABLE! Peer bcomes Reachable , if it doesn’t then asterisks’ attempts tto find that peer will be exposed by “sip set debug ip . . .” And if the replies are missing then tcpdump the host for a better look.

Yes, itt monitors the file through logrotations even. You might want to create/reuse a less noisy log file, you only need NOTICE.

"make your version of “unreachable” be a regex that matches exactly what you get when your trunk disappears, add that line to /etc/rc.local "

Can I just input UNREACHABLE! and look for any unreachable peer? Matching the logfile exactly could be difficult with time and other variables changing for each alert.

You will have trouble with the ! character for esoteric reasons but UNREACHABLE would work.

I tried Dicko’s excellent suggestion in a previous post. Any event written to the logfile can be used to trigger an alert. I also successfully tested it using netcat to send http notifications instead of emails.

I will eventually use this to generate messages to trigger video recording when the Call button on a doorphone is pressed. I painfully found out how to use elif statements so that several devices can be monitored simultaneously.

1 Like

if [[ $i =~ “UNREACHABLE” && $i =~“805”]]…

Is an ‘and’ in bash

if [[ $i =~ “UNREACHABLE” || $i =~“Reachable”]]…

Is an ‘or’

It seems like we’re close but I haven’t been sent an email alert yet. Here’s what I have.

Logfile: [2016-07-05 15:08:33] NOTICE[3097] chan_sip.c: Peer ‘102’ is now UNREACHABLE! Last qualify: 11

Found in asterisk logfiles full.NimbusDemo

Here is the command I put in rc.local folder

tail -F /var/log/asterisk/full.NimbusDemo|while read i;do if [[ $i =~ “UNREACHABLE” ]];then echo $i|mail myemail address ;fi;done

Did I miss something? Assuming the answer is yes!

Well, apart from how you made /var/log/asterisk/full.NimbusDemo then it should work IF all the elements in the bash pipes work , so does (your words, intrepret as necessary)

echo “Does this work”|mail myemail address

work? If not you need to fix that.

Edit:-

Did you either reboot or run /etc/rc.local after making the changes because the script needs to be running . . . ? Also you forgot putting the script in the backgound ( the final & ) further /etc/rc.local is NOT a folder it is a file!

Thanks dicko, I will be trying your script!

Actually, that’s incorrect. The syntax is:

if [[ $i =~ "UNREACHABLE" -o $i =~ "805" ]]; then

‘And’ is -a. The use of || and && are for handling the exit code of programs, so you could do this as a one-liner:

[[ $i =~ "UNREACHABLE" -o $i =~ "805" ]] && echo This is a one line script

For more information run ‘man test’ on your machine.

Well that might depend on the version of bash you are using, for me I use

echo $BASH_VERSION
4.3.30(1)-release

and it works fine.

as does a random FreePBX distro

echo $BASH_VERSION
4.1.2(1)-release

i=805
if [[ $i =~ “UNREACHABLE” || $i =~ “805” ]];then echo OK;fi
OK
if [[ $i =~ “UNREACHABLE” && $i =~ “805” ]];then echo OK;else echo no;fi
no

I’m sure the old (and deprecated) -a and -o probably work also but not within the double brackets and not with the =~ either

For more information read:-

http://mywiki.wooledge.org/BashFAQ/031

on any machine :slight_smile:

Much thanks for your help. So far I haven’t gotten an email when a phone goes unreachable for my test. Here is what I have in my etc/rc.d/rc.local

the logfile I know has the unreachable notices is the full.NimbusDemo log, any ideas why I’m not getting alerts? Is there a way to test this with a command? thank you for any insight you might have

#!/bin/sh

This script will be executed after all the other init scripts.

You can put your own initialization stuff in here if you don’t

want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

Make sure asterisk starts on boot

/usr/local/sbin/amportal start

tail -F /var/log/asterisk/full.NimbusDemo|while read i;do if [[ $i =~ “UNREACHABLE!” ]];then echo $i|mail [email protected] ;fi;done

Don’t try and match on ! bash might interpret it as a request for history. Just use REACH, test from bash with

cat /var/log/asterisk/full.NimbusDemo|grep -i reach

if you get a hit(s)

cat /var/log/asterisk/full.NimbusDemo|while read i;do if [[ $i =~ REACH || $i =~ Reach ]];then echo $i ;fi;done

then add the pipe through mail if your email system is working properly.