Skip to main contentSkip to footer

Erkennung und Regeln

Was der Agent in den Logs findet, die ein Server ohnehin schreibt: die vierzehn Quelltypen und ihre Schwellwerte, wie eine Quelle nachgetragen wird, die der Installer nicht fand, was die Maschine verlässt und was sie nie verlässt, und die Regeldateien, aus denen jeder Erkenner besteht, auch die, die Sie selbst schreiben.

Was der Agent in Ihren Logs findet

Jede Quelle hat ihren eigenen Detektor und ihren eigenen Schwellwert, denn fünf gescheiterte SSH-Logins in zehn Minuten und fünfzig verdächtige Web-Anfragen in zwei Stunden sind dieselbe Aussage über einen Angreifer und nicht dieselbe Zahl. Rotation, copytruncate und ein Log, das eine Weile verschwindet, sind abgedeckt, und eine unlesbare Datei erzeugt eine Warnung statt einer pro Lesevorgang.

Die vierzehn Quelltypen

TypTypischer PfadWas als Treffer zählt
sshdjournald, sonst /var/log/auth.log oder /var/log/secureFalsche Passwörter, ungültige Benutzer, abgelehnte Keys für einen Benutzer, den es nicht gibt, überschrittene Versuchsgrenzen, und die Fehler vor der Authentifizierung, die Scanner ausmachen: kein Identification String, eine falsche Protokollversion, Müll im Banner-Austausch. Ein abgelehnter Key für einen gültigen Benutzer zählt bewusst nicht, denn ein Admin mit fünf Keys schreibt vier davon pro erfolgreichem Login. Ein erfolgreicher Login löscht die Fehlschläge dieser Adresse.
web/var/log/nginx/access.log oder ein Glob pro SiteLogin-POSTs, unabhängig vom Statuscode gezählt, und Pfade, die kein legitimer Client abfragt. Alles andere in einem Access-Log wird ignoriert, denn das ist die Quelle mit echten Kunden dahinter.
web-error/var/log/nginx/error.log, /var/log/apache2/error.logAnfragen, die der Webserver selbst abgelehnt hat, gescheiterte HTTP-Basic-Auth, und ModSecurity-Zeilen kritischer Schwere, wenn sie hier statt in einem Audit-Log landen. Zeilen von Rate Limits zählen bewusst nicht: ein Limit greift auch bei einem echten Browser mit zwanzig Tabs. TLS-Handshake- und PHP-Meldungen sagen etwas über den Server und nichts über den Client.
postfix/var/log/mail.log, /var/log/maillogDrei getrennte Ereignisquellen aus einer Datei: gescheiterte SASL-Authentifizierungen, NOQUEUE-Rejects, die wirklich 5xx sind (ein 450 ist Greylisting und zählt nicht), und Amavis-Blocks. Zugestellte Mail ist nie ein Treffer.
dovecotdasselbe Mail-LogGescheiterte IMAP- und POP3-Logins, einer pro Zeile, egal was „N attempts“ sagt. Die entfernte Adresse kommt aus dem Feld rip=, nie aus lip=, denn das ist die eigene Adresse des Servers. Ein abgebrochener Login ohne Authentifizierungsversuch ist kein Treffer: das ist ein TLS-Scan, und es wurde kein Passwort probiert.
exim/var/log/exim4/mainlog, /var/log/exim/main.logGescheiterte Authentifizierungen und abgelehnte Absender. Nicht gegen einen Live-Host verifiziert: die Muster kommen aus dem dokumentierten Logformat.
ftp/var/log/syslog, /var/log/messagesGescheiterte Authentifizierungen von pure-ftpd, proftpd und vsftpd. Alle drei loggen über syslog, und jeder schreibt die Gegenstelle anders, also werden drei Muster genutzt. pure-ftpd ist gemessen: 494 von 494 Zeilen auf einem Produktionshost hatten eine einzige Form.
nameddasselbe syslogNur eine eingehende Anfrage, die bind abgewiesen hat. Die große Falle ist die umgekehrte Richtung: connection refused resolving ist der eigene Resolver dieses Hosts, der den Nameserver eines anderen nicht erreicht, und 90 Prozent der gemessenen Zeilen waren das. Ein Detektor ohne diese Ausnahme meldet fremde Nameserver als Angreifer.
panel/var/log/ispconfig/auth.logGescheiterte Logins am ISPConfig-Panel. Die Datei ist auf jedem gemessenen Host 0 Byte groß, und das ist kein Fehler: das Panel schreibt dort einfach nichts hin. doctor weist nach einer Woche darauf hin.
modsec/var/log/apache2/modsec_audit.logEin Ereignis pro Transaktion, deren Urteil kritische Schwere trägt. Das ist der einzige Detektor mit Zustand, denn eine Transaktion geht über mehrere Zeilen. Nichts aus der Anfrage reist im Ereignis mit: nicht die Regel-ID, nicht die getroffenen Daten, nicht die URI.
csf/var/log/lfd.logWas CSF tatsächlich geblockt hat, nie was es nur erkannt hat. Kein zweiter Schwellwert darüber: lfd hat gezählt, bevor der Agent die Zeile sah, ein Block ist also ein Report.
fail2bandas Journal der Unit, sonst /var/log/fail2ban.logNur Bann-Aktionen. Ein Restore Ban wird nie gemeldet, denn das spielt ein fail2ban-Neustart aus seiner eigenen Datenbank nach und ist kein neuer Angriff. Eine Found-Zeile eines Filters wird auch nicht gemeldet: das Jail hat noch nicht entschieden.
imunify360fragt imunify360-agent abVorfälle aus dem CLI, über das Präfix des Regelnamens Kategorien zugeordnet. Experimentell und nicht gegen eine lizenzierte Installation verifiziert; der Decoder überspringt, was er nicht lesen kann, statt aus einer unerwarteten Antwort eine tote Quelle zu machen.
scandas Kernel-Journal (journalctl -k), sonst /var/log/kern.log oder /var/log/messagesDie Zeilen der Port-Scan-Regel, die der Sync-Lauf mit dieser Quelle anlegt: ein SYN auf einen Port, auf dem dieser Host nicht lauscht, mit dem Präfix rip-scan:. Zehn Anfragen in zehn Minuten von einer Adresse sind ein Scan. Nichts in einer Kernel-Log-Zeile stammt von der Gegenstelle. Siehe unten.

