Realtime-Attack-Map
SURICATA / LIVE FEED

BunkerWeb: Mehr Sicherheit für Web-Dienste

Eine Web Application Firewall blockt bösartigen Traffic direkt an der Haustür.

BunkerWeb: Mehr Sicherheit für Web-Dienste

Die Bereitstellung aller eigenen Webservices im Internet erfordert ein verlässliches Tor zum lokalen Netzwerk. Ein klassischer Reverse Proxy, wie nginx-proxy-manager, leitet den Datenverkehr zwar ordnungsgemäß weiter, bietet aber keinen echten Schutz vor automatisierten Scannern oder gezielten Attacken. Durch den konsequenten Einsatz einer Web Application Firewall (WAF) wie BunkerWeb lassen sich sämtliche exponierten Dienste hinter einem intelligenten Schutzschild bündeln.

Inhaltsverzeichnis

    Szenarien für den Einsatz einer Web Application Firewall

    In einem typischen Homelab oder Unternehmensnetzwerk gibt es zahlreiche Dienste, die oft nur rudimentär gegen Angriffe aus dem Netz gehärtet sind. Eine Firewall auf Basis von BunkerWeb, die unter der Haube Nginx mit ModSecurity und dem OWASP Core Rule Set kombiniert, spielt ihre Stärken in unterschiedlichen Situationen aus.

    BunkerWeb - the open-source Web Application Firewall (WAF)
    Fool attackers and protect your web services with BunkerWeb, the open-source and next-gen Web Application Firewall (WAF).

    Ein WordPress- oder Ghost-Blog steht permanent unter Beschuss. Brute-Force-Attacken auf das Login-Formular oder Versuche, bekannte Plugin-Schwachstellen auszunutzen, gehören zum Grundrauschen im Netz. Eine vorgeschaltete WAF erkennt diese typischen Muster und blockiert die Anfragen, bevor das eigentliche CMS überhaupt etwas davon mitbekommt.

    Wie bereits bei der Einrichtung des Webservers mit offiziellen Zertifikaten beobachtet wurde, prasseln sekündlich Verbindungsversuche auf öffentlich erreichbare IPs ein. BunkerWeb integriert Mechanismen wie DNS-Blocklisten und automatische Bot-Erkennung. Das entlastet die nachgelagerten Systeme erheblich - ähnlich wie ein intelligenter Spamfilter, der Junk-Mails aussortiert, bevor der Posteingang vollläuft.

    Zudem laufen im Hintergrund gelegentlich alte Web-Anwendungen, für die es keine Updates mehr gibt, die aber zwingend benötigt werden. Ein direktes Exponieren ins Internet gleicht hier einem offenen Fenster im Erdgeschoss. Durch die WAF-Schicht werden fehlerhafte Eingaben oder typische Exploits direkt am Eingang abgefangen, was der Applikation einen starken virtuellen Schutzpanzer verleiht.

    Vor dem Wechsel auf BunkerWeb

    Der Umstieg von einem einsteigerfreundlichen System wie dem Nginx Proxy Manager auf eine ausgewachsene WAF bringt einige technische Besonderheiten mit sich. BunkerWeb richtet sich primär an sicherheitsbewusste Administratoren. Die Oberfläche und das Konzept sind sehr funktional, dafür aber weniger poliert als bei reinen Klick-Lösungen.

    Die Migration aller bestehenden Dienste erfordert etwas Handarbeit. Vorhandene Hosts, SSL-Zertifikate, Umleitungen und spezifische Konfigurationen müssen auf das neue System übertragen werden. Bei einer überschaubaren Anzahl an Diensten ist dies ein gut machbares Nachmittagsprojekt. Das Resultat ist ein deutlich sichereres Gesamtsetup. Eine KI kann eine nginx-config in eine Raw-Configuration für BunkerWeb umwandeln:

    Wenn man jedoch einen frischen Dienst anlegt, so ist der Dreh- und Angelpunkt das Anlegen eines Service.

    Falls man den Zugriff einschränken will...

    Damit ist das meiste bereits eingestellt. Die anderen Parameter haben seht gute Voreinstellungen. Dann einfach abspeichern, und schon kümmert sich BunkerWeb um das Beschaffen des Zertifikates für den Server.

    Nach der Inbetriebnahme zeigt sich oft eine etwas steilere Lernkurve. Da BunkerWeb den Datenverkehr tiefgreifend analysiert, greifen die strengen Regeln von ModSecurity. Das führt gerade in der Anfangszeit gelegentlich zu sogenannten False Positives - legitime Anfragen werden dann fälschlicherweise als Angriff gewertet und blockiert. Ein regelmäßiger Blick in die Logdateien der WAF ist unerlässlich, um Ausnahmen zu definieren und die Regeln optimal auf die eigenen Anwendungen abzustimmen.

    Bereits mit den Standardeinstellungen lassen sich auffällige IP-Adressen sofort identifizieren. Das betrifft sowohl bekannte Anfragen aus Blacklisten (DNSBL) als auch Angriffsversuche auf Passwörter oder Benutzerdaten.

    Auch die Performance wird minimal beeinflusst. Die tiefe Inhaltsprüfung der Datenpakete benötigt logischerweise etwas mehr Rechenleistung als die reine Weiterleitung. In einem durchschnittlichen Setup ohne extrem hohe Zugriffsraten ist dieser Overhead in der Praxis jedoch absolut vernachlässigbar.

    BunkerWeb sicher in Docker integrieren

    Der Umbau der Umgebung erfordert den Austausch des bisherigen Proxy-Stacks. Das virtuelle Docker-Netzwerk web bleibt erhalten und dient weiterhin als Brücke zwischen der WAF und den zu schützenden Applikationen. Neu hinzu kommt ein isoliertes Netzwerk für die Kommunikation mit dem Socket-Proxy.

    Die finale Konfiguration sieht wie folgt aus:

    # M. Meister
    # docker-compose.yml für BunkerWeb
    services:
      bunkerweb:
        image: bunkerity/bunkerweb:1.6.14
        container_name: bunkerweb
        ports:
          - "80:8080/tcp"
          - "443:8443/tcp"
          - "443:8443/udp"
        environment:
          API_WHITELIST_IP: "127.0.0.0/8 172.16.0.0/12 10.0.0.0/8 192.168.0.0/16"
          API_TOKEN: "Dein-API-Token"
          DATABASE_URI: "mariadb+pymysql://bunkerweb:Dein-DB-Passwort@bw-db:3306/db"
          TZ: "Europe/Berlin"
        restart: "unless-stopped"
        networks:
          - backend
          - web
    
      bw-scheduler:
        image: bunkerity/bunkerweb-scheduler:1.6.14
        container_name: bw-scheduler
        environment:
          API_WHITELIST_IP: "127.0.0.0/8 172.16.0.0/12 10.0.0.0/8 192.168.0.0/16"
          API_TOKEN: "Dein-API-Token"
          DATABASE_URI: "mariadb+pymysql://bunkerweb:Dein-DB-Passwort@bw-db:3306/db"
          BUNKERWEB_INSTANCES: "bunkerweb"
          SERVER_NAME: ""
          MULTISITE: "yes"
          UI_HOST: "http://bw-ui:7000"
          USE_REDIS: "yes"
          REDIS_HOST: "redis"
          TZ: "Europe/Berlin"
        volumes:
          - ./bw-storage:/data
        restart: "unless-stopped"
        networks:
          - backend
    
      bw-ui:
        image: bunkerity/bunkerweb-ui:1.6.14
        container_name: bw-ui
        ports:
          - "7000:7000"
        environment:
          API_WHITELIST_IP: "127.0.0.0/8 172.16.0.0/12 10.0.0.0/8 192.168.0.0/16"
          API_TOKEN: "Dein-API-Token"
          DATABASE_URI: "mariadb+pymysql://bunkerweb:Dein-DB-Passwort@bw-db:3306/db"
          TOTP_ENCRYPTION_KEYS: "Dein-TOTP-Key"
          PROXY_NUMBERS: "1"
          REDIS_HOST: "redis"
          UI_USE_REDIS: "yes"
          TZ: "Europe/Berlin"
        restart: "unless-stopped"
        volumes:
          - ./bw-logs:/var/log/bunkerweb
          - ./bw-lib:/var/lib/bunkerweb
        networks:
          - backend
    
      bw-db:
        image: mariadb:11
        container_name: bw-db
        command: --max-allowed-packet=67108864
        environment:
          MYSQL_RANDOM_ROOT_PASSWORD: "yes"
          MYSQL_DATABASE: "db"
          MYSQL_USER: "bunkerweb"
          MYSQL_PASSWORD: "Dein-DB-Passwort"
          TZ: "Europe/Berlin"
        volumes:
          - ./bw-data:/var/lib/mysql
        restart: "unless-stopped"
        networks:
          - backend
    
      redis:
        image: redis:8-alpine
        container_name: bw-redis
        command: >
          redis-server
          --maxmemory 256mb
          --maxmemory-policy volatile-lru
          --save 60 1000
          --appendonly yes
        volumes:
          - ./redis-data:/data
        restart: "unless-stopped"
        environment:
          TZ: "Europe/Berlin"
        networks:
          - backend
    
    networks:
      web:
        external: true
      backend:
        driver: bridge

    Gestartet wird der neue Proxy ganz klassisch über die Konsole:

    # M. Meister
    docker compose up -d && docker compose logs -f
    

    Inbetriebnahme

    Für einen initialen Funktionstest kann versucht werden, die neu angebundene Seite (wie oben gezeigt) mit einem typischen Angriffs-String aufzurufen. Das Resultat ist die BunkerWeb Fehlerseite mit einem HTTP 403 Forbidden. Die WAF erkennt die versuchte Datenextraktion sofort und blockiert den Zugriff.

    Auch unzulässige Aufrufe über die reine IP-Adresse werden standardmäßig abgewiesen. So laufen neugierige Port-Scanner effektiv ins Leere, während die eigenen Dienste geschützt bleiben.

    Und so füllt sich die Liste der geblockten IPs schnell:

    Wenn man sich selbst versehentlich auf diese Liste gesetzt hat, kann man hier entscheiden, wie man weiter verfahren will. Von der Aufhebung des Bannes bis zur permanenten Sperrung ist alles möglich. Doch man muss sich zunächst mit den neuen Möglichkeiten vertraut machen. So hatte ich mich beispielsweise für die lokale Administration ausgesperrt und musste eine Möglichkeit finden per ssh meine IP wieder freizugeben:

    docker compose exec bw-scheduler bwcli unban 192.168.314.152   # ;-)

    Logging

    Natürlich kann man die Syslogs an sein SIEM weiterleiten. Aber die meisten Angriffe werden bereits an der Tür abgewimmelt. Was bis zum Server durchkommt, wird durch aktive Reaktionen meiner internen Sicherheitsmechanismen abgearbeitet.

    Usecases mit wazuh
    Logeinträge zu Alarmen korrelieren.
    Wazuh on Steroids: AI-Powered Incident Analysis On-Demand
    Upgrade Wazuh with an AI-powered active response for on-demand, deep-dive incident analysis.

    Fazit

    Der Wechsel von einem einfachen Reverse Proxy zu einer integrierten Web Application Firewall ist der logische nächste Schritt für den Schutz der eigenen Internetdienste. So bleibt das System strukturell sicher und unangreifbarer. Die Initialeinrichtung und das Feintuning der Regeln erfordern Einarbeitungszeit, belohnen den Aufwand aber mit einem autonom arbeitenden System, das Angriffe sehr zuverlässig filtert.