schmatzler

How to run a secured NOLF server on Linux

Recommended Posts

Hi guys,

 

I wanted to create a new NOLF server, but I have only a decent Linux box running Debian. But I thought, 2x2,4 GHz and 8 Gig of RAM would make a damn fine machine for all NOLFers out there, so I figured out a way to run it on Linux anyway. Without a monitor, in shell and with an extra user in its own environment, so it should not be possible to use its security holes for gaining access to your machine. I also added a failsafe script that kicks in and restarts the server if it crashes.

 

First, we login to our machine via ssh (as root user) and create a new user called gameserver. This one will be used for running our NOLF server:

 

useradd --home-dir /home/gameserver --password swordfish --shell /bin/false gameserver

 

Now we have a new user without a shell. No one can login to your box with this user. Its home directory is /home/gameserver. Fine. Lets move on, the next step is installing the needed software for running the NOLF server:

 

apt-get install wine xvfb

 

Wine is needed to emulate a windows environment, xvfb is creating a virtual screen later on, so we can run the server without a screen attached.

 

Now create a new directory /home/gameserver/nolf with

 

mkdir /home/gameserver/nolf

 

and place the following files into it:

 

autoexec.cfg  nolf003cres.rez  NOLFGOTY.REZ  nolfu003cres.rez  startup.txt
ltmsg.dll	 NOLF2.REZ		NOLF.REZ	  nolfu003.rez
NetHost.txt   NOLFCRES003.REZ  NolfServ.exe  server.dll

 

Note that the NetHost.txt is generated after running NolfSrv.exe the first time. So you should start up the program at least one time on your windows box and do all the required settings in the wizard. After that, you have a preconfigured NetHost.txt you can copy to your linux box.

 

This is it - the nolf server files are on your box and your user is created. Now we set up a script that starts your nolf server.

 

Create a new crontab for the gameserver user with the following command:

 

EDITOR=mcedit crontab -e -u gameserver

 

An editor should open up. If not, install the program mc with apt-get install mc.

 

Paste the following content into the editor and press F2+F10 to save and close it:

 

MAILTO=""
* * * * * /home/gameserver/nolf_check.sh

 

What this does: It starts the script nolf_check.sh every 60 seconds - so we gonna have to create that and fill it with contents:

 

mcedit /home/gameserver/nolf_check.sh

 

The editor opens again. This time, paste the following commands into it. Close with F2+F10.

 

#!/bin/bash
# check daemon
ps -ef | grep -v grep | grep NolfServ.exe
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
cd nolf && nohup xvfb-run -a wine NolfServ.exe -nowiz -NetUsePassword "false" >/dev/null 2>/dev/null &
else
echo "nolf found - do nothing"
fi

 

Important: Don't just write "-nowiz" as an option alone. This does not work and opens the wizard. Since we have no screen, we can't use it to start the server. I added the option -NetUsePassword "false" after it, since I don't use a password either.

 

Now we will make sure, that the whole directory belongs to the right user and that the script is executable:

 

chown -R gameserver:gameserver /home/gameserver

chmod +x /home/gameserver/nolf_check.sh

 

Done! Now wait some seconds and your server should show up in the master list! If not, unblock the ports 2300-2400 (TCP) and 27888 (UDP) in your firewall.

 

You can check my server status here, it is running very stable via wine:

 

http://hirnschwund.net/?s=3

Edited by schmatzler

Share this post


Link to post
Share on other sites

Nice tutorial.

Share this post


Link to post
Share on other sites

My pleasure. :) I also figured out how to access the interface directly.

 

If you type in

 

ps -ef | grep -v grep | grep Xvfb

 

you will see the virtual screen the NOLF server is running on. Its a number like :1, :2 or :99. Just remember this number and start up a VNC server with this command:

 

x11vnc -display :99

 

Now you can connect to your server with any VNC viewer on Windows or Linux and administrate your server with your mouse. Doesn't look pretty, but it works:

 

bla.png

 

If you don't want anyone be able to connect to your interface, password protext x11vnc. It prints out instructions on how to do that when you start it up.

Share this post


Link to post
Share on other sites

Just a quick addition: I refined the script that checks if the server is running.
It also runs a second check on my web frontend here to see if the server is really online.

Doing the sidecheck will restart the server if the .exe is still running, but it has lost access to the internet, because it somehow broke. This will also cover things like "Damn, it runs but takes up my CPU". :)

#!/bin/bash
# if online is NULL, it's down. May change maps, so wait and check again:
if [ -z "$(curl -sSf http://hirnschwund.net/?s=4 | grep "ONLINE")" ]
then
sleep 60
elif [ -z "$(curl -sSf http://hirnschwund.net/?s=4 | grep "ONLINE")" ]
then
pkill NOLF2Srv.exe
fi

# check daemon
ps -ef | grep -v grep | grep NolfServ.exe
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
cd nolf && nohup xvfb-run -a wine NolfServ.exe -nowiz -NetUsePassword "false" >/dev/null 2>/dev/null &
else
echo "found, leave."
fi.
Edited by schmatzler
  • Like 1

Share this post


Link to post
Share on other sites

