GameServerManagers / LinuxGSM

The command-line tool for quick, simple deployment and management of Linux dedicated game servers.
https://linuxgsm.com
MIT License
4.35k stars 823 forks source link

Don't exit script when ip is 0.0.0.0 #1741

Closed 991jo closed 4 years ago

991jo commented 6 years ago

when the ip parameter in the config files is set to 0.0.0.0 the script prints an error

[ WARN ] Multiple active network interfaces

Manually specify the IP you want to use within the csgoserver script.
Set ip="0.0.0.0" to one of the following:

(The corresponding FAQ article is https://github.com/GameServerManagers/LinuxGSM/wiki/FAQ#-warn--multiple-active-network-interfaces )

I have multiple problems with this:

  1. It prints a warning and then the script exits. Warnings should not should prohibit the server start. Critical events do that.
  2. It is sometimes required to run the server with a 0.0.0.0 ip, because in the case of many srcds-based servers it's needed for many LAN settings. If you do not have a -ip setting the server will bind it's rcon to 127.0.1.1 and will therefore not be reachable from the network if you add a -ip setting that is not 0.0.0.0 the server only binds to that ip and does not listen to broadcast traffic anymore, therefore it is not found by the LAN server browser anymore. (sv_lan 1 is required for this to work)

Possible workarounds are modifying the start-parameters and adding a valid ip variable that is not used at all. e.g. adding somethin like this to the lgsm config files:

ip=1.2.3.4
fn_parms(){
parms="-game fof -strictportbind -ip 0.0.0.0 -port ${port} +clientport ${clientport} +tv_port ${sourcetvport} +map ${defaultmap} +servercfgfile ${servercfg} -maxplayers ${maxplayers}"
} 

But this means that updates on the startup parameters are ignored. This is not a nice solution.

dgibbs64 commented 6 years ago

Thanks for the feedback. I belive the WARN message should be changed to a FAIL instead. As it is a critical error.

The check IP feature is designed to ensure that an IP is correctly set to allow servers to be queried using gsquery, display correct IP details and to bind to the correct IP. Not specifying a specific IP causes issues with LinuxGSM itself and for some game servers it can give odd results, because of this not specifying an IP will prevent the server from starting.

If you are using a LAN IP for example 192.168.1.5 then the IP should be set to that address.

I don't understand what you mean by when you say that setting an IP other than 0.0.0.0 will prevent LAN broadcast as your LAN IP should be set.

it also should be possible to remove the -ip setting from parms all together if it is causing an issue.

Hope this helps

991jo commented 6 years ago

Hi

I just realized, that the script say [ FAIL ], the wiki article is not up to date. Regarding the broadcast: I am using Fistful of Frags, but this should work with any other srcds game. When using -ip with the correct IP address, then all sockets of the server bind to that IP:

sudo netstat -tulpn | grep srcds
tcp        0      0 192.168.100.128:27015   0.0.0.0:*               LISTEN      12090/./srcds_linux 
udp        0      0 192.168.100.128:27005   0.0.0.0:*                           12090/./srcds_linux 
udp        0      0 192.168.100.128:27015   0.0.0.0:*                           12090/./srcds_linux 
udp        0      0 192.168.100.128:27020   0.0.0.0:*                           12090/./srcds_linux 

when you open up tcpdump or wireshark you can see the clients query packets via broadcast but no responses from the server (client and server running on the same host, no firewalls in place that could block packets)

sudo tcpdump port 27015 -i any -A             
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
09:03:13.779157 IP agony.52503 > 255.255.255.255.27015: UDP, length 25
E..5.0@.@.W_..d.......i..!%[....TSource Engine Query.

now with -ip 0.0.0.0:

tcp        0      0 0.0.0.0:27015           0.0.0.0:*               LISTEN      13423/./srcds_linux 
udp        0      0 0.0.0.0:27005           0.0.0.0:*                           13423/./srcds_linux 
udp        0      0 0.0.0.0:27015           0.0.0.0:*                           13423/./srcds_linux 
udp        0      0 0.0.0.0:27020           0.0.0.0:*                           13423/./srcds_linux 
sudo tcpdump port 27015 -i any -A 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
09:01:51.928876 IP agony.33146 > 255.255.255.255.27015: UDP, length 25
E..5..@.@.X...d......zi..!%[....TSource Engine Query.
09:01:51.939334 IP agony.27015 > agony.33146: UDP, length 72
E..dV.@.@.....d...d.i..z.PJ.....I.no IP Bind.fof_depot.fof.Shootout......dl..429...i..Zg.$@.........

Only with the second case with the 0.0.0.0 IP bind the server answers the query packets that are send via broadcast. This means that either srcds is broken since possibly ever or this is intended by srcds which means there is a valid reason to bind to 0.0.0.0.

Nodens- commented 6 years ago

0.0.0.0 means listening on everything. This should be allowed and is actually needed for many things.

How LinuxGSM should handle it is simple. Allow the use of 0.0.0.0 and simply choose one of the ips (eg the first) for LinuxGSM use as a process listening on all, will listen and respond to any ip unless blocked by a firewall (which is another matter entirely and fall under misconfiguration of firewall).

UltimateByte commented 6 years ago

1) It is pointless for a game server to listen to all available IPs and risk conflicting with other game servers 2) You cannot properly query the server with 0.0.0.0 3) Some game server services don't accept listening on 0.0.0.0 4) I like to be alerted/stopped when I forget to configure major stuff on my server

