All Linux HowTo's

Create Your Own Public Half-Life 2 DM Server on CentOS 7/8

This article walks you through the process of building your own publicly accessible Half-Life 2 Death Match server on CentOS 7 and should work with 8 too but that’s untested.

There’s plenty that can go wrong in this process. See the bottom of this article for common problems and solutions. I’m the first to admit this is a work-in-progress and there may be mistakes and things to be reconsidered. This article is the result of my notes when setting up a Half Life 2 DM server. It should work without SELinux issues. In my case, I’ve left SELinux enabled and it’s working fine.

For more specific options for customising the server/game, check out “”.

Permit traffic on the firewall. If this is a cloud-based server, remember to permit these ports/protocols on the network-based firewall too. I suspect the server needs to respond to pings (ICMP) so make sure that’s permitted too.

firewall-cmd --add-port 27021/tcp --permanent
firewall-cmd --add-port 27000-27030/udp --permanent
firewall-cmd --reload

Install Screen and some libraries (see the troubleshooting section if you get errors with this). This process can be improved upon but I lost my notes on the precise packages that need to be installed:

yum install screen SDL2*

Create the local user to run the server as:

useradd -m hl2dmuser

Create the directory to install to and run from:

mkdir /opt/hl2dm
cd /opt/hl2dm
chown hl2dmuser.hl2dmuser/opt/hl2dm

Switch to the new user and download the server software:

su hl2dmuser
cd /opt/hl2dm
tar -xzf steamcmd_linux.tar.gz

Start the installer script:

login anonymous

The above should produce the following sample output:

Connecting anonymously to Steam Public...OK
Waiting for client config...OK
Waiting for user info...OK

Install the server software:

force_install_dir ./halflife2
app_update 232370 validate

As the “root” user: Edit the file below and add the sample content. The file may not exists so create it if it isn’t already there. These were gathered from “”:


Use this as a template. Customise as you see fit:

// The name of your server within the global server list
hostname "Half Life 2 DM Server (Beginners)"

// Server contact name / url / email
sv_contact "My Name ("

// server password for players to join (default "")
//sv_password "mypassword"

// Respawn weapons timeout
sv_hl2mp_weapon_respawn_time 20

// Respawn items timeout
sv_hl2mp_item_respawn_time 30

// set to 1 if this is a teamplay server
mp_teamplay 1

// allow or disallow damage from teammates
mp_friendlyfire 0

// how much damage is inflicted from falls, default 0
mp_falldamage 0

// set to 1 if weapons stay (immediate pickup by players without weapons)
// requires that there be additional ammo (can't pick up a weapon to get more ammo)
mp_weaponstay 0

// set to force players to respawn after death
mp_forcerespawn 1

// enable player footstep sounds
mp_footsteps 1

// enable flashlight
mp_flashlight 1

// enable autocrosshair (default is 1)
mp_autocrosshair 1

// allow bots
mp_allowNPCs 1

// world gravity (default 600)
sv_gravity 600

// spectator settings
sv_noclipaccelerate 5
sv_noclipspeed 5

sv_specaccelerate 5
sv_specspeed 3
sv_specnoclip 1

// misc default vehicle settings (leave these alone)
//r_VehicleViewDampen 1
//r_JeepViewDampenFreq 7.0
//r_JeepViewDampenDamp 1.0
//r_JeepViewZHeight 10.0
//r_AirboatViewDampenFreq 7.0
//r_AirboatViewDampenDamp 1.0
//r_AirboatViewZHeight 0.0

// teamplay talk all (1) or team only (0)
sv_alltalk 0

// enable voice on server
sv_voiceenable 1

// disable pause on server (set this to 0 always)
sv_pausable 0

// disable cheats (set this to 0 always)
sv_cheats 0

// teamserver coop (default 0)
coop 0

// deathmatch - set this to 1
deathmatch 1

// allow players to upload sprays (default 1)
sv_allowupload 1

// allow sprays and map content to be downloaded (default 1)
sv_allowdownload 1

// how often players can spray tags (default 20)
decalfrequency 20

// fast http download url address

// Enable instanced baselines - Saves network overhead
sv_instancebaselines 0

//Force server side preloading (default 0)
sv_forcepreload 1

// set fraglimit before mapchange
mp_fraglimit 20

// set timelimit before map change
mp_timelimit 20

// Max bandwidth rate allowed on server, 0 == unlimited
sv_maxrate 9999

