Difference between revisions of "Linux dedicated server"

From Team Fortress Wiki
Jump to: navigation, search
m (Troubleshooting)
m (Fix typo on main TF2 port 27015)
(10 intermediate revisions by 5 users not shown)
Line 4: Line 4:
  
 
Basic installation and configuration for a '''Linux dedicated server''' is the same for all distributions, but small details, such as package names, directories, etc. may differ from distribution to distribution. It is recommended that you check your distribution's repositories for the required packages before continuing. A link to a chef recipe based on this guide is also available in the "See also" section.  
 
Basic installation and configuration for a '''Linux dedicated server''' is the same for all distributions, but small details, such as package names, directories, etc. may differ from distribution to distribution. It is recommended that you check your distribution's repositories for the required packages before continuing. A link to a chef recipe based on this guide is also available in the "See also" section.  
 +
 +
NOTE: Information about [[Windows dedicated server|running a server on Windows]] is often applicable. Check that page for additional details and suggestions. Information in that page and this one may also be useful on other Unix-like platforms.
  
 
== Reading this article ==
 
== Reading this article ==
Line 9: Line 11:
  
 
* A command prefixed by <code>#</code> (a hash) is meant to be run as '''root'''. Most distributions have a separate root account; for other distributions such as Ubuntu, Linux Mint, Crunchbang, etc., the '''sudo''' prefix to a command will ensure the command is run as root, or you can use the '''su''' command to make all following command be run as '''root'''.
 
* A command prefixed by <code>#</code> (a hash) is meant to be run as '''root'''. Most distributions have a separate root account; for other distributions such as Ubuntu, Linux Mint, Crunchbang, etc., the '''sudo''' prefix to a command will ensure the command is run as root, or you can use the '''su''' command to make all following command be run as '''root'''.
* A command prefixed by <code>$</code> (a dollarsign) is meant to be run as a '''user'''.
+
* A command prefixed by <code>$</code> (a dollar sign) is meant to be run as a '''user'''.
 
* <code>./</code> means "current working directory".
 
* <code>./</code> means "current working directory".
  
Line 17: Line 19:
 
* Write-access to the current working directory
 
* Write-access to the current working directory
 
* <code>glibc >= 2.3.6</code>
 
