Suricata IPS: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(36 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
=Grundlagen und Installation=
 
=Grundlagen und Installation=
*[[Suricata Grundlagen]]
+
Wir installieren Suricata auf der Firewall
*[[Suricata Installation]]
 
  
=Versuchsaufbau=
+
=Installation=
{{#drawio:ips-netz}}
+
*sudo apt update
 +
*sudo apt -y install suricata
 +
*systemctl stop suricata
 +
*suricata -V
 +
This is Suricata version 6.0.1 RELEASE
 +
 
 +
<!--
 +
=Update Rules=
 +
 
 +
* suricata-update
 +
-->
 +
 
 +
 
 +
*[[Chrome Dev Tools]]
  
 
=IPS=
 
=IPS=
*Wir können mit iptables Pakete abfangen und einer QUEUE übergeben
+
*Wir können mit nf/iptables Pakete abfangen und einer QUEUE übergeben
 
*Diese QUEUE wird von suricata gelesen und ihrem REGELWERK übergeben.
 
*Diese QUEUE wird von suricata gelesen und ihrem REGELWERK übergeben.
 
*Wenn das Paket mit einer Regel übereinstimmt, wird eine Aktion ausgelöst.
 
*Wenn das Paket mit einer Regel übereinstimmt, wird eine Aktion ausgelöst.
Zeile 23: Zeile 35:
 
vars:
 
vars:
 
   address-groups:
 
   address-groups:
     LAN: "[172.17.113.0/24]"
+
     LAN: "[172.26.2XX.0/24]"
     DMZ: "[10.88.113.0/24]"
+
     DMZ: "[10.88.2XX.0/24]"
     SERVER: "[172.16.113.0/24]"
+
     SERVER: "[10.2XX.1.0/24]"
 
     INT: "[$LAN,$DMZ,$SERVER]"
 
     INT: "[$LAN,$DMZ,$SERVER]"
 
     HOME_NET: "$INT"
 
     HOME_NET: "$INT"
 
     EXTERNAL_NET: "!$INT"
 
     EXTERNAL_NET: "!$INT"
  
#Suricate nimmt die Pakete von Iptables wieder auf
+
#Suricate nimmt die Pakete von NF/IPtables wieder auf
 
nfq:
 
nfq:
 
   mode: repeat
 
   mode: repeat
Zeile 61: Zeile 73:
 
       totals: yes
 
       totals: yes
 
       threads: no
 
       threads: no
 +
  - eve-log:
 +
      enabled: yes
 +
      filetype: regular
 +
      filename: eve.json
 +
      types:
 +
        - alert
 +
        - drop
 +
        - http
 +
        - dns
 +
        - tls
 +
        - flow
 +
        - ssh
 +
        - stats
 +
  
 
# Logging-Einstellungen
 
# Logging-Einstellungen
Zeile 114: Zeile 140:
 
classification-file: /etc/suricata/classification.config
 
classification-file: /etc/suricata/classification.config
  
# Referenzkonfigurationsdatei
 
reference-config-file: /etc/suricata/reference.config
 
  
  
Zeile 172: Zeile 196:
 
                                          
 
                                          
 
</pre>
 
</pre>
 +
*[[suricata.yaml Erklärung]]
  
 
= Local Rules =
 
= Local Rules =
  
 
*cat /etc/suricata/rules/local.rules
 
*cat /etc/suricata/rules/local.rules
<pre>
+
 
alert icmp any any -> any any (msg:"ICMP Test"; flow:to_server; sid:1;)
+
{{suricata-rules}}
drop http any any -> any any (msg: "SQL Injection Attempt!"; flow:established,to_server; http.request_body; content: "OR 1=1"; sid:2;)
+
 
drop dns any any -> any any (msg:"Kein Googlen"; dns.query; content:"google"; nocase; sid:3;)
+
=Beschreibung=
drop http any any -> any any (msg: "Possible SQL Injection attack (Contains singlequote POST DATA)"; flow:established,to_server; content:"%27"; nocase; http_client_body; sid:4;)
+
{{suricata-rules-beschreibung}}
drop http any any -> any any (msg: "Possible Command Injection attack (Contains semicolon POST DATA)"; flow:established,to_server; content:"%3B"; nocase; http_client_body; sid:5;)
 
</pre>
 
  
 
= Firewallanpassung =
 
= Firewallanpassung =
Zeile 188: Zeile 211:
 
= NFQUEUE Repeat =
 
= NFQUEUE Repeat =
  
* Damit Suricata die nicht gedroppten Pakete automatisch akzeptiert, sondern dies der Firewall überlässt, kann es diese Pakete markieren und zurück zu iptables schicken
+
* Damit Suricata die nicht gedroppten Pakete automatisch akzeptiert, sondern dies der Firewall überlässt, kann es diese Pakete markieren und zurück zu nftables schicken
 
* Markierungen folgen der Syntax $''MARK''/$'''MASK'''
 
* Markierungen folgen der Syntax $''MARK''/$'''MASK'''
  
 +
<!---
 
== iptables Version ==
 
== iptables Version ==
 
* '''vim /usr/local/sbin/firewall'''
 
* '''vim /usr/local/sbin/firewall'''
Zeile 199: Zeile 223:
 
  iptables -A FORWARD -j LOG --log-prefix "iptables return from Suricata: "
 
  iptables -A FORWARD -j LOG --log-prefix "iptables return from Suricata: "
 
  # Hier geht es mit den normalen Regeln weiter
 
  # Hier geht es mit den normalen Regeln weiter
 +
--->
  
 
== nftables Version ==
 
== nftables Version ==
 
* '''vim /etc/nftables.conf'''
 
* '''vim /etc/nftables.conf'''
  
<syntaxhighlight lang="nftables">
+
table inet filter {
table inet filter {
+
  chain forward {
  chain forward {
+
    type filter hook forward priority 0; policy drop;
    type filter hook forward priority 0; policy drop;
+
    '''# An Suricata übergeben, wenn Mark-Bit 0 nicht gesetzt'''
    # An Suricata übergeben, wenn Mark-Bit 0 nicht gesetzt
+
    '''meta mark and 1 != 1 queue'''
    meta mark and 1 != 1 queue
+
    '''# Logging und Akzeptanz nach Rückgabe durch Suricata (mit gesetztem Mark)'''
    # Logging und Akzeptanz nach Rückgabe durch Suricata (mit gesetztem Mark)
+
    l'''og prefix "nftables return from Suricata: "'''
    log prefix "nftables return from Suricata: "
+
    ct state established,related accept
    ct state established,related accept
+
    # Hier geht es mit den normalen Regeln weiter
    # Hier geht es mit den normalen Regeln weiter
+
  }
  }
+
}
}
+
;Firewall neu starten
</syntaxhighlight>
+
*nft -f /etc/nftables.conf
  
== Suricata Anpassung ==
 
...
 
nfq:
 
  mode: repeat
 
  repeat-mark: ''1''
 
  repeat-mask: '''1'''
 
...
 
 
==Start suricata==
 
==Start suricata==
  
Zeile 237: Zeile 255:
  
 
= Suricata als IPS mit systemd starten =
 
= Suricata als IPS mit systemd starten =
Die Standard-Installation von Suricata unter Debian startet im IDS-Modus.
+
*[[Suricata als IPS mit systemd starten]]
 
+
=EveBox=
Für den Betrieb im IPS-Modus über NFQUEUE ist eine eigene systemd-Service-Datei erforderlich.
+
*[[EveBox]]
 
+
=Tests=
;Bestehende Service-Datei kopieren:
+
==ping==
*cp /lib/systemd/system/suricata.service /etc/systemd/system/suricata-ips.service
+
*ping -c 1 1.1.1.1
* vim /etc/systemd/system/suricata-ips.service
+
==DNS Policy==
<pre>
+
*host google.de
[Unit]
+
==Command Injection==
Description=Suricata IDS/IDP daemon
+
*curl -X POST http://www.it2XX.int/host.php --data-urlencode "fqdn=example.com;ls" -d "submit=Auflösen"
After=network.target network-online.target
+
==SQL Injection==
Requires=network-online.target
+
*curl -X POST http://www.it2XX.int/sql-classic.php --data-urlencode "username=' OR '1'='1' --"
Documentation=man:suricata(8) man:suricatasc(8)
+
==Brute Force SSH==
Documentation=https://suricata-ids.org/docs/
+
*apt install hydra
 +
*wget https://xinux.de/downloads/bad-passwords
 +
*hydra -l christine -P bad-passwords ssh://www.it2XX.int
  
[Service]
+
==SSH Connection Attempt==
Type=forking
+
*ssh kit@10.88.2XX.21
PIDFile=/run/suricata.pid
 
ExecStart=/usr/bin/suricata -D -q 0 -c /etc/suricata/suricata.yaml --pidfile /run/suricata.pid
 
ExecReload=/usr/bin/suricatasc -c reload-rules ; /bin/kill -HUP $MAINPID
 
ExecStop=/usr/bin/suricatasc -c shutdown
 
Restart=on-failure
 
ProtectSystem=full
 
ProtectHome=true
 
  
[Install]
+
==HTTP User-Agent Erkennung==
WantedBy=multi-user.target
+
*sqlmap -u "http://www.it2XX.int/sql-classic.php" --data "username=test"
</pre>
+
*curl http://www.it2XX.int/host.php
;systemd-Konfiguration neu laden:
+
==ICMP Tunnel Erkennung==
* systemctl daemon-reexec
+
*ping -c 5 -s 500 10.88.2XX.21
* systemctl daemon-reload
+
==DoS==
;neuen IPS-Dienst aktivieren und starten:
+
*ab -n 1000 -c 500 http://www.it2XX.int/
* systemctl enable --now suricata-ips.service
+
*hping3 -S --flood -V -p 80 10.88.2XX.21
;optional: IDS-Dienst deaktivieren:
+
==Nmap Scans==
* systemctl disable suricata.service
+
;SYN-Sweep
;Status oder Logausgabe prüfen:
+
*nmap -sS -p1-100 10.88.2XX.21
* journalctl -u suricata-ips.service -f
+
;UDP-Sweep
 +
*nmap -sU --min-rate=1000 10.88.2XX.21
 +
;Ping-Sweep
 +
*nmap -sn 10.88.2XX.0/24
 +
;NULL-Scan
 +
*nmap -sN -p1-100 10.88.2XX.21
  
 
= Links =
 
= Links =

Aktuelle Version vom 12. Mai 2026, 13:09 Uhr

Grundlagen und Installation

Wir installieren Suricata auf der Firewall

Installation

  • sudo apt update
  • sudo apt -y install suricata
  • systemctl stop suricata
  • suricata -V
This is Suricata version 6.0.1 RELEASE


IPS

  • Wir können mit nf/iptables Pakete abfangen und einer QUEUE übergeben
  • Diese QUEUE wird von suricata gelesen und ihrem REGELWERK übergeben.
  • Wenn das Paket mit einer Regel übereinstimmt, wird eine Aktion ausgelöst.
  • Alert führt zu einer Meldung
  • Bei Drop wird das Paket verworfen.

Konfiguration Suricata

  • vim /etc/suricata/suricata.yaml
%YAML 1.1
---
# Variablen für die Adressgruppen festlegen
vars:
  address-groups:
    LAN: "[172.26.2XX.0/24]"
    DMZ: "[10.88.2XX.0/24]"
    SERVER: "[10.2XX.1.0/24]"
    INT: "[$LAN,$DMZ,$SERVER]"
    HOME_NET: "$INT"
    EXTERNAL_NET: "!$INT"

#Suricate nimmt die Pakete von NF/IPtables wieder auf
nfq:
  mode: repeat
  repeat-mark: 1
  repeat-mask: 1


# Standard-Log-Verzeichnis
default-log-dir: /var/log/suricata/

# Statistiken aktivieren
stats:
  enabled: yes
  interval: 8

# Ausgaben konfigurieren
outputs:
  - fast:
      enabled: yes
      filename: fast.log
      append: yes
  - alert-debug:
      enabled: yes
      filename: alert-debug.log
      append: yes
  - stats:
      enabled: yes
      filename: stats.log
      append: yes
      totals: yes
      threads: no
  - eve-log:
      enabled: yes
      filetype: regular
      filename: eve.json
      types:
        - alert
        - drop
        - http
        - dns
        - tls
        - flow
        - ssh
        - stats


# Logging-Einstellungen
logging:
  default-log-level: notice
  outputs:
  - console:
      enabled: yes
  - file:
      enabled: yes
      level: info
      filename: suricata.log



# PID-Datei
pid-file: /var/run/suricata.pid

# Coredump-Einstellungen
coredump:
  max-dump: unlimited

# Host-Modus
host-mode: auto

# Unix-Befehlseingabe konfigurieren
unix-command:
  enabled: yes
  filename: /var/run/suricata-command.socket

# Engine-Analyse-Einstellungen
engine-analysis:
  rules-fast-pattern: yes
  rules: yes

# Defragmentierungseinstellungen
defrag:
  memcap: 32mb
  hash-size: 65536
  trackers: 65535
  max-frags: 65535
  prealloc: yes
  timeout: 60

# Standardregelverzeichnis
default-rule-path: /etc/suricata/rules

# Regel-Dateien
rule-files:
  - local.rules

# Klassifikationsdatei
classification-file: /etc/suricata/classification.config



# Referenzkonfigurationsdatei
reference-config-file: /etc/suricata/reference.config
app-layer:
  protocols:
    http:
      enabled: yes
    tls:
      enabled: yes
    dcerpc:
      enabled: yes
    smb:
      enabled: yes
    ftp:
      enabled: yes
    ssh:
      enabled: yes
    smtp:
      enabled: yes
    dns:
      enabled: yes
    modbus:
      enabled: yes
    enip:
      enabled: yes
    dnp3:
      enabled: yes
    nfs:
      enabled: yes
    ntp:
      enabled: yes
    tftp:
      enabled: yes
    ikev2:
      enabled: yes
    krb5:
      enabled: yes
    dhcp:
      enabled: yes
    snmp:
      enabled: yes
    sip:
      enabled: yes
    rfb:
      enabled: yes
    mqtt:
      enabled: yes
    rdp:
      enabled: yes
    http2:
      enabled: yes
    imap:
      enabled: yes
                                        

Local Rules

  • cat /etc/suricata/rules/local.rules
# ICMP: einfacher Ping/Traceroute (schneller Funktionstest)
# Test: ping -c 1 1.1.1.1
alert icmp any any -> any any (msg:"ICMP Test"; classtype:misc-activity; sid:9000041;)

# HTTP: mögliches Command-Injection-Merkmal (Semikolon) in POST-Body
# Test: curl -X POST http://www.it2XX.int/host.php --data-urlencode "fqdn=example.com;ls" -d "submit=Auflösen"
alert http any any -> any any (msg:"Command Injection - Semicolon in POST DATA"; classtype:web-application-attack; flow:established; content:"%3B"; nocase; http_client_body; sid:9000002;)

# HTTP: mögliches SQLi-Merkmal (einfaches Hochkomma) in POST-Body
# Test: curl -X POST http://www.it2XX.int/sql-classic.php --data-urlencode "username=' OR '1'='1' --"
alert http any any -> any any (msg:"Possible SQL Injection (singlequote in POST)"; classtype:web-application-attack; flow:established,to_server; content:"%27"; nocase; http_client_body; sid:9000003;)

# DNS: Policy - verbietet "google" in DNS-Queries
# Test: host google.de
drop dns any any -> any any (msg:"Kein Googlen"; dns.query; content:"google"; nocase; classtype:policy-violation; sid:9000043;)

# DoS: viele identische kurze HTTP-GETs (LOIC-ähnlich)
# Test: ab -n 1000 -c 500 http://www.it2XX.int/
drop tcp any any -> any any (msg:"ET DOS Terse HTTP GET Likely LOIC"; flow:to_server,established; dsize:18; content:"GET / HTTP/1.1|0d 0a 0d 0a|"; depth:18; threshold:type both,track by_dst,count 500,seconds 60; classtype:own-dos; sid:9000054; rev:2;)

# Scan: TCP SYN-Sweep (viele SYN in kurzer Zeit)
# Test: nmap -sS -p1-100 10.88.2XX.21
drop tcp any any -> any any (msg:"OWN SCAN TCP SYN sweep"; flow:stateless,to_server; flags:S; detection_filter:track by_src,count 20,seconds 5; classtype:attempted-recon; sid:9000060; rev:1;)

# Scan: TCP NULL-Scan (keine Flags gesetzt)
# Test: nmap -sN -p1-100 10.88.2XX.21
drop tcp any any -> any any (msg:"OWN SCAN TCP NULL scan"; flow:stateless,to_server; flags:0; detection_filter:track by_src,count 5,seconds 10; classtype:attempted-recon; sid:9000061; rev:1;)

# Scan: UDP-Sweep mit leerer Payload
# Test: nmap -sU --min-rate=1000 10.88.2XX.21
drop udp any any -> any any (msg:"OWN SCAN UDP sweep (empty probes)"; flow:to_server; dsize:0; detection_filter:track by_src,count 15,seconds 10; classtype:attempted-recon; sid:9000064; rev:1;)

# Scan: ICMP Ping-Sweep (viele Echo-Requests)
# Test: nmap -sn 10.88.2XX.0/24
drop icmp any any -> any any (msg:"OWN SCAN ICMP ping sweep"; itype:8; detection_filter:track by_src,count 10,seconds 5; classtype:attempted-recon; sid:9000065; rev:1;)

# Brute Force SSH
# Test: hydra -l kit -P bad-passwords ssh://10.88.2XX.21
drop tcp any any -> any 22 (msg:"OWN SSH Brute Force"; flow:to_server,stateless; flags:S; detection_filter:track by_src,count 10,seconds 60; classtype:attempted-recon; sid:9000066; rev:1;)

# HTTP: sqlmap User-Agent erkennen
# Test: sqlmap -u "http://www.it2XX.int/sql-classic.php" --data "username=test"
alert http any any -> any any (msg:"SQLmap Scanner detected"; http.user_agent; content:"sqlmap"; nocase; classtype:web-application-attack; sid:9000070; rev:1;)

# HTTP: curl User-Agent erkennen
# Test: curl http://www.it2XX.int/host.php
alert http any any -> any any (msg:"curl User-Agent detected"; http.user_agent; content:"curl"; nocase; classtype:policy-violation; sid:9000071; rev:1;)

# ICMP Tunnel - großes Payload
# Test: ping -c 5 -s 500 10.88.2XX.21
alert icmp any any -> any any (msg:"OWN ICMP Large Payload - possible tunnel"; itype:8; dsize:>200; classtype:misc-attack; sid:9000072; rev:1;)

# TCP SYN Flood
# Test: hping3 -S --flood -V -p 80 10.88.2XX.21
alert tcp any any -> any any (msg:"TCP SYN Flood Potential Detected"; flags:S; threshold: type both, track by_dst, count 150, seconds 10; classtype:misc-attack; sid:9000073; rev:1;)

# SSH Connection Attempt
# Test: ssh root@10.88.2XX.21
alert tcp any any -> any 22 (msg:"SSH Connection Attempt"; content:"SSH"; nocase; classtype:misc-activity; sid:9000074; rev:1;)

Beschreibung

Schlüsselwort Beschreibung
alert / drop Aktion bei Regelübereinstimmung. alert erzeugt einen Logeintrag, drop verwirft das Paket zusätzlich.
icmp / tcp / udp / http / dns Protokoll das überwacht wird.
any Platzhalter für beliebige IP-Adresse oder Port.
-> Richtung des Datenverkehrs (Quelle → Ziel).
msg:"..." Beschreibung die im Alert-Log erscheint.
classtype:... Kategorie des Angriffs (z.B. web-application-attack, attempted-recon, policy-violation).
sid:... Eindeutige Signatur-ID der Regel. Eigene Regeln beginnen ab 9000000.
flow:... Verbindungsstatus (z.B. established, to_server, stateless).
content:"..." Zeichenkette nach der im Paketinhalt gesucht wird.
nocase Groß-/Kleinschreibung wird beim content-Vergleich ignoriert.
http_client_body Sucht den content nur im HTTP-Request-Body.
http.user_agent Sucht den content im HTTP User-Agent Header.
dns.query Sucht den content im DNS-Query-Namen.
flags:... TCP-Flags (z.B. S=SYN, F=FIN, FPU=XMAS).
itype:... ICMP-Typ (z.B. 8 = Echo Request).
dsize:... Größe der Nutzdaten in Bytes.
detection_filter:... Schwellenwert für Häufigkeit bevor die Regel auslöst.
threshold:... Begrenzung wie oft ein Alert pro Zeitraum ausgelöst wird.
rev:... Revisionsnummer der Regel.

Firewallanpassung

NFQUEUE Repeat

  • Damit Suricata die nicht gedroppten Pakete automatisch akzeptiert, sondern dies der Firewall überlässt, kann es diese Pakete markieren und zurück zu nftables schicken
  • Markierungen folgen der Syntax $MARK/$MASK


nftables Version

  • vim /etc/nftables.conf
table inet filter {
  chain forward {
    type filter hook forward priority 0; policy drop;
    # An Suricata übergeben, wenn Mark-Bit 0 nicht gesetzt
    meta mark and 1 != 1 queue
    # Logging und Akzeptanz nach Rückgabe durch Suricata (mit gesetztem Mark)
    log prefix "nftables return from Suricata: "
    ct state established,related accept
    # Hier geht es mit den normalen Regeln weiter
  }
}
Firewall neu starten
  • nft -f /etc/nftables.conf

Start suricata

  • suricata -D -q 0
  • Den Unterschied zwischen repeat und accept kann man mit Ping und SSH testen (falls SSH in der FORWARD Kette blockiert ist)
  • Die Verstöße können folgendermaßen gesehen werden
  • tail -fn0 /var/log/suricata/fast.log

Suricata Fernbedienung

Reload Rules
  • suricatasc -c "reload-rules"
Shutdown
  • suricatasc -c "shutdown"

Suricata als IPS mit systemd starten

EveBox

Tests

ping

  • ping -c 1 1.1.1.1

DNS Policy

  • host google.de

Command Injection

SQL Injection

Brute Force SSH

SSH Connection Attempt

  • ssh kit@10.88.2XX.21

HTTP User-Agent Erkennung

ICMP Tunnel Erkennung

  • ping -c 5 -s 500 10.88.2XX.21

DoS

Nmap Scans

SYN-Sweep
  • nmap -sS -p1-100 10.88.2XX.21
UDP-Sweep
  • nmap -sU --min-rate=1000 10.88.2XX.21
Ping-Sweep
  • nmap -sn 10.88.2XX.0/24
NULL-Scan
  • nmap -sN -p1-100 10.88.2XX.21

Links