I vote for keeping the current way.

dgibbs64 commented 6 years ago

@Nodens- what sort of things? I see no reason as to why you need a game server to listen on more than one interface. Unless I am missing somthing.

991jo commented 6 years ago

You cannot properly query the server with 0.0.0.0

You cannot properly use srcds in a LAN without binding to 0.0.0.0 as demonstrated above.

I like to be alerted/stopped when I forget to configure major stuff on my server

Then just make it a warning at startup and continue running the server.

dgibbs64 commented 6 years ago

@991jo the LAN issue does need to be investigated further. However this is an issue with srcds only as far as I am aware. So an exception may have to be made for srcds in LAN mode. This currently would mean that gsquery would not be able to work as it needs an IP to query. A change in the proccess will have to be made but I am not sure the best way to go about this. It will require some thought

991jo commented 6 years ago

Since the scripts can somehow detect the IP addresses gsquery can just take one of them if it binds to all. possibly even 127.0.0.1.

Nodens- commented 6 years ago

@dgibbs64: Here's a big one, servers with failover addresses and DDOS mitigation. If you are forced to bind to a single address you can't utilize that. All my servers utilize this. A common setup for example is detecting a DDOS and nullroute the ip getting attacked. Server still functions properly on the failover. I just used LinuxGSM today for the first time while setting up a Project Zomboid server and I've hit two issues, the one I posted (python dependency not detected--which is minor since it does not prevent script execution) and this one that I would post myself if it was not already here heh. The server I was setting it up on has currently 6 ipv4 addresses and 6 ipv6.

@UltimateByte: Regarding your points: 1) Nothing can conflict by using 0.0.0.0. 0.0.0.0 is just INADDR_ANY in code if you want to look it up. All it does is listening at any ip address vs binding to a single ip only. You can have N software listening at any address with no problem whatsoever. In fact this is the default in both linux and windows unless specifically set otherwise. The only problem is when you want to use the same port on 2 different pieces of software. At that point though you know what you're doing (you're doing this on purpose) so you can either bind each to a different ip or use different ports.

2) If you want to query the server you can query any address whatsoever.. just pick one at random. So basic script logic should say if ip is 0.0.0.0, query the primary ip and you're good to go. Hell you can even query the loopback and avoid checking for ips altogether. Just query 127.0.0.1.