web-app ist kein Quelltyp und kann nicht in sources geschrieben werden. Es ist ein zweiter Erkenner, der auf den Zeilen läuft, die eine web-Quelle schon liest, und er hat seinen eigenen Schwellwert, deshalb steht er in der Schwellwert-Tabelle weiter oben unter seinem eigenen Namen. Ein Agent, dessen Konfiguration ihn nennt, startet nicht: sources[0]: type "web-app" is not supported in this version.

Port-Scans, aus dem Kernel-Log

Jede andere Quelle liest ein Log, das ein Dienst schreibt. Die Quelle scan liest den Kernel, und sie ist die eine Quelle, die auch die Firewall verändert: steht sie in der Config, legt der Sync-Lauf hinter den Listen eine Regel an, die ein SYN auf einen Port protokolliert, auf dem dieser Host nicht lauscht, mit dem Präfix rip-scan: und nach einem ersten Schub von 20 höchstens zehn Zeilen je Minute, damit ein Scan aller 65535 Ports das Journal nicht flutet. Mit dem ipset-Backend ist das eine eigene Kette, rip-blacklist-scan, mit nftables eine Regel in der Kette. Die lauschenden Ports werden bei jedem Sync aus /proc gelesen, ein Dienst, den Sie starten, ist nach dem nächsten Lauf also kein Scan-Ziel mehr, und es gibt nichts zu deklarieren. Als lauschend zählt nur ein Socket, den von außen etwas erreichen könnte. Ein Port, der allein auf 127.0.0.1 oder ::1 gebunden ist, bleibt in der Regel, denn ein Paket, das dort aus dem Netz eintrifft, ist die Probe auf einen geschlossenen Port und sonst nichts. Die Liste aus dem letzten Sync ist nicht die einzige Prüfung: Die Regel fragt beim Eintreffen des Pakets auch den Kernel, und ein SYN auf einen Port, auf dem in diesem Moment ein Socket lauscht, ist eine Verbindung und wird nie geloggt. Das deckt einen Dienst ab, der seit dem letzten Sync gestartet wurde, und einen Daemon, der einen Port nur für eine einzelne Übertragung öffnet. Den Passivbereich eines laufenden FTP-Servers (pure-ftpd, proftpd, vsftpd) liest der Sync aus dessen Konfiguration und nimmt ihn aus der Regel heraus; läuft der Server ohne konfigurierten Bereich, bleibt stattdessen der ephemere Portbereich des Kernels außen vor. Ein Kernel ohne Socket-Match behält die Regel ohne diese Prüfung.