* <code>glibc >= 2.3.6</code>
* Approximately 4.49GB hard-drive space (for a barebones server with no custom maps, sounds, etc.)
+
* Approximately 4-5GB hard-drive space (for a barebones server with no custom maps, sounds, etc.) and ~8GB on linux
* If you are installing on FreeBSD (which is not Linux at all), you must enable Linux compatibility in the kernel and install a base system via the ports collection.  Instructions to get you started are located [https://www.ian-justman.com/wiki/index.php?title=HowTos:SRCDS_under_FreeBSD here]. '''WARNING''': This guide is outdated. Consider consulting the [https://www.freebsd.org/doc/handbook/linuxemu-lbc-install.html FreeBSD Handbook] or other more recent sources of information.
+
* If you are installing on FreeBSD (not Linux but these instructions are largely applicable), you must enable Linux compatibility in the kernel and install a base system via the ports collection.  Instructions to get you started are located [https://www.ian-justman.com/wiki/index.php?title=HowTos:SRCDS_under_FreeBSD here]. '''WARNING''': This guide is outdated. Consider consulting the [https://www.freebsd.org/doc/handbook/linuxemu-lbc-install.html FreeBSD Handbook] or other more recent sources of information.
 
* In the case of a '''64-bit''' distribution, the package '''lib32gcc1''' or '''ia32-libs''' is required to be installed:
 
* In the case of a '''64-bit''' distribution, the package '''lib32gcc1''' or '''ia32-libs''' is required to be installed:
 
:On  64-bit CentOS run:   
 
:On  64-bit CentOS run:   
Line 26: Line 28:
 
:On 64-bit Debian/Ubuntu/Linux Mint run:   
 
:On 64-bit Debian/Ubuntu/Linux Mint run:   
 
:
 
:
:<code>$ sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 lib32gcc1 lib32stdc++6</code>
+
:<code>$ sudo dpkg --add-architecture i386</code>
 +
:<code>$ sudo apt-get update</code>
 +
:<code>$ sudo apt-get install lib32z1 lib32ncurses5 libbz2-1.0:i386 lib32gcc1 lib32stdc++6 </code>
 
:
 
:
 
:For x86_64 Arch Linux run (you need to have multilib repositories enabled):
 
:For x86_64 Arch Linux run (you need to have multilib repositories enabled):
 
:
 
:
 
:<code># pacman -Syy lib32-gcc-libs</code>
 
:<code># pacman -Syy lib32-gcc-libs</code>
 +
 +
You may also need to install other packages in their 32-bit forms (eg libcurl4-gnutls).
  
 
==Download and install the SteamCMD Tool==
 
==Download and install the SteamCMD Tool==
Line 36: Line 42:
 
'''It is recommended you create a separate user (such as "gameserver") to install and run game servers.'''
 
'''It is recommended you create a separate user (such as "gameserver") to install and run game servers.'''
  
*Create a directory in which SteamCMD will be installed, i.e './hlserver':
+
*Create a directory in which SteamCMD will be installed, eg './hlserver':
 
  mkdir ./hlserver && cd hlserver
 
  mkdir ./hlserver && cd hlserver
 
*Download [http://media.steampowered.com/installer/steamcmd_linux.tar.gz steamcmd_linux.tar.gz] :
 
*Download [http://media.steampowered.com/installer/steamcmd_linux.tar.gz steamcmd_linux.tar.gz] :
Line 44: Line 50:
  
 
==Create a SteamCMD update script==
 
==Create a SteamCMD update script==
*Create a file called 'tf2_ds.txt' using your favoured text editor in the install directory, i.e nano:
+
*Create a file called 'tf2_ds.txt' using your favourite text editor in the install directory, eg nano:
 
  nano tf2_ds.txt
 
  nano tf2_ds.txt
 
*Edit the file with the following details:
 
*Edit the file with the following details:
Line 57: Line 63:
  
 
==Create an updating shell script==
 
==Create an updating shell script==
*Create a file called 'update.sh' in the folder where you installed the tool using your favoured text editor, i.e nano:
+
*Create a file called 'update.sh' in the folder where you installed the tool with the following contents:
nano update.sh
 
*Edit the file with the following details:
 
 
  #!/bin/sh
 
  #!/bin/sh
 
  ./steamcmd.sh +runscript tf2_ds.txt
 
  ./steamcmd.sh +runscript tf2_ds.txt
 
+
*Make the script executable:
 +
chmod +x update.sh
 
==Start the download/update==
 
==Start the download/update==
*Run ./update.sh to start the download. '''WARNING:''' This may take several hours as dedicated server content is currently about '''5GB in size.'''
+
*Run ./update.sh to start the download. '''WARNING:''' This may take several hours as dedicated server content is currently about '''~8GB in size.'''
*If, however, you get a permission denied error, execute this:
+
*If you receive the error, "Error! App '258550' state is 0x202 after update job." it means you do not have enough available disk space.  
chmod +x update.sh
 
*If you receive the error, "Error! App '258550' state is 0x202 after update job." it means you do not have enough available disk space.
 
*Or if you see an error like "Fatal Error: Failed to load libsteam.so" , execute this:
 
chmod -R 777 /directory/to/steam/
 
 
*You may need to run the file *multiple* times until the message "Success! App '232250' fully installed." displays.
 
*You may need to run the file *multiple* times until the message "Success! App '232250' fully installed." displays.
 
*To update the server in the future, execute this file again.
 
*To update the server in the future, execute this file again.
  
 
==Create/Update server files==
 
==Create/Update server files==
*Move to the directory called '~/hlserver/tf2/tf/cfg' and create a file called 'server.cfg' using your favoured text editor, i.e nano:
+
*In the directory called '~/hlserver/tf2/tf/cfg', create a file called 'server.cfg', eg:
 
  cd ~/hlserver/tf2/tf/cfg && nano server.cfg
 
  cd ~/hlserver/tf2/tf/cfg && nano server.cfg
*Edit the file with the following details:
+
*Edit the file with the following details (see [[Windows dedicated server]] for more info):
 
  hostname "Your_Server's_Name"
 
  hostname "Your_Server's_Name"
 
  rcon_password "Your_Rcon_Password"
 
  rcon_password "Your_Rcon_Password"
 
  sv_contact "admin@yourdomain.com"
 
  sv_contact "admin@yourdomain.com"
 
  mp_timelimit "30"  
 
  mp_timelimit "30"  
* Edit the files motd.txt, maplist.txt and mapcycle.txt all found in the '~/hlserver/tf2/tf' folder.
+
* Edit the files motd.txt, maplist.txt (?), and mapcycle.txt, all found in the '~/hlserver/tf2/tf' folder.
  
 
==Create a shell script to run the server==
 
==Create a shell script to run the server==
*Create a file in './hlserver/' called 'tf.sh' using your favoured text editor, i.e nano:
+
*Create a file in './hlserver/tf.sh' with the following contents:
cd ~/hlserver/ && nano tf.sh
 
*Edit the file with the following details:
 
 
  #!/bin/sh
 
  #!/bin/sh
  tf2/srcds_run -console -game tf -nohltv +sv_pure 1 +map ctf_2fort +maxplayers 24
+
  tf2/srcds_run -console -game tf +sv_pure 1 +randommap +maxplayers 24
*Run the file tf.sh to start your server
+
*Run the file tf.sh to start your server: <code> $ chmod u+x tf.sh;  ./tf.sh</code>
*Note: You could create an alias in your '~/.bash_aliases' file for this command as well, in which executing 'tf2server' would run the server.
+
 
  alias tf2server='bash ~hlserver/tf.sh'
+
== StartUp Errors ==
 +
* <i>[S_API FAIL] SteamAPI_Init() failed; SteamAPI_IsSteamRunning() failed.</i>
 +
** safe to ignore. It's just the Steam code looking for but not finding the Steam client.
 +
* <i>dlopen failed trying to load: /home/ubuntu/.steam/sdk32/steamclient.so</i>
 +
** TF2 server could not locate 32-bit binary. Solution: <code>$ ln ~/hlserver/tf2/bin ~/.steam/sdk32</code> 
 +
* <i>Could not load: replay_srv.so</i>
 +
** need more binary: <code>$ sudo apt-get install libtinfo5:i386 libncurses5:i386 libcurl3-gnutls:i386</code>
 +
* <b>Segmentation fault (core dumped)</b>
 +
** This means tf2 server crash.  Issue must be resolved. Add "-debug" to the tf2/srcds_run command line to generate a debug.log.
 +
 
 +
== Successful Startup ==
 +
* if all is well, console log will display
 +
:<code>Connection to Steam servers successful.</code>
 +
:<code> Public IP is X.X.X.X.</code>
 +
:<code>Assigned anonymous gameserver Steam ID [A:1:XXXXXXXXXXX:NNNN].</code>
 +
* You can test connecting to the server using its public IP from steam client
 +
:<code>Client "play_username" connected (x.x.x.x:27005) </code>
 +
* Set up auto-start upon system reboot via rc.d scripts (see further section).
 +
 
 +
== Inbound Port ==
 +
* Ports used by TF2 & those that need to be opened on your server to allow connection by users out there. See below section on setting up port
 +
** UDP 27015 - Main connection port (MUST). This is the port and protocol used by the server browser, allows clients to connect.
 +
** TCP 27015 - This port is used for RCON such as with SourceBans (if needed).
 +
** UDP 27020 - SourceTV (if enabled). You can disable this port by adding "-nohltv" to the start up command.
 +
** UDP 27005 - This is an outgoing connection used by clients. Typically you would not need to open this port in your firewall because this is for OUTBOUND connections.
 +
* if you are using AWS EC2, open at least the main inbound port UDP 27015 src 0.0.0.0/0, and add as other ports as needed.
 +
* To see ports used by TF2 and user connecting: <code>$ netstat -a |egrep 270 </code>
 +
 
 
=== Other command line options ===
 
=== Other command line options ===
  
Line 111: Line 137:
  
 
=== screen ===
 
=== screen ===
Many server operators choose to run the server under [http://www.gnu.org/software/screen/ <code>screen</code>], as it allows you to switch between the console and the shell at will, as well as end your SSH session without killing the server. It can be installed via your distribution's package manager. The server can then be run with:
+
Many server operators choose to run the server under [http://www.gnu.org/software/screen/ <code>screen</code>] or similar packages (eg tmux), as it allows you to switch between the console and the shell at will, as well as end your SSH session without killing the server. It can be installed via your distribution's package manager. The server can then be run with:
  
 
  $ screen -m -S {{botignore|tf2}} ./srcds_run ''parameters''
 
  $ screen -m -S {{botignore|tf2}} ./srcds_run ''parameters''
Line 124: Line 150:
 
In the event of unexpected power outages, it might be useful to automatically restart your server.
 
In the event of unexpected power outages, it might be useful to automatically restart your server.
 
===== Systemd service and timer =====
 
===== Systemd service and timer =====
 +
''TODO: Rewrite this to more usefully use systemd''
 +
 
For systems that have '''systemd''' instead of init scripts you need to make a '''systemd service'''
 
For systems that have '''systemd''' instead of init scripts you need to make a '''systemd service'''
 
Make a file at /etc/systemd/system/ called tf2server.service and put the following text into it:
 
Make a file at /etc/systemd/system/ called tf2server.service and put the following text into it:
Line 149: Line 177:
  
 
===== Debian init script =====
 
===== Debian init script =====
 +
NOTE: Most modern systems should be able to use systemd (see above) rather than a sysvinit script. Use these instructions only if you are unable/unwilling to use systemd.
 +
 
The following example Debian LSB init script can be used to automatically restart the server. Note that  <code>screen</code> is used. This script should be named tf2-server and can be put in the folder /etc/init.d. After doing that, run:
 
The following example Debian LSB init script can be used to automatically restart the server. Note that  <code>screen</code> is used. This script should be named tf2-server and can be put in the folder /etc/init.d. After doing that, run:
  
Line 243: Line 273:
  
 
===== Upstart script =====
 
===== Upstart script =====
Alternatively, if you'd rather use an upstart script, paste the following into /etc/init/tf2-server.conf
+
As above, a systemd script is preferable. But if you'd rather use an upstart script, paste the following into /etc/init/tf2-server.conf
  
 
<pre>
 
<pre>
Line 275: Line 305:
  
 
== iptables rules ==
 
== iptables rules ==
 +
TODO: This currently depends on a very specific network configuration. Fix so it is more general, and preferably can be saved as a script.
 +
 
Firstly, run <code>sudo -i</code> to get a root prompt. Then, enter this (all one line). To leave the root prompt and return to the standard user, just type <code>exit</code> like normal.
 
Firstly, run <code>sudo -i</code> to get a root prompt. Then, enter this (all one line). To leave the root prompt and return to the standard user, just type <code>exit</code> like normal.
 
<pre>
 
<pre>
Line 402: Line 434:
  
 
; My server doesn't work with rcon and/or refuses to broadcast UDP logs
 
; My server doesn't work with rcon and/or refuses to broadcast UDP logs
: Do you have IPv6 or multiple network interfaces? If so, the server will have an existential crisis when trying to perform these, and you'll need to reassure it by giving it IPs to listen on:
+
; Do you have IPv6 or multiple network interfaces? If so, the server will have an existential crisis when trying to perform these, and you'll need to reassure it by giving it IPs to listen on:
: To do this, include <code>+ip 0.0.0.0</code> on the command-line arguments and add <code>rcon_address 0.0.0.0</code> to your server.cfg
+
; To do this, include <code>+ip 0.0.0.0</code> on the command-line arguments and add <code>rcon_address 0.0.0.0</code> to your server.cfg
: ''Note: <code>rcon_address</code> is not exclusively used by rcon, UDP logging will fail without it.''
+
; ''Note: <code>rcon_address</code> is not exclusively used by rcon, UDP logging will fail without it.''
  
 
; steamclient.so error - 64bit
 
; steamclient.so error - 64bit
Line 417: Line 449:
 
; Could not load replay_srv.so
 
; Could not load replay_srv.so
 
run <code>sudo dpkg --add-architecture i386; sudo apt-get update;sudo apt-get install mailutils util-linux tmux lib32gcc1 libstdc++6 libstdc++6:i386 libcurl4-gnutls-dev:i386</code>
 
run <code>sudo dpkg --add-architecture i386; sudo apt-get update;sudo apt-get install mailutils util-linux tmux lib32gcc1 libstdc++6 libstdc++6:i386 libcurl4-gnutls-dev:i386</code>
 +
 +
 +
;Server fails to start with ./srcds_run line 324 18491 Segmentation fault $HL_CMD
 +
run the following 2 commands
 +
;<code>yum install libcurl.i686</code>
 +
;<code>ln -s /usr/lib/libcurl.so.4 /usr/lib/libcurl-gnutls.so.4</code>
  
 
== See also ==
 
== See also ==

Revision as of 23:00, 5 November 2017

This is a setup guide that allows you to install a basic Team Fortress 2 Linux dedicated server. In the below example the server is installed into the user's home directory in a directory called 'hlserver'.

Basic installation and configuration for a Linux dedicated server is the same for all distributions, but small details, such as package names, directories, etc. may differ from distribution to distribution. It is recommended that you check your distribution's repositories for the required packages before continuing. A link to a chef recipe based on this guide is also available in the "See also" section.

NOTE: Information about running a server on Windows is often applicable. Check that page for additional details and suggestions. Information in that page and this one may also be useful on other Unix-like platforms.

Reading this article

This article has been written according to standard Linux documentation syntax, meaning the following:

  • A command prefixed by # (a hash) is meant to be run as root. Most distributions have a separate root account; for other distributions such as Ubuntu, Linux Mint, Crunchbang, etc., the sudo prefix to a command will ensure the command is run as root, or you can use the su command to make all following command be run as root.
  • A command prefixed by $ (a dollar sign) is meant to be run as a user.
  • ./ means "current working directory".

Requirements

A number of requirements exist in order to run a Team Fortress 2 server on the Linux platform, namely:

  • Write-access to the current working directory
  • glibc >= 2.3.6
  • Approximately 4-5GB hard-drive space (for a barebones server with no custom maps, sounds, etc.) and ~8GB on linux
  • If you are installing on FreeBSD (not Linux but these instructions are largely applicable), you must enable Linux compatibility in the kernel and install a base system via the ports collection. Instructions to get you started are located here. WARNING: This guide is outdated. Consider consulting the FreeBSD Handbook or other more recent sources of information.
  • In the case of a 64-bit distribution, the package lib32gcc1 or ia32-libs is required to be installed:
On 64-bit CentOS run:
# yum install ncompress libgcc.x86_64 libgcc.i686 glibc.i686 zlib.i686 ncurses-libs.i686
On 64-bit Debian/Ubuntu/Linux Mint run:
$ sudo dpkg --add-architecture i386
$ sudo apt-get update
$ sudo apt-get install lib32z1 lib32ncurses5 libbz2-1.0:i386 lib32gcc1 lib32stdc++6
For x86_64 Arch Linux run (you need to have multilib repositories enabled):
# pacman -Syy lib32-gcc-libs

You may also need to install other packages in their 32-bit forms (eg libcurl4-gnutls).

Download and install the SteamCMD Tool

It is recommended you create a separate user (such as "gameserver") to install and run game servers.

  • Create a directory in which SteamCMD will be installed, eg './hlserver':
mkdir ./hlserver && cd hlserver
wget http://media.steampowered.com/installer/steamcmd_linux.tar.gz
  • Use the tar command to uncompress the archive into the directory:
tar zxf steamcmd_linux.tar.gz

Create a SteamCMD update script

  • Create a file called 'tf2_ds.txt' using your favourite text editor in the install directory, eg nano:
nano tf2_ds.txt
  • Edit the file with the following details:
login anonymous
force_install_dir ./tf2
app_update 232250
quit
  • Save the file by pressing Ctrl + X.
  • If you want to opt-in to the pre-release version of the TF2 dedicated server, add this line before the 'app_update' line (line 3):
beta prerelease

Create an updating shell script

  • Create a file called 'update.sh' in the folder where you installed the tool with the following contents:
#!/bin/sh
./steamcmd.sh +runscript tf2_ds.txt
  • Make the script executable:
chmod +x update.sh

Start the download/update

  • Run ./update.sh to start the download. WARNING: This may take several hours as dedicated server content is currently about ~8GB in size.
  • If you receive the error, "Error! App '258550' state is 0x202 after update job." it means you do not have enough available disk space.
  • You may need to run the file *multiple* times until the message "Success! App '232250' fully installed." displays.
  • To update the server in the future, execute this file again.

Create/Update server files

  • In the directory called '~/hlserver/tf2/tf/cfg', create a file called 'server.cfg', eg:
cd ~/hlserver/tf2/tf/cfg && nano server.cfg
hostname "Your_Server's_Name"
rcon_password "Your_Rcon_Password"
sv_contact "admin@yourdomain.com"
mp_timelimit "30" 
  • Edit the files motd.txt, maplist.txt (?), and mapcycle.txt, all found in the '~/hlserver/tf2/tf' folder.

Create a shell script to run the server

  • Create a file in './hlserver/tf.sh' with the following contents:
#!/bin/sh
tf2/srcds_run -console -game tf +sv_pure 1 +randommap +maxplayers 24
  • Run the file tf.sh to start your server: $ chmod u+x tf.sh; ./tf.sh

StartUp Errors

  • [S_API FAIL] SteamAPI_Init() failed; SteamAPI_IsSteamRunning() failed.
    • safe to ignore. It's just the Steam code looking for but not finding the Steam client.
  • dlopen failed trying to load: /home/ubuntu/.steam/sdk32/steamclient.so
    • TF2 server could not locate 32-bit binary. Solution: $ ln ~/hlserver/tf2/bin ~/.steam/sdk32
  • Could not load: replay_srv.so
    • need more binary: $ sudo apt-get install libtinfo5:i386 libncurses5:i386 libcurl3-gnutls:i386
  • Segmentation fault (core dumped)
    • This means tf2 server crash. Issue must be resolved. Add "-debug" to the tf2/srcds_run command line to generate a debug.log.

Successful Startup

  • if all is well, console log will display
Connection to Steam servers successful.
Public IP is X.X.X.X.
Assigned anonymous gameserver Steam ID [A:1:XXXXXXXXXXX:NNNN].
  • You can test connecting to the server using its public IP from steam client
Client "play_username" connected (x.x.x.x:27005)
  • Set up auto-start upon system reboot via rc.d scripts (see further section).

Inbound Port

  • Ports used by TF2 & those that need to be opened on your server to allow connection by users out there. See below section on setting up port
    • UDP 27015 - Main connection port (MUST). This is the port and protocol used by the server browser, allows clients to connect.
    • TCP 27015 - This port is used for RCON such as with SourceBans (if needed).
    • UDP 27020 - SourceTV (if enabled). You can disable this port by adding "-nohltv" to the start up command.
    • UDP 27005 - This is an outgoing connection used by clients. Typically you would not need to open this port in your firewall because this is for OUTBOUND connections.
  • if you are using AWS EC2, open at least the main inbound port UDP 27015 src 0.0.0.0/0, and add as other ports as needed.
  • To see ports used by TF2 and user connecting: $ netstat -a |egrep 270

Other command line options

Some other common command-line options for TF2 are:

  • +ip 0.0.0.0 - Bind to a specific IP. By default, listens on all network interfaces
  • -port 27015 - Bind to a different port (27015 is the default)
  • -secured - VAC secured
  • -timeout 0 - Faster server restart on crash
  • -strictportbind - If a server is already running on the specified port, stop the server from running
  • +randommap - Use instead of +map to select a map at random
  • +servercfgfile - Which tf/cfg/ file to execute on map change, defaults to server.cfg
  • +mapcyclefile - Which tf/cfg/ file contains this server's mapcycle, defaults to mapcycle.txt. Will also look in tf/
  • -replay - Executes replay.cfg and adds an additional slot for the replay bot, but removes it from the player count.
  • -autoupdate - Attempts to auto-update the server when an update comes out. You MUST use -steam_dir and -steamcmd_script
  • -steam_dir ~/hlserver/ - Location of steamcmd. Required by -autoupdate
  • -steamcmd_script ~/hlserver/tf2_ds.txt - SteamCMD script to update this server. Required by -autoupdate
  • +sv_shutdown_timeout_minutes 360 - When autoupdating, automatically restart after this many minutes. Defaults to 360 (6 hours).

screen

Many server operators choose to run the server under screen or similar packages (eg tmux), as it allows you to switch between the console and the shell at will, as well as end your SSH session without killing the server. It can be installed via your distribution's package manager. The server can then be run with:

$ screen -m -S tf2 ./srcds_run parameters

Command string example:

$ screen -m -S tf2.MapNameHere -t MapNameHere /home/Username/hlserver/srcds_run -game tf +map MapFileNameHere -maxplayers 32 -autoupdate -steam_dir /home/Username/hlserver/ -steamcmd_script /home/Username/hlserver/tf2_ds.txt +sv_shutdown_timeout_minutes 5 -port 27015 +exec server.cfg +mapcyclefile mapcycle.txt

where parameters is your normal srcds_run parameters. You can use Ctrl+A+D to minimize the console, and screen -r tf2 to bring it back up. Ctrl+D will terminate the session (make sure you use the killserver console command first) and Ctrl+A, followed by Esc will allow you to scroll through it using and . See the manual for more commands and parameters.

Automated startup at server boot

In the event of unexpected power outages, it might be useful to automatically restart your server.

Systemd service and timer

TODO: Rewrite this to more usefully use systemd

For systems that have systemd instead of init scripts you need to make a systemd service Make a file at /etc/systemd/system/ called tf2server.service and put the following text into it:

[Unit]
Description=Team Fortress 2 server
RefuseManualStart=no
RefuseManualStop=yes

[Service]
Type=oneshot
ExecStart=/bin/sh /home/tf2server/hlserver/tf2.sh

[Install]
WantedBy=multi-user.target

This should run the shell script at /home/tf2server/hlserver/tf2 at server boot. You can change /home/tf2server/hlserver/tf2.sh in the ExecStart=/bin/sh /home/tf2server/hlserver/tf2.sh line of the tf2server.service to the path your shell script for running the server is. Now only thing left to do is tell systemd to refresh the the *.service files and add the file to the startup:

# systemctl daemon-reload
# systemctl enable tf2server.service

And you should have the server run at startup.

Debian init script

NOTE: Most modern systems should be able to use systemd (see above) rather than a sysvinit script. Use these instructions only if you are unable/unwilling to use systemd.

The following example Debian LSB init script can be used to automatically restart the server. Note that screen is used. This script should be named tf2-server and can be put in the folder /etc/init.d. After doing that, run:

$ update-rc.d tf2-server defaults

This should ensure a proper startup of the server after each reboot.

#!/bin/sh

### BEGIN INIT INFO
# Provides:          tf2server
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Team Fortress 2 server
# Description:       Starts a Team Fortress 2 server
### END INIT INFO

NAME="Team Fortress 2"
USER="tf2server"
SCREENREF="tf2"
BINARYPATH="/home/tf2server/hlserver/tf2"
BINARYNAME="srcds_run"
PIDFILE="tf2server.pid"

OPTS="-game tf +sv_pure 1 +maxplayers 32 +ip 0.0.0.0 +map mvm_decoy -autoupdate -steam_dir /home/tf2server/hlserver/ -steamcmd_script /home/tf2server/hlserver/tf2_ds.txt +sv_shutdown_timeout_minutes 5"

cd "$BINARYPATH"

running() {
    if [ -n "`pgrep -f $BINARYNAME`" ]; then
        return 0
    else
        return 1
    fi
}

start() {
    if ! running; then
        echo -n "Starting the $NAME server... "
        start-stop-daemon --start --chuid $USER --user $USER --chdir $BINARYPATH --exec "/usr/bin/screen" -- -dmS $SCREENREF $BINARYPATH/$BINARYNAME $OPTS
        pgrep -f $BINARYNAME > $PIDFILE
        if [ -s $PIDFILE ]; then
            echo "Done"
        else
            echo "Failed"
            rm $PIDFILE
        fi
    else
        echo "The $NAME server is already started."
    fi
}

stop() {
    if running; then
        echo -n "Stopping the $NAME server... "
        kill `cat $PIDFILE`
        while running; do
            sleep 1
        done
        rm $PIDFILE
        echo "Done"
    else
        echo "The $NAME server is already stopped."
    fi
}

case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
	stop
        start
    ;;
    status)
        if running; then
            echo "The $NAME server is started."
        else
            echo "The $NAME server is stopped."
        fi
    ;;
    *)
        echo "Usage: $0 (start|stop|restart|status)"
        exit 1
esac
exit 0
Upstart script

As above, a systemd script is preferable. But if you'd rather use an upstart script, paste the following into /etc/init/tf2-server.conf

description     "TF2 Server"
author          "TF2 Wiki"

start on runlevel [2345]
stop on starting rc RUNLEVEL=[016]

pre-start script
    cd /home/tf2-server/hlserver
    su -c "screen -dmS tf2 ./srcds_run -game tf +sv_pure 1 +maxplayers 32 +ip 0.0.0.0 +map mvm_decoy -autoupdate -steam_dir /home/tf2-server/hlserver/ -steamcmd_script /home/tf2-server/hlserver/tf2_ds.txt +sv_shutdown_timeout_minutes 5" tf2server
    while [ -z "$(pidof srcds_linux)" ]; do
        sleep 1
    done
end script

script
    while [ -n "$(pidof srcds_linux)" ]; do
        sleep 1
    done
end script

post-stop script
    fuser -k /home/tf2-server/hlserver/tf2/srcds_run 
    while [ -n "$(pidof srcds_linux)" ]; do
        sleep 1
    done
end script

iptables rules

TODO: This currently depends on a very specific network configuration. Fix so it is more general, and preferably can be saved as a script.

Firstly, run sudo -i to get a root prompt. Then, enter this (all one line). To leave the root prompt and return to the standard user, just type exit like normal.

iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27015 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27005 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27015 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27005 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27016 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27017 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27018 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27019 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p tcp -m tcp --dport 27020 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27016 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27017 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27018 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27019 -m state --state NEW,ESTABLISHED -j ACCEPT && iptables -A INPUT -i venet0 -p udp -m udp --dport 27020 -m state --state NEW,ESTABLISHED -j ACCEPT


CentOS 6.4 (minimal install)

on CentOS 6.4 the default iptables rules has a reject line as the last entry. This will cause all traffic to be rejected if you append (as the above commands recommend). To fix this I recommend first running the server to determine what ports it uses:

netstat -lnptu

This should output something like this:

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      -                   
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      -                   
tcp        0      0 0.0.0.0:27015               0.0.0.0:*                   LISTEN      1393/./srcds_linux  
tcp        0      0 :::22                       :::*                        LISTEN      -                   
tcp        0      0 ::1:25                      :::*                        LISTEN      -                   
udp        0      0 0.0.0.0:27020               0.0.0.0:*                               1393/./srcds_linux  
udp        0      0 0.0.0.0:26901               0.0.0.0:*                               1393/./srcds_linux  
udp        0      0 0.0.0.0:68                  0.0.0.0:*                               -                   
udp        0      0 0.0.0.0:27005               0.0.0.0:*                               1393/./srcds_linux  
udp        0      0 0.0.0.0:27015               0.0.0.0:*                               1393/./srcds_linux

The ports listed with the ./srcds_linux name are being used by your server. In this instance port 27015 is using TCP, and ports 26901, 27005, 27015, and 27020 are using UDP. These ports need to be added to the iptables rules so that the firewall will not block access to incoming traffic.

To add them, first you should find out what is currently in your iptables config. You must do all these commands as root. The best practice is to add your account to the sudoers file so that you are somewhat restricted and access will time out. The choice is yours, su and login, or sudo

sudo iptables -nL --line-numbers

Which should output something like this:

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
5    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination  

Notice that line 5 says "REJECT all..." This means your server will reject everything. If you choose to append new rules to the iptables, you will still have no success with the server as the rules are followed in the order they appear in iptables. The commands you would like to run (again as root or sudo) are:

sudo iptables -I INPUT 5 -p tcp --dport 27015 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -I INPUT 6 -p udp --dport 27015 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -I INPUT 7 -p udp --dport 27005 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -I INPUT 8 -p udp --dport 27020 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -I INPUT 9 -p udp --dport 26901 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo service iptables save
sudo service iptables restart

This will add the new rules above the reject line. If you look at the commands, they have a section that says "-I INPUT 5,6,7,8,9." This is telling what to make the rule number for this entry. Each time you add a new rule, you move the reject line down one, so you increment the rule number. You can choose to just keep adding the commands all as "-I INPUT 5". and everything will still work, but I like to keep my iptables nice and orderly. call me OCD. If you wanted, you could delete the REJECT LINE (sudo iptables -D INPUT 5) and re-add it later, but you have to get the syntax correct so it is easier to insert them above. The save will keep your iptables for reboot, and you must restart the service so the new rules are recognized. Your iptables should now look like this:

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
5    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:27015 state NEW,ESTABLISHED 
6    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:27015 state NEW,ESTABLISHED 
7    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:27005 state NEW,ESTABLISHED 
8    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:27020 state NEW,ESTABLISHED 
9    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:26901 state NEW,ESTABLISHED 
10   REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination 

This should fix your firewall issues.


Troubleshooting

My server doesn’t show up in the LAN tab of my client’s server browser.
I cannot access my loadout when playing on this server.
Are you still able to connect using connect <ip-address> in the Developer Console?
During startup, does your server report the following?
*	Unable to load Steam support library.*
*	This server will operate in LAN mode only.*
When you connect with your client, does the server say the following?
NULL ISteamGameServer in ConnectClient. Steam authentication may fail.
…
Cannot verify load for invalid steam ID […]
If so, then both of these problems have the same solution: Make sure you have a steam_appid.txt file containing the number 232250 in your orange box folder. See Running the server, above.
My server doesn’t auto-update on startup.
When starting up, does your server say the following?
ERROR: -autoupdate requires -steam_dir and -steamcmd_script.
WARNING: Failed to locate steam binary.
WARNING: Could not locate steam binary:, ignoring.
If so, then you need point srcds_run to the location of your SteamCMD binary, using the -steam_dir argument and to your steamcmd update script using the -steamcmd_script argument. See Other command line options, above.
My server is stuck at 0/0 during updates
When an update is running, does the console output the following?
force_install_dir /home/your/server/directory
app_update 232250 validate
Initial App state (0x4) installed
App state (0x4) installed, progress: 0.00 (0 / 0)
Success! App '232250' already up to date.
If so, remove the "validate" instruction from the update command.


My server doesn't work with rcon and/or refuses to broadcast UDP logs
Do you have IPv6 or multiple network interfaces? If so, the server will have an existential crisis when trying to perform these, and you'll need to reassure it by giving it IPs to listen on
To do this, include +ip 0.0.0.0 on the command-line arguments and add rcon_address 0.0.0.0 to your server.cfg
Note: rcon_address is not exclusively used by rcon, UDP logging will fail without it.
steamclient.so error - 64bit

dlopen failed trying to load: ~/.steam/sdk32/steamclient.so with error: ~/.steam/sdk32/steamclient.so: cannot open shared object file: No such file or directory

File is not in the ~.steam/sdk32/ run cp ~/hlserver/linux32/steamclient.so ~/.steam/sdk32/

Could not load replay_srv.so

run sudo dpkg --add-architecture i386; sudo apt-get update;sudo apt-get install mailutils util-linux tmux lib32gcc1 libstdc++6 libstdc++6:i386 libcurl4-gnutls-dev:i386


Server fails to start with ./srcds_run line 324 18491 Segmentation fault $HL_CMD

run the following 2 commands

yum install libcurl.i686
ln -s /usr/lib/libcurl.so.4 /usr/lib/libcurl-gnutls.so.4

See also