Fail2ban package, guidelines for Python3

Dear all,

I would like to contribute a package for fail2ban inclusion in LEDE. The idea is to able to produce accurate banlists on the fly and use them internally or submit them to DNSBL blacklists. fail2ban does that very well.

I am aware that this is Python3 code, but there is no C equivalent today and please let me know of any equivalent software.

Are there special guidelines to include a Python3 software in LEDE?

Kind regards,
French Fries

1 Like

Hoops !

LEDE does not hold any package, right?
How to submit packages?

I think that it would be great to have a shell script that running on cron that inspect syslog using grep searching for fails attemps to ssh (or uhttps/luci) and run a proper iptables command, but on LEDE usually people just disable web access to those ports from WAN interface or add port-knocking (enabling just one ip at the time) or even add port-knocking for port redirection too.

You can also try:

-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m limit --limit 5/min --limit-burst 5 -j ACCEPT

better yet:

# drop IP that tries to connect to ssh more than 15 times on one minute
-A INPUT -p tcp --dport 22 -i eth1 -m state --state NEW -m recent --set
-A INPUT -p tcp --dport 22 -i eth1 -m state --state NEW -m recent  --update --seconds 60 --hitcount 16 -j DROP
-A INPUT -p tcp --dport 22 -j ACCEPT

there are dropBrute now bearDropper but I don't know if it is widely used or not, I never tried, if you do so fell free to comment about them here.

yes, fail2ban will be only possible with python, for python needs to have extroot, and opkg install python3

bearDropper seems very nice, I will have a look at it. But it only supports SSH. Maybe could be extended to ban all attacks on WAN? Will look at it, thanks.

@ffries
hey

for, python3 you could take reference from a few existing packages in https://github.com/openwrt/packages/
that repo is shared between LEDE & OpenWrt
the main thing you need to do, is include python3-package.mk and define a few package names, and for packages that need to build via Python(3) magic, call $(eval $(call Py3Package,python3-jinja2)) ;
for most cases, you shouldn't need extra stuff ; but you never know
maybe you need to override the Py3Build/Compile rule

you can try to experiment

some packages you could take a look at [for inspiration]

 sandu@northlight  ~/work/packages   master  grep -r python3-pack
utils/i2c-tools/Makefile:$(call include_mk, python3-package.mk)
lang/python/python-yaml/Makefile:$(call include_mk, python3-package.mk)
lang/python/Flask/Makefile:$(call include_mk, python3-package.mk)
lang/python/python-lxml/Makefile:$(call include_mk, python3-package.mk)
lang/python/Jinja2/Makefile:$(call include_mk, python3-package.mk)
lang/python/python-gnupg/Makefile:$(call include_mk, python3-package.mk)
lang/python/python-pycparser/Makefile:$(call include_mk, python3-package.mk)
lang/python/MarkupSafe/Makefile:$(call include_mk, python3-package.mk)
lang/python/python3-bottle/Makefile:$(call include_mk, python3-package.mk)
lang/python/pyodbc/Makefile:$(call include_mk, python3-package.mk)
lang/python/itsdangerous/Makefile:$(call include_mk, python3-package.mk)
lang/python/Werkzeug/Makefile:$(call include_mk, python3-package.mk)
lang/python/click/Makefile:$(call include_mk, python3-package.mk)
lang/python/python3/Makefile:include ./files/python3-package.mk
lang/python/python3/Makefile:include ./files/python3-package-*.mk
lang/python/python3/Makefile:		./files/python3-package.mk \
lang/python/python3/Makefile:		./files/python3-package-install.sh \
lang/python/python3/files/python3-package.mk:	if [ -e files/python3-package-install.sh ] ; then \
lang/python/python3/files/python3-package.mk:		$(SHELL) files/python3-package-install.sh \
lang/python/python3/files/python3-package.mk:	elif [ -e $(STAGING_DIR)/mk/python3-package-install.sh ] ; then \
lang/python/python3/files/python3-package.mk:		$(SHELL) $(STAGING_DIR)/mk/python3-package-install.sh \
lang/python/python3/files/python3-package.mk:		echo "No 'python3-package-install.sh' script found" ; \
lang/python/python-ply/Makefile:$(call include_mk, python3-package.mk)
lang/python/python-cffi/Makefile:$(call include_mk, python3-package.mk)
net/radicale/Makefile:$(call include_mk, python3-package.mk)

