Firewall Freischaltung mittels Wesberver Log

Möchte man Besucher für Dienste (Ports) freischalten, kann beispielsweise ein Webserver-Log herangezogen werden und auf Grundlage des HTTP-Status-Codes eine Freischaltung erfolgen. Hierzu ein einfaches Skript als Beispiel, das je nach Bedarf angepasst werden kann.

#!/usr/bin/bash

# Datei zum auslesen der Zugriffe
file="/var/log/nginx/my-host.access.log"

while true; do
    # Datei folgend öffnen, filtern und zeilenweise lesen
    tail -n1 -F "${file}" --retry | grep --line-buffered '"GET / HTTP/1.1" 200'  | while read line;do
        # IP-Adresse aus der Zeile extrahieren (Split nach Leerzeichen)
        ip=${line%% *};
        echo "whitelisting IP [$ip]";
        # Hinzufügen der IP-Adresse in IP-Set myset mit 24 Stunden Timeout
        nft add element inet filter myset { ${line%% *} timeout 24h };
    done
done

Das Skript öffnet hierbei mittels tail das Access-Log und folgt diesem. Logrotates und Verschiebungen werden ebenfalls berücksichtigt und im Anschluss gefolgt. Existiert ein Logfile noch nicht, wird nach dem Anlegen auch dieses erkannt und herangezogen (-F und –retry).
Nach der Pipe wird mittels Grep auf den HTTP-Code 200 geprüft und nur Zeilen mit erfolgreichem Aufruf von / ermittelt. Dies kann auch ein gänzlich anderer Pfad wie zum Beispiel /auth-xyz sein. Je nach persönlichem Empfinden.
Die IP-Adresse wird im Anschluss ermittelt und an nft übergeben. Der Befehl schreibt die IP-Adresse anschließend mit einem Timeout von 24 Stunden in das Set myset.
In NFTables sollte dieses Set vorab existieren und deshalb in der Konfiguration hinterlegt werden! Außerdem muss das Set noch in Firewall-Regeln hinterlegt werden!

table inet filter {

    set myset {
        type ipv4_addr
        flags timeout
    }
    
.....

}

Im Nginx sollte dann auf dem vHost (my-host) zum Beispiel ein Basic Auth aktiviert werden. Benutzer die sich nicht korrekt anmelden werden eine 403 Meldung zurückbekommen, während korrekt Authentifizierte Benutzer einen 200er Code erhalten.
Diese Meldungen erscheinen im Log und werden anschließend verarbeitet.