IP-Adressbereich blockieren?

Hallo, ich versuche, ein missbräuchliches /16-Subnetz vorübergehend zu blockieren, das ein Discourse-Forum mit Anfragen überflutet. Ich habe Folgendes versucht…

…aber ich sehe immer noch eine riesige Anzahl neuer Anfragen aus demselben Bereich in /var/discourse/shared/standalone/log/var-log/nginx/access.log.

Da diese in Discourse konfiguriert sind, bin ich ziemlich sicher, dass die IPs von Discourse und nicht von NGINX blockiert werden, sodass sie in den NGINX-Protokollen angezeigt werden. Es ist Discourse, das sie blockiert, nicht nginx. Wenn Sie sie blockieren möchten, damit sie nicht in den NGINX-Protokollen angezeigt werden, könnten Sie sie mit Ihrer Firewall blockieren.

1 „Gefällt mir“

Danke Jay, du hast Recht, dass es immer noch in den Nginx-Protokollen angezeigt würde, wenn es auf Anwendungsebene blockiert würde. Das Blockieren auf Anwendungsebene tut jedoch auch nicht das, was ich erwarten würde. Ich habe versucht, über ein VPN eine Verbindung herzustellen, und dann meine eigene IP-Adresse zur Liste „Screened IPs“ hinzugefügt, aber ich konnte trotzdem im Forum navigieren. Ich denke, es muss „Screened IPs“ und nicht „Blocked IPs“ genannt werden, weil es vielleicht nur verhindert, dass diese IPs ein Konto registrieren?

Ich brauche, dass die Discourse-App den Zugriff auf die angeforderten Seiten für Anfragen von diesen Adressen verweigert und insbesondere, dass sie diese Seiten nicht rendert, da alle diese Anfragen die CPU belasten.

Sieht Discourse, dass Sie von einer der gesperrten IPs kommen, wenn Sie den Benutzerdatensatz von /admin/users aus aufrufen? (Wenn Sie sich hinter einem Proxy wie Cloudflare befinden, sieht Discourse möglicherweise Ihre Proxy-IP und nicht die IP des Benutzers.)

Ja, wenn ich mich mit dem VPN verbinde und dann die letzte IP meines Benutzerkontos in Discourse ansehe, wird die IP angezeigt, die mir mein VPN gegeben hat. Wenn ich jedoch ein Inkognito-Browserfenster öffne und versuche, ein neues Konto zu registrieren, wird dies nicht zugelassen:

Neue Registrierungen sind von Ihrer IP-Adresse nicht erlaubt.

Es scheint also, dass “Screened IPs” nur für die Registrierung gelten und nicht für die vollständige Sperrung des Zugriffs auf die Website.

Und um die Dinge noch komplizierter zu machen, blockiert ufw auf dem Host-Server anscheinend nicht wie erwartet innerhalb von Docker:

1 „Gefällt mir“

Ich bin mir nicht sicher, wo wir das dokumentieren, aber es ist in letzter Zeit ein paar Mal aufgetaucht.

„Screened IPs“ blockiert Registrierungen und Anmeldungen von übereinstimmenden blockierten IPs, aber nicht bestehende Sitzungen.

Ich bin mir nicht sicher, wo (wenn überhaupt) wir das dokumentieren.

3 „Gefällt mir“

Danke für die Bestätigung.

Was wäre also die einfachste Methode, Anfragen von einer IP-Adresse oder einem IP-Adressbereich abzulehnen? Ich habe das hier gefunden, aber es scheint das Gegenteil von dem zu sein, was ich brauche. (Whitelist statt Blacklist) und das Herumfummeln an der Nginx-Konfiguration innerhalb des Containers fühlt sich wie ein totaler Hack an:

Ich denke, das geht mit UFW oder IPTABLES. Das stoppt es, bevor Discourse überhaupt involviert wird. Ich habe immer vage Angst, an Firewalls herumzuspielen, aus Furcht, mich selbst auszusperren, aber wenn man nur Port 443 anvisiert, besteht keine Gefahr.

Digital Ocean hat einige Hinweise: UFW Essentials: Common Firewall Rules and Commands for Linux Security | DigitalOcean. Ich würde einfach nach Beispielen googeln.

Genau meine Befürchtung auch. Aber ich habe es auf dem Host aktiviert und trotzdem blockiert es die problematische IP-Reichweite immer noch nicht. Anscheinend benötigt es eine komplizierte Reihe von Regeln, damit die Deny-Regeln auf die Docker-Container angewendet werden.

Oh. Ja. Das stimmt absolut. Ich habe schließlich den Zugriff von meinen Docker-basierten Webservern auf die Docker-basierte PostgreSQL-Datenbank blockiert (wahrscheinlich nicht eines Ihrer Probleme).

Hier ist eine weitere Idee: Geo Blocking plugin

Danke, ich habe mir das auch angesehen, aber es scheint keine numerischen IP-Bereiche blockieren zu können, nur ganze Länder?

Ich habe es noch nicht kürzlich installiert, aber ich bin ziemlich sicher, dass es das tut

(Hervorhebung hinzugefügt)

