xt_recent mit syslog-ng 2


Die unter Block outdated clients vorgestellte Lösung funktioniert zumindest mit syslog-ng 3.4.2 nicht, da syslog-ng “lseek()” verwendet, um das Ende von z.B. /proc/net/xt_recent/irgendwas zu erreichen, während die destination program lediglich ein externes Programm startet.

Mit file als destination sieht das im Log dann so aus:
Aug 29 00:00:44 mx03.schaal-24.de syslog-ng[20351]: Error suspend timeout has elapsed, attempting to write again; fd='24'

Aug 29 00:00:44 mx03.schaal-24.de syslog-ng[20351]: I/O error occurred while writing; fd='24', error='Input/output error (5)'

Aug 29 00:00:44 mx03.schaal-24.de syslog-ng[20351]: Suspending write operation because of an I/O error; fd='24', time_reopen='10
'

Die grundsätzliche Konfiguration funktioniert weiter, es muss nur die destination von file auf program geändert und ein entsprechendes shell-script angelegt werden.

destination deny-mirror {
  program("/root/scripts/syslog/ban-recent.sh"
  template("+${APACHE.SRC-IP} clamav-403\n"));
};

Das entsprechende Script sieht dann so aus:
#!/bin/bash
IP=`echo $1|cut -d" " -f1`
JAIL=`echo $1|cut -d" " -f2`
echo +$IP > /proc/net/xt_recent/$JAIL

Grundsätzlich würde auch
#!/bin/sh
echo +$1 > /proc/net/xt_recent/$2

reichen, durch die erste Variante sind dann aber noch Erweiterungen wie eine Whitelist möglich. Ich schließe dadurch immer ein paar IP vom Eintrag in die Firewall aus und schreibe die Daten in eine Datenbank:
#!/bin/bash
WHITELIST_MX_02="1.2.3.4 4.5.6.7"
WHITELIST_MX_03="10.11.12.13 14.15.16.17"

WHITELIST=$WHITELIST_MX_02" "$WHITELIST_MX_03"

SQLBIN=`which mysql`
DB="system-log"
TAB=iptables

IP=`echo $1|cut -d" " -f1`
JAIL=`echo $1|cut -d" " -f2`

for IP_WL in $(echo $WHITELIST); do
  if [ $IP != $IP_WL ]; then
    echo +$IP > /proc/net/xt_recent/$JAIL
    $SQLBIN $DB -e "INSERT INTO $TAB VALUES(INET_ATON('$IP'),INET_ATON('0.0.0.0'),80,'$JAIL',1,now(),DEFAULT) ON DUPLICATE KEY UPDATE hits=hits+1,remote=DEFAULT;"
  fi
done;


Kommentar erstellen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

2 Gedanken zu “xt_recent mit syslog-ng

  • Jan

    Thanks for hinting at the lseek() issue! I’ve been wondering for a while why my rules stopped working after the upgrade.
    Some hints, though …

    If you’re using bash anyway,

    IP=`echo $1|cut -d” ” -f1`
    JAIL=`echo $1|cut -d” ” -f2`

    is better written as

    IP=${1%% *}
    JAIL=${1#* }

    to avoid creating two new processes.

    Also I don’t think your whitelist loop works like that … Did you really intend to jail the source ip if you find one ip in the whitelist that doesn’t match? If your whitelist has two different ips, this will jail all candidates. I think what you want is to check all ips in the whitelist, and jail the candidate if it doesn’t match any of them.

    Finally, syslog-ng (at least for version 3.5 that I’m looking at) keeps the script running and expects it to read further input through stdin. This is kind of obscurely implied in the documentation here:
    https://syslog-ng.com/documents/html/syslog-ng-ose-3.5-guides/en/syslog-ng-ose-guide-admin/html/reference-destination-program.html

    You’ll notice if you add logging to the script: The log output is written many times per second, because when the script exits, syslog-ng restarts it immediately, even before there’s anything to log.

    Thus you want to wrap the script in an endless loop, like so:

    while true ; do
    {
    read ip target
    [ -z “$ip” ] && continue
    echo +$ip > /proc/net/xt_recent/$target
    date +”%F %T $ip $target”
    } 2>&1 >> /var/log/ban.log
    done

    The `read` will block until input is available.

    I’m still seeing empty output every 20 minutes … guessing syslog-ng still restarts the script regularly even if nothing has happened. That’s what the “empty parameter – continue” shortcut is for.

    I’ve also wrapped the echo-to-proc in with the logging so that next time this throws errors, I’ll see them in the ban.log.

    HTH! Jan