Skip to content

Instantly share code, notes, and snippets.

@nathanctech
Created May 1, 2020 14:23
  • Star 36 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
FXServer Reverse Proxy

Proxying FiveM Connections using Nginx

As of server version 2377, support was added to FiveM to run a custom streaming proxy similar to cfx.re, but proxying the data connection (UDP) as well. This can be accomplished very easily with nginx acting as a proxy, and you can combine the caching proxy with it.

Requirements

  • Nginx 1.17+ (1.16 absolute minimum, guide tested on 1.17)
  • Server with reasonable network bandwidth (500mbps uplink strongly suggested)
  • FXserver version 2377 or later
  • SSL certificate for the domain you're using (highly recommended)

Steps

Prerequisites Setup

Some older linux distributions do not have the required version of nginx packaged. You can install the latest via the official nginx repositories if required. More information can be found here: https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#installing-prebuilt-debian-packages

Nginx Configuration

Below is an example configuration of implementing a combined proxy for both cache and the game server itself. You would place this file inside /etc/nginx/sites-available and use it just like any other website.

proxy-web.conf


upstream backend {
	server your.fivem.server.ip:30120;
}

proxy_cache_path /srv/cache levels=1:2 keys_zone=assets:48m max_size=20g inactive=2h;

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name yourhost.yourdomain.com;

    # SSL is highly encouraged but optional. If not using SSL, comment the below and change the listen blocks above.
    ssl_certificate /path/to/certificate.pem;
    ssl_certificate_key /path/to/privkey.pem;

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

    # if you do not wish to use the caching proxy, remove the below block
    location /files/ {
        proxy_pass http://backend$request_uri;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_cache_lock on;
        proxy_cache assets;
        proxy_cache_valid 1y;
        proxy_cache_key $request_uri$is_args$args;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 1;
    }
}

The next file should be placed outside this directory (i.e, in /etc/nginx):

stream-proxy.conf

stream {
    upstream backend{
        server your.fivem.server.ip:30120;
    }
    server {
		listen 30120;
		proxy_pass backend;
	}
	server {
		listen 30120 udp reuseport;
		proxy_pass backend;
	}
}

nginx.conf

Add the following within the http {} block, preserving everything else. You can configure the options based on your needs.

proxy_cache_path /srv/cache levels=1:2 keys_zone=assets:48m max_size=20g inactive=2h;

Add the following after the close of your http {} block:

include /etc/nginx/stream-proxy.conf

Use service nginx reload (varies by distribution, you just need to reload nginx via your favorite service manager) to apply your changes. You need to do the FXServer steps next before it will be usable.

FXServer Config

This configuration is pretty straightforward.

sv_forceIndirectListing true
sv_listingHostOverride yourhost.yourdomain.com
sv_listingIpOverride "your.proxy.ip.address"
sv_proxyIPPranges "your.proxy.ip.address/32"

# below is optional if you are not using the caching proxy
adhesive_cdnKey "randomKeyHere"
fileserver_add ".*" "https://yourhost.yourdomain.com/files"

Place this in your server.cfg and restart the server.

Testing

First, test your setup by trying to browse to https://yourhost.yourdomain.com/info.json. If you can see your server's information page, good job! If not, review logs for troubleshooting steps and check your configuration.

Next, attempt to connect to the server via the server list. If connection succeeds, you've successfully set up the server.

You can also connect to your server by using connect "https://yourhost.yourdomain.com", similar to using the cfx.re proxy you get with Nucleus.

Troubleshooting

HTTP errors

Review nginx logs (example, in /var/log/nginx/error.log) for clues. Double check your upstream {} entries as well.

"Failed to getinfo after 3 attempts"

This error is caused by your client not receiving UDP packets from the proxy. Review upstream settings to ensure you're actually passing these to the server. For this issue, you may have to use wireshark/tcpdump to trace where the packets get lost. Occasionally, the proxy server's host may be to blame.

"Failed to connect after 3 attempts"

Check your nginx version with nginx -t. This guide has been tested with 1.17.10 specifically, but any meeting the requirements above should work.

@BennoArnautovic
Copy link

BennoArnautovic commented Apr 16, 2021

