This post shows how to setup a full dedicated TF2 multiplayer server on a modern Linux system (including process supervising and some privilege separation). Additionally we install some addons and plugins to increase the functionality and comfort.
Team Fortress 2 is a multiplayer online shooter - that even though it's now more than 10 years old - still has a active and loyal community. The rate of updates has dropped to nearly zero, yet the community is still alive and loyal.
⚠️ Before we begin: This post has been a draft for multiple years now, as I started it as a reference for myself but was never happy enough to publish it. As TF2's time is slowly going to an end, I'm releasing it now to to fully waste all the effort in writing and researching this.
I'm using mostly Ubuntu 18.04 for this tutorial (and already updated parts for 20.04), as it's a LTS release which is still supported until 2023.
These instructions have been tested on a fresh Ubuntu Server installation, but should also work on existing systems. You need full root access to setup the base, the game server itself will run under it's own user account.
Note that most of the instructions can also be applied to other Source Engine based games like Garry's Mod, Counter Strike or Left 4 Dead (2).
Setting up the base server
Before installing the actual game server, it's necessary to setup the system and install some needeed packages.
Initial updates
Execute the following three commands on your systems. They update the cache of the package manager, upgrade any old packages and restart the system. The latter is required to apply any kernel updates.
Firewall
The following commands allow traffic for all needed ports for the server (SSH + Game Server) and put the firewall in a secure default mode.
Note: If you want to host the server on a different port or multiple servers, add more exceptions accordingly.
Note: We only allow game server connections using UDP. If you want to use RCON, it's more reliable and secure to use SourceMod for that (sm_rcon
command).
Base packages
Now let's install some basic packages that are useful to us later. This is pretty much the default set I use when I start with a server.
Setup steamcmd and more packages
To ease the setup, the steamcmd
command used to install game servers on dedicated machines has already been packaged for Ubuntu, so we can install it using the regular package manager.
Note: The documentation on which packages are exactly needed are rather sparse, so I added everything I could find - some might not bee needed anymore.
If some of the packages are missing in later Ubuntu versions, they often just increased the package's version nummer in the name (e.g. lib32ncurses5
-> lib32ncurses6
). Searching for packages using apt-cache search
can help finding those.
As one of the last steps as root, let's make a user account for our game server.
Install MariaDB (MySQL fork)
Note: This step is actually optional, but recommended for SourceMod as it allows to store configuration information and bans into the database and provides easier and external (in the sense of scripts) access to it.
Now, let's setup a database user for SourceMod:
Please change the password to something actually secure!
Install the actual game server
Everything that happens here must be executing using the steam user. For security reasons we do not want to ever run the game server as root, which would allow exploits to takeover the entire operating system. Use the following command to change your current the shell to it:
Now, let's install TF2 into a subdirectory. If you want to have multiple servers, change the installation path accordingly. In theory you can start multiple servers from the same installation, but it takes further configuration tweaks especially when using SourceMod, which are not discussed here.
Note: The same command can be used later to update and validate the server and all it's files. Maybe put it into a bash script?
After this is finished, link a file to remove some warnings when the server starts up:
We're nearly done for the first part! Now let's start the server to see if it boots up:
If you can connect to the server using the game client, you made it!
If the server crashes or you cannot connect, make sure all required packages are installed and the firewall has a rule to allow the traffic (ufw status
). Copying error messages in Google is also useful. 😉
A Source Engine server by itself is just the bare minimum to run the game, but as admin of a custom server you generally want more that the regular game.
For this, we need Metamod:Source and SourceMod, which provides a scripting language for easier access to the Source Engine and a wide variety of plugins created by the community.
Note: The versions used in this tutorial are surely outdated when you read this, so please check the linked websites above to download the most recent versions.
Note: The cd
at the beginning are important to ensure the files are extracted at the right location.
After this is done, start the server again and try the following commands in the server console:
Should output something like:
If both work, SourceMod has been installed successfully - and you can start adding plugins to your server. Examples for this will be show in the next chapter.
Before going public with your server, you should at least modify the following files:
For a reference of options for the server.cfg
, check out this page in the TF2 Wiki.
Tip: To save and exit vim, press ESC
once, then directly enter :wq
(write + quit) and press ENTER
to confirm.
Set up the Database
If you have installed and want to use MariaDB, this is the time to setup the schema and configure SourceMod to use your database.
In case you have multiple game servers and depending on your use cases, either share databases between MariaDB servers or create own databases for each. In general your database does not need a lot of resources (it's just for user checking and sometimes stats after all).
Note: Execute these commands as root, so you don't have to enter a MariaDB password. (Depending on your distribution, at least on Ubuntu...)
Next, edit the file /home/steam/tf2/tf/addons/sourcemod/configs/databases.cfg
and replace the default
connection with the following code. Don't forget to replace the password with the one you've chosen when setting up the database.
Also, enable the plugins needed to manage SourceMod admins using the database:
Start your server again and enter the following commands in the server console, to give yourself (or me, in the example) full admin permissions:
To find out your own Steam ID, go to Steam ID Finder, enter your profile URL and then use the value of steamID
(see above for the right format).
You should now be able to open the admin menu in-game using either /sm_admin
in the chat or sm_admin
in the game console. I recommend to bind the latter to a key (e.g. bind p sm_admin
)
The command sm_reloadadmins
is always required after changing admins in the database, as SourceMod is caching all users in memory for performance.
Automatic start and reboots
Starting a server in a SSH shell (even with screen or byobu) is annoying and needs a lot of maintanance to work stable. A better and easier way is to use systemd, a process supervisor that is available in most modern Linux distributions. It also allows you auto-restart the server for updates and cleanup and provides additional security features to further tighten security.
To use it, we need to add a service definition to it's configuration directory and notify it about it. Additionally, we'll add a timer unit to restart the server daily, which makes sure any memory leaks won't survive for long and all updates (if they were any 😅) are applied at least daily.
Save as: /etc/systemd/system/tf2.service
Heads up:
- Replace SERVER_STEAM_ACCOUNT with your Steam server account. While this is optional for TF2, it allows players to keep their favorites if your server's IP changes for any reason.
- Change the default map and maxplayers. My default is 32, as we sometimes run MvM (which requires it for the bots managed by the game).
Alternatively, you could create a bash script with the launch command and use it's path instead in the ExecStart
line. This task is up to the reader.
Additional, you need to create the file /home/steam/tf2_ds.txt
, which is the update script for steamcmd:
Now enable the service and start it:
You can check the logs using the systemd journal:
Depending on the server's performance and number of installed plugins, it can take up to a minute for the server to be fully ready for client connections.
Note that by starting the server using systemd, you cannot use the interactive console of the server. You can generally replace it with SourceMod's sm_rcon
command after joining the server.
If you lack the permissions to do so (e.g. to re-add admins), stop the systemd service and start the server manually again, as done above.
Daily reboot for updates
Using the systemd configuration above, the server only updates itself when it's fully restarted using systemd, not by it's internal update system (which has other bugs).
Now add this line at the end, which restarts the server always at 03:00 in the night:
Ideally this would be a systemd timer unit, but it takes much more code to do the same thing.
FastDL
When you have custom resources on your server like maps or additional textures, the game uses by default it's own protocol to download these files to the client - and that's really slow (capped to 20 KiB/s according to some sources). Instead, we'll add a small webserver which will be used to deliver the file.
Now create this file: /etc/nginx/sites-enabled.d/tf2-fastdl.conf
Then update your server.cfg
and add the following lines:
Finally, restart all services to pick up the new configuration:
Why not HTTPS?
Cause the Source Engine doesn't support it...
Where to go from here
You should now have a working TF2 game server including SourceMod and a database for managing admins.
Depending on what the server is for, you might want to add additional SourceMod plugins.
Also, please don't contact me for support, as I'm no longer hosting TF2 servers. ;-)
Further resources / references
Post changelog
- May 2022
- Updated SourceMod download list, added rm commands to Metamod/SourceMod instructions
- Added
gdb
to installed system packages - Fixed a warning with the order of
force_install_dir
- Added example output of
meta list
and sm plugins