Zum Inhalt

Deine eigene Domain im FiveM-Server-Browser anzeigen

Diese Anleitung erklärt von Anfang bis Ende, wie du deine eigene Domain (z. B. play.example.com) im ingame-Server-Browser von FiveM zum Vorschein bringst, wenn Spieler nach deinem Server suchen, und wie du connect play.example.com aus der F8-Konsole funktionsfähig machst.

Wir behandeln:

  • Was Zaroz Cloud automatisch einrichtet, wenn du eine Domain an deine Bestellung anhängst.
  • Die zusätzlichen Zeilen in server.cfg, die nötig sind, damit die Domain in der Liste tatsächlich erscheint (statt der rohen IP).
  • Wie das cfx.re-Listing-Backend wirklich arbeitet, damit du es debuggen kannst, wenn etwas schiefläuft.
  • Das fortgeschrittene Setup (eigener Reverse Proxy), wenn du die IP für DDoS-Schutz komplett verstecken willst.

Wie eine eigene Domain überhaupt in die Liste kommt

Bevor wir an irgendeine Config rangehen, brauchst du das mentale Modell. FiveM macht zwei völlig unterschiedliche Dinge über zwei völlig unterschiedliche Code-Pfade:

  1. Beitritt mit connect <name> in der F8-Konsole. Dieser Pfad nutzt DNS. Der Client schlägt einen SRV-Record (_cfx._udp.<deine-domain>) nach, um den Port zu finden, dann einen A-Record für die IP, und verbindet sich. Er fragt das cfx.re-Listing-Backend zu keinem Zeitpunkt etwas.

  2. Den Server im ingame-Browser suchen oder beitreten. Dieser Pfad nutzt das cfx.re-Listing-Backend. Das Backend pingt deinen Server periodisch über eine URL wie https://<host>/dynamic.json an, um die Listing-Daten zu aktualisieren. Wenn ein Spieler im Browser auf "Connect" klickt, gibt das Backend dem Client ein connectEndPoints-Feld zurück, das ihm sagt, wohin er sich wirklich verbinden soll. Dieser connectEndPoints-Wert entscheidet, ob der Spieler deine IP oder deine Domain sieht.

Die beiden Pfade sind voneinander unabhängig: SRV-Records lassen den connect-Befehl funktionieren, aber sie haben null Einfluss darauf, was der ingame-Browser anzeigt. Um den Browser zu steuern, musst du deinem eigenen Server sagen, welche Domain er gegenüber dem Listing-Backend bewerben soll.