Die Regel steht hinter der Whitelist und hinter den Listen. Eine Adresse auf Ihrer Whitelist hat die Kette vorher verlassen und erzeugt keine Zeile, und eine Adresse, die die Listen ohnehin verwerfen, erreicht sie ebenfalls nicht. In mode: log und mode: off tut sie das, was alles andere in diesen Modi tut.

Die Quelle liest das Kernel-Journal, journalctl -k, und weicht auf /var/log/kern.log oder /var/log/messages aus, wo es kein Journal gibt; ein gesetzter path gewinnt. Die gelieferte Regel scan zählt zehn Anfragen in zehn Minuten von einer Adresse, meldet sie unter Kategorie 14 (Port Scan) als port probes und sperrt die Adresse wie jeden anderen Fund. Ein Client, der einen geschlossenen Port wiederholt anfragt, schickt höchstens sechs Pakete, deshalb liegt die Schwelle bei zehn. install schreibt die Quelle auf einem frischen Host als letzten Eintrag unter sources; ein früher installierter Host behält seine Konfiguration, und das Nachtragen ist eine Zeile, gefolgt von einem Neustart des Watch-Dienstes und einem Sync für die Regel.

yaml
# config.yaml: the source, next to the ones the installer wrote
sources:
  - type: sshd
  - type: scan

# /etc/reportedip-agent/rules.d/50-scan.yaml: ban a scanner on this
# host, but leave the report to hosts that see more of it. Every field
# not named here stays as shipped.
format: 1
rules:
  - id: scan
    action: {ban: true, report: false}

# The same file with enabled: false switches the rule off; the firewall
# rule and its log lines stay. A threshold of your own goes into
# config.yaml and wins over the file:
thresholds:
  scan: {hits: 20, window_minutes: 10}

Eine Quelle nachtragen, die der Installer nicht fand

Eine Quelle, die der Installer nicht gefunden hat, fehlt einfach in der Config, und sie nachzutragen ist ein Eintrag mit einem Pfad oder einem Glob. Weil eine Datei mit einem sources-Block die Standardliste vollständig ersetzt, gehört Ihr Eintrag neben die bestehenden und nicht in einen zweiten Block.