Hello, when i'm trying to connect to my server with the proxy host, the player IP is not forwarded => it's the proxy ip adresse, it's normal ?
But when i'm trying with the CFX url it's the user IP :)

Same here, can someone help ? Also to add on this, when connecting using connect "https:\\proxy.domain.com" it also gets real ip ( using quotes and https)

@nefariousxyz
Copy link

Why i got stucked at Connecting...

@BennoArnautovic
Copy link

Why i got stucked at Connecting...

Check your nginx verison using nginx -v, it has to be 1.17 and higher

@viet
Copy link

viet commented Apr 20, 2021

I was able to successfully create a anti DDoS reverse proxy (via Lectron.com),

but it only works when players F8 and do "connect join.gta5rp.vn", the problem is the real server IP is still accessible via server list, causing DDoS to happen

The big question for me is that: How can I configure so that players who click on my server on the public FiveM server list to connect to the reverse proxy (join.gta5rp.vn) instead of the server's backend real IP?

@TheGreenkey
Copy link

Hello, when i'm trying to connect to my server with the proxy host, the player IP is not forwarded => it's the proxy ip adresse, it's normal ?
But when i'm trying with the CFX url it's the user IP :)

Same here, can someone help ? Also to add on this, when connecting using connect "https:\\proxy.domain.com" it also gets real ip ( using quotes and https)

I'm having the same issue. Seems that something broke around here. Before that it seems to have worked but now the proxy ip address isn't recognized as a proxy ip and the proxy ip is then added as the endpoint for every user.

@MathiAs2Pique
Copy link

MathiAs2Pique commented May 1, 2021

Hey, I got HTTP 502 error :/ Can you help me ?

And btw nothing in the nginx's logs...

@CoPilot36
Copy link

Hello!
I have some problems about this.

Sometimes when players connect they get: "Failed to fetch server variables. Empty reply from server - CURL error code 52 (Server returned nothing (no headers, no data))"

It works from time to time, and i get a feeling that the error coming when more players trying to connect.

I have followed the guide to 100%. And did exactly what it says.

Please give me some help :)

@hoangtran2703
Copy link

It's not sv_proxyIPPranges "your.proxy.ip.address/32", it's sv_proxyIPRanges "your.proxy.ip.address/32", there's an extra P next to proxyIP.

@tnschr
Copy link

tnschr commented Dec 17, 2021

I've installed the proxy server and I get connection to my backend server. When I hit my-server.com/info.json I get 404 error. Except of that when I connect to my backend server it gives me this error in my console.
Server list query returned an error: System.OperationCanceledException: The operation was canceled. <- System.TimeoutException: The operation was canceled. <- System.Threading.Tasks.TaskCanceledException: The request was canceled due to the configured HttpClient.Timeout of 30 seconds elapsing. <- System.Exception: Could not query via https://my-server.com/ - check if your sv_listingHostOverride is correct

Any ideas?

@MathiAs2Pique
Copy link

MathiAs2Pique commented Dec 17, 2021 via email

@tnschr
Copy link

tnschr commented Dec 17, 2021

I made a selfasigned ssl and now the error is:

erver list query returned an error: System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found). <- System.Exception: Could not query via https://comebacks.eu/ - check if your sv_listingHostOverride is correct

@MathiAs2Pique
Copy link

Can we move this con. to Discord ? add me on MathiAs2Pique_#1717

@CarmeloCampos
Copy link

I really try and it doesn't work.
Will there be a possibility to have multiple proxies?
Not just be one.

For example, a proxy for Brazil, another in Spain, another in Colombia.
But that they all point to the same IP. And that IP if it is public.

@suryabhaiin
Copy link

suryabhaiin commented Jan 19, 2022

Firstly very thank full for this artical. it work form me and protect my server from DDoS.

@damonho316
Copy link

I have some problems about this.

Sometimes when players connect they get: "Failed to fetch server variables. Empty reply from server - CURL error code 52 (Server returned nothing (no headers, no data))"

It works from time to time, and i get a feeling that the error coming when more players trying to connect about 11 player.

I have followed the guide to 100%. And did exactly what it says.

Please help

@suryabhaiin
Copy link

suryabhaiin commented Apr 9, 2022

I have some problems about this.

