Integrations · fail2ban

Feed a HoneyLabs blocklist into fail2ban

fail2ban normally bans IPs after they fail against your own logs. A list-fed jail flips that around: it bans IPs that HoneyLabs sensors already caught scanning the internet, before their first attempt on your box. The recipe is a jail with no log filter plus a cron that feeds it the plain-text feed.

  1. 01

    Save a query

    Sign in (free) and save the HoneyLabs query you want the feed to track on the feeds page. Any lookup query works: a port, an ASN, a tag, or a boolean combination. The feed returns the source IPs currently matching it, so a tighter query means a tighter blocklist.

    # Example saved queries and what they feed you
    port:22 AND NOT tag:scanner     # SSH brute-forcers, known researchers removed
    tag:scanner                     # every recognized scanner IP
    cve:CVE-2024-4577               # IPs probing one specific CVE
    asn:14061 AND port:445          # SMB scans out of DigitalOcean
  2. 02

    Mint a feed token

    On the same page, mint a feed URL for the saved query. The token alone authorizes the fetch: no cookies, no headers, safe to paste into an appliance. Mint one token per consumer so you can revoke a leaked URL without breaking the others.

    # Your feed URL looks like
    https://honeylabs.net/feed/<token>        # plain text, one IP per line
    https://honeylabs.net/feed/<token>.csv    # ip,first_seen,last_seen,events,asn,country
    https://honeylabs.net/feed/<token>.json   # same fields as JSON
  3. 03

    Create a list-fed jail

    The jail exists only to hold bans, so its filter matches nothing and its logpath is /dev/null. Bans go through the normal fail2ban machinery: same ban action, same unban timer, visible in fail2ban-client status.

    # /etc/fail2ban/filter.d/honeylabs.conf
    [Definition]
    failregex =
    ignoreregex =
    
    # /etc/fail2ban/jail.d/honeylabs.conf
    [honeylabs]
    enabled   = true
    filter    = honeylabs
    logpath   = /dev/null
    banaction = iptables-allports
    bantime   = 6h
    
    # reload
    fail2ban-client reload
  4. 04

    Cron the feed into the jail

    Every 30 minutes, pull the list and ban each IP. banip is idempotent, so re-banning an already-banned IP is a no-op, and bantime keeps the set self-cleaning: an IP that drops out of the feed unbans itself when its timer expires.

    # /etc/cron.d/honeylabs-fail2ban
    */30 * * * * root curl -fsS 'https://honeylabs.net/feed/<token>' \
      | while read -r ip; do fail2ban-client set honeylabs banip "$ip" >/dev/null; done
    
    # Verify
    fail2ban-client status honeylabs

Worth knowing

  • Banning one IP at a time is fine up to a few thousand entries. For larger lists, the ipset recipe on the integrations page scales better: one kernel set, one iptables rule.
  • Match bantime to your cron interval or longer, otherwise bans expire between refreshes.

The feed is plain text (one IP per line), CSV, or JSON, is revocable per token, and is edge-cached for five minutes, so a tight refresh schedule never hammers anything. Create yours on the feeds page, or browse the other integrations.