Heutzutage werden Anwendungen oft in Frontend-Anwendungen und Back-End-API aufgeteilt.
Das Frontend wird normalerweise in Object Storage (wie AWS S3 oder Google Cloud Storage) gespeichert, und davor wird ein CDN konfiguriert (wie CloudFront oder dasselbe CloudFlare). Dieses Schema hat sich bewährt, und bei DDoS ist eine solche Ressource unwirksam. Auch wenn DDoS wirklich mächtig ist, leistet CloudFlare hervorragende Arbeit beim Herausfiltern von unerwünschtem Traffic und fordert die Benutzer auf, als letzten Ausweg ein Recaptcha durchzuführen.
Aber wenn es um API-Dienste geht, sind die Dinge noch schlimmer. Selbst nach dem Bestehen einer JS-Herausforderung in einem Browser kann ein gültiger Benutzer nicht immer einfach auf den API-Dienst hinter CloudFlare in der Unter Beschuss Modus.
Wenn wir über APIs sprechen, die von anderen Diensten verwendet werden, die nicht interaktiv funktionieren (verschiedene Bots, benutzerdefinierte Dienste usw.), dann aktivieren Sie die Unter Beschuss Ein Modus für eine API kann gleichbedeutend damit sein, den Zugriff darauf zu blockieren.
Was ist in diesem Fall zu tun?
CloudFlare selbst hat eine Artikel auf der Support-Ressource. Es empfiehlt, einfach den zu senken Sicherheitsstufe zu den API-Endpunkten, Ausschalten der Immer online Modus, ausschalten Zwischenspeichern, und ausschalten Browser-Integritätsprüfung.
Dies hilft natürlich, das Problem der unerwünschten API-Blockierung zu beseitigen, aber es wird das Schutzniveau so stark reduzieren, dass Ihr API-Backend überlastet und sogar der Dienst verweigert werden kann.
In diesem Artikel werden wir uns zwei Möglichkeiten ansehen, mit denen Sie 100% des unerwünschten Datenverkehrs filtern und Fehlalarme sowie das Blockieren gültiger Benutzeranfragen vollständig eliminieren können.
Wie der Titel schon sagt, übertragen wir die primäre Validierung von Anfragen an die CloudFlare-Seite und übergeben nur die in Ihrer Anwendung registrierten API-Schlüssel.
Diese Methode eignet sich nur für private APIs (die am beliebtesten sind). Wenn Sie eine öffentliche API verwenden, über die jeder eine Anfrage an Ihren Dienst stellen kann, sollten Sie auf einen Zustrom von unerwünschtem Datenverkehr vorbereitet sein. Diese Praxis der letzten Jahre zeigt, dass selbst öffentliche APIs auf das Zugriffsmodell per Token umsteigen, das nur nach der Registrierung abgerufen werden kann. Auf diese Weise können Sie den Prozess der bereitgestellten Dienste besser kontrollieren und gleichzeitig den Schutz vor Angriffen konfigurieren.
CloudFlare bietet Serverless-Unterstützung — Cloudflare-Mitarbeiter. Dies ist ein wirklich leistungsstarkes und flexibles Tool, das auch einen sehr niedrigen Preis hat (von 0 bis 5 USD/Monat, keine Überschreitung des Datenverkehrs). In jüngerer Zeit bietet Cloudflare einen zusätzlichen Dienst an - Speicherung von Schlüsselwerten, wodurch Sie direkt von CloudFlare-Mitarbeitern aus darauf zugreifen können.
Diese beiden Technologien helfen uns bei der Implementierung unseres Primärfilters:
Wie wir im obigen Diagramm sehen können, verwenden wir Cloudflare Workers, um zu überprüfen, ob ein API-Schlüssel in der Key-Value-Datenbank vorhanden ist. Wenn der Schlüssel in der Anfrage nicht vorhanden ist — oder nicht im KV-Store — erhält der Client einen HTTP-403-Status. Wenn der Schlüssel korrekt angegeben ist, wird die Anfrage wie gewohnt an das Backend weitergeleitet.
Besondere Aufmerksamkeit sollte dem gelten Synchronisationsskript für API-Schlüssel. Dies ist ein Skript, das die Liste der Schlüssel enthalten muss Cloudflare IV aktuell, was bedeutet, dass, sobald ein Schlüssel zu Ihrer Anwendung hinzugefügt oder blockiert/entfernt wird, sein Status in Cloudflare IV so schnell wie möglich.
Idealerweise findet dieser Prozess in Echtzeit statt.
Kode:
async function handleRequest(request) {
const {searchParams} = new URL(request.url)
const key = searchParams.get(API_KEY_NAME)
const isKeyPresent = await TOKENS_KV.get(key)
if (!key || !isKeyPresent) {
const data = {
"status": "REQUEST_DENIED",
"error_message": "Access denied."
}
const json = JSON.stringify(data, null, 2)
return new Response(json, {
status: 403,
headers: {
"content-type": "application/json;charset=UTF-8"
}
})
}
return await fetch(request)
}
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
Kode:
import logging
import CloudFlare
class CF:
CF_ACCOUNT_ID = ''
CF_API_TOKEN = ''
CF_KV_NAMESPACE_ID = ''
def __init__(self):
self.cf = CloudFlare.CloudFlare(token=self.CF_API_TOKEN)
def get_active_tokens_list():
"""
Need define
"""
return []
def get_tokens(self):
return [i['name'] for i in
self.cf.accounts.storage.kv.namespaces.keys.get(self.CF_ACCOUNT_ID, self.CF_KV_NAMESPACE_ID)]
def create_tokens(self, tokens):
data = [{"key": token, "value": "enabled"} for token in tokens]
self.cf.accounts.storage.kv.namespaces.bulk.put(self.CF_ACCOUNT_ID, self.CF_KV_NAMESPACE_ID, data=data)
def delete_tokens(self, tokens):
self.cf.accounts.storage.kv.namespaces.bulk.delete(self.CF_ACCOUNT_ID, self.CF_KV_NAMESPACE_ID,
data=list(tokens))
def update_tokens(self):
old_tokens = set(self.get_tokens())
new_tokens = set(self.get_active_tokens_list())
to_delete_tokens = old_tokens - new_tokens
self.delete_tokens(to_delete_tokens)
self.create_tokens(new_tokens)
logging.info('CF KV tokens update status: {old} old / {new} new / {deleted} deleted'.format(old=len(old_tokens),
new=len(new_tokens),
deleted=len(to_delete_tokens)))
if __name__ == '__main__':
c = CF()
c.update_tokens()
F: Aber wie kann ich Cloudflare Zugriff auf alle API-Schlüssel meines Dienstes gewähren? Es ist nicht sicher!
A: Sie gewähren Cloudflare bereits Zugriff auf Ihren gesamten Traffic, indem Sie ihn im Proxy-Modus konfigurieren. Und nicht nur du. Untersuchungen zufolge Cloudflare wird von 80,9% verwendet aller Websites, deren Reverse-Proxy-Service wir kennen. Das sind 14,7% aller Websites.
Die beschriebene Methode wurde von uns in der Praxis für einen API-Dienst angewendet, der einem DDOS-Angriff in Höhe von mehreren Milliarden Anfragen pro Tag erlag (bei einer normalen Auslastung von Zehntausenden von Anfragen pro Tag).
Diese Lösung wehrte den Angriff zu 100% ab und blockierte keine echten Benutzeranfragen. Gleichzeitig waren die Kosten lächerlich — bis zu 50$ pro Monat (bei übermäßiger Nutzung von Anfragen an Cloudflare-Mitarbeiter, was in der Gebühr von 5$ pro Monat zum Zeitpunkt des Angriffs enthalten war). Daraus können wir ableiten, dass eine solche Lösung nicht nur sehr effektiv ist, sondern auch die kostengünstigste Option zum Schutz der API ist. Zum Vergleich: Spezialisierte Dienste zum Schutz der API vor DDoS-Angriffen auf diesen Datenverkehr würden für dasselbe Volumen zwischen 800 und 1500 US-Dollar kosten. Gleichzeitig sind wir uns des Potenzials von CloudFlare bewusst, und wir können sicher sein, dass diese Lösung vor massiveren Angriffen schützt.