3) As far as I know about socket programming as a software engineer, there are almost 0 programs out there that absolutely require binding to a single ip. Most of the software out there (mostly desktop-oriented) does not even support binding to a single ip (no configuration option for it) making it troublesome to route only through VPNs for security, for example. If you want to bind you can. The issue here is that non-binding is not supported by the scripts.

4) This can be solved by a status message on run saying something like: "Listening on any address" vs "Listening on x.x.x.x". The information you want right on spot :)

UltimateByte commented 6 years ago

@Nodens- I'm not new to Linux, it's even my job to administrate Linux server. 1) is of course referring overlapping ports. Most users are noobs and don't even know that they can change ports. Also, what's the point of having multiple IPs if all of your services listen to all of them? I don't know how YOU do DDoS mitigation, but i've never seen anybody doing what you're saying. 2) Valid point, we can change that for sure to query on localhost if it listens on 0.0.0.0. 3) Well, it's been a while since I didn't face issues because of that, since I always bind my game servers to specific IPs, but I'm sure I resolved many issues by doing so. However, some re-testing would be required to validate or invalidate my point. 4) I'd rather have some option like allownobinding="on/off" and remove any warning if it is "on".

joshhsoj1902 commented 6 years ago

Another use case for using ip 0.0.0.0 is when you're trying to run LGSM inside a docker container in docker swarm.

In that case the container will have multiple IP's, Traffic can get into the container on any of those interfaces (depending on how the swarm is accessed) and binding to a single one means that some methods of hitting the swarm don't work.

I've been trying to build a little docker container around LGSM for a little while now, this 0.0.0.0 ip binding limitation is the part I'm having most trouble work around.

Nodens- commented 6 years ago

Sorry, I somehow missed your reply @UltimateByte Of course I never implied that you are new to Linux or anything of the sort. I was just replying to your points :)

Regarding DDOS mitigation it is a common trick to null route targeted ips and use secondary/tertiary/etc to keep services online. On low budget it's the only thing you can do and it's effective unless the botnet attacking you cat detect new ip and redirect the attack. Of course, if you have bigger budget you get behind proper DDOS mitigation but for low budget networks the null route+failover ips is the only option as far as I know.

allownobinding switch sounds good. Basically any implementation that would allow INADDR_ANY sounds good :)

UltimateByte commented 6 years ago

I probably said that because I found that you were trying to teach me too basic stuff, whatever, I was in an arrogant piece of shit mood, I apologize for this. :o))

Interesting way of mitigating, however if it's a bandwidth flood and your bandwidth is saturated, it will still be saturated even if you drop packets, also, I still don't think most game server admins know about it, and in many cases, an IP change would break the system, for example in the case of a basic Apache server running in Plesk, where the vhost is bound to a specific IP or for game servers, people would need to know the secondary IP, which would basically make you lose most of your players since you usually distribute one IP for a game server.

We've been talking with Daniel about greatly reworking LinuxGSM, which would most likely change the way config files, IP and ports are handled. That might be the moment when we solve this issue.

UltimateByte commented 6 years ago

About the LAN issue, some person found that what actually matters for LAN discovery seems to be the ports that you use. According to him, Source game server only checks for specific ports ranges.

991jo commented 6 years ago

Yes, they check only for ports in 27015-27020 or something like that and some others via a broadcast packet. But as mentioned in the first message of the issue: The server does not answer to those packets anymore when not binding to 0.0.0.0.

Nodens- commented 6 years ago

@UltimateByte Was not trying to teach anything either heh. I just have the habit of overanalyzing my arguments. A practice acquired while debating solutions on corporate bug trackers while I was working a lot with corporations. If you don't extensively analyze the argument there, you're inviting 20 more questions that actually delay solution with all the extra back and forth. Hectic environments really heh. No worries mate, no harm done. :)

Regarding null-routing. There's very low performance impact when you do that and silent dropping is supported by all routers. The trick is to setup 2-3-4-etc A records for the same subdomain (Round Robin DNS style) or script the change of ip in DNS. Of course with very very low TTL values so they're barely cached. Say test.test.com resolves to both 1.1.1.1 and 1.1.1.2. When 1.1.1.1 gets DDOSed it gets null routed and traffic continues properly on 1.1.1.2 as soon as the client/browser retries the connection as long as the software listens to 0.0.0.0 or if it has multiple bind support to both addresses. It is effective unless the attacker has a mechanism for resolving again after a while and switching targets in which case using 4-5 ips will allow you to keep functioning with intermittent breakage (obviously not good for a game but for a web server it's good enough/better than being completely inaccessible hehe). Also most attackers don't do that cause botnets charge per ip There are some cheap dedicated server providers out there who automatically null route attacked ips without even asking you about it (eg Hetzner) so basically getting a second ip from them and setting it up like this is your best option to avoid downtime. And cheaper than cloudflare per domain cost for example. ;) In case of httpd vhosts you would need them all listening on :80/:443, differentiating via FQDN only, or on 2+ ips each. If you're selling VPS it gets tricky as you need a lot of IPs (a problem with ipv4 but easily doable with ipv6) which is why most small time VPS sellers just null route the ip to mitigate the attack without caring about the VPS' connectivity. ;)

Looking forward to the rework! 👍

UltimateByte commented 6 years ago

Interesting, thanks for this enlightenment. Sadly, this is not conveniently possible with Plesk that I use for hosting. https://support.plesk.com/hc/en-us/articles/213956385-How-to-set-multiple-IP-addreses-on-one-subscription-

As for the rework, you can have a look at my idea for the new file system on LinuxGSM Discord, feedback and suggestions appreciated https://gameservermanagers.com/discord channel #linuxgsm-dev :)

JimTR commented 6 years ago

@UltimateByte why not switch to webmin .. this has a simple interface for adding IP's and is freeware, below is the result

eth

UltimateByte commented 6 years ago

Wow, Webmin had greatly improved since the last time I checked! Thanks, will have a look on a VM soon! Though I need to stay on Plesk for my main web server since the hosting company I work in only uses it and masters it pretty well. I'll be happy to feedback on Discord (we're a bit off topic here :p ) :)

Fedcomp commented 6 years ago

I don't understand why i can't specify 0.0.0.0 to listen on all interfaces, both wan and lan. Make ip="" and show warning, but allow usage of 0.0.0.0, it's is too common to use it.

UltimateByte commented 6 years ago

@Fedcomp You cannot listen on a WAN IP lol. You can only listen on interface IP. Read this, it'll do good to you! https://github.com/GameServerManagers/LinuxGSM/wiki/Ports

GitHub
GameServerManagers/LinuxGSM
LinuxGSM - Linux Game Server Managers_
UltimateByte commented 5 years ago

Note: The bind message shouldn't show on server stop. Note2: Users can start the server anyway with ./gameserver console command. They should only be able to start it with "debug" IMO.

dgibbs64 commented 5 years ago

There is a lot of comments here. I need a quick summary to understand what is required. Keep in mind that this will affect the behaviour of every game server supported. I think the main issue is query to ensure that it will always work if 0.0.0.0 is used. Secondly showing 0.0.0.0 as the IP on alerts is a possible issue. However, a new displayip variable is now available.

Current IP address vars

ip the port the game server binds too extip the internet IP uses https://ifconfig.co displayip an optional var to change the ip/hostname displayed in alerts. Will alert default to the extip

So I think this is potentially possible to implement and will save the annoyance of manually filling out an ip address.

What is my IP address? — ifconfig.co
What is my IP address?
Nodens- commented 5 years ago

To sum it up.

1) Ability to start with no address bind/bound to 0.0.0.0 2) As @UltimateByte suggested a configuration flag

allownobinding="on/off"

aimed at warning you if you start a game daemon without binding an address or not. For the purpose of having the default to off and make it immediately obvious if you've forgot to set up an address for the game daemon.

dgibbs64 commented 4 years ago

This will need to be investigated as part of improving docker support.

h3o66 commented 4 years ago

Connected to #3015

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.