I like the Symbiosis firewall system, but started to look at improving it, mostly aimed at catching and stopping ‘persistent’ offenders, who often are using exhaustive decryption to get logins and passwords. I posted some thoughts about it in the Symbiosis Github site - see https://github.com/BytemarkHosting/symbiosis/issues/136. Big caveat: all of this has been done on stretch, I am unsure if it will work on previous Debian systems,
I’ve now made some changes with a view to allowing them to be installed without changing the current set of distributed files. The main thinking is to make better use of the sqlite3 database that is used to record firewall ‘incidents’, allowing the past to have much better effect on the future.
Provide a local version of symbiosis-firewall-blacklist, which is the script that looks for patterns in files and manages files in /etc/symbiosis/firewall/blacklist.d, these files later are used to create the firewall.
The new version has two new arguments:
–block-period (or -A)
Allows you to specify the number of days that are taken into account when the script finds a matching line, and counts to see if the --block-after count has been reached. Zero means look at all entries in the database for the matching IP and use the sum of all incidents.
The installed script only looks at the count from the current processing cycle, which can be quite a short time because the script only looks at the section of the log file that has been added since the last time the script was run. So if effect, it isn’t using its memory, and bad sites that come back intermittently don’t rack up an appropriate score.
–block-all-period (or -B)
Allows you to specify the number of days taken into account when evaluating IPs that should be blocked on all ports, because their incident count is is larger than the number specified in the --block-all-after argument (default 100). The number for this argument can also be zero which means that it uses the entire stored incident database.
The installed script only looks at the counts for the last 24 hours, so is not really using its memory effectively, bad IPs can come back every other day and avoid being picked up.
I’ve installed my revised version of symbiosis-firewall-blacklist in /usr/local/sbin, and placed the revised blacklist.rb file in /usr/local/lib/site_ruby.I am by no means a ruby coder, and putting the file here may not be ‘right’, it appears to work, but may not be following the rules that should be followed. I am sure that someone will pick me up on any transgression should this not be ‘OK’.
Then I changed the cron.d file - /etc/cron.d/symbiosis-firewall from
5,20,35,50 * * * * root [ -x /usr/sbin/symbiosis-firewall-blacklist ] && /usr/sbin/symbiosis-firewall-blacklist
5,20,35,50 * * * * root [ -x /usr/local/sbin/symbiosis-firewall-blacklist ] && /usr/local/sbin/symbiosis-firewall-blacklist -a 10 -e 5 -A 0 -B 0
–block-after (-a) to 10 incidents (rather than the default 25)
–expire-after to 5 days (rather than the default 2 days)
–block-period to check all entries in the database
–block-all-period to check all entries in the database
The effect of this is that: you catch persistent offenders more often and simply keep them out.
It occurred to me that there was no feedback from the firewall itself in this loop. So after 5 days, these people would be let in again and they would be detected again. But the firewall is only updated hourly, so in that time they could come back and hammer away. The solution is to provide a script that’s run just before the firewall is updated, which looks to see which of the IP addresses has tried to access the machine, and then updates the time on the appropriate file if they have. Updating the time stops the file from being removed automatically, and simply keeps persistent robots out.
This uses a new script symbiosis-update-blacklist - which is written in python (because I was happier with that). This gets installed in /usr/local/sbin too. Then the firewall reload line in /etc/cron.d/symbiosis-firewall is changed from
@hourly root [ -x /usr/sbin/symbiosis-firewall ] && /usr/sbin/symbiosis-firewall
@hourly root [ -x /usr/sbin/symbiosis-firewall ] && ( /usr/local/sbin/symbiosis-update-blacklist; /usr/sbin/symbiosis-firewall )
This idea really works, I’ve got at least two sites who hammer away, ones been trying for over a month now. Eventually some of these do seem to go away.
To get hold of the code download from:
I am wondering about adding a deny rule into the acl_check_connect section of exim4 which looks up the IP in the incident database (exim4 is apparently compiled with sqlite3 support) and then says ‘goodbye’ if it finds a match with perhaps an incident count over 100. My database has several sites that come back every two or three months and try their luck. I think that the rule needs to allow me to whitelist addresses, using the current whitelist system, just in case.
Maybe more on this later.