Bad Robots
Wenn du magst, kannst du diesen Artikel ein wenig musikalisch untermalen: https://www.youtube.com/watch?v=EY5AQtEpnn4
Das Thema Scraping Bots, insbesondere von AI Scraping Bots die Daten für die verschiedenen LLMs (Large Language Model) sammeln, ist aktuell immer wieder in den Medien und auch einige andere Anbieter wie ReadTheDocs oder auch CloudFlare haben bereits darüber geschrieben. Natürlich geht das Thema auch an einem Webhoster wie uns nicht vorbei und auch wir sehen das aktuelle Verhalten, sowie die zunehmende Aggressivität dieser Bots, als großes Problem. Deshalb haben wir bereits vor einigen Wochen Gegenmaßnahmen ergriffen, die leider auch vereinzelt negative Auswirkungen auf unsere Nutzer*innen hatten. Damit unsere Überlegungen und Maßnahmen für euch besser nachvollziehbar sind, wollen wir diese heute mit euch teilen.
Angriffe auf unsere Infrastruktur und bei uns gehoste Webseiten sind normal, das muss man bedauerlicherweise so sagen. Sobald etwas im Internet öffentlich erreichbar ist, fangen Bots an, Server und Website auf Schwachstellen zu scannen und diese bei Bedarf automatisiert auszunutzen. Beispiele dafür sind Login Versuche mit SSH oder Botnetze, die anfangen, einzelne WordPress-Installationen oder auch ganze Server bei uns anzugreifen. Diese Anfragen sind dann, im Fall von WordPress, meist an die xmlrpc.php oder die wp_login.php gerichtet und erzeugen dort eine zum Teil enorme Last, die eine ganze Uberspace VM oder auch einen ganzen VM Host (mit mehreren Uberspace VMs) stark beeinträchtigen kann. Das hat dann leider immer auch Auswirkungen auf alle anderen Dienste und Websites auf diesen Systemen, weshalb bei zu hoher Last auch immer unser On-Call Notdienst für euch alarmiert wird.
In den letzten anderthalb Jahren kamen zu diesen üblichen Angriffen aber auch andere Zugriffe dazu, die unsere Systeme immer wieder an ihre Grenze gebracht haben. In diesem zweiten Fall sind es überwiegend Bots großer Firmen und Startups, die Produkte im Bereich KI entwickeln und dafür große Mengen an Daten benötigen, die sie, häufig ohne auf die Rechte der Inhalte zu achten, aus dem gesamten öffentlichen Internet einsammeln. Früher kam gelegentlich mal eine Suchmaschine vorbei und hat die neuesten Inhalte indiziert; das ging auch noch gut. Dabei wurde auch die sogenannte robots.txt Datei beachtet, die vorgibt, welche Inhalte ein Bot in seine Datenbank übernehmen darf. Diese robots.txt Datei ist aber immer nur ein Kompromiss mit guten Bots, die diese beachten und nicht verpflichtend. Viele neuere Bots tun das leider nicht mehr, allen voran der sogenannte claudebot
der Firma Anthropic. Dieser scannt zum Teil mit über 5000 IPs gleichzeitig verschiedenste Seiten auf unseren Uberspaces und bringt diese damit an ihre Grenze. Es gibt aber auch andere Bots die ebenfalls unglaublich viele Anfragen stellen oder auch solche, die sich in Suchfeldern oder ähnlichem verheddern und dann quasi unbegrenzt sinnlos versuchen Inhalte zu scannen.
Bei einem Vorfall am 24. Juni haben wir mal eine Statistik über alle unsere Hosts mit den aktuellen Log-Daten durchgeführt, um zu sehen, wie viele aller Anfragen an alle Websites auf allen Servern von claudebot
oder facebookexternalhit
kommen. Hier die Liste für alle Uberspace VMs mit einem Ergebnis von mehr als 25 % :
arend.uberspace.de: 49 % Bots
antares.uberspace.de: 49 % Bots
euporie.uberspace.de: 46 % Bots
borrelly.uberspace.de: 43 % Bots
atria.uberspace.de: 40 % Bots
atria.uberspace.de: 40 % Bots
crux.uberspace.de: 38 % Bots
skiff.uberspace.de: 34 % Bots
arcturus.uberspace.de: 34 % Bots
fomalhaut.uberspace.de: 33 % Bots
schuster.uberspace.de: 32 % Bots
charon.uberspace.de: 31 % Bots
crommelin.uberspace.de: 31 % Bots
bus.uberspace.de: 30 % Bots
howell.uberspace.de: 30 % Bots
bus.uberspace.de: 30 % Bots
hippocamp.uberspace.de: 29 % Bots
halimede.uberspace.de: 28 % Bots
ciffreo.uberspace.de: 27 % Bots
alkaid.uberspace.de: 26 % Bots
schedar.uberspace.de: 26 % Bots
alkaid.uberspace.de: 26 % Bots
An diesem Tag kamen die meisten dieser Anfragen von facebookexternalhit
. Dabei ist zu sehen, dass zum Teil die Hälfte aller Anfragen, die unsere Server für euch bearbeitet haben, von Bots kommen. Eine wirklich absurde Statistik. Dabei ist der facebookexternalhit
Bot besonders problematisch für uns. Nicht nur, dass dieser sehr, sehr viele Anfragen stellt, Facebook selbst sagt auch, dass dieser nur dazu verwendet wird, eine Link-Vorschau für geteilte Beiträge auf den von Meta betriebenen Plattformen zu generieren. Das passt aber absolut nicht zu dem Verhalten, das wir für diesen Bot in der Vergangenheit beobachtet haben. Es ist natürlich möglich, dass böse Akteure diesen User Agent gewählt haben, um sich zu tarnen; eine Stichprobe hat jedoch immer bestätigt, dass diese Anfragen aus dem Facebook-Netz stammen.
Neben der massiven Verschwendung von Ressourcen durch diese Bots und KI als Gesamtes, hat dieses Problem aber auch Auswirkungen auf uns und damit auch indirekt auf euch. Die Bots brauchen nicht nur Ressourcen wie Traffic, CPU-Leistung und vieles mehr, die uns auch Geld kosten, sondern machen evtl. auch eure Website langsamer und sorgen für Alarmierungen in unserem On-Call die Zeit und Geld (min. 25 € pro Stunde außerhalb der Arbeitszeit für den On-Call Einsatz.) kosten. Alles Zeit und Geld, das wir nicht nutzen können, um Uberspace besser zu machen und das nur um milliardenschwere Konzerne für einen fragwürdigen Nutzen noch reicher zu machen.
Zusammenfassend lässt sich sagen, dass nach unserer Beobachtung rund 30 %-50 % aller Anfragen für kleine Seiten inzwischen von Bots generiert werden. Für große Seiten schwankt diese Zahl sogar zwischen 20 % und 75 %.
In unseren Augen und mit Ignorieren der robots.txt ist damit inzwischen ein Punkt erreicht, an dem dieses Verhalten von Bots nicht mehr akzeptabel ist und unserem Betrieb schadet. Daher haben wir uns bisher dazu entschlossen, die schlimmsten Bots entweder in der Firewall oder mit einem HTTP 403 Forbidden zu blockieren. Das machen wir mit der folgenden Zeile in unserem Nginx, der vor allen Webseiten hängt. Zugriffe von diesen 6 Bots werden also nicht mehr regulär beantwortet.
if ($http_user_agent ~* "claudebot|facebook\.com\/externalhit|semrushbot|mj12bot|bytespider|amazonbot") {
return 403;
}
Leider führt das insbesondere beim User Agent facebookexternalhit
dazu, dass die Website-Verifizierung und der Link-Preview auf Facebook für Websites, die ihr bei uns betreibt, nicht mehr funktionieren. Aktuell überlegen wir noch, wie wir es schaffen können, valide Anfragen von Scanning zu unterscheiden.
Am Ende liegt es aber an Facebook, sich hier ordnungsgemäß zu verhalten und nicht, entgegen ihrer Doku, ein und denselben User Agent für verschiedene Aufgaben zu nutzen.
Bedauerlicherweise ist das Problem damit aber noch immer nicht gelöst, denn es gibt auch noch den Fall von Anbietern, die Anfragen ihrerseits als Facebook tarnen, vermutlich um Paywalls oder andere Filter zu umgehen. So setzt Apple für die Link-Preview in iMessage und an anderer Stelle gerne mal auf den User Agent facebookexternalhit/1.1 Facebot Twitterbot/1.0
wo man sich schon fragt, was das soll. Das umgehen wir, indem wir auf die URL zur Dokumentation filtern, die Facebook selbst bei seinen Anfragen immer im User Agent stehen hat. Aber auch hier ist extra Arbeit nötig, um das Fehlverhalten anderer abzufangen, damit möglichst wenige Menschen unbegründet blockiert werden.
Immer wieder haben wir gelesen, dass Menschen deshalb für ihre Seiten dann auf filternde CDN Dienste wie Cloudflare setzen, aber es kann doch nicht die Lösung sein, dass ich, um mich gegen die vielen Anfragen der großen Firmen zu schützen, Dienste bei einer anderen großen Firma buchen muss. Das ist keine nachhaltige Lösung und führt am Ende im Zweifel nur zu mehr großen quasi Monopolen. Unserer Meinung nach sollten wir KI und die damit verbundenen Bots streng regulieren, besonders dreckige Kohlekraftwerke, die unserer Umwelt viel mehr schaden als nutzen sind doch inzwischen meist ebenfalls verboten.
Unser erster Ansatz, um das Problem für uns in den Griff zu bekommen, war der Versuch, entsprechende IPs der Bots immer wieder auf den Hosts oder sogar global auf unseren Routern zu blockieren. Leider ist das bei tausenden IPs, die sich zum Teil dank AWS und Co auch täglich ändern, eine eher unbefriedigende und nur kurz wirkende Lösung. Der nächste schnell wirkende Ansatz war dann, wie oben beschrieben, das Blocken der schlimmsten User Agents via Nginx. Da das bedauerlicherweise auch einige False Positives, also fälschlich blockierte legitime Anfragen bedeutet, und uns einige von euch auch schon geschrieben haben, arbeiten wir aktuell daran, fail2ban noch in U7 zu integrieren, sodass wir zwar wenige Anfragen erlauben können, bei einer plötzlichen Flut an Anfragen aber auch einfach automatische blockieren können, ohne das wir jedes Mal manuell aktiv werden müssen. Das ist dann auch schneller und hat so hoffentlich weniger Auswirkungen auf andere Seiten.
Warum wir fail2ban bisher nicht einsetzen? Als wir es das letzte Mal versucht haben, mussten wir leider feststellen, dass der RAM-Verbrauch und die CPU-Zeit, die es benötigte, für uns in keinem guten Verhältnis stand. Das ist inzwischen aber auch einige Jahre her und unser Setup hat sich seitdem deutlich verändert, sodass wir es jetzt erneut für U7 versuchen. Für U8 sind wir aktuell noch am Evaluieren, ob wir auch dort fail2ban einsetzen oder auf modernere Lösungen wie Crowdsec (vermutlich eher in der lokalen Version) setzen wollen. Unabhängig davon planen wir ein Tool zu bauen, das diesen Tools und unserem Support das globale Blocken von IPs auf Router Ebene erlaubt, um Angriffe direkt für alle Hosts zu verhindern und nicht nur Host für Host. Zusätzlich ist dann eine Reputationsdatenbank geplant, die uns zeigt wie oft eine IP bei uns schon aufgefallen ist. Das ist aber alles noch Zukunftsmusik.
Foto von Erik Mclean auf Unsplash