Wer mehrere OPNsense-Firewalls betreibt, kennt das Problem: Blocklisten müssen auf jeder Instanz einzeln konfiguriert werden. Alias anlegen, URL eintragen, Floating Rule erstellen, aktivieren — pro Firewall und pro Liste. Bei 5 Blocklisten und 10 Standorten sind das 100 manuelle Konfigurationsschritte. Mit DATAZONE Control und einem Shell-Script erledigt sich das in Sekunden — zentral, konsistent und nachvollziehbar.
Warum IP-Blocklisten?
IP-Blocklisten enthalten Adressen bekannter Angreifer, Botnet-Command-and-Control-Server, Spam-Netzwerke und gekaperte IP-Bereiche. Eine Firewall, die diese Listen als Alias einbindet, blockiert den Datenverkehr zu und von diesen Adressen automatisch — bevor ein Angriff überhaupt beginnen kann.
Die wichtigsten öffentlichen Blocklisten:
| Liste | Inhalt | Aktualisierung |
|---|---|---|
| Spamhaus DROP | Gekaperte Netzbereiche (Hijacked) | Täglich |
| Firehol Level 2 | Angriffe der letzten 48 Stunden | Täglich |
| DShield | Top-Angreifer weltweit | Täglich |
| blocklist.de | Angriffe aus Deutschland | 2× täglich |
| Spamhaus DROPv6 | IPv6-Variante der DROP-Liste | Täglich |
Diese Listen ergänzen sich gegenseitig: Spamhaus fokussiert auf gekaperte Netzblöcke, Firehol aggregiert aktive Angreifer, DShield und blocklist.de liefern tagesaktuelle Angriffs-IPs. Zusammen decken sie ein breites Bedrohungsspektrum ab.
Wichtig: Firehol Level 1 ist bewusst ausgelassen — diese Liste enthält „fullbogons” und private IP-Bereiche (10.0.0.0/8, 172.16.0.0/12), die in internen Netzwerken legitim genutzt werden. Firehol Level 2 ist die sichere Wahl.
Das Problem: Manuelle Konfiguration skaliert nicht
Auf einer einzelnen OPNsense ist die Einrichtung überschaubar:
- Alias anlegen: Firewall → Aliases → URL Table (IPs) → URL der Blockliste eintragen
- Floating Rule erstellen: Firewall → Rules → Floating → Block-Regel mit dem Alias als Source (eingehend) und Destination (ausgehend)
- Aktivieren und Apply
Das dauert etwa 5 Minuten pro Liste. Bei 5 Listen sind es 25 Minuten — pro Firewall. Bei 10 Firewalls summiert sich das auf über 4 Stunden reine Konfigurationsarbeit. Dazu kommt: Jede Änderung (neue Liste hinzufügen, URL aktualisieren, Liste deaktivieren) muss auf jeder Instanz einzeln durchgeführt werden.
Die Lösung: Automatisierung mit DATAZONE Control
DATAZONE Control kann Shell-Scripts auf allen verwalteten OPNsense-Instanzen gleichzeitig ausführen. Der DATAZONE Agent auf jeder Firewall hat Zugriff auf die lokale OPNsense-API — mit API-Credentials, die sicher in der Agent-Konfiguration gespeichert sind.
Wie es funktioniert
┌─────────────────────┐
│ DATAZONE Control │
│ (Zentrale Konsole) │
└──────────┬──────────┘
│ Script ausführen
┌─────┼─────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│OPNsense│ │OPNsense│ │OPNsense│
│Standort│ │Standort│ │Standort│
│ A │ │ B │ │ C │
└────────┘ └────────┘ └────────┘
│ │ │
▼ ▼ ▼
Lokale Lokale Lokale
OPNsense OPNsense OPNsense
API API API
- Das Script wird über DATAZONE Control auf alle OPNsense-Hosts verteilt
- Auf jeder Firewall liest der Agent die lokalen API-Credentials
- Das Script prüft bestehende Aliase und Regeln
- Fehlende Aliase werden erstellt, vorhandene validiert
- Floating Block-Regeln werden für jede Liste angelegt (IN + OUT)
- Am Ende erfolgt eine Validierung: Sind die Listen geladen?
Das Script im Detail
Das folgende Shell-Script führt die komplette Blocklist-Konfiguration durch. Es arbeitet idempotent — es kann beliebig oft ausgeführt werden und erstellt nur fehlende Einträge:
#!/bin/sh
# DATAZONE Control - OPNsense Blocklist Setup
# Arbeitet lokal gegen 127.0.0.1 - keine Parameter nötig.
set -e
PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:${PATH}"
# --- Konfiguration aus Agent-Config lesen ---
AGENT_CONFIG="/usr/local/etc/datazone-agent.json"
# JSON-Wert extrahieren (kein jq nötig auf FreeBSD)
_json_val() {
grep -o "\"${1}\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" "$AGENT_CONFIG" \
| head -1 | sed 's/.*:[[:space:]]*"\(.*\)"/\1/'
}
API_KEY=$(_json_val "opnsense_api_key")
API_SECRET=$(_json_val "opnsense_api_secret")
BASE_URL="https://127.0.0.1"
# --- Blocklisten-Definitionen ---
# Format: NAME|BESCHREIBUNG|URL|REFRESH_TAGE
BLOCKLISTS="
BL_Spamhaus_DROP|Spamhaus DROP|https://www.spamhaus.org/drop/drop.txt|1
BL_Firehol_Level2|Firehol Level2 - Angriffe 48h|https://raw.githubusercontent.com/.../firehol_level2.netset|1
BL_DShield|DShield Top Attackers|https://feeds.dshield.org/block.txt|1
BL_Blocklist_de|blocklist.de Angriffe|https://lists.blocklist.de/lists/all.txt|0.5
BL_Spamhaus_DROPv6|Spamhaus DROPv6|https://www.spamhaus.org/drop/dropv6.txt|1
"
# --- Alias erstellen (URL Table) ---
create_alias() {
local name="$1" description="$2" url="$3" refresh="$4"
curl -s -k -u "${API_KEY}:${API_SECRET}" \
-X POST -H "Content-Type: application/json" \
-d "{\"alias\":{\"enabled\":\"1\",\"name\":\"${name}\",
\"description\":\"${description} [DATAZONE]\",
\"type\":\"urltable\",\"updatefreq\":\"${refresh}\",
\"content\":\"${url}\"}}" \
"${BASE_URL}/api/firewall/alias/addItem"
}
# --- Floating Block-Regel erstellen ---
create_block_rule() {
local alias="$1" desc="$2" direction="$3"
local src="any" dst="any"
[ "$direction" = "in" ] && src="$alias"
[ "$direction" = "out" ] && dst="$alias"
curl -s -k -u "${API_KEY}:${API_SECRET}" \
-X POST -H "Content-Type: application/json" \
-d "{\"rule\":{\"enabled\":\"1\",\"action\":\"block\",
\"quick\":\"1\",\"direction\":\"${direction}\",
\"ipprotocol\":\"inet\",\"protocol\":\"any\",
\"source_net\":\"${src}\",\"destination_net\":\"${dst}\",
\"log\":\"1\",\"description\":\"${desc} (${direction}) [DATAZONE]\"}}" \
"${BASE_URL}/api/firewall/filter/addRule"
}
# --- Hauptprogramm ---
# Phase 1: Aliase prüfen/erstellen
echo "$BLOCKLISTS" | while IFS='|' read -r name desc url refresh; do
[ -z "$name" ] && continue
check_or_update_alias "$name" "$desc" "$url" "$refresh"
done
# Phase 2: Alias-Konfiguration anwenden
curl -s -k -X POST -u "${API_KEY}:${API_SECRET}" \
"${BASE_URL}/api/firewall/alias/reconfigure"
# Phase 3: Floating Rules erstellen (IN + OUT pro Liste)
echo "$BLOCKLISTS" | while IFS='|' read -r name desc url refresh; do
[ -z "$name" ] && continue
create_block_rule "$name" "$desc" "in"
create_block_rule "$name" "$desc" "out"
done
# Phase 4: Firewall-Regeln anwenden
curl -s -k -X POST -u "${API_KEY}:${API_SECRET}" \
"${BASE_URL}/api/firewall/filter/apply"
(Gekürzter Auszug — das vollständige Script enthält zusätzlich Validierung, Update-Logik für bestehende Aliase und detailliertes Logging.)
Ablauf im Detail
Phase 1 — Aliase prüfen: Das Script prüft für jede Blockliste, ob der zugehörige Alias bereits existiert. Falls ja, wird die URL verglichen und bei Abweichung aktualisiert. Deaktivierte Aliase werden automatisch reaktiviert. Falls der Alias fehlt, wird er als URL-Table-Alias angelegt.
Phase 2 — Aliase anwenden: Nach dem Anlegen aller Aliase wird ein Reconfigure ausgelöst. OPNsense lädt daraufhin die URL-Tables und löst die IPs auf.
Phase 3 — Floating Rules: Für jede Blockliste werden zwei Floating Rules erstellt — eine für eingehenden Traffic (Source = Blockliste) und eine für ausgehenden Traffic (Destination = Blockliste). Floating Rules greifen interfaceübergreifend und mit quick als erste Regel.
Phase 4 — Anwenden: Die Firewall-Regeln werden aktiviert. Anschließend validiert das Script, ob die Alias-Tabellen tatsächlich Einträge enthalten.
Warum Floating Rules?
Floating Rules in OPNsense haben einen entscheidenden Vorteil gegenüber Interface-spezifischen Regeln: Sie gelten auf allen Interfaces gleichzeitig. Eine einzelne Floating Rule blockiert den Datenverkehr zu einer Blockliste auf WAN, LAN, DMZ und allen VLANs — ohne dass für jedes Interface eine separate Regel erstellt werden muss.
Die Option quick sorgt dafür, dass die Regel sofort greift, ohne weitere Regeln zu evaluieren. Das ist bei Blocklisten gewollt: Traffic von bekannten Angreifern soll ohne Umwege verworfen werden.
Ergebnis: 5 Listen, alle Firewalls, ein Durchlauf
Nach der Ausführung über DATAZONE Control zeigt jede OPNsense-Instanz:
- 5 URL-Table-Aliase mit automatischem Refresh (täglich bzw. 2× täglich)
- 10 Floating Rules (je 2 pro Liste: IN + OUT)
- Logging aktiv auf allen Block-Regeln für Nachvollziehbarkeit
Die Ausgabe des Scripts auf einer Firewall sieht so aus:
=============================================================================
DATAZONE Control - OPNsense Blocklist Setup
Datum: 2026-03-02 10:15:42
=============================================================================
[OK ] Verbindung zu OPNsense erfolgreich
[INFO ] === Phase 1: Blocklist-Aliase pruefen ===
[FIX ] Alias 'BL_Spamhaus_DROP' erstellt (UUID: a1b2c3d4...)
[OK ] Alias 'BL_Firehol_Level2' existiert und URL ist korrekt
...
[INFO ] === Phase 5: Validierung ===
[OK ] Alias 'BL_Spamhaus_DROP' geladen: 1247 Eintraege
[OK ] Alias 'BL_Firehol_Level2' geladen: 3891 Eintraege
...
[OK ] Blocklist-Setup abgeschlossen - keine Fehler
Vorteile der zentralen Verwaltung
| Aspekt | Manuell | Mit DATAZONE Control |
|---|---|---|
| Zeitaufwand (10 Firewalls) | ~6 Stunden | ~2 Minuten |
| Konsistenz | Fehleranfällig | Garantiert identisch |
| Neue Liste hinzufügen | 10× manuell | 1× Script anpassen, ausrollen |
| Audit/Nachweis | Schwer dokumentierbar | Automatisches Logging |
| Rollback | Manuell pro Instanz | Zentral steuerbar |
Best Practices für Blocklisten
Kein Firehol Level 1: Diese Liste enthält „fullbogons” und RFC-1918-Adressen (10.0.0.0/8, 192.168.0.0/16). In Unternehmensnetzwerken führt das zu Selbstblockade. Level 2 enthält nur verifizierte Angriffs-IPs.
Logging aktivieren: Alle Block-Regeln sollten mit Logging konfiguriert sein. So lässt sich nachvollziehen, wie oft und welche Blocklisten greifen — und ob legitimer Traffic fälschlich geblockt wird.
Refresh-Frequenz beachten: Angriffs-Listen (blocklist.de) ändern sich häufiger als Netblock-Listen (Spamhaus DROP). Das Script konfiguriert die Refresh-Frequenz entsprechend — 0,5 Tage (12 Stunden) für volatile Listen, 1 Tag für stabilere.
Bidirektional blocken: Eingehenden UND ausgehenden Traffic blockieren. Eingehend schützt vor Angriffen von außen. Ausgehend verhindert, dass kompromittierte interne Geräte mit C2-Servern kommunizieren — das ist bei Ransomware-Erkennung entscheidend.
Häufig gestellte Fragen
Verlangsamen Blocklisten die Firewall?
Nein. OPNsense nutzt pf-Tables für URL-Table-Aliase. Diese werden als Hash-Tabelle im Kernel gehalten — der Lookup dauert unabhängig von der Listengröße O(1). Selbst 100.000 Einträge haben keinen messbaren Performance-Einfluss.
Was passiert bei einem False Positive?
Sollte eine legitime IP auf einer Blockliste stehen, kann diese per Whitelist-Alias ausgenommen werden. In der Praxis sind False Positives bei den ausgewählten Listen extrem selten — Spamhaus und abuse.ch haben strenge Aufnahmekriterien.
Funktioniert das Script auch auf älteren OPNsense-Versionen?
Das Script nutzt die OPNsense API, die seit Version 18.1 stabil ist. Alle aktuell unterstützten Versionen (22.x, 23.x, 24.x, 25.x) sind kompatibel.
Kann ich eigene Blocklisten hinzufügen?
Ja. Im Script einfach eine weitere Zeile in der BLOCKLISTS-Variable ergänzen — mit Name, Beschreibung, URL und Refresh-Frequenz. Beim nächsten Ausführen wird der Alias automatisch erstellt.
Sie betreiben mehrere OPNsense-Firewalls und möchten Blocklisten zentral verwalten? Kontaktieren Sie uns — wir richten DATAZONE Control ein und automatisieren Ihre Firewall-Konfiguration.
Mehr zu diesen Themen:
Weitere Artikel
Backup-Strategie für KMU: Proxmox PBS + TrueNAS als zuverlässiges Backup-Konzept
Backup-Strategie für KMU mit Proxmox PBS und TrueNAS: 3-2-1-Regel umsetzen, PBS als primäres Backup-Target, TrueNAS-Replikation als Offsite-Kopie, Retention Policies und automatisierte Restore-Tests.
OPNsense Suricata Custom Rules: Eigene IDS/IPS-Signaturen schreiben und optimieren
Suricata Custom Rules auf OPNsense: Rule-Syntax, eigene Signaturen für interne Services, Performance-Tuning, Suppress-Lists und EVE-JSON-Logging.
Systemd Security: Linux-Services härten und absichern
Systemd Security-Hardening: Unit-Hardening mit ProtectSystem, PrivateTmp, NoNewPrivileges, CapabilityBoundingSet, systemd-analyze security, Sandboxing, Resource Limits und eigene Timer erstellen.