yaml
sources:
  - type: sshd
  - type: web
    path: /var/log/nginx/access.log

  # A second web server on a different path
  - type: web
    path: /var/log/caddy/access.log

  # Every site of a panel host, rescanned every ten minutes.
  # At most five wildcard segments.
  - type: web
    glob: /var/www/clients/*/web*/log/access.log
    exclude:
      # This site reports to the API on its own, through Hive or a
      # honeypot. Without the exclude the host sends every address
      # twice and pays twice out of the daily quota.
      - /var/log/ispconfig/httpd/honeypot.example.com/*

  # Exim on a host the installer saw as a Postfix machine
  - type: exim
    path: /var/log/exim4/mainlog

Zwei Pfade, die auf dieselbe Datei zeigen, sind kein Problem und brauchen kein exclude: ISPConfig veröffentlicht jedes Access-Log zweimal, unter /var/www und unter /var/log/ispconfig, und der Agent liest so eine Datei einmal. Bevor Sie einem neuen Eintrag vertrauen, lassen Sie reportedip-agent test über die Datei laufen, starten dann den Watch-Dienst neu und schauen in status: der Abschnitt sources zeigt Treffer pro Quelle. doctor zeigt je Quelle einen Wert files=, und eine Quelle mit dem Wert null findet keine einzige Datei.

Was die Maschine verlässt

Ein Report enthält die Adresse, die IDs der Threat Categories und einen generierten Satz. Keine Logzeile, kein Request-Body, kein User-Agent, keine URL und kein Benutzername wird je übertragen, ein Report kann also auch aus Versehen nicht Ihre Kunden, Ihre Pfade oder Ihre Zugangsdaten verraten.

Eine Präzisierung, denn eine absolute Zusage wäre hier falsch. Zwei Quellen setzen einen Namen aus dem Log in diesen generierten Satz: bei fail2ban den Namen des Jails, das gesperrt hat, bei imunify360 den Namen der Regel, die gegriffen hat. Beide werden auf Buchstaben, Ziffern, Punkt, Bindestrich und Unterstrich gefiltert und auf 32 Zeichen gekürzt, bevor sie die Maschine verlassen, denn ein Jail-Name stammt aus einer Logzeile und ist damit angreifernahe Eingabe. Keine andere Quelle schickt überhaupt etwas aus einer Logzeile.

Der Hostname wird mitgesendet, und das nur zu einem Zweck: damit Sie Ihre eigene Maschine in der Serverliste wiedererkennen, statt Zufallskennungen zu vergleichen. Er wird auf dem Client auf A-Za-z0-9._- gefiltert, alles andere wird entfernt und nicht ersetzt, auf 191 Zeichen gekürzt, und er geht nie ohne die Install-ID daneben hinaus.

Die Identität ist weiterhin die Install-ID. Der Hostname ist eine Bezeichnung und nichts weiter: die Maschine umzubenennen ändert nichts an der Lizenz, nichts daran, welcher Host sie hält, und nichts an dem, was der Server entscheidet. Sie können zusätzlich in Ihrem Konto ein eigenes Label vergeben; es steht vor dem Hostnamen und wird nie aus der Maschine abgeleitet.

Vier Dinge werden nie gemeldet und nie geblockt, und das ist eine Grenze im Code statt einer Einstellung: private und reservierte Bereiche, das Loopback, jede Adresse der eigenen Interfaces dieses Servers samt Default-Gateway, und alles in Ihrer Whitelist. Die SSH-Client-Adresse aus der Installation steht in der Auto-Whitelist und gehört damit zur letzten Gruppe.

Regeln

Eine Regel sagt, welche Zeilen einer Quelle Treffer sind, wo in so einer Zeile die Adresse steht, wie ein Treffer heißt und wie viele davon in wie vielen Minuten zu einer Sperre oder einer Meldung werden. Jeder Detektor des Agenten ist eine Regel, und jede Regel ist eine Datei. Drei Ebenen werden gelesen und über die Regel-ID zusammengeführt:

EbeneWo sie liegtWas sie ist
1In der BinärdateiDie mitgelieferten Regeln, eine Datei je Quelltyp. Sie laufen aus der Binärdatei. Nach dem nächsten Sync liegt eine Kopie zum Lesen unter /var/lib/reportedip-agent/rules.d/standard/; eine Änderung dort überschreibt der Sync danach wieder. install legt dieses Verzeichnis und daneben packs/ schon leer an, damit die drei Ebenen sichtbar sind, bevor der erste Sync zwei davon füllt.
2Ein signiertes Regelpaket von reportedip.comDer Sync-Lauf holt es, prüft seine Signatur gegen einen in die Binärdatei eingebauten Schlüssel, bevor ein einziges Byte davon als Regel gelesen wird, und bewahrt es im State-Verzeichnis auf. Ein Host, der den Dienst nicht erreicht, behält das Paket, das er hat. Ein Paket, dessen Signatur nicht stimmt, wird abgewiesen, und das vorhandene auf der Platte bleibt.
3/etc/reportedip-agent/rules.d/*.yamlIhre Dateien: Überschreibungen mitgelieferter Regeln und eigene Regeln.

Das Paket gewinnt über die Binärdatei, Ihre Dateien gewinnen über das Paket. Eine Überschreibung nennt eine Regel über ihre id und nur die Felder, die sich ändern; jedes Feld, das sie nicht nennt, behält den Wert der Ebene darunter. match und examples werden als Ganzes ersetzt, action Feld für Feld. enabled: false schaltet eine Regel ab. Der Dateiname spielt keine Rolle: eine Datei namens 10-sshd.yaml unter rules.d verdeckt nicht die mitgelieferte Datei dieses Namens, sie wird wie jede andere gelesen und über die IDs darin zusammengeführt, ein Release, das eine mitgelieferte Datei umbenennt, kann aus Ihrer Überschreibung also kein Duplikat machen.

Das Dateiformat

Eine Datei enthält beliebig viele Regeln. Das hier ist eine vollständige, aus der Testsuite des Agenten selbst:

yaml
format: 1
rules:
  - id: my-sshd
    source: sshd
    match:
      regex: '(Failed password|Invalid user) .* from '
      anchors: ["Failed password", "Invalid user", "Accepted "]
      reset: 'Accepted (password|publickey) for .* from '
    addr: {after: " from ", occurrence: last}
    categories: [22, 18]
    noun: failed logins
    threshold: {hits: 5, window_minutes: 10}
    examples:
      match:
        - {line: "Sep 24 14:47:38 host sshd[1]: Failed password for root from 45.33.32.156 port 51422 ssh2", addr: 45.33.32.156}
      inject:
        - {line: "Sep 24 14:47:38 host sshd[1]: Invalid user x from 8.8.8.8 port 22 from 45.33.32.156 port 51422", addr: 45.33.32.156}
      nomatch:
        - "Sep 24 14:47:38 host sshd[1]: Connection closed by 45.33.32.156 port 1"
FeldBedeutungWas der Lader prüft
formatDie erste Zeile jeder Regeldatei. Dieser Agent liest Format 1.Eine Datei mit einer höheren Nummer wurde für einen neueren Agenten geschrieben und wird übersprungen; eine Datei ohne die Zeile ebenso.
idDer Name der Regel, so wie rules list und das Journal ihn zeigen.a-z, 0-9 und - ab dem zweiten Zeichen, höchstens 32 Bytes. Eine ID, die in einer tieferen Ebene schon existiert, macht die Regel zur Überschreibung.
sourceDer Quelltyp, dessen Zeilen die Regel liest, einer der vierzehn: sshd, fail2ban, web, web-error, postfix, dovecot, exim, ftp, named, panel, modsec, csf, imunify360, scan.Pflicht für eine neue Regel.
eventDie Event-Quelle, unter der die Treffer zählen, also der Name, auf den sich ein Eintrag unter thresholds in der config.yaml bezieht, und der Name im Kommentar einer Meldung. Voreinstellung ist die ID.Derselbe Zeichensatz wie eine ID. Regeln mit derselben Event-Quelle teilen sich deren Schwellwert, und ein Treffer zählt einmal, egal welche von ihnen ihn gefangen hat. Eine eigene Regel kann die Event-Quelle einer mitgelieferten Regel nicht übernehmen: überschreiben Sie stattdessen diese Regel über ihre ID.
enabledtrue oder false; ein fehlender Schlüssel heißt true.enabled: false in einer Überschreibung schaltet eine mitgelieferte Regel ab, ohne ihre Datei anzufassen.
match.regexDas Muster, das entscheidet, ob eine Zeile ein Treffer ist, und sonst nichts. RE2-Syntax, so wie Go sie liest.Höchstens 512 Bytes. Keine Flags wie (?i), (?s) oder (?m), keine benannten Gruppen: die Adresse kommt nicht aus dem Muster.
match.anchorsWörtliche Zeichenfolgen, die jeder Treffer enthält. Das Muster läuft nur auf einer Zeile, die eine davon enthält; jede andere Zeile erreicht es nie.Pflicht. Jeder Anker mindestens 6 Bytes und wörtlich Teil von regex oder reset. Ist reset gesetzt, muss mindestens ein Anker darin vorkommen, sonst greift der Reset nie.
match.ignoreMuster, die eine Zeile verwerfen, bevor regex sie sieht.RE2, dieselben Grenzen wie regex.
match.resetDas Muster einer Zeile, die den Zähler einer Adresse löscht, ein erfolgreicher Login.RE2, dieselben Grenzen. Die Adresse wird genauso gelesen wie bei einem Treffer.
match.builtinStatt eines Musters der Name eines kompilierten Detektors. Die mitgelieferten Regeln für web, web-app, web-error, modsec, exim, panel, named, fail2ban, csf und imunify360 sind von dieser Art und tragen nur die Policy.Nicht zusammen mit regex, und ohne anchors, ignore, reset, addr oder examples.
addrWo in einer passenden Zeile die Adresse steht. Genau eine Form: after mit occurrence: last oder first; between: [left, right]; in_brackets: N, das N-te [...], gezählt ab 1; before_byte: ":", ein Byte; field: N, das N-te durch Leerraum getrennte Feld, gezählt ab 0. Ein optionales upto: "<" schneidet die Zeile am ersten Vorkommen dieser Marke ab, bevor die Form angewendet wird, ein Feld, das die Gegenseite dahinter schreibt, ist damit unerreichbar.Pflicht für eine Regex-Regel. after braucht mindestens 3 Bytes und eine occurrence; upto hat höchstens 16 Bytes.
categoriesDie IDs der Threat Categories, die eine Meldung trägt. Es gibt 63, nummeriert von 1 bis 63.Pflicht, wenn die Regel meldet. Jede mindestens 1.
nounWie ein Treffer im Kommentar einer Meldung heißt, etwa failed logins.Buchstaben, Ziffern und Leerzeichen, höchstens 40.
thresholdhits innerhalb von window_minutes, das Paar, das ein fail2ban-Jail maxretry und findtime nannte.hits 1 bis 10000, window_minutes 1 bis 1440. Ohne den Block gelten min_hits und window_minutes aus der config.yaml. Ein Eintrag unter thresholds in der config.yaml gewinnt über beides.
actionban und report, jeweils true oder false; beide sind true, wenn sie fehlen.Beide false wird abgewiesen: eine Regel, die nichts tut, wird stattdessen mit enabled: false abgeschaltet.
examplesDie Tests der Regel. match: Zeilen und die Adresse, die jede liefert. inject: Zeilen mit einer zweiten, untergeschobenen Adresse in einem Feld, das die Gegenseite schreibt, und die Adresse, die die Regel trotzdem liefern muss. nomatch: Zeilen, die die Regel nicht treffen darf.Pflicht für eine Regex-Regel, mindestens eine je Art, und mindestens eine nomatch-Zeile muss eine Adresse enthalten. Sie laufen bei jedem Laden der Regel; eine Regel, deren Beispiele nicht aufgehen, lädt nicht.

Warum die Adresse keine Capture-Gruppe ist

fail2ban hatte das zweimal, CVE-2013-2178 und CVE-2009-0362, und beide Male war es derselbe Fehler: die Adresse kam aus dem Muster, und ein Angreifer hatte eine Adresse seiner Wahl in ein Feld geschrieben, das das Muster erreichte. RE2 findet den am weitesten links stehenden Treffer, in Invalid user x from 8.8.8.8 port 22 from 45.33.32.156 port 51422 würde eine Gruppe hinter dem ersten from also 8.8.8.8 sperren, und das ist der Benutzername, den der Angreifer getippt hat. addr: {after: " from ", occurrence: last} nimmt das letzte, das, das sshd selbst geschrieben hat. Darum nennt eine Regel eine Position statt einer Gruppe, und darum trägt jede Regel eine inject-Zeile, die das beweist.

Was Sie vor Ihrer eigenen Regel schützt

Die Beispiele laufen bei jedem Laden der Regel, ein Muster, das seine eigenen Zeilen nicht mehr trifft, lädt also nicht. Eine Musterregel, die Ihre Ebene hinzufügt oder überschreibt, sperrt in den ersten 24 Stunden ihres Inhalts und meldet nicht (eine Regel mit match.builtin nie): ein falscher Kernel-Eintrag läuft ab und steht in ban list, eine falsche Meldung lässt sich nicht zurücknehmen. rules status markiert so eine Regel als young. Ein Neustart des Daemons beginnt den Tag von vorn.

Zwei Wächter beobachten eine Regel im Betrieb. Erreichen drei Adressen aus Ihrer Whitelist innerhalb von zehn Minuten ihren Schwellwert, liest die Regel das falsche Feld, denn echte Angreifer stehen nie auf der Whitelist; sie meldet dann nicht mehr, bis ihre Datei sich ändert, sperrt aber weiter, und davor schützt die Whitelist. Schiebt eine junge Regel innerhalb einer Minute mehr als 50 verschiedene Adressen über ihren Schwellwert, trifft sie jeden Besucher und wird ganz ausgesetzt, Sperren und Meldungen, bis ihr Inhalt sich ändert. Eine etablierte Regel wird für einen Ansturm nie ausgesetzt: ein verteilter Brute-Force-Angriff mit Hunderten Quellen pro Minute ist genau das, wofür eine sshd-Regel da ist. Eine Regel aus dem Paket beobachtet der Ansturm-Wächter wie eine junge, weil ein Paket alle Hosts auf einmal erreicht.

Ein Eintrag unter thresholds in der config.yaml gewinnt weiter über die Datei, ein Host, den Sie eingestellt haben, verliert also nichts. Eine Datei, die kein gültiges YAML ist oder ein neueres Format nennt, wird allein übersprungen, die anderen laden. Eine Regel, die an einer der Prüfungen oben scheitert, kostet Ihre ganze Ebene: die mitgelieferten Regeln und das Paket laufen weiter, status und doctor sagen es, und rules check nennt Datei, Zeile und ID.

Die rules-Befehle

bash
reportedip-agent rules list                 # every rule: id, source, event, kind, state, threshold, action
reportedip-agent rules show sshd            # one rule as merged, and whether it is overridden
reportedip-agent rules check                # load rules.d the way the daemon does, and say what is wrong
reportedip-agent rules check /root/my.yaml  # try a file before it is put in place
reportedip-agent rules export sshd          # print the shipped file of a rule, as the template
reportedip-agent rules status               # state, hits since the daemon started, young and suspended rules
reportedip-agent rules disable sshd         # write enabled: false for one id; enable takes it back
reportedip-agent test --rule my-sshd /var/log/auth.log   # run one rule alone over a real log

list, show, check, export und status lesen und geben aus. check ohne Datei lädt Ihr Verzeichnis genau so, wie der Daemon es täte; mit Dateien lädt es stattdessen diese über den mitgelieferten Regelsatz, eine Datei lässt sich also prüfen, bevor sie in rules.d liegt. export gibt die mitgelieferte Datei aus, in der eine Regel steht, mit Kommentaren, als Ausgangspunkt einer Überschreibung. enable und disable sind die beiden, die schreiben: eine einzige generierte Datei, 90-agent-toggles.yaml, nur für root zugänglich, bei jedem Aufruf neu geschrieben. test --rule lässt nur diese eine Regel laufen und keinen kompilierten Detektor daneben, nimmt den Quelltyp aus der Regel und meldet und sperrt nichts, wie test immer.

Eine eigene Regel anlegen

  1. Mit einer mitgelieferten Datei anfangen. reportedip-agent rules export sshd > /root/60-sshd.yaml gibt die Datei aus, in der die Regel steht, mit Kommentaren und Beispielen.
  2. Kürzen, oder eine neue ID vergeben. Für eine Überschreibung bleiben die id und nur die Felder, die sich ändern; die Datei unten ist vollständig. Für eine eigene Regel vergeben Sie eine neue id mit source, match, addr, categories und examples, wie my-sshd oben. Eine neue ID ist eine neue Event-Quelle, die mitgelieferte Regel läuft daneben weiter.
  3. Prüfen. reportedip-agent rules check /root/60-sshd.yaml lädt die Datei über den mitgelieferten Regelsatz genau so, wie der Daemon es täte, und gibt jedes Problem mit Datei, Zeile und ID aus, oder eine Zeile, die ok sagt.
  4. Ablegen. install -m 644 -o root -g root /root/60-sshd.yaml /etc/reportedip-agent/rules.d/. Das Verzeichnis und jede Datei darin müssen root gehören und für niemanden sonst beschreibbar sein, und ein Symlink, der aus dem Verzeichnis hinauszeigt, wird abgewiesen; sonst wird die ganze Ebene nicht benutzt.
  5. Eine Minute warten. Der Daemon übernimmt die Änderung von selbst, ohne Neustart, und die Zähler beginnen von vorn. reportedip-agent rules status zeigt die Regel, am ersten Tag als young markiert. reportedip-agent test --rule my-sshd /var/log/auth.log zeigt derweil, was sie gefangen hätte.
yaml
# /etc/reportedip-agent/rules.d/60-sshd.yaml: the shipped sshd rule,
# stricter on this host. Everything not named here stays as shipped.
format: 1
rules:
  - id: sshd
    threshold: {hits: 3, window_minutes: 10}

Zuletzt aktualisiert: · Betreut vom ReportedIP-Team

Security Focused
DSGVO-konform
Made in Germany
Zurück zur Doku