The idea is to have fail2ban watch your server’s log file. Every request counts as “failed login” from fail2ban’s point of view.

The setup has two parts.

Create a filter file in /etc/fail2ban/filter.d/ and call it “gemini.conf” or something like that. The name is important and will get reused in the jail definition below!

Here’s an example where we define a “datepattern” and “failregex” for this filter. The exact pattern probably depends on your software, so you’ll have to tinker with it.

[Init]
# 2018/08/25-09:08:55 CONNECT TCP Peer: "[000.000.000.000]:56281" Local: "[000.000.000.000]:70"
datepattern = ^%%Y/%%m/%%d-%%H:%%M:%%S

[Definition]
# ANY match in the logfile counts!
failregex = CONNECT TCP Peer: "\[<HOST>\]:\d+"

Next, create a jail in /etc/fail2ban/jail.d/ and call it “gemini.conf” or something like that, again. The first line refers to the filter file in square brackets: it’s called “[gemini]” because “filter.d/gemini.conf” is your filter.

[gemini]
enabled = true
port    = 1965
logpath = /home/alex/farm/gemini-wiki.log
findtime = 40
maxretry = 20

Make sure the log path is correct. “findtime” is the timewindow fail2ban is going to consider, and “maxretry” is the number of “failed logins” it allows before blocking a visitor. But as the filter definition above shows, we’re counting every hit as a “failed login” and therefore this means: we allow 20 hits in 40 seconds, or an average of 1 hit ever 2 seconds. Fair reading speed for a human, but unbearably slow for a bot, of course.

What about Tor users?

If you are concerned about blocking Tor users, you can give them a free pass. First, set up a cron job that gets the list of exit notes and saves it somewhere. Create /etc/cron.d/tor and add the following line, for example:

14 4 * * * curl --output=/etc/tor/torbulkexitlist https://check.torproject.org/torbulkexitlist

See “man --section=5 crontab” to learn more about the format.

Now that we have a list of Tor exit nodes, we can add a line to our jail, providing “ignorecommand” – making sure that we don’t block IP numbers on the list of Tor exit nodes.

ignorecommand = /bin/grep <ip> /etc/tor/torbulkexitlist

See “man --section=5 jail.conf” to learn more about the format.