[ L4D2 Server — Install Guide ]
Step-by-step guide for installing a Left 4 Dead 2 dedicated server with SourceMod and MetaMod:Source on a fresh Debian or Ubuntu VPS. Covers everything from base OS prep through to a working SourceMod console you can load plugins onto. Once this is done, the L4D2 Stats Install Guide covers adding persistent player stats with a web UI on top.
[ Overview ]
Assumptions
- Fresh Debian 12+ or Ubuntu 22.04+ VPS - ~10 GB free disk, 2 GB+ RAM - Non-root user with sudo (commands below assume your user, not root) - Open ports: 27015/udp (game), 27020/udp (SourceTV)
Time estimate
30–60 minutes including the ~10 GB game file download. Most of that is wall time waiting on SteamCMD.
[ 1. Prep the system ]
L4D2 dedicated server is a 32-bit (i386) binary. Multi-arch is required.
sudo dpkg --add-architecture i386 sudo apt update sudo apt upgrade -y sudo apt install -y curl wget file tar bzip2 gzip unzip bsdmainutils \ python3 util-linux ca-certificates binutils bc jq tmux netcat-openbsd \ lib32gcc-s1 lib32stdc++6 libcurl4-openssl-dev:i386 libsdl2-2.0-0:i386
(libsdl2-2.0-0:i386 is what L4D2 needs at runtime; missing
it = silent crash on first launch.)
[ 2. Create a dedicated user ]
Never run game servers as root.
sudo adduser --disabled-password --gecos "" l4d2server sudo passwd l4d2server # set a password if you want SSH access sudo su - l4d2server
The rest of the guide runs as l4d2server.
[ 3. Install LinuxGSM ]
LinuxGSM is the standard wrapper for Source-engine dedicated servers — handles updates, start/stop, monitoring, console capture.
wget -O linuxgsm.sh https://linuxgsm.sh chmod +x linuxgsm.sh bash linuxgsm.sh l4d2server
This downloads the LinuxGSM script tailored for L4D2 and saves it as
l4d2server in your home directory.
[ 4. Install the game files ]
./l4d2server install
The installer will:
- Check dependencies
- Prompt for hostname, rcon password, admin SteamID (you can leave
blanks and edit later)
- Run SteamCMD to download ~10 GB of L4D2 server files (takes 5-20 min
depending on connection)
When it finishes you should see Install complete and the
prompt comes back.
[ 5. Get a Steam Game Server Login Token (GSLT) ]
Required to show up as a public server (without one, your server is invisible to the in-game browser).
1. Open https://steamcommunity.com/dev/managegameservers in your browser
2. Sign in with a Steam account
3. Create a GSLT for App ID 222860 (L4D2)
4. Give it a memo like "my-l4d2-vps"
5. Copy the token string
On the VPS:
nano ~/lgsm/config-lgsm/l4d2server/l4d2server.cfg
Add (or uncomment and set):
gslt="YOUR_TOKEN_HERE"
Save (Ctrl+O, Enter, Ctrl+X).
[ 6. Configure server basics ]
Edit the gameplay config:
nano ~/serverfiles/left4dead2/cfg/server.cfg
Minimum useful contents:
hostname "My L4D2 Server" sv_search_key "anything" rcon_password "USE_OPENSSL_RAND_HEX_24" sv_lan 0 mp_gamemode "coop" sv_allow_lobby_connect_only 0 sv_steamgroup_exclusive 0 sv_region 1
Generate a strong RCON password with openssl rand -hex 24
(run in another terminal). Don't paste passwords anywhere afterward.
LinuxGSM-specific config (start parameters, hostname, etc.) lives in
~/lgsm/config-lgsm/l4d2server/l4d2server.cfg. The two configs
are loaded at different times — l4d2server.cfg (LinuxGSM)
is for startup parameters, server.cfg (game engine) is
exec'd on each map load.
[ 7. Patch executable stack flags (required on modern Linux) ]
Modern Linux kernels refuse to load shared libraries flagged with
executable stacks. L4D2's bundled .so files have this
flag set, causing the server to fail silently on startup.
Save this Python script as ~/clear_execstack.py:
#!/usr/bin/env python3 import os, struct, sys def clear_execstack(path): with open(path, 'r+b') as f: if f.read(4) != b'\x7fELF': return False f.seek(0x10) e_type = struct.unpack('<H', f.read(2))[0] if e_type not in (2, 3): # EXEC or DYN return False f.seek(0x20) e_phoff = struct.unpack('<I', f.read(4))[0] f.seek(0x2A) e_phentsize = struct.unpack('<H', f.read(2))[0] e_phnum = struct.unpack('<H', f.read(2))[0] for i in range(e_phnum): f.seek(e_phoff + i * e_phentsize) p_type = struct.unpack('<I', f.read(4))[0] if p_type == 0x6474e551: # PT_GNU_STACK f.seek(e_phoff + i * e_phentsize + 0x18) flags = struct.unpack('<I', f.read(4))[0] if flags & 1: # PF_X set f.seek(e_phoff + i * e_phentsize + 0x18) f.write(struct.pack('<I', flags & ~1)) return True return False if __name__ == '__main__': target = sys.argv[1] if len(sys.argv) > 1 else '/home/l4d2server/serverfiles' fixed = 0 for root, _, files in os.walk(target): for fname in files: if fname.endswith('.so') or fname.endswith('.so.1'): path = os.path.join(root, fname) try: if clear_execstack(path): print(f"Patched: {path}") fixed += 1 except Exception as e: print(f"Skip {path}: {e}") print(f"\n{fixed} files patched.")
Run it:
chmod +x ~/clear_execstack.py python3 ~/clear_execstack.py
You'll need to re-run this after every L4D2 game update (Valve
ships fresh .so files unpatched).
[ 8. First start ]
./l4d2server start ./l4d2server details
details shows hostname, IPs, ports, current status. The
server should be running on 27015/udp.
To watch the live console:
./l4d2server console
(Detach without killing the server: Ctrl+B then
D.)
If it crashes immediately, check:
tail -50 ~/log/console/l4d2server-console.log
[ 9. Test the connection ]
In L4D2 client, open the in-game console (~ key, must be enabled in Keyboard/Mouse options) and:
connect YOUR_VPS_IP:27015
You should load into the default map (c5m1_waterfront
unless you've changed it).
[ 10. Install MetaMod:Source ]
MetaMod is the loader that lets SourceMod hook into the engine.
cd /tmp wget https://mms.alliedmods.net/mmsdrop/1.12/mmsource-latest-linux.tar.gz tar xzf mmsource-latest-linux.tar.gz -C ~/serverfiles/left4dead2/
Verify:
ls ~/serverfiles/left4dead2/addons/ # Should show: metamod metamod.vdf
[ 11. Install SourceMod ]
cd /tmp wget https://sm.alliedmods.net/smdrop/1.12/sourcemod-latest-linux.tar.gz tar xzf sourcemod-latest-linux.tar.gz -C ~/serverfiles/left4dead2/
[ 12. Make yourself an admin ]
Find your SteamID in Steam-style format
(STEAM_1:1:xxxxx). Easiest way:
steamid.io.
Edit:
nano ~/serverfiles/left4dead2/addons/sourcemod/configs/admins_simple.ini
Add at the end:
"STEAM_1:1:YOUR_NUMBER" "z"
z = root flag (all admin powers).
[ 13. Restart and verify SourceMod loaded ]
./l4d2server restart sleep 15 ./l4d2server send "meta version" sleep 2 ./l4d2server send "sm version" sleep 2 tail -30 ~/log/console/l4d2server-console.log | grep -iE "metamod|sourcemod"
You should see Metamod and SourceMod version banners with no errors.
[ 14. Useful day-to-day commands ]
./l4d2server start # start the server ./l4d2server stop # stop the server ./l4d2server restart # restart ./l4d2server details # show status / IPs / ports ./l4d2server console # attach to live console (Ctrl+B D to detach) ./l4d2server send "command" # send a console command ./l4d2server update # update game files (re-run clear_execstack.py after) ./l4d2server update-lgsm # update LinuxGSM scripts ./l4d2server backup # back up server files (config + plugins, not game files)
[ 15. Basic hardening ]
# Firewall sudo apt install -y ufw sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp comment 'SSH' sudo ufw allow 27015/udp comment 'L4D2 game' sudo ufw allow 27020/udp comment 'SourceTV' sudo ufw enable # Auto-apply security updates sudo apt install -y unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # SSH brute-force protection sudo apt install -y fail2ban sudo systemctl enable --now fail2ban
Don't expose 27015/tcp (RCON) unless you specifically
use external RCON tools — most admins don't, and it's a
brute-force target.
[ 16. Common gotchas ]
Server won't start, no obvious error:
- Run clear_execstack.py — missing this is the #1 silent failure on fresh Debian/Ubuntu - Check libsdl2-2.0-0:i386 is installed
LinuxGSM uses l4d2server.cfg, not
server.cfg:
- ~/lgsm/config-lgsm/l4d2server/l4d2server.cfg LinuxGSM startup parameters (GSLT, hostname, ports) - ~/serverfiles/left4dead2/cfg/server.cfg engine-level gameplay cvars, exec'd on map load
Server not visible in browser:
- GSLT not set, set wrong, or banned by Valve (request a new one)
- sv_lan 1 accidentally set (use 0 for public)
- Firewall blocking 27015/udp
Steam "Invalid platform" on SteamCMD:
Sometimes needed for L4D2 updates: prefix with
+@sSteamCmdForcePlatformType windows before login (rare workaround)
Can't open in-game console:
- Steam → Settings → In-Game → enable Developer Console
- Default key is ~, can be rebound in keyboard options
[ Where to go from here ]
Now you have a base server. Optional next steps:
- Add persistent player stats with a web UI Self-host the dashboard + leaderboard stack like the one running at l4d2.magikh0e.pl. - Install the L4D2 server pack Four small SourceMod plugins for welcome chat, kill leaderboard, admin map-jump shortcuts, and auto-rotation after finale wins. - Install community plugins — forums.alliedmods.net has hundreds, indexed by game. - Add custom maps, mutations, or gamemodes. - Set up automated backups and a daily cron restart.
The server will run indefinitely with LinuxGSM monitoring it
(l4d2server monitor can be cronned every few minutes to
auto-restart on crash).
[ Raw markdown ]
This guide is also available as a single markdown file:
📄 l4d2-server-install-guide.md
