citizenfx / fivem

The source code for the Cfx.re modification frameworks, such as FiveM, RedM and LibertyM, as well as FXServer.
https://cfx.re/
3.56k stars 2.1k forks source link

Issue with 'sv_listingHostOverride' and Reverse Proxy URL Resolution #2280

Open MiguelFGM opened 11 months ago

MiguelFGM commented 11 months ago

Following up on the issue: Always Attempting to Connect Using Default Port Related pull request in docs: Proxy Setup Guide URL Resolution Clarification

Issue: While using the sv_listingHostOverride for Reverse Proxying setup, FiveM is not properly resolving into the correct URL that it should, I'll provide an example, where this setting is being used as:

Resulting behavior:

  1. connect play.domain.com wrongly attempts to connect to "https://play.domain.com:30120"
  2. connect http://play.domain.com or connect https://play.domain.com correctly attempts to connect to "http://play.domain.com" or "https://play.domain.com"

Concern: Now let's put logic into action here, when we are setting up a Reverse Proxy, we are trying to make the TCP ports go forward into a Reverse Proxy system such as NGINX or any Content Delivery Network, which can provide us tons of security and flexible ways to develop our firewalls, which prevent issues such as DDoS Attacks. In these terms, we should be aware that we are dealing with players that are non-related to IT environments (in most cases). When we set up CloudFlare as Reverse Proxying (Ignoring products such as Argo Tunnels) we know that Cloudflare will proxy_pass those connections to port 80 or 443, leaving the door closed to the possibility of proxying pass into other ports, such as any other reverse proxy, they only proxy_pass into port 80 or 443. So in this environment why are forcing the default domain connections using the connect command that has a reverse proxy setup on it to resolve into play.domain.com:30120? In these terms we are being forced to set our reverse proxy with NGINX in our own server and not use AnyCast networks of services such as content delivery networks like Cloudflare, ignoring completely DDoS Protection and developing a pseudo-proxy that in the end will do nothing, Reverse Proxy should point to 80 or 443 and NOT 30120 otherwise we would simply use the server IP as in the end, it would be the same.

Sure, we can use "connect http://play.domain.com" or "connect https://play.domain.com" but good luck for us making our players who are NOT related to IT understand that they should place https:// or http:// before writing the domain in question.

I'm writing this because we can't properly set a reverse proxy due to the same fact (it's resolving to https://play.domain.com:30120) and our reverse proxy only proxy_passes to port 80 or 443 (as any other reverse proxy solution), we limited to either pay 200€/mo for a dedicated IP where they can allow port 30120, or remove the reverse proxying function and get DDoS Attacks.

I would also like to mention that, when a connection happens by the serverList it will properly resolve into "https://play.domain.com", so, via serverList, it always works as it doesn't add the :30120 at the end of the connection, so I have no clue why the connect command does.

Request: Clarification and resolution of this issue to enable secure and efficient server operation using standard reverse proxy configurations.

Thank you for your attention to this critical matter.

bosskitz commented 11 months ago

I totally understand and agree. This is the current situation, where players have to add "http://" or "https://" protocols to be able to connect properly as it defaults to 30120 when it's missing. In addition to this, server listing will list the server as offline sometimes. An HTTP error also prints on the log when it happens. I am not as techy as @MiguelFGM, and a lot of server owners aren't too but with this above, if implemented, would greatly benefit the players and the owners.

blattersturm commented 11 months ago

The listing host override flag applies to the listing specifically: specifying a URL in the connect command has no relation to listings whatsoever. In theory, something could be implemented in client code to resolve a bare host name to both :30120 as well as :443 in parallel and take whichever works, so this doesn't have the confusing behavior described here.

Servers showing as offline when they aren't would be a separate issue and it might help if you'd send the log line with the HTTP error you described (and this shouldn't prevent the connection button from being clickable! if it does, that would be a bug), however you can also directly connect using the server ID like e.g. connect 7b6bor which should use the address from the listing.

bosskitz commented 11 months ago

@blattersturm Hey, kinda late to respond to this but I have the error I was looking for. [ citizen-server-impl] Server list query returned an error: System.Net.Sockets.SocketException: Resource temporarily unavailable <- System.Net.Http.HttpRequestException: Resource temporarily unavailable (sub.domain.com:443) <- System.Exception: Could not query viahttps://sub.domain.com/- check if your sv_listingHostOverride is correct

Fully aware that this might be for another topic just to answer the above.

Got this error while players are inside the city and the others who are attempting to connect could not join because the connect button on the server list is greyed out. Not sure why it's greyed out when a lot of us are currently inside. Some others can connect though. Thanks for the response above by the way. Frankly, didn't know that it's possible to connect using the code :D

blattersturm commented 11 months ago

Right, that would be a backend issue on here indeed (running out of ephemeral TCP client ports?), this should be escalated there by someone.

Similarly 'might be offline' shouldn't prevent connection unless this also leads to the connection endpoint being emptied out when using a fallback, both are still unintended behavior.

xDope7137 commented 9 months ago

image

Create a SRV record with correct UDP port and it will work. (Not tested with reverse proxy enabled, I assume it works)

Just tested, it works. However, there is a visual glitch in FiveM that it will show port 30120, but in reality it is connecting to SRV port you put in viz 30121 in my case.

image

xDope7137 commented 9 months ago

Another thing;

If you want a full DDOS protection, block 80, 443 ports directly in windows/linux firewall and only allow CDN's IP to access those ports. Block everything else. Windows is pretty easy. Inbound and Outbound both should be locked to just CDN to access nginx's server no other IP needs to see the proxy server.

I run fivem + nginx on same machine with Cloudflare as CDN and I just pay for VPS. Free DDOS protection with high download speeds for (most) regions.

I have mitigated all DDOS's after doing that. However, you need to keep fivem port open to public as client fetches information through that port before connecting to actual server for downloading assets.