Die offiziellen Regeln, wie ein Client ein Verbindungsziel auflöst, sind in der Cfx.re-Proxy-Doc zusammengefasst:

  • Reine Hosts (z. B. play.example.com) werden zu http://play.example.com:30120/.
  • Hosts mit Port (z. B. play.example.com:30121) werden zu http://play.example.com:30121/.
  • URLs mit Schema (z. B. https://play.example.com/) werden so übernommen, mit den Default-Ports des Schemas (80/443).

Die letzte Regel ist die wichtigste für die Liste: Wenn du willst, dass die Liste Spielern eine saubere https://play.example.com/-URL ausliefert (ohne Port, ohne Schema zum Selbsteintippen), muss das Listing-Backend deinen Server unter exakt dieser URL erreichen können.

Was Zaroz Cloud für dich erledigt

Wenn du eine Domain im Dashboard an deine Bestellung anhängst (Bestellseite → Tab External Access → Custom domain):

  1. Wir nehmen das gewählte Parent-Domain (z. B. play.zaroz.cloud) und deinen gewählten Subdomain (z. B. myserver) und bauen daraus den vollständigen Hostnamen, z. B. myserver.play.zaroz.cloud.
  2. Über Cloudflare legen wir einen A-Record für diesen Hostnamen an, der auf die öffentliche IP zeigt, die wir deiner Bestellung zugewiesen haben.
  3. Für FiveM-Bestellungen legen wir zusätzlich einen SRV-Record unter _cfx._udp.<dein-host> an, der zurück auf denselben Hostnamen mit dem UDP-Game-Port deiner Bestellung zeigt. (Bei Minecraft ist es _minecraft._tcp.<host>, bei Factorio _factorio._udp.<host>.)
  4. Ein Hintergrund-Reconciliation-Job hält beide Records synchron, falls deine Bestellung auf einen anderen Node umzieht oder ihr Port neu zugewiesen wird.

Der Nettoeffekt ist, dass sobald die Domain angehängt ist, Spieler bereits mit connect myserver.play.zaroz.cloud aus der F8-Konsole beitreten können, auch ohne Port. Der SRV-Record sagt dem FiveM-Client, welcher UDP-Port zu nehmen ist, und der A-Record liefert die IP.

Was das allein nicht tut: es ändert nicht, was der ingame-Server-Browser anzeigt. Das verlangt weiterhin Änderungen in deiner server.cfg.

Minimales server.cfg-Setup für den Server-Browser

Wenn dir die SRV-basierte connect-Variante reicht (Adresse in der F8-Konsole eintippen), brauchst du die server.cfg gar nicht anzufassen. Die Records, die wir anlegen, reichen.

Wenn du willst, dass der Server-Browser deine Domain zeigt, wenn Spieler nach dir suchen, pack diese Zeilen oben in deine server.cfg:

# Tut so, als ob du keine statische IP hättest. Zwingt das Listing-Backend
# dazu, connectEndPoints/sv_listingHostOverride zu nutzen, statt die IP zu leaken.
sv_forceIndirectListing true

# Sagt dem Listing-Backend, welchen Host es abfragen soll und welchen Host es
# den Spielern im "Connect"-Button zurückgibt.
sv_listingHostOverride "http://myserver.play.zaroz.cloud:30120/"

Nutze die vollständige URL-Form, nicht nur den Hostnamen:

  • Das Schema (http://) sagt dem Listing-Backend, dass dein Server reines HTTP spricht, nicht HTTPS. Der Default-FXServer-Endpunkt ist HTTP, nicht HTTPS.
  • Der Port (:30120) ist der echte Game-/HTTP-Port deines Containers. Lässt du ihn weg, geht das Listing-Backend von Port 80 aus, auf dem FXServer aber nicht lauscht, und der Heartbeat schlägt fehl.

Bei Zaroz Cloud findest du <port> ganz oben in deiner server.cfg, in der Zeile endpoint_add_tcp "0.0.0.0:<port>", die unser Entrypoint bei jedem Containerstart neu schreibt. Du kannst ihn auch direkt aus dem Dashboard ablesen, unter Bestellseite → External Access → Player connection:

Player-connection-Panel mit Serveradresse und Port

Der Teil hinter dem Doppelpunkt in Server address ist der Port, den du in sv_listingHostOverride einsetzen musst.

Nach einem Neustart sollte der Master das Override innerhalb weniger Minuten aufgreifen und anfangen, deinen Hostnamen in der Liste zu bewerben. Wie du das prüfst, steht weiter unten unter "So überprüfst du, dass es geklappt hat".

Warum jede Zeile gebraucht wird

sv_forceIndirectListing true

Aus der offiziellen Doc: "prevents the server list from advertising your server using its actual IP" (verhindert, dass die Liste deinen Server mit seiner echten IP bewirbt).

Wenn das aus ist, veröffentlicht die Liste weiterhin die rohe IP, egal was sv_listingHostOverride sagt, weil das Backend annimmt, dass jeder Client direkt zur Quell-IP verbinden kann und der Host-Override nur intern für den Heartbeat gilt. Ist es an, wird die IP unterdrückt, und das Feld connectEndPoints trägt stattdessen den Hostnamen.

sv_listingHostOverride

Aus der offiziellen Doc: "makes the server list backend request https://server1.example.com/ instead of the default" (lässt das Listing-Backend https://server1.example.com/ abfragen statt der Standardadresse).

Es erfüllt zwei Rollen gleichzeitig:

  1. Wo das Backend dich pingt. Der cfx.re-Heartbeat ruft <host>/dynamic.json, <host>/info.json und <host>/players.json an dieser URL ab.
  2. Was Spieler sehen / wohin sie verbinden. Wenn das indirekte Listing aktiv ist, geht derselbe Wert als connectEndPoints an die Clients zurück, was den "Connect"-Button im ingame-Browser steuert.

Wegen dieser Doppelrolle muss der Wert aus dem öffentlichen Internet erreichbar sein. Bei Zaroz ist der HTTP-Endpunkt deines Containers an 0.0.0.0:<dein-port> gebunden, und dein A-Record zeigt den Hostnamen bereits auf die richtige IP, also funktioniert http://<host>:<port>/ ohne zusätzliche Infrastruktur.

Was ist mit sv_listingIpOverride?

Auf Zaroz Cloud musst du das normalerweise nicht setzen. Aus der offiziellen Doc: "this value is only needed if the server list backend can't guess the IP to query itself, and is not provided to any front-end connection" (nur nötig, wenn das Listing-Backend die IP nicht selbst herausfinden kann, und wird an keine Client-Verbindung weitergegeben).

Unser Entrypoint schreibt bereits den passenden sv_listingIpOverride für die öffentliche IP, die wir dir zugewiesen haben, bei jedem Containerstart. Das ist die IP, mit der der Master deine dynamic.json ansteuert, wenn kein Host-Override gesetzt ist. Mit sv_listingHostOverride ist der IP-Override größtenteils redundant, aber unschädlich.

Was ist mit sv_endpoints?

sv_endpoints ist "the actual endpoint your server is hosted on, or one or multiple server endpoint proxies" (der echte Endpunkt, auf dem dein Server läuft, oder ein oder mehrere Endpoint-Proxies).

In einem normalen Setup ohne Proxy brauchst du das nicht: Das Listing-Backend nutzt die IP, die es pingt, und den Port, den es entdeckt. Du setzt es nur, wenn du deinen eigenen Reverse Proxy oder DDoS-Tunnel zwischen Spielern und FXServer betreibst, und den Spielern gesagt werden soll, dass sie sich mit der IP/dem Port des Proxys verbinden, nicht mit denen des FXServers.

DNS-Records, in voller Pracht

Falls du auf der Cloudflare-Seite nachsehen willst, was wir eingetragen haben, so sieht ein funktionierender Zaroz-Custom-Domain aus:

;; A-Record
myserver.play.zaroz.cloud.   60   IN   A   188.213.7.49

;; SRV-Record (FiveM)
_cfx._udp.myserver.play.zaroz.cloud.  60  IN  SRV  0 0 32541 myserver.play.zaroz.cloud.

Felder in Reihenfolge: Priority (0), Weight (0), Port (der UDP-Game-Port deiner Bestellung, z. B. 32541), Target (dein Hostname, mit Punkt am Ende).

Die IP und der Port sind Platzhalter; sie spiegeln das wider, was der Kernel deiner Bestellung im Moment der Record-Erstellung zugewiesen hat. Wird deine Bestellung auf einen anderen Node verschoben oder ihr Port neu zugewiesen, schreibt der Reconcile-Job beide Records um.

So überprüfst du, dass es geklappt hat

Nachdem du den Server mit der neuen server.cfg neu gestartet hast, kannst du drei Wege prüfen.

1. Endpunkte im Browser aufrufen

Diese sollten alle JSON (oder zumindest HTTP 200) zurückgeben:

  • http://<deine-domain>:<dein-port>/info.json
  • http://<deine-domain>:<dein-port>/players.json
  • http://<deine-domain>:<dein-port>/dynamic.json

Wenn einer davon ins Timeout läuft oder einen Verbindungsfehler liefert, kommt auch der Master nicht durch. Prüf deine Firewall und vergewissere dich, dass die URL in sv_listingHostOverride zu dem passt, worauf dein Container tatsächlich lauscht.

2. Server-Konsole beobachten

Nach dem Boot schau nach Logzeilen von [citizen-server-impl]. Ein gesunder Server loggt nach kurzer Zeit erfolgreiche Heartbeats. Siehst du Server list query returned an error: server request failed for endpoint http://<host>:<port>/dynamic.json, ist der Master gegen das Override gestoßen und gescheitert; die häufigste Ursache (License-Key-Cache-Verzögerung) ist in der Anleitung zum Server-list-query-Fehler beschrieben.

3. Öffentliche Servers-API abfragen

Geh zu https://servers.fivem.net/api/servers/single/<deine-cfx-id> (die cfx-ID ist die kurze alphanumerische Zeichenkette in deiner ingame-Listing-URL) und such im JSON nach dem Feld connectEndPoints. Sobald dein Override durchgereicht ist, sollte da deine Domain stehen, nicht die rohe IP.

Fortgeschritten: eigener Reverse Proxy

Das Basis-Setup oben versteckt deine IP aus der Serverliste, aber ein entschlossener Angreifer kann sie immer noch finden, indem er direkt mit den richtigen Paketen auf den Game-Port klopft. Wenn du die IP komplett verstecken willst (zum Beispiel hinter einem Cloudflare-Spectrum-Tunnel oder deinem eigenen nginx auf einer separaten IP), brauchst du einen echten Reverse Proxy.

Referenzlayout, abgeleitet aus der offiziellen Proxy-Doc und dem Community-nginx-Gist:

# HTTP-Layer-Proxy: 443 → HTTP-Game-Port des FXServers
upstream fivem_http {
    server <deine-zaroz-ip>:<dein-port>;
}

server {
    listen 443 ssl http2;
    server_name myserver.example.com;

    ssl_certificate     /etc/letsencrypt/live/myserver.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myserver.example.com/privkey.pem;

    location / {
        proxy_pass http://fivem_http;
        proxy_set_header Host             $host;
        proxy_set_header X-Real-IP        $remote_addr;
        proxy_set_header X-Forwarded-For  $remote_addr;
        proxy_http_version 1.1;
    }

    location /files/ {
        proxy_pass        http://fivem_http$request_uri;
        proxy_cache       assets;
        proxy_cache_valid 1y;
    }
}

# Stream-Layer-Proxy: TCP + UDP 30120 → Game-Port des FXServers
stream {
    upstream fivem_game {
        server <deine-zaroz-ip>:<dein-port>;
    }
    server {
        listen 30120;
        proxy_pass fivem_game;
    }
    server {
        listen 30120 udp reuseport;
        proxy_pass fivem_game;
    }
}

Mit diesem Proxy davor wird server.cfg zu:

sv_forceIndirectListing true
sv_listingHostOverride  "https://myserver.example.com/"
sv_endpoints            "<deine-proxy-ip>:30120"
sv_proxyIPRanges        "<deine-proxy-ip>/32"

Zwei Dinge zu diesem Setup:

  • Du kannst nicht den Zaroz-verwalteten Subdomain wiederverwenden (z. B. myserver.play.zaroz.cloud), weil dessen A-Record bereits auf die IP deines Containers zeigt und wir ihn automatisch verwalten. Nimm eine Domain, die dir gehört (eine Custom-Domain, deren DNS du in Cloudflare oder anderswo hostest).
  • sv_proxyIPRanges ist Pflicht; ohne lehnt der FXServer den X-Real-IP-Header ab, den der Proxy setzt, und der Per-IP-Rate-Limiter pegelt gegen die eine Proxy-IP, was schnell zu Engpässen führt.

Häufige Fallstricke

  • Schema oder Port in sv_listingHostOverride vergessen. sv_listingHostOverride "myserver.play.zaroz.cloud" (nur den Host) zu schreiben, lässt das Listing-Backend http://myserver.play.zaroz.cloud:30120/ versuchen, egal welcher Port deine Bestellung wirklich nutzt, und das schlägt fehl. Nimm immer die vollständige URL-Form mit korrektem Schema und Port.
  • sv_forceIndirectListing true nicht gesetzt. Ohne das leakt deine IP weiterhin in der Liste, obwohl das Override gesetzt ist, weil das Backend sv_listingHostOverride als rein internen Wert behandelt und für Clients trotzdem die rohe IP bewirbt.
  • Erwarten, dass SRV-Records den Server-Browser beeinflussen. SRV-Records wirken nur auf den connect-Befehl in der F8-Konsole. Der Server-Browser nutzt das Listing-Backend, das nur sv_listingHostOverride und sv_forceIndirectListing beachtet.
  • DNS-Propagation. Cloudflare propagiert schnell (typischerweise in unter einer Minute), aber das cfx.re-Listing-Backend hat seinen eigenen Cache. Rechne mit ein paar Minuten nach Konfigurationsänderungen, bevor das neue connectEndPoints in der öffentlichen Servers-API auftaucht.

Wann du dich melden solltest

Wenn du die Anleitung befolgt hast und:

  • Die Endpunkte (/info.json, /dynamic.json, /players.json) im Browser erreichbar sind, und
  • Dein ingame-Server immer noch die rohe IP zeigt, oder
  • Das connectEndPoints in https://servers.fivem.net/api/servers/single/<cfx-id> nach einem Neustart immer wieder auf die IP zurückfällt,

schick uns deine server.cfg (mit rcon_password und sv_licenseKey geschwärzt), die cfx.re-ID deines Servers und deine Bestellnummer. Wir prüfen, ob das Listing-Backend uns erreicht, und bestätigen, dass auf unserer Seite nichts dein Override überschreibt.