I have a bunch of remarks when I read your scripts. (don't be mad that I try to polish it a bit)

 

Why /bin/bash ? I'm pretty sure you could run this via /bin/sh.

Advantage? No shellshock and sh might be a bit faster to boot. Debian has it's own posix shell but many other distro just link sh to bash.

You can then change gameserver to have sh as the user default shell even by purism. sh is more portable than bash, that's why everyone should use it and not fallback to bash directly :) )

 

Why this double redirections?

You can simply redirect the output by using "command > /dev/null 2>&1" and avoid to write twice /dev/null.

 

One last question: Is there a specific reason not to use the classic init/systemd daemon manager to do the job but - instead - fallback on crontab?

Edited by Barto

Share this post


Link to post
Share on other sites

I have a bunch of remarks when I read your scripts. (don't be mad that I try to polish it a bit)

 

Thanks! :-) I'm not mad, I'm always willing to improve my setup.

 

 

Why /bin/bash ? I'm pretty sure you could run this via /bin/sh.

 

Mmmh no particular reason. I like bash, it's the default shell in my home system and it's highly customizable via .bashrc so I just put it at the top, because I like it. If the script works with sh, others can feel free to use that. ;)

 

 

You can simply redirect the output by using "command > /dev/null 2>&1" and avoid to write twice /dev/null.

 

Cool. I did not know that! :) Wrote that stuff a while back and it worked, so I didn't put any more thought into it.

 

 

One last question: Is there a specific reason not to use the classic init/systemd daemon manager to do the job but - instead - fallback on crontab?

 

I don't want to write init scripts for my host system. When I decide to switch from Debian to another distribution, I would have to change the init scripts. Also, systemd is total junk - software from Lennart Poettering tends to break everything, so I will stay away from it whenever I can.

 

cron is simple enough to do the job and I use it for various other tasks, so it suits my setup.

 

Thanks for your input :)

Share this post


Link to post
Share on other sites

Oh, and while driving back home from studies this evening, I thought a bit more about it and I realized you could maybe check in a better way if the server is running. I have not tested it but I guess it should. :)

 

Just do this mostly:

1. echo $$ > /tmp/lock-nolf (mostly creating a lock file with your pid in /tmp/ if it does not exists, stop here if it there is already this file)

2. start nolf server

3. rm /tmp/lock-nolf (beware you should also do this when you recieve a signal - handled with the trap command)

With this you would only check if the server is running if and only if the file exists (if [ -f /tmp/nolf-lock ]; then command; fi). This avoids the tricky "grep -v grep" in your previous code. I can name many other softwares doing the same to check if they are open or if they have a specific file open.

 

"2>&1 /dev/null" is mostly redirecting the output numbered 2 (stderr) into output numbered 1 (stdout) which is then put into /dev/null. I mainly use it when I want to keep some compilation logs on my machine. Just a random question from curious me this time, do you currently store any server's log this way or not?

 

Oh, it seems I found a systemd hater :P Usually init scripts is just sh files and it is widely supported among many distributions (even systemd can run those file as far as I recall - my archlinux machine has systemd-sysvcompat package for that matter). But hell, the good old crontab is still doing the awesome job and I do not complain about it :)

 

Have a good evening :)

Share this post


Link to post
Share on other sites

No, I don't store any server logs. I believe the NOLF servers create their own log files and I discovered one day that they had grown to several gigabytes. I symlinked them to /dev/null. I don't really need them - who would need thousands of lines of kill and join messages?

 

The lockfile is a bad idea. Since the server sometimes loses the connection but the interface is still accessible, the lockfile would never get deleted. I prefer to use it as it is now, because it just works. And that is all I wanted. :)

Edited by schmatzler

Share this post


Link to post
Share on other sites

Oh, that's right, my method only works if there is a hard link between the server state and the nolf binary (which is - here - not the case). I took too much habbit about how quake based servers are running I guess :P

Share this post


Link to post
Share on other sites

I've updated my script today. I noticed that my server was offline and nothing was kicking in. What happened?

 

Well, Nolf2Srv.exe lost the connection - so far, so good. It also got killed because the damn sucker didn't behave. But: Somehow it broke so badly, that the virtual display (running via Xvfb) did not close. Since Xvfb was already running, it couldn't be spawned again and the .exe couldn't start.

 

I've added another check that terminates the virtual display, too. My complete script is now this:

#!/bin/bash
# if online is NULL, it's down. May change maps, so wait and check again:
if [ -z "$(curl -sSf http://hirnschwund.net/?s=4 | grep "ONLINE")"]; then
echo "'frack' is offline"
sleep 90
fi
if [ -z "$(curl -sSf http://hirnschwund.net/?s=4 | grep "ONLINE")"]; then
echo "'frack' is still offline"
echo "Killing process"
pkill NOLF2Srv.exe
echo "Making sure the X window is usable"
pkill -f "Xvfb :110"
sleep 2
echo "Starting server"
env WINEPREFIX="/home/gameserver/.wine-nolf2" && cd nolf2 && nohup xvfb-run -n 110 wine NOLF2Srv.exe -mod LivesForever > /dev/null 2>&1 &
else
echo "NOLF2 is running, leave."
fi

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.