Sometimes when players connect they get: "Failed to fetch server variables. Empty reply from server - CURL error code 52 (Server returned nothing (no headers, no data))"

It works from time to time, and i get a feeling that the error coming when more players trying to connect about 11 player.

I have followed the guide to 100%. And did exactly what it says.

Please help

Due to IP rate limiting

@suryabhaiin
Copy link

I really try and it doesn't work. Will there be a possibility to have multiple proxies? Not just be one.

For example, a proxy for Brazil, another in Spain, another in Colombia. But that they all point to the same IP. And that IP if it is public.

Yes you can. it easy.

@McLovinIt101
Copy link

McLovinIt101 commented Dec 19, 2022

Is there a way to have mutable servers for the cache proxy? to see where the closed client is? and pick that server

@MathiAs2Pique
Copy link

For the cache I’m using CloudFlare’s edge cache, it’s redirecting the request to the closest CF cache server. Very efficient and free.

@McLovinIt101
Copy link

Hey! thanks for replaying, Its great that someone has done this. would you mind going into a little detail on how you set this up? Thanks!

@Klay4
Copy link

Klay4 commented Jan 3, 2023

@MathiAs2Pique hi, if possible could you explain us what caching rules you created on cloudflare? Thanks

@Klay4
Copy link

Klay4 commented Jan 4, 2023

Is it possible to ad a domain i the upstream backend -> server? I need this because the proxy vps has a static IP, so there's no problem, but the fivem server has a dynamic IP so I need a DDNS

@MathiAs2Pique
Copy link

@MathiAs2Pique hi, if possible could you explain us what caching rules you created on cloudflare? Thanks

Create a rule in CF dashboard under "rules" that contains something like this :
URL : cdn.example.com/files/*
Cache level: Everything
Cache edge TTL: 3 hours.

It will enable CF's edge cache.

@Klay4
Copy link

Klay4 commented Jan 6, 2023

@MathiAs2Pique hi, if possible could you explain us what caching rules you created on cloudflare? Thanks

Create a rule in CF dashboard under "rules" that contains something like this : URL : cdn.example.com/files/* Cache level: Everything Cache edge TTL: 3 hours.

It will enable CF's edge cache.

Thanks!

@SuryaRajgor
Copy link

SuryaRajgor commented Jan 10, 2023

everything is working fine but the backend Ip port Show in

netstat -an

Also players able to connect with real IP
and if Cloudflare proxy is on in A record then fivem not connect backend it connects to Cloudflare IP

@Klay4
Copy link

Klay4 commented Jan 27, 2023

do I need to even use the nginx proxy vps cache or I can just use the cloudflare page rule?

@McLovinIt101
Copy link

do I need to even use the nginx proxy vps cache or I can just use the cloudflare page rule?

you will still need to do the nginx proxy cache

#     location /files/ {
    proxy_pass http://backend$request_uri;
    add_header X-Cache-Status $upstream_cache_status;
}

}

@RamitaLewd
Copy link

Does this still work? I just followed the tutorial 100% but when I want to access the info.json I receive a 404 error and in the server console the following error
Server list query returned an error: System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found). <- System.Exception: Could not query via https://somethingsomething.com/` - check if your sv_listingHostOverride is correct`

I have the domain through cloudflare proxy and only the http, https and fivem ports are open on the server

@MathiAs2Pique
Copy link

MathiAs2Pique commented Mar 14, 2023

Does this still work? I just followed the tutorial 100% but when I want to access the info.json I receive a 404 error and in the server console the following error Server list query returned an error: System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found). <- System.Exception: Could not query via [https://somethingsomething.com/](https://somethingsomething.com/%60) - check if your sv_listingHostOverride is correct

I have the domain through cloudflare proxy and only the http, https and fivem ports are open on the server

Hard to say without the config, send it to me over Discord if you want some help with it.

btw I just made an utility to configure anything automatically:
https://github.com/MathiAs2Pique/Fivem-Proxy-Install.sh

@Kevinvincentals
Copy link

For the cache I’m using CloudFlare’s edge cache, it’s redirecting the request to the closest CF cache server. Very efficient and free.

I've just added you on discord regarding this. Thank you :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment