Making access lists update for Cisco ASA, from failed login attempts in maillog

Making access lists update for Cisco ASA, from failed login attempts in maillog
Photo by Jake Walker / Unsplash

I had enough of checking everyday maillog on various systems so I wanted to have complete list from last day of IPs that I need to block on my firewall.

I already have ACL for mail server, and I wanted to copy-paste already prepared commands on top of it, as adding on bottom will not deny traffic because there are already allow statement.

Here is my script, and more details are below it:

grep "SASL LOGIN authentication failed: UGFzc3dvcmQ6" /var/log/maillog | awk {'print $7'} | cut -b 9-100 | sed -e 's/]://' | sort | uniq > /tmp/ipki
cat /tmp/ipki | sed -e 's/^/access-list mail_server_acl line 1 extended deny tcp host /g' > /tmp/ipkif
cat /tmp/ipkif | sed -e 's/$/ any/g' > /tmp/ipkifb
cat /tmp/ipkifb | mail -s "ACL to add to <COMPANY> firewall"
rm /tmp/ipki*

First we need to fine every line with failed login attempt. In my log it looks like this:

Sep 28 14:54:03 claptrap postfix/smtpd[25417]: warning: unknown[]: SASL LOGIN authentication failed: UGFzc3dvcmQ6

So after greping it out from log, we need to scrape only IP, which is seventh (with default space as delimeter) field in line. This is what awk is for. It prints to stdout only 7th value from line. But if space is delimeter we got some garbage in front of and at the end:


Now commadn cut comes in handy. With -b option we can tell which byte we want to print, so adding cut -b 9-100 tells script that we want to ommit first 8 bytes which are "unknown[" and start printing from byte 9 which will always be first digit of IP, then print up to 100 byte which is way to much, but IPs can vary in range, and end of lines we will cut with sed so its fine. So after scrapping unnecessery chars in front we have now:]:]:]:]:]:]:

Looks good, now only to delete remaining characters at the end. To delete ]: from every line we can use sed in interactive mode. This is command: sed -e 's/]://'

This tells script to do sed inline with every apperance of ]: to be changed to "nothing". Breakdown:

sed -e - do sed inline

' - start with command what sed have to make

s/ - replace all occurance of...

]: ... what need to be replaced

/ - replace with

now here is just empty space

/' - end of command

This gives us proper output of only IPs:

Finally we are sorting and printing only uniq IPs so we dont have doubles. At the end we store this in file: sort | uniq > /tmp/ipki

Now we can list all IPs with cat, and then using sed change beginning of every line with our text which will be our ACL command to add this IP on top of access list. This line with sed is clear. "^" means "on beggining of line" and last /g means to add to whole file. Then prepared beggining of our ACL we can save to different file.

So we now have file /tmp/ipkif with content like this:

access-list mail_server_acl line 1 extended deny tcp host

We need to add "any" after IP, so we do the same with file ipkif. We list it then alter it with sed, this time on every line end. This is "$" char for. Notice that any have space before it. This is because every line ends with IP and we dont want to end with something like "". Instead we want " any". Finally we can save to another file with completed commands.

Last step is to show complete file and pipe output to mail command with subject that tells us what firewall this is for, and send to proper email address.

Last line is only for cleanup, but by using > instead of >> every run will clean those file as well.

If done correctly and put into the cron for example at 6:55 everyday, if you start working at 7:00 you got complete list from last day to block.

I also plan to further automate it with another script that will insert it into ASA.