hope this helps

1 Like

Many thanks.

beardropper works really good... but it only detect ssh login.. not webserver login (as you know... nginx never log failed login from luci)

Keep in mind that LEDE is an embedded system, it does not perform equally as a Desktop or Server system, It does not contains full and granular logging neither luci.

By default luci runs on top of uhttpd, even if you replace it by nginx or apache it will not perfom well on an embedded system when it receive multiple connections attacks, You should use port-knocking, or a solid iptables set of rules to be able and manage properly the detection and blocking or wan access to web ui configuration...

Keep in mind that if you leave open access to web ui, even it is secured by password hackers will probably be able to use some exploit or method to gain access, if they had that kind of access is like having full access through SSH, to your private network router, is like giving them access to your entire network.

Port-knocking feature will only open port to your specific remote IP address and only when you want it.
There is also some implementations of on-demand opening ports using iptables using TOTP Softwares like Google Authenticator (may be HOTP could also be implemented in some way)...

Fail2ban is based on iptables, so ports are never open, only filtered. Fail2ban is too big for some systems I agree.

When using fail2ban ports that are listening are open, fail2ban watches the log for fails on authentications (usually user-password) and when a limit is breached it performs the creation of iptables rule (drop or reject) or route rule (in the config file this behaviour can be configured by each jail).

Fail2ban it is easy to install, to use, and configure in a web/mail server online without need to configure portknocking or iptables rate-limiting or other methods, methods that if you configure improperly you will be kick out by undefined time, but by default fail2ban just ban on a configurable time basis and just one remote public IP address. Both allow to wait a few minutes or just use another internet connection in order to gain access again.

if you need help, with at least 2 cpu and 128mb ram, it is easy to do it, is all autocreated and it works perfect.
i use linksys190acss v2 and dlink 860l, and i restrcit dropbear, ssh, nginx, wordpress, all you want, except for sendmail it uses msmtp. that it works and not slows the router at all. it's awesome!

try to make it work today :

cd /root
git clone https://github.com/peci1/fail2ban_openwrt

## comments set -e in install_fail2ban.sh

REF :

root@LPM:~# ln -s /usr/bin/python3 /usr/bin/python

root@LPM:~# service fail2ban restart

root@LPM:~# ps |grep fail2ban
10195 root     22836 S    {fail2ban-server} python /usr/bin/fail2ban-server
10291 root      9484 R    python /usr/bin/fail2ban-server -xf --logtarget=syslog -p /var/run/fail2ban/fail2ban.pid -s /var/run/fail2ban/fail2ban.sock start
10293 root      1348 R    grep fail2ban
root@LPM:~# cat /var/log/fail2ban.log 
2021-02-08 13:50:33,098 fail2ban.server         [10195]: INFO    --------------------------------------------------
2021-02-08 13:50:33,100 fail2ban.server         [10195]: INFO    Starting Fail2ban v1.0.1.dev1
2021-02-08 13:50:33,102 fail2ban.server         [10195]: INFO    Daemon started
2021-02-08 13:50:33,109 fail2ban.observer       [10195]: INFO    Observer start...
2021-02-08 13:50:33,198 fail2ban.database       [10195]: INFO    Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2021-02-08 13:50:33,224 fail2ban.database       [10195]: WARNING New database created. Version '4'
root@LPM:~# fail2ban-client -d
2021-02-08 13:55:38,048 fail2ban.configreader   [10403]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
['set', 'syslogsocket', 'auto']
['set', 'loglevel', 'INFO']
['set', 'logtarget', '/var/log/fail2ban.log']
['set', 'allowipv6', 'auto']
['set', 'dbfile', '/var/lib/fail2ban/fail2ban.sqlite3']
['set', 'dbmaxmatches', 10]
['set', 'dbpurgeage', '1d']

So all look to work okay now...
Me idea/needs is to get a central syslog on my router, and then use the centralized logs files to be checked by fail2ban to blacklist attacks directly on the router !
Any clue and advices will be welcome ! :wink:

Okay, I have got it to work.
I get my nextcloud attempts beeing logged and bans issued after too many bad tries !
Will now try to document it fully...

Any advices how to protect from windows services ?
As I actually do from linux services... using syslog-ng and centralizing logs to the main routeur, where fail2ban is installed and listening.

but still no progress... error in building (nothing to compile)

Anyone can help ?

moved here : Fail2ban packaging for OpenWrt and python3