// Min bandwidth rate allowed on server, 0 == unlimited
sv_minrate 5000

// Maximum updates per second that the server will allow (default 60)
sv_maxupdaterate 30

// Minimum updates per second that the server will allow (default 10)
sv_minupdaterate 10

// explosion size (default 1)
sv_robust_explosions 0

// rcon failure settings
sv_rcon_banpenalty 0
sv_rcon_maxfailures 10
sv_rcon_minfailures 5
sv_rcon_minfailuretime 30

//The region of the world to report this server in (255 = world)
sv_region 255

// gather server statistics
sv_stats 1

//After this many seconds without a message from a client, the client is dropped (default 65)
sv_timeout 65

//Specifies which voice codec DLL to use in a game. Set to the name of the DLL without the extension
// miles is the only voice codec available for Source games
sv_voicecodec vaudio_miles

//toggles whether the server allows spectator mode or not
mp_allowspectators 0

// If set to 1 then Server is a lan server (no heartbeat, no authentication, no non-class C addresses, 9999.0 rate, etc. )
// set to 0 for internet server
sv_lan 0

// execute SteamID based ban list
// this file must be located in the cfg folder
exec banned_user.cfg

// execute IP based ban list
// this file must be located in the cfg folder
exec banned_ip.cfg

// Set packet filtering by IP mode (default 1)
sv_filterban 1

// log all bans in logfile
sv_logbans 1

// enable logging and start log file (always last thing)
sv_logfile 1
log on

As the “root” user: Add a “MOTD” Message Of The Day. I’m not sure yet which file needs the content so adding them all doesn’t hurt. The files are:

/opt/hl2dm/halflife2/hl2mp/cfg/motd_default.txt (html)
/opt/hl2dm/halflife2/hl2mp/cfg/motd_text_default.txt (text)
/opt/hl2dm/halflife2/hl2mp/cfg/motd_text.txt (text)

… and the contents can be something like the following (for the MOTD):

Thanks for playing. Sponsored by Me at

Start the game with the following example. Use “screen” if you want to leave the server running long after your gone. For testing, the following is sufficient.

./srcds_run -game hl2mp +port 27021 +map dm_runoff +autoupdate -maxplayers 10

You should be able to see your server in the global list. If not, the problem is likely to do with firewalls. Check out the following troubleshooting section to help find any solutions you need.


If you have problems with the above. Consider starting the game server with the “-debug” option appended to the above. It will create a debug file (debug.log found in the same directory) that you can explore for more specific descriptions of problems.


The "yum" command downloads the packages but failed to install them. 

Try running this “yum” command “yum install screen SDL2* –exclude=SDL2_gfx-*”. to exclude the “gfx” package which had issues with my system.


Command not found: #!/usr/bin/env

This executable exists on my server. Not sure why it’s error’ing. I can’t find the reference to it anyway.


WARNING: Failed to load 32-bit or
  Please install (lib32tinfo5 / ncurses-libs.i686 / equivalent) to enable readline.

You can install “ncurses-libs.i686” using “yum install ncurses-libs.i686”. I’ve left that out of the initial instructions because, for all I know, it’s an edge case for this installation and version of CentOS.


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

The file “” is not in that location, it is located at “/opt/hl2dm/halflife2/bin/”. As the “hl2dmuser” user, create the subdirectory “mkdir /home/hl2dmuser/.steam/sdk32/” and then copy the file in “cp /opt/hl2dm/halflife2/bin/ /home/hl2dmuser/.steam/sdk32/”.


Could not find steamerrorreporter binary. Any minidumps will be uploaded in-processWarning: failed to init SDL thread priority manager: SDL not found

This error can apparently be ignored. See “”. My effort to resolve this is in the “yum” command at the top of the article. I couldn’t resolve it.


WARNING: Port 27020 was unavailable - bound to port 27021 instead
Network: IP, mode MP, dedicated Yes, ports 27020 SV / 27005 CL

Adjust your firewall to accommodate the new port. Both your host-based firewall and your network-based firewall.

Note: The server listens on the following ports and protocols:

tcp        0      0 *               LISTEN      12345/./srcds_linux
udp        0      0 *                           12345/./srcds_linux
udp        0      0 *                           12345/./srcds_linux
udp        0      0 *                           12345/./srcds_linux

Please add your errors and potential solutions in the comments section.

Similar Posts:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.