Aber dann habe ich das gefunden:

Ich denke also, dass Sie dort jedes gewünschte Netzwerk eingeben können.

1 „Gefällt mir“
/var/discourse/launcher enter app
apt install nano
nano /etc/nginx/conf.d/discourse.conf

Und im server {-Block fügen Sie hinzu:

## 2025-10-27
deny 12.34.0.0/16;

Speichern Sie dann und

nginx -t
service nginx reload

Ich verstehe nicht ganz, warum ich immer noch Treffer von 12.34.x.x im Nginx access.log sehe, aber es scheint zu funktionieren, da die CPU-Auslastung wieder normal ist. Ein unglaublich komplizierter Prozess meiner Meinung nach, aber vorerst gut genug, um die Seite wieder zum Laufen zu bringen.

Ja, aber derzeit werden nur AS-Nummern und keine CIDR-Notation wie 1.2.3.0/24 akzeptiert.

1 „Gefällt mir“

Hat das funktioniert? Ich glaube, du musst machen

sv restart nginx

Aber wenn du keinen Fehler bekommen hast, liege ich falsch.

Nginx sieht diese immer noch? Zeigt es, dass es sie bedient? Siehst du diese in der Rails production.log?

Ah. Vielleicht hätte ich dieser Wikipedia-Seite über AS-Nummern mehr Aufmerksamkeit schenken sollen.

Ich glaube, das sind beides alte Aliase, die jetzt auf systemd-Befehle abgebildet sind, also wäre systemctl restart nginx am korrektesten.
EDIT: Es scheint, dass systemctl nicht innerhalb von Docker funktioniert. Hier sind einige Erklärungen zu den Unterschieden:

Ja, im access.log erscheinen sie immer noch so:

[28/Oct/2025:00:29:27 +0000] \"myforum.com\" 12.34.56.78 \"GET /permalink/12345 HTTP/1.1\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\" \"-\" 403 691 \"-\" - 0.000 \"-\" \"-\" \"-\" \"-\" \"-\" \"-\" \"-\"

Sie scheinen jetzt hauptsächlich Permalinks zu treffen (migriert von einer alten Forenplattform). Gibt es eine Art Hintertür bei Permalinks, die es erlaubt, die deny-Regel zu umgehen? Ich habe die production.log noch nicht überprüft.

Insgesamt würde ich sagen, dass das Fehlen einer grafischen Benutzeroberfläche zur Überprüfung der Zugriffsprotokolle und keine IP-Blockliste auf App-Ebene eine ziemlich signifikante Einschränkung von Discourse darstellt. Es ist ein seltenes Vorkommnis, aber wenn man von einem dieser Bot-/Scraper-/Crawler-Angriffe getroffen wird, möchte man einfach sofort die Quelle identifizieren und mildern, ohne sich mit einer Menge von Konfigurationsdateien und obskuren Befehlen herumschlagen zu müssen, insbesondere nicht auf Ebenen tief in einem Docker-Container mit all der seltsamen Abstraktion, die dort stattfindet. Die sehr alte Forenplattform, von der ich migriert habe, zeigte eine einfache Liste der Benutzer oder IPs mit der höchsten Anzahl von Anfragen in einem einstellbaren Zeitfenster an, und sie konnte sogar nach Benutzern und/oder IPs gefiltert werden, die die meiste CPU-Zeit beanspruchten. Auf diese Weise konnte ich die störende Adresse oder den störenden Bereich schnell identifizieren, und dann gab es eine Point-and-Click-Oberfläche, um sie zu einer Blockliste hinzuzufügen, und es würde Anfragen von diesen IPs mit einem 404 ablehnen.

Wenn Sie eine deny-Regel haben, werden die Dinge trotzdem in Nginx protokolliert. Und es funktioniert korrekt, da dort eine 403 steht, was bedeutet, dass der Client den Zugriff verweigert bekommen hat.

Diese Anfragen werden nicht an Discourse weitergeleitet. Wenn Sie wissen möchten, ob Ihre Blockierung korrekt funktioniert, sollten Sie entweder

  • stattdessen in der Discourse production.log nachsehen
  • in den Nginx-Protokollen nachsehen, aber jeden Eintrag ignorieren, der eine 403 im Feld des HTTP-Antwortcodes hat.
3 „Gefällt mir“

Ist dieses Thema jetzt gelöst? Gibt es einen Beitrag von @rgj oder @pfaffman, den ich als Lösung auswählen kann? Es scheint, dass Sie bei diesem Thema zusammengearbeitet haben!

:handshake:

Hallo, ich würde sagen, dass dieses Problem derzeit nicht mit „normalen“ Methoden lösbar ist. Die Admin-Oberfläche für „Screened IPs“ tut nicht das, was die meisten Benutzer wahrscheinlich erwarten würden, und die Methode, die tatsächlich funktioniert, beinhaltet das Herumfummeln im Docker-Container von Discourse, sodass es meiner Meinung nach eher ein schmutziger Hack als eine Lösung ist. Es wäre toll, wenn dies etwas mehr Aufmerksamkeit bekommen würde: