Einleitung: Warum die Erwartung „Ich kaufe einen Proxy und bekomme einen Webhook“ nicht aufgeht

Im Support von Proxy-Diensten kommt regelmäßig dieselbe Frage in unterschiedlichen Formulierungen an. „Ich habe einen mobilen Proxy gekauft, seine Adresse in die Integrationseinstellungen eingetragen, aber das Zahlungs-Gateway schickt keine Benachrichtigungen.“ „Ich habe die IP des Proxys als Webhook-URL im CRM angegeben, es kommt ein Verbindungsfehler.“ „Mein Skript sieht durch den Proxy alles, aber mich sieht durch denselben Proxy niemand – warum?“ Die Formulierungen unterscheiden sich, doch die Wurzel ist dieselbe: ein falsches mentales Modell davon, was ein Proxy überhaupt leistet.

Die Erwartung ist nachvollziehbar. Ein Proxy gibt Ihnen „eine andere IP-Adresse“, und diese Adresse ist öffentlich – das zeigen alle Prüfdienste. Die Logik legt nahe: Wenn ich eine öffentliche Adresse habe, kann man mich darüber finden. Doch das stimmt nicht. Ein Proxy, auch der mobile Proxy von Proxeon, löst die Aufgabe ausgehender Anfragen: Ihr Code initiiert eine Verbindung, sie läuft über den Proxy-Knoten, und der entfernte Server sieht die Adresse dieses Knotens. Die umgekehrte Aufgabe – dass ein entfernter Server selbst eine Verbindung zu Ihnen aufbaut – löst ein Proxy überhaupt nicht. Nicht, weil im Tarif etwas fehlt, sondern weil sie grundlegend anders funktioniert.

In diesem Beitrag gehen wir der Sache auf den Grund. Sie erfahren, worin sich eine ausgehende von einer eingehenden Verbindung auf TCP-Ebene unterscheidet, warum ein Proxy-Client keinen Listening-Port öffnet und Ihnen keine Adresse gibt, die von außen erreichbar ist, warum die Teilnehmeradresse eines Mobilfunknetzes von Natur aus nicht von außen adressierbar ist – und vor allem, was Sie tatsächlich zum Empfang von Webhooks nutzen sollten: einen Server mit öffentlicher Adresse, einen Reverse-Tunnel, eine Event-Queue auf Anbieterseite oder ein sauber gestaltetes Polling. Wir schauen uns außerdem an, wo der Proxy in diesem Szenario doch seinen Platz hat – und den gibt es. Portweiterleitung und die Einrichtung heimischer Router lassen wir außen vor: Das ist ein Nachbarthema, wir markieren nur die Grenze seiner Anwendbarkeit.

Der Beitrag richtet sich an Entwickler von Integrationen, DevOps-Ingenieure und technische Spezialisten, die Automatisierung auf Basis fremder APIs aufbauen. Die Codebeispiele sind in Python und als Shell-Befehle gehalten und können als Grundlage dienen.

Grundlagen: Verbindungsrichtung, oder wer bei wem anklopft

Beginnen wir mit dem Fundament, ohne das es keinen Sinn ergibt, weiterzugehen. In TCP/IP-Netzen hat jede Verbindung einen Initiator und einen Listener. Der Initiator sendet das erste Paket mit dem SYN-Flag. Der Listener hat vorher einen Port geöffnet, wartet darauf und antwortet mit SYN-ACK. Erst nach diesem Handshake fließen Daten in beide Richtungen. Das Schlüsselwort ist hier „vorher“: Der Listener muss sich bereits auf einer Adresse befinden, die aus dem Internet geroutet wird, und den Port bereits geöffnet haben, wenn der Initiator anklopfen möchte.

Schema einer ausgehenden Anfrage über einen Proxy

Stellen wir das Schema als Text dar. Ihr Skript läuft zu Hause oder im Büro hinter NAT oder sogar auf einem Laptop mit Mobilfunkmodem.

  • Schritt 1. Ihr Skript initiiert eine Verbindung zum Proxy-Knoten: [Ihr Code] klopft an [Proxeon-Knoten].
  • Schritt 2. Der Proxy-Knoten initiiert in eigenem Namen eine Verbindung zur Zielseite: [Proxeon-Knoten] klopft an [api.example.com].
  • Schritt 3. Die Zielseite antwortet über die bereits geöffnete Verbindung in umgekehrter Richtung, der Proxy-Knoten leitet die Antwort über Ihre geöffnete Verbindung an Sie weiter.

Beachten Sie: Die Antwort des Servers ist keine eingehende Verbindung. Es sind Daten, die über den von Ihnen geöffneten Kanal zurückfließen. Sie haben die Tür geöffnet und halten sie, solange der Austausch läuft. Sobald Sie die Verbindung schließen, gibt es keinen Weg zurück. Niemand von außen kann „das Gespräch“ aus eigenem Antrieb fortsetzen.

Schema eines Webhooks

Nun der Webhook. Ein Zahlungsanbieter, ein Messenger, ein CRM oder ein Marktplatz möchte Ihnen ein Ereignis mitteilen: Die Zahlung ist durchgelaufen, eine Nachricht ist eingegangen, der Bestellstatus hat sich geändert.

  • Schritt 1. Der Anbieter nimmt die URL, die Sie bei der Anmeldung angegeben haben, und löst den Domainnamen in eine IP-Adresse auf.
  • Schritt 2. Der Anbieter initiiert eine Verbindung zu dieser Adresse auf Port 443: [Server des Anbieters] klopft an [Ihre URL].
  • Schritt 3. Auf dieser Adresse und diesem Port muss jemand lauschen, den TLS-Handshake mit gültigem Zertifikat annehmen, die HTTP-Anfrage parsen und mit Code 2xx antworten.

Hier ist der Initiator der Anbieter. Der Listener müssen Sie sein. Und hier steht die Frage, auf die dieser ganze Artikel eine ausführliche Antwort gibt: Welche Adresse geben Sie dem Anbieter? Die Proxy-Adresse? Aber der Proxy-Knoten lauscht nicht für Sie. Die Adresse Ihres Heimanschlusses? Die ist entweder privat oder hinter dem NAT des Anbieters. Ein Laptop mit Modem? Der hat überhaupt keine routingfähige Adresse.

Eine Analogie, die alles an seinen Platz rückt

Ein Proxy ähnelt einem Kurierdienst für ausgehende Briefe. Sie geben den Brief dem Kurier, er bringt ihn zum Empfänger, und auf dem Umschlag steht die RücksendeAdresse der Kurierfiliale, nicht Ihre Privatadresse. Der Empfänger kann die Antwort in denselben Umschlag legen, der Kurier kommt zurück und gibt sie Ihnen, weil er sich merkt, von wem er den Brief angenommen hat. Doch wenn der Empfänger eine Woche später selbst schreiben möchte, schreibt er an die Adresse der Filiale. Die Filiale erhält den Brief und weiß nicht, an welchen von tausend Kunden er adressiert ist. Wahrscheinlich kommt er gar nicht im Postfach der Filiale an, weil es dort kein Postfach für eingehende Post gibt. Um Briefe zu erhalten, brauchen Sie eine eigene Postadresse und keinen Zustelldienst für ausgehende Post.

Tiefere Betrachtung: Warum ein Proxy-Client keinen Port öffnet und keine öffentliche Adresse vergibt

Gehen wir auf die Protokollebene. Es gibt zwei große Proxy-Familien: HTTP-Proxys und SOCKS-Proxys. Schauen wir, was jede kann, und überzeugen uns, dass eingehende Verbindungen zu Ihrem Dienst weder auf dem Papier noch in der Praxis dazugehören.

Wie ein HTTP-Proxy funktioniert

Ein HTTP-Proxy nimmt vom Client eine Anfrage der Form GET http://host/path oder für HTTPS den Befehl CONNECT host:443 entgegen. Im zweiten Fall öffnet der Proxy eine TCP-Verbindung zum Zielhost und leitet dann einfach Bytes in beide Richtungen weiter, ohne in den verschlüsselten Verkehr zu schauen. Das ist alles. Im Protokoll gibt es keinen Befehl „beginne einen Port für mich zu lauschen“ oder „registriere mir eine Adresse“. Der Client ist immer Initiator, der Proxy immer Vermittler in Richtung „vom Client in die Welt“.

Hier ein Minimalbeispiel für eine ausgehende Anfrage über einen Proxy in Python. Es funktioniert, weil die Richtung stimmt:

import requests

PROXY = 'http://user:pass@gate.proxeon.net:PORT'
proxies = {'http': PROXY, 'https': PROXY}

r = requests.get('https://api.example.com/v1/status', proxies=proxies, timeout=(5, 30))
print(r.status_code, r.json())

Und hier der zum Scheitern verurteilte Versuch. Angenommen, Sie haben die externe IP des Proxys herausgefunden, etwa über einen Adressprüfdienst, und wollen sie als Webhook-URL angeben:

curl -v --max-time 10 http://203.0.113.45/webhook
# result: connect() timed out or Connection refused

Warum ist das so? Auf der Adresse 203.0.113.45 läuft Proxy-Software, die ihren Dienstport für den Empfang von Client-Befehlen lauscht, aber nicht Ihren Pfad /webhook. Selbst wenn auf Port 80 etwas antworten würde, wäre das nicht Ihr Code. Ihr Code läuft auf einer anderen Maschine, unter einer anderen Adresse, und der Proxy-Server hat keine Ahnung, dass eine Anfrage auf den Pfad /webhook genau an Sie weitergeleitet werden muss und nicht an einen der hundert anderen Kunden, die dieselbe Ausgangsadresse nutzen.

Und was ist mit SOCKS5 und dem BIND-Befehl?

Hier beginnt der interessanteste Teil, den nur wenige kennen. Die SOCKS5-Spezifikation beschreibt tatsächlich drei Befehle: CONNECT, BIND und UDP ASSOCIATE. Der BIND-Befehl war genau für das umgekehrte Szenario gedacht: Ein Client bittet den Proxy, einen Listening-Port zu öffnen und dann eine eingehende Verbindung anzunehmen und an den Client weiterzuleiten. Das ist ein Erbe des FTP-Protokolls im aktiven Modus, wo der Server sich für die Datenübertragung zum Client verbinden muss.

Man könnte meinen, das sei die Lösung. Doch es gibt drei Gründe, warum BIND Ihnen in der Praxis nicht hilft:

  1. BIND nimmt genau eine eingehende Verbindung an und erst, nachdem Sie bereits eine ausgehende zu demselben Host aufgebaut haben. Das ist kein „Port dauerhaft für jeden lauschen“, sondern „öffne die Tür für genau einen Gesprächspartner, mit dem ich schon spreche“.
  2. Die überwiegende Mehrheit kommerzieller Proxy-Server implementiert den BIND-Befehl nicht oder deaktiviert ihn aus Sicherheitsgründen. Ein offener Listening-Port auf einem gemeinsamen Knoten mit hunderten Clients ist ein Angriffsvektor und eine Quelle von Missbrauch, deshalb gibt es ihn einfach nicht.
  3. Selbst dort, wo BIND existiert, werden Adresse und Port dynamisch und für kurze Zeit vergeben und eignen sich keinesfalls für die Registrierung als Webhook-URL mit TLS-Zertifikat.

Fazit: Die theoretische Möglichkeit existiert in der Spezifikation, praktischen Nutzen für den Empfang von Webhooks hat sie nicht.

Was Sie mit einem Proxy bekommen – und was nicht

Formulieren wir es ganz klar. Wenn Sie einen Proxy kaufen, bekommen Sie:

  • eine Ausgangs-IP-Adresse, die entfernte Server bei Ihren ausgehenden Anfragen sehen;
  • geografische und netzwerkseitige Zugehörigkeit dieser Adresse, etwa eine Adresse aus dem Mobilfunk-Pool eines bestimmten Anbieters in einer bestimmten Region;
  • die Möglichkeit, diese Adresse zu rotieren oder sie im Gegenteil während einer Sitzung stabil zu halten;
  • die Aufteilung ausgehenden Verkehrs auf verschiedene Kanäle, wenn Sie mehrere unabhängige Integrationen betreiben.

Sie bekommen nicht:

  • einen Listening-Port auf der Ausgangsadresse;
  • eine routingfähige Adresse, zu der Dritte eine Verbindung initiieren können;
  • einen Domainnamen und ein TLS-Zertifikat, die an Ihren Dienst gebunden sind;
  • die Garantie, dass die Ausgangsadresse in einer Stunde dieselbe ist, wenn der Tarif Rotation vorsieht.

Sobald diese Tabelle im Kopf sitzt, ist die Frage „Warum kommt der Webhook nicht am Proxy an?“ keine Frage mehr. Sie wird zur Selbstverständlichkeit.

Mobilfunknetze und geteilte Adressen: Warum die Teilnehmeradresse nicht von außen adressierbar ist

Eine gesonderte Betrachtung verdienen Mobilfunknetze, weil gerade mobile Proxys am häufigsten die Hauptrolle in Geschichten über „der Webhook kommt nicht an“ spielen. Hier kommt zu den Einschränkungen des Proxys selbst die Architektur des Mobilfunknetzes hinzu, die den Effekt um ein Vielfaches verstärkt.

Adressknappheit und CGNAT

Es gibt weltweit etwa vier Milliarden öffentliche IPv4-Adressen, doch aktive Mobilfunkverbindungen sind deutlich mehr. Kein Anbieter kann jedem Teilnehmer eine eigene öffentliche Adresse geben. Deshalb nutzen die Anbieter Carrier-Grade NAT (CGNAT, Adressübersetzung auf Betreiberebene). Das Teilnehmergerät erhält eine private Adresse aus dem speziell reservierten Bereich 100.64.0.0/10 oder aus dem üblichen 10.0.0.0/8, und am Netzrand steht ein leistungsfähiges NAT-Gateway, das tausende Teilnehmeradressen in eine oder mehrere öffentliche Adressen übersetzt.

Wie sieht das in Bezug auf Adressierbarkeit aus? Wenn Ihr Modem ein Paket nach außen sendet, notiert das Gateway in seiner Tabelle: „Teilnehmer 100.72.14.9, Port 51234 → öffentliche Adresse 203.0.113.45, Port 40001“. Eine Antwort, die an 203.0.113.45:40001 eingeht, ordnet das Gateway dem Eintrag zu und gibt sie an Sie zurück. Doch Einträge entstehen nur durch ausgehenden Verkehr und leben Sekunden oder Minuten ohne Aktivität. Wenn jemand von außen ein Paket an 203.0.113.45 auf Port 443 sendet, gibt es in der Tabelle keinen passenden Eintrag. Das Gateway verwirft es. Nicht „blockiert“, sondern es kann einfach nicht verstehen, an welchen von tausend Teilnehmern es adressiert ist.

Warum das auf Teilnehmerseite nicht behoben werden kann

Beim Heim-Provider ist es manchmal anders: Einige Tarife vergeben eine echte öffentliche Adresse an den Router, und dann ergibt sich das Nachbarthema Portweiterleitung und Router-Einrichtung. Wir beschreiben es bewusst nicht, sondern halten nur die Grenze der Anwendbarkeit fest: Portweiterleitung ergibt nur dort Sinn, wo auf Ihrer Hardware eine echte routingfähige Adresse liegt. Im Mobilfunknetz hat der Teilnehmer eine solche Adresse grundsätzlich nicht, es gibt nichts weiterzuleiten und nichts einzurichten, die Hardeware-Konfiguration ändert daran nichts. Die Option einer öffentlichen Adresse für Mobilfunkteilnehmer fehlt bei den meisten Anbietern oder wird als separate Unternehmensdienstleistung angeboten, was mit Proxys nichts mehr zu tun hat.

Zusätzliche Schichten: Rotation und Filterung

Zum CGNAT kommen zwei weitere Faktoren. Erstens ändert sich die öffentliche Adresse, über die ein Teilnehmer hinausgeht, regelmäßig: bei Neuverbindung, bei Lastverteilung, bei Wechsel der Basisstation. Die mobilen Proxys von Proxeon nutzen genau diese Eigenschaft als Vorteil: Die Adresse kann nach Zeitplan oder auf Anfrage rotiert werden. Für den Empfang von Webhooks ist die Stabilität der Adresse jedoch kritisch, und hier fehlt sie per Definition. Zweitens filtern die Anbieter einen Teil des eingehenden Verkehrs am Netzrand, weil Teilnehmergeräte nicht als Server gedacht sind. Selbst dort, wo ein Teilnehmer eine öffentliche IPv6-Adresse erhält, sind eingehende Verbindungen zu ihm oft durch die Firewall des Anbieters geschlossen.

Das Fazit dieses Kapitels sollte man hervorheben: Die Adresse eines mobilen Proxys ist eine ausgehende Identität, keine Adresse eines Dienstes. Das ist kein Mangel des Produkts, sondern seine Natur. Einen mobilen Proxy kauft man, damit ausgehende Anfragen wie der Verkehr eines normalen Teilnehmers eines bestimmten Anbieters und einer bestimmten Region aussehen. Genau weil dieser Verkehr von Teilnehmerverkehr nicht zu unterscheiden ist, hat er auch die fehlende externe Adressierbarkeit eines Teilnehmers geerbt.

Was die Aufgabe des Webhook-Empfangs tatsächlich löst: vier praxistaugliche Ansätze

Wir gehen von der Diagnose zur Behandlung über. Es gibt vier ausgereifte Wege, Ereignisse von externen Systemen zu empfangen, wenn Ihr Code hinter NAT, hinter einem Mobilfunkmodem oder überhaupt auf einem Laptop läuft. Jeder hat seine Nische, seinen Preis und seine Einschränkungen. Wir gehen sie der Reihe nach mit Beispielen durch.

Ansatz 1. Server mit öffentlicher Adresse

Der direkteste und zuverlässigste Weg. Sie mieten einen virtuellen Server bei einem Hosting-Anbieter, erhalten dazu eine öffentliche IPv4-Adresse, binden einen Domainnamen daran, stellen ein TLS-Zertifikat aus und starten den Empfänger. Webhook-Anbieter verlangen im Jahr 2026 fast ausnahmslos HTTPS mit gültigem Zertifikat, dieser Schritt ist also verpflichtend.

Schritt-für-Schritt-Plan:

  1. Mieten Sie einen VPS mit minimaler Konfiguration in einer Jurisdiktion, die Ihren Anforderungen an die Datenhaltung entspricht.
  2. Erstellen Sie einen A-Eintrag für eine Domain wie hooks.yourdomain.tld, der auf die Serveradresse zeigt.
  3. Installieren Sie einen Reverse-Proxy auf Webebene (nginx oder ähnlich) und stellen Sie ein Zertifikat über einen ACME-Client aus.
  4. Starten Sie die Empfänger-Anwendung auf einem lokalen, von außen geschlossenen Port und richten Sie den Webserver darauf aus.
  5. Richten Sie Signaturprüfung und Verarbeitungsqueue ein, um dem Anbieter schnell zu antworten.

Beispiel eines Empfängers in Flask mit HMAC-Signaturprüfung und schneller Antwort. Die schwere Verarbeitung schieben wir in eine Queue, weil die meisten Anbieter nicht länger als 5–10 Sekunden auf eine Antwort warten:

import hmac, hashlib, json, os
from flask import Flask, request, abort
from queue import Queue

app = Flask(__name__)
SECRET = os.environ['WEBHOOK_SECRET'].encode()
jobs = Queue()

def valid_signature(raw_body, header_sig):
expected = hmac.new(SECRET, raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header_sig or '')

@app.post('/webhook/payments')
def payments():
raw = request.get_data()
if not valid_signature(raw, request.headers.get('X-Signature')):
abort(401)
event = json.loads(raw)
jobs.put(event) # Verarbeitung im Hintergrund, sofortige Antwort
return '', 200

Beachten Sie drei Details. Die Signatur wird über den Rohinhalt der Anfrage geprüft, nicht über das geparste JSON, sonst zerbricht jede Umformatierung den Vergleich. Der Vergleich erfolgt über compare_digest, um keine Zeitinformationen preiszugeben. Die Antwort 200 wird vor der Verarbeitung gesendet, das Ereignis selbst geht in die Queue. Wenn der Anbieter nicht innerhalb der vorgegebenen Zeit 2xx erhält, betrachtet er die Zustellung als fehlgeschlagen und beginnt mit Wiederholungen – Sie erhalten Duplikate.

Ansatz 2. Reverse-Tunnel

Wenn der Code genau auf Ihrer lokalen Maschine und nicht auf einem Server laufen soll, nutzen Sie einen Reverse-Tunnel. Die Idee ist elegant und deckt sich vollständig mit allem, was wir oben besprochen haben: Ihre Maschine initiiert selbst eine ausgehende Verbindung zu einem öffentlichen Server, und dieser beginnt, einen Port in Ihrem Namen zu lauschen und eingehende Anfragen in den bereits geöffneten Kanal zu leiten. Die Initiierungsrichtung ist ausgehend, also stören NAT und CGNAT nicht. Der öffentliche Listener befindet sich auf dem Server, also kann der Webhook-Anbieter ihn erreichen.

Die einfachste Umsetzung mit SSH. Auf dem öffentlichen Server muss in der sshd-Konfiguration die Option GatewayPorts aktiviert sein, oder man nutzt einen lokalen Webserver als Frontend. Von der lokalen Maschine aus:

# lokaler Empfänger lauscht auf 127.0.0.1:8080
# Server bitten, auf 127.0.0.1:9000 zu lauschen und Verkehr an uns weiterzuleiten
ssh -N -R 9000:127.0.0.1:8080 tunnel@hooks.yourdomain.tld

# auf dem Server leitet nginx https://hooks.yourdomain.tld/webhook -> 127.0.0.1:9000

Für den Produktivbetrieb ist ein einzelner ssh-Prozess nicht zuverlässig genug: Die Verbindung kann abreißen. Verwenden Sie eine Hülle mit automatischer Wiederverbindung (autossh oder einen ähnlichen Supervisor) und aktivieren Sie ServerAliveInterval, damit Abbrüche in Sekunden erkannt werden. Es gibt auch spezialisierte Tunnel-Dienste und selbst gehostete Lösungen auf Basis desselben Prinzips mit automatischer Zertifikatsausstellung und Web-Oberfläche. Das Prinzip ist überall gleich: Ein lokaler Agent hält die ausgehende Verbindung, die öffentliche Seite empfängt die Webhooks.

Die Einschränkungen dieses Ansatzes sollte man im Blick behalten. Solange der Tunnel unterbrochen ist, gehen Webhooks verloren oder landen in den Wiederholungen des Anbieters. Temporäre Adressen mancher Tunnel-Dienste ändern sich bei Neustart, was für die Produktion inakzeptabel ist: Man braucht eine feste Domain. Und ein Tunnel fügt Latenz und einen Single Point of Failure hinzu. Für Entwicklung und Debugging ist er ideal, für den Betrieb taugt er nur in Verbindung mit Monitoring.

Ansatz 3. Event-Queue auf Anbieterseite

Viele ausgereifte APIs bieten eine Alternative zum Push-Modell: Ereignisse werden in einem Journal oder einer Queue auf Anbieterseite abgelegt, und Sie holen sie ab, wann es Ihnen passt. Das dreht die Verbindungsrichtung für Sie ins Ausgehende, und das ganze Adressierbarkeitsproblem verschwindet.

Das kanonische Beispiel ist die Bot-API eines Messengers mit der Methode getUpdates: Der Server speichert ungelesene Updates bis zu einem Tag, und der Client holt sie regelmäßig ab und übergibt dabei den Offset des zuletzt verarbeiteten. Ähnliche Mechanismen gibt es bei Zahlungssystemen als Ereignisliste mit Cursor, bei Marktplätzen als Queue von Bestelländerungen, bei Cloud-Anbietern als verwaltete Nachrichtenqueues, in die man Webhooks leiten und sie dann vom Client auslesen kann.

import requests, time

TOKEN = 'your-bot-token'
BASE = f'https://api.messenger.example/bot{TOKEN}'
offset = 0

while True:
resp = requests.get(f'{BASE}/getUpdates',
params={'offset': offset, 'timeout': 50},
timeout=60)
for upd in resp.json().get('result', []):
handle(upd)
offset = upd['update_id'] + 1

Der Parameter timeout=50 aktiviert hier das Long Polling: Der Server hält die Verbindung offen, bis ein Ereignis eintritt oder das Timeout abläuft, und Sie erhalten fast sofortige Zustellung ohne häufige leere Anfragen. Das ist eine ausgehende Verbindung, sie funktioniert problemlos hinter NAT, hinter einem Mobilfunkmodem und bei Bedarf auch über einen Proxy.

Wenn der Anbieter keine eingebaute Queue bietet, lässt sie sich aus dem ersten Ansatz selbst bauen: Ein minimaler Empfänger auf einem VPS nimmt Webhooks entgegen und legt sie in eine Nachrichtenqueue, und Ihre lokale Maschine liest die Queue aus. Das ergibt einen Hybrid, der die Zuverlässigkeit einer öffentlichen Adresse mit der Flexibilität lokaler Ausführung verbindet.

Ansatz 4. Polling statt Subscription

Wenn der Anbieter weder Webhooks noch eine Event-Queue hat, bleibt das klassische Status-Polling: Sie fragen regelmäßig eine Ressource ab und vergleichen mit dem vorherigen Zustand. Das ist der universellste Ansatz, weil er vom Anbieter nichts außer einer gewöhnlichen Lese-API verlangt. Aber er ist auch der anspruchsvollste im Design: Eine naive Schleife mit festem Intervall stößt schnell an Rate-Limits, verschwendet Budget für leere Antworten und verpasst dennoch Ereignisse. Der nächste Abschnitt ist ganz dem gewidmet, wie man das vermeidet.

Werkzeuge, die sich bewähren

  • Webserver als Frontend (nginx oder Äquivalent) für TLS-Terminierung und Routing zur Anwendung.
  • ACME-Client für automatische Ausstellung und Erneuerung von Zertifikaten.
  • Nachrichtenqueue (Redis Streams, RabbitMQ oder eine verwaltete Cloud-Queue) zur Pufferung von Ereignissen zwischen Empfang und Verarbeitung.
  • Tunnel-Supervisor mit automatischer Wiederverbindung für Reverse-Tunnel.
  • Lokaler Request-Inspektor zum Debuggen: Jeder minimale HTTP-Server, der Header und Body protokolliert, hilft zu sehen, was der Anbieter genau sendet.
  • Proxeon-Proxy für ausgehende Aufrufe an fremde APIs aus den Handlern, worauf wir unten ausführlich eingehen.

Polling als Webhook-Ersatz: Wie man es plant, ohne an Limits zu stoßen

Polling wird für Verschwendung gescholten, oft zu Recht. Doch verschwenderisch ist nicht das Polling an sich, sondern seine schlechte Umsetzung. Ein richtig geplanter Poller ist in der API-Last mit Webhooks vergleichbar und dabei zuverlässiger, weil er nicht von der Zustellbarkeit eingehender Verbindungen abhängt. Wir schauen uns die Prinzipien an.

Prinzip 1. Cursor statt vollständiger Auswahl

Fragen Sie niemals „alle Bestellungen“ ab und suchen Sie Änderungen auf Ihrer Seite. Nutzen Sie Parameter wie since, updated_after, cursor oder page_token, die es in fast jeder modernen API gibt. Speichern Sie den letzten Cursor persistent, damit ein Neustart des Prozesses nicht zum erneuten Abruf der Historie führt. Die Antwort über einen Cursor ist klein, schnell verarbeitet und belastet den Anbieter nicht.

Prinzip 2. Bedingte Anfragen

Wenn die Ressource die Header ETag und If-None-Match oder Last-Modified und If-Modified-Since unterstützt, nutzen Sie sie. Die Antwort 304 Not Modified enthält keinen Body und wird oft nicht oder nur vergünstigt auf das Limit angerechnet. Das ist eine kostenlose Möglichkeit, den Verkehr um ein Vielfaches zu reduzieren.

Prinzip 3. Adaptives Intervall mit Jitter

Ein festes Intervall ist doppelt schlecht: In ruhigen Stunden verschwendet es Anfragen, in Spitzenzeiten kommt es zu spät. Das adaptive Schema ist einfach: Nach einer leeren Antwort erhöhen Sie das Intervall (z. B. multiplizieren mit 1,5 bis zur Obergrenze), nach einer nicht leeren setzen Sie es auf das Minimum zurück. Fügen Sie eine zufällige Streuung von 10–20 Prozent hinzu, damit mehrere Ihrer Instanzen nicht synchron auf die API schlagen.

Prinzip 4. Respekt vor den Signalen des Servers

Die Header Retry-After, X-RateLimit-Remaining und X-RateLimit-Reset existieren nicht zum Spaß. Wenn Sie 429 erhalten, warten Sie genau so lange, wie angegeben. Wenn der Rest des Limits unter einen Schwellenwert fällt, werden Sie vorher langsamer. Das ist nicht nur Höflichkeit, sondern auch Schutz vor temporären Sperren des Schlüssels.

Prinzip 5. Idempotente Verarbeitung

Polling kann von Natur aus dasselbe Ereignis zweimal liefern: an der Cursorgrenze, nach einem Ausfall, bei überlappenden Fenstern. Jedes Ereignis sollte eine eindeutige Kennung haben, und der Handler eine Tabelle bereits verarbeiteter Kennungen mit angemessener Aufbewahrungsfrist. Dieselbe Regel schützt auch vor Duplikaten von Webhooks bei wiederholten Zustellungen.

Fertiges Gerüst eines adaptiven Pollers

import random, time, requests

MIN_INTERVAL, MAX_INTERVAL = 5, 300
interval = MIN_INTERVAL
cursor = load_cursor() # aus DB oder Datei
etag = None
seen = SeenStore(ttl_hours=48) # Speicher für verarbeitete IDs

while True:
headers = {'If-None-Match': etag} if etag else {}
r = requests.get('https://api.example.com/v1/events',
 params={'cursor': cursor, 'limit': 100},
 headers=headers, timeout=(5, 30))

if r.status_code == 429:
time.sleep(int(r.headers.get('Retry-After', 60)))
continue
if r.status_code == 304:
interval = min(interval * 1.5, MAX_INTERVAL)
elif r.ok:
etag = r.headers.get('ETag')
events = r.json()['data']
for ev in events:
if not seen.contains(ev['id']):
handle(ev)
seen.add(ev['id'])
if events:
cursor = r.json()['next_cursor']
save_cursor(cursor)
interval = MIN_INTERVAL
else:
interval = min(interval * 1.5, MAX_INTERVAL)

remaining = int(r.headers.get('X-RateLimit-Remaining', 1000))
if remaining < 50:
interval = max(interval, 60)

time.sleep(interval * random.uniform(0.9, 1.2))

Checkliste für das Polling-Design

  • Cursor oder Zeitstempel werden persistent gespeichert und überleben einen Neustart.
  • Bedingte Anfragen werden genutzt, wenn die API sie unterstützt.
  • Das Intervall ist adaptiv, mit Obergrenze und Jitter.
  • Code 429 und Header Retry-After werden explizit behandelt.
  • Jedes Ereignis wird idempotent über eine eindeutige Kennung verarbeitet.
  • Timeouts für Verbindung und Lesen sind explizit und getrennt gesetzt.
  • Metriken: Anfragefrequenz, Anteil leerer Antworten, Latenz vom Ereignis bis zur Verarbeitung.
  • Wenn der Anbieter Long Polling unterstützt, ist es aktiviert und das gewöhnliche Polling ausgeschaltet.

Mit diesem Design erreicht ein Poller mit minimalem Intervall von 5 Sekunden in Ruhephasen ein Intervall von 5 Minuten und macht rund 300 Anfragen pro Tag und Ressource. Das ist dutzendfach weniger als eine naive Schleife alle 10 Sekunden, die 8640 Anfragen pro Tag mit derselben durchschnittlichen Zustelllatenz in aktiven Stunden macht.

Wo der Proxy neben Webhooks doch gebraucht wird: ausgehende Antworten und Aufrufe fremder APIs

Es wäre falsch, mit dem Gedanken zu enden, „der Proxy hat nichts mit Webhooks zu tun“. Er hat, und zwar einen sehr konkreten, nur auf der anderen Seite des Schemas. Nach dem Empfang eines Ereignisses macht Ihr Handler fast immer ausgehende Anfragen: Er bestätigt die Operation, fragt Bestelldetails nach, sendet Daten an ein anderes System, benachrichtigt einen Nutzer. All diese Anfragen sind ausgehend, und hier ist der Proxy an seinem Platz.

Szenario 1. Verifikation des Ereignisses durch Rückfrage

Eine gute Sicherheitspraxis: dem Webhook-Body nicht blind zu vertrauen, sondern nach der Signaturprüfung das Objekt beim Anbieter über seine Kennung nachzufragen. Diese Anfrage geht von Ihrem Server an die API des Anbieters. Wenn der Anbieter den Zugriff regional einschränkt oder eine Verhaltensanalyse der Quelle betreibt, macht eine stabile Ausgangsadresse aus der gewünschten Region über Proxeon das Verkehrsbild vorhersagbar.

Szenario 2. Aufrufe fremder APIs aus dem Handler

Ein Webhook-Handler eines Marktplatzes kann APIs eines Zustelldienstes, eines Dienstes zur Geschäftspartnerprüfung, einer Karten-API aufrufen. Jede hat ihre eigenen Limits pro IP-Adresse. Die Aufteilung der Integrationen auf verschiedene Ausgangsadressen isoliert sie voneinander: Die Erschöpfung eines Limits durch eine Integration lähmt nicht die übrigen.

Szenario 3. Trennung der Identität ausgehenden Verkehrs

Wenn ein Server mehrere unabhängige Kunden oder Projekte bedient, ist es nützlich, ihren ausgehenden Verkehr zu externen APIs über verschiedene Adressen laufen zu lassen. Das vereinfacht die Diagnose (an der Adresse erkennt man, wessen Anfrage es ist) und senkt das Risiko, dass Probleme eines Projekts andere treffen.

Beispiel: Empfänger direkt, ausgehend über Proxy

Die wichtigste Regel: Der Webhook-Empfänger lauscht direkt auf einer öffentlichen Adresse, der Proxy wird nur für ausgehende Aufrufe genutzt. Versuchen Sie nicht, den Empfänger „in den Proxy zu wickeln“, das ist aus allen oben genannten Gründen sinnlos.

import requests
from flask import Flask, request

app = Flask(__name__)

OUT_PROXY = 'http://user:pass@gate.proxeon.net:PORT'
outbound = requests.Session()
outbound.proxies = {'http': OUT_PROXY, 'https': OUT_PROXY}

@app.post('/webhook/orders')
def orders():
event = request.get_json()
# Empfang läuft direkt, ohne Proxy
order_id = event['order_id']
# ausgehende Verifikation und Aufrufe fremder APIs - über Proxy
full = outbound.get(f'https://api.marketplace.example/orders/{order_id}',
timeout=(5, 20)).json()
outbound.post('https://api.delivery.example/shipments',
 json={'order': full}, timeout=(5, 20))
return '', 200

Einige praktische Anmerkungen. Halten Sie eine separate Session für ausgehende Aufrufe bereit, damit die Proxy-Einstellungen nicht in andere Teile der Anwendung durchsickern. Setzen Sie Timeouts explizit: Über den Proxy ist der Weg länger, und ein hängender ausgehender Aufruf darf die Antwort an den Webhook-Anbieter nicht verzögern. Idealerweise machen Sie ausgehende Aufrufe nicht im HTTP-Handler, sondern in einem Hintergrund-Worker, der die Queue ausliest. Und wenn die API eines Drittanbieters verlangt, Ihre Adresse auf eine Whitelist zu setzen, nutzen Sie einen Tarif mit statischer Ausgangsadresse, keinen rotierenden.

Tabelle „Aufgabe – passende Lösung“

Fassen wir alles in einem einheitlichen Nachschlagewerk zusammen. Für jede typische Aufgabe steht dabei, ob der Proxy sie löst und was stattdessen oder zusätzlich genutzt werden sollte.

  • Aufgabe: ausgehende Anfragen an externe APIs aus einer bestimmten Region oder von einem bestimmten Anbieter machen. Lösung: Proxeon-Proxy, statischer oder rotierender Tarif je nach Anforderung. Rolle des Proxys: Hauptrolle.
  • Aufgabe: Webhooks von einem Zahlungs-Gateway in der Produktion empfangen. Lösung: VPS mit öffentlicher Adresse, Domain, TLS, Empfänger mit Signaturprüfung und Queue. Rolle des Proxys: nur für ausgehende Aufrufe aus dem Handler.
  • Aufgabe: den Webhook-Empfang auf dem lokalen Entwicklerrechner debuggen. Lösung: Reverse-Tunnel zu einem öffentlichen Server mit fester Domain. Rolle des Proxys: keine.
  • Aufgabe: Ereignisse von einem Messenger oder einer API mit Queue erhalten, Code läuft zu Hause oder hinter einem Mobilfunkmodem. Lösung: Long Polling von Methoden wie getUpdates, Auslesen der Anbieter-Queue. Rolle des Proxys: optional für ausgehende Anfragen.
  • Aufgabe: Änderungen in einer API ohne Webhooks und Queues verfolgen. Lösung: adaptives Polling mit Cursor, bedingten Anfragen und Respekt vor Limits. Rolle des Proxys: Lastverteilung auf Ausgangsadressen im Rahmen der Anbieter-Limits.
  • Aufgabe: Webhooks auf einem Computer empfangen, der über ein Mobilfunkmodem verbunden ist. Lösung: direkt unmöglich wegen CGNAT; nutzen Sie Reverse-Tunnel oder Queue. Rolle des Proxys: keine.
  • Aufgabe: mehrere Integrationen auf einem Server dürfen sich bei fremden API-Limits nicht stören. Lösung: separate Proxeon-Ausgangsadressen pro Integration plus separate Queues. Rolle des Proxys: Hauptrolle für den ausgehenden Teil.
  • Aufgabe: eine fremde API verlangt, die Adresse auf eine Whitelist zu setzen. Lösung: statische Ausgangsadresse; für den Empfang von Webhooks die öffentliche Adresse Ihres Servers. Rolle des Proxys: statischer Tarif für den ausgehenden Teil.
  • Aufgabe: eine öffentliche Adresse am Heimrouter bekommen. Lösung: Nachbarthema, hängt vom Heim-Provider ab; nur anwendbar, wenn auf der Hardware eine echte öffentliche Adresse liegt. Rolle des Proxys: keine.

Typische Fehler: Was man nicht tun sollte

Sammeln wir die Stolperfallen, in die man am häufigsten tappt. Manche kosten Stunden Debugging, manche verlorene Zahlungen.

Fehler 1. Die Proxy-Adresse als Webhook-URL angeben

Oben ausführlich besprochen, doch wiederholt: Auf der Ausgangsadresse des Proxys gibt es keinen Listener von Ihnen. Der Anbieter erhält ein Timeout oder eine Verbindungsabsage und deaktiviert nach einigen Fehlschlägen die Subscription. Manche Anbieter blockieren die URL bei wiederholten Fehlern für längere Zeit.

Fehler 2. Eine lokale oder private Adresse angeben

Eine URL wie http://192.168.1.10:8080/hook oder http://localhost/hook wird nur innerhalb Ihres Netzes geroutet. Der Anbieter kann sie physisch nicht erreichen. Viele Anbieter lehnen solche URLs schon bei der Registrierung der Subscription ab, aber nicht alle.

Fehler 3. Selbstsigniertes Zertifikat oder einfaches HTTP

Webhook-Anbieter prüfen das Zertifikat. Ein selbstsigniertes oder abgelaufenes Zertifikat führt zu stiller Zustellungsverweigerung. Einfaches HTTP ohne TLS lassen die meisten Anbieter gar nicht zu.

Fehler 4. Lange Verarbeitung im HTTP-Handler

Wenn der Handler Daten aus drei externen APIs zieht und vor der Antwort an den Anbieter in die Datenbank schreibt, überschreitet er leicht das Warte-Timeout. Der Anbieter betrachtet die Zustellung als fehlgeschlagen und wiederholt. Sie verarbeiten ein Ereignis mehrfach. Die Antwort sollte in Hunderten von Millisekunden rausgehen, die Verarbeitung in die Queue.

Fehler 5. Fehlende Idempotenz

Wiederholte Zustellungen sind die Norm, nicht die Ausnahme. Ohne Berücksichtigung verarbeiteter Kennungen erstellen Sie zweimal eine Bestellung, senden zweimal eine Benachrichtigung oder buchen zweimal in der Buchhaltung.

Fehler 6. Blindes Vertrauen in den Webhook-Body

Eine öffentliche URL ist für alle erreichbar. Ohne Signaturprüfung kann jeder ein gefälschtes Ereignis „Zahlung erfolgt“ senden. Prüfen Sie HMAC und fragen Sie bei kritischen Operationen das Objekt beim Anbieter nach.

Fehler 7. Temporäre Tunnel-Adresse in der Produktion

Eine zufällig generierte Domain eines Tunnel-Dienstes ändert sich beim Neustart. Die Subscription des Anbieters bleibt an die alte URL gebunden. Ereignisse gehen verloren, bis es jemand bemerkt. Im Betrieb ist ein Tunnel nur mit fester Domain und Monitoring zulässig.

Fehler 8. Polling mit festem kurzem Intervall

Jede Sekunde ohne Cursor und bedingte Anfragen ist ein direkter Weg zu 429 und einer temporären Sperre des Schlüssels. Schlimmer noch: Bei einer Sperre erhalten Sie überhaupt nichts mehr, und die Zustelllatenz wird unendlich.

Fehler 9. Ausgehende Aufrufe über Proxy ohne Timeouts

Ein Proxy fügt einen Zwischenknoten hinzu. Ohne explizite Timeouts hält ein hängender ausgehender Aufruf den Worker, und wenn er im HTTP-Handler gemacht wird, reißt er auch die Antwort an den Anbieter ab. Setzen Sie immer Timeout für Verbindung und Lesen getrennt.

Fehler 10. Erwarten, dass der BIND-Befehl in SOCKS5 Sie zum Server macht

Das kommt bei denen vor, die die Spezifikation gelesen haben. Auf kommerziellen Knoten ist der Befehl in der Regel nicht implementiert, und wo er es ist, liefert er eine einzelne Verbindung für kurze Zeit. Für Webhooks ungeeignet.

Fälle und Ergebnisse: Wie es in der Praxis aussieht

Drei Geschichten aus typischen Situationen der Integrationsentwicklung. Die Zahlen sind gerundet, aber die Größenordnung ist real.

Fall 1. Zahlungsbenachrichtigungen eines Onlineshops

Ein kleines Team entwickelte einen Shop auf einem Website-Baukasten und schrieb einen Python-Handler für Zahlungen, der auf einem Bürocomputer hinter einem Mobilfunkmodem lief. In den Einstellungen des Zahlungsanbieters wurde die Adresse des mobilen Proxys angegeben, weil „sie ist ja öffentlich“. Der Anbieter wiederholte die Zustellung nach Zeitplan 1, 5, 30 Minuten, 2 Stunden und deaktivierte dann die Subscription. In einer Woche sammelten sich etwa 40 Bestellungen im Status „wartet auf Zahlung“ bei tatsächlich erfolgten Zahlungen, was einen manuellen Abgleich erforderte.

Lösung: Ein minimaler VPS wurde gemietet, ein Empfänger mit Signaturprüfung und Queue auf Redis eingerichtet, der Handler blieb lokal und liest die Queue über eine ausgehende Verbindung. Zusätzlich läuft stündlich ein Abgleich-Polling der Zahlungsliste der letzten 24 Stunden mit Cursor, das Ereignisse abfängt, die durch jegliche Störungen verloren gingen. Ergebnis: In den folgenden drei Monaten wurden keine Abweichungen zwischen Anbieter und Buchhaltung festgestellt, die Zeit von der Zahlung bis zur Statusänderung der Bestellung betrug im Durchschnitt 1,2 Sekunden.

Fall 2. Support-Bot auf einem Laptop mit Modem

Ein Entwickler schrieb einen Bot für ein internes Team und wollte ihn von einem Laptop aus starten, der über ein Mobilfunkmodem verbunden war. Der Versuch, einen Webhook auf die Proxy-Adresse zu registrieren, scheiterte erwartungsgemäß. Der Wechsel zu Long Polling über getUpdates mit Timeout 50 Sekunden löste die Aufgabe in einer halben Stunde: Die Verbindung ist ausgehend, weder Modem noch CGNAT stören. Der Anfrageverbrauch liegt bei etwa 1700 pro Tag im vollen Leerlauf, was für diese API unbedeutend ist. Zum Debuggen der Integration mit einem externen CRM, das nur Webhooks kann, wurde ein Reverse-SSH-Tunnel zu einem gemieteten Server mit fester Domain aufgesetzt, und in der Produktion zog der Empfänger auf den Server selbst um.

Fall 3. Status-Monitoring auf einem Marktplatz ohne Webhooks

Ein Betreiber mehrerer Shops auf einem Marktplatz verfolgte die Bestellstatus über eine API, die keine Webhooks hatte. Naives Polling alle 10 Sekunden pro Shop ergab rund 50.000 Anfragen pro Tag und stieß regelmäßig an 429. Nach der Neugestaltung nach den Prinzipien aus dem sechsten Abschnitt (Cursor updated_after, adaptives Intervall von 15 Sekunden bis 10 Minuten, Behandlung von Retry-After, Idempotenz über die Bestellkennung) sank die Last auf etwa 4.000 Anfragen pro Tag, also um mehr als den Faktor 12, während die durchschnittliche Erkennungslatenz in Arbeitszeiten unter 20 Sekunden blieb. Ausgehende Anfragen an die Marktplatz-API und an die API des Zustelldienstes wurden auf separate Proxeon-Ausgangsadressen verteilt, damit die Limits einer Integration die andere nicht beeinflussen und damit an der Quelladresse in den Logs sofort erkennbar ist, welcher Shop die Anfrage initiiert hat.

FAQ: Häufige Fragen zu Proxy und Webhook-Empfang

Wenn ich eine statische dedizierte IP eines Proxys habe, kann ich darauf Webhooks empfangen?

Nein. Die Statik der Adresse löst die Frage der Vorhersagbarkeit für ausgehende Anfragen und für Whitelists auf Seiten fremder APIs. Aber ein Listening-Port mit Ihrem Code auf dieser Adresse gibt es weiterhin nicht: Dort läuft Proxy-Software, nicht Ihr Empfänger. Für den Empfang braucht man einen Server, den Sie kontrollieren.

Warum zeigen IP-Prüfdienste eine öffentliche Adresse, wenn sie von außen nicht adressierbar ist?

Der Prüfdienst sieht die Quelladresse der eingehenden Anfrage an ihn, also die Adresse des NAT-Gateways des Anbieters oder des Proxy-Knotens. Das ist die Adresse, von der Verkehr ausgeht, nicht die Adresse, unter der man bei Ihnen hereinkommen kann. Sichtbarkeit der Adresse von außen und die Möglichkeit, eine Verbindung zu ihr zu initiieren, sind verschiedene Eigenschaften.

Kann man Webhooks über SOCKS5 mit dem BIND-Befehl empfangen?

In der Praxis nein. Der Befehl ist in der Spezifikation beschrieben, aber auf kommerziellen Knoten aus Sicherheitsgründen meist nicht implementiert, und wo er es ist, nimmt er eine eingehende Verbindung für kurze Zeit nach einer ausgehenden zum selben Host an. Für die Registrierung einer dauerhaften Webhook-URL mit TLS ist das ungeeignet.

Worin unterscheidet sich ein Reverse-Tunnel von Portweiterleitung am Router?

Portweiterleitung funktioniert nur, wenn auf Ihrer Hardware eine echte öffentliche Adresse liegt: Der Router nimmt eine eingehende Verbindung an und leitet sie ins Netz weiter. Ein Reverse-Tunnel braucht bei Ihnen überhaupt keine öffentliche Adresse: Ihre Maschine initiiert selbst eine ausgehende Verbindung zu einem öffentlichen Server, und dieser lauscht in Ihrem Namen. In Mobilfunknetzen mit CGNAT ist der erste Weg grundsätzlich nicht verfügbar, der zweite funktioniert.

Ist ein Reverse-Tunnel für die Produktion zuverlässig?

Unter Bedingungen: feste Domain, automatische Wiederverbindung, Prüfung der Verbindungslebendigkeit, Monitoring von Abbrüchen und Pufferung auf der öffentlichen Seite während der Nichtverfügbarkeit. Ohne diese Bedingungen taugt der Tunnel für Entwicklung, nicht für den Betrieb. Für kritische Integrationen ist es zuverlässiger, den Empfänger direkt auf einem öffentlichen Server zu platzieren.

Ist Polling in der Latenz wirklich nicht schlechter als Webhooks?

Long Polling liefert eine Latenz, die mit Webhooks vergleichbar ist: Das Ereignis kommt im Moment seines Auftretens. Gewöhnliches adaptives Polling liefert eine Latenz vom minimalen Intervall in aktiven Stunden bis zum maximalen in Ruhephasen. Für viele Geschäftsprozesse ist eine Latenz von 15–30 Sekunden akzeptabel. Webhooks hängen dagegen von der Zustellbarkeit eingehender Verbindungen ab und benötigen einen Abgleichmechanismus für Verluste, sodass in realen Systemen Polling Webhooks oft ergänzt und nicht gegen sie verliert.

Braucht man einen Proxy, wenn man schon einen VPS mit öffentlicher Adresse hat?

Für den Empfang von Webhooks nicht. Für ausgehende Anfragen aus den Handlern ist er nützlich, wenn eine fremde API empfindlich auf die Herkunftsregion reagiert, wenn die Limits verschiedener Integrationen nach Adressen isoliert werden sollen oder wenn Anfragen wie der Verkehr eines Mobilfunkteilnehmers eines bestimmten Anbieters aussehen sollen. Das ist eine separate Aufgabe, die mit einem separaten Werkzeug gelöst wird.

Wie stellt man sicher, dass der Anbieter überhaupt versucht, den Webhook zuzustellen?

Die meisten Anbieter führen ein Zustellprotokoll mit Antwortcodes und Fehlerursachen. Schauen Sie zuerst dort hinein: Man sieht, ob die Domain aufgelöst wird, ob TLS aufgebaut wird, welchen Code Ihr Server zurückgegeben hat und in wie vielen Millisekunden. Für die lokale Diagnose starten Sie einen minimalen HTTP-Server, der Header und Body protokolliert, und richten Sie den Tunnel darauf.

Was tun, wenn der Anbieter eine Antwort in 3 Sekunden verlangt, die Verarbeitung aber 10 dauert?

Empfang und Verarbeitung trennen. Der Empfänger prüft die Signatur, legt das Ereignis in eine Queue und antwortet in Dutzenden von Millisekunden mit 200. Ein Worker liest die Queue aus und verarbeitet das Ereignis so lange wie nötig, mit ausgehenden Aufrufen an fremde APIs, bei Bedarf über einen Proxy, mit expliziten Timeouts und Wiederholungen.

Fazit: Das richtige Modell und die nächsten Schritte

Wenn man den Artikel auf einen Gedanken reduziert, lautet er: Ein Proxy ändert, von wo aus Sie ins Netz gehen, aber er schafft keinen Ort, an dem man zu Ihnen hereinkommen kann. Die Verbindungsrichtung ist eine fundamentale Eigenschaft, und kein Tarif dreht sie um. Der mobile Proxy von Proxeon macht Ihre ausgehenden Anfragen zum Verkehr eines Teilnehmers eines bestimmten Anbieters, und genau deshalb erbt er die fehlende externe Adressierbarkeit eines Teilnehmers: Hinter CGNAT gibt es keine Listening-Ports, und die Adresse ändert sich von Natur des Netzes aus.

Der Empfang von Webhooks wird mit Werkzeugen einer anderen Klasse gelöst. Ein öffentlicher Server mit Domain und TLS ist die Basisvariante für den Betrieb. Ein Reverse-Tunnel ist für die Entwicklung und für Fälle, in denen Code lokal laufen muss. Eine Event-Queue und Long Polling auf Anbieterseite sind die eleganteste Variante, wenn der Anbieter sie bietet. Adaptives Polling mit Cursor, bedingten Anfragen und Respekt vor Limits ist der universelle Ausweichweg, der bei gutem Design an praktischem Wert nicht hinter Webhooks zurücksteht.

Und der Proxy kehrt dort ins Schema zurück, wo sein Platz ist: bei ausgehenden Aufrufen aus Handlern, bei der Verifikation von Ereignissen durch Rückfrage, bei der Isolierung von Limits verschiedener Integrationen über Ausgangsadressen. Der Empfänger lauscht direkt, Ausgehendes läuft über den Proxy – diese Formel deckt die überwiegende Mehrheit realer Aufgaben ab.

Was nach dem Lesen zu tun ist

  1. Öffnen Sie die Einstellungen jeder Ihrer Webhook-Subscriptions und prüfen Sie, wohin die URL zeigt: auf einen Server, den Sie kontrollieren und der auf Port 443 mit gültigem Zertifikat lauscht.
  2. Stellen Sie sicher, dass der Empfänger schnell antwortet und die Verarbeitung in eine Queue ausgelagert ist; prüfen Sie das Vorhandensein von Signaturprüfung und Berücksichtigung verarbeiteter Kennungen.
  3. Schreiben Sie für Integrationen ohne Webhooks das Polling nach der Checkliste aus dem sechsten Abschnitt um und messen Sie, wie sich Anzahl der Anfragen und Latenz verändert haben.
  4. Überprüfen Sie die ausgehenden Aufrufe aus den Handlern: Wo eine stabile regionale Adresse oder eine Isolierung von Limits nötig ist, binden Sie einen Proxy mit separater Session und expliziten Timeouts ein.
  5. Fügen Sie als Absicherung für kritische Webhooks ein Abgleich-Polling hinzu: Fragen Sie stündlich Ereignisse des letzten Intervalls ab und vergleichen Sie sie mit den verarbeiteten.

Die Trennung der Aufgaben in ausgehend und eingehend ist kein Pedantismus, sondern ein Weg, keine Stunden mehr mit dem Debuggen von etwas zu verbringen, das per Definition nicht funktionieren kann, und sie stattdessen in das zu investieren, was funktionieren wird.