CS2 dropped the old SRCDS launcher and a lot of the guides you'll find are still half-written for CS:GO. The server binary, the app id, the launch string — enough changed that copy-pasting a 2023 tutorial gets you a server that won't boot. Here's what actually works today. It's lighter than Rust: a 12–16 slot competitive server is happy with 2 GB and two cores.

TL;DR:

# deps + steam user
apt update && apt install -y steamcmd lib32gcc-s1 tmux
adduser --disabled-password --gecos "" steam
sudo -iu steam

# CS2 dedicated server is app 730, anonymous
steamcmd +force_install_dir /home/steam/cs2 \
  +login anonymous +app_update 730 validate +quit

# launch (needs a GSLT — see below)
cd /home/steam/cs2/game/bin/linuxsteamrt64
./cs2 -dedicated -port 27015 +map de_dust2 \
  +sv_setsteamaccount YOUR_GSLT_TOKEN +game_type 0 +game_mode 1

Details below. Same SteamCMD pattern as /rust-dedicated-server-linux/.

Install SteamCMD and the server

Deps as root, everything else as an unprivileged steam user:

apt update
apt install -y steamcmd lib32gcc-s1 tmux
adduser --disabled-password --gecos "" steam
sudo -iu steam

If apt can't find steamcmd, enable multiverse + i386 and accept the license non-interactively:

add-apt-repository multiverse && dpkg --add-architecture i386 && apt update
echo steam steam/question select "I AGREE" | debconf-set-selections
apt install -y steamcmd

CS2's dedicated server is app id 730 — the same id as the game, pulled anonymously. No Steam account needed for the download itself:

steamcmd +force_install_dir /home/steam/cs2 \
  +login anonymous +app_update 730 validate +quit

It's ~35 GB. Keep validate in the command; Valve pushes frequent updates and a truncated pull gives you a server that starts and then VAC-kicks everyone.

You need a GSLT

This is the step people miss. A public CS2 server must authenticate with a Game Server Login Token, or it runs but never shows up in the browser and rejects connections after a while. Get one (free) at Steam's Game Server Account Management page — steamcommunity.com/dev/managegameservers — using app id 730. You get a token string; pass it as +sv_setsteamaccount.

One token per server. Don't share a token across two running servers — Steam invalidates it and both drop.

The launch string, decoded

CS2's binary lives deep in the tree and takes cvars as +key value, engine flags as -flag:

cd /home/steam/cs2/game/bin/linuxsteamrt64
./cs2 -dedicated -usercon \
  -port 27015 \
  +sv_setsteamaccount YOUR_GSLT_TOKEN \
  +map de_dust2 \
  +game_type 0 +game_mode 1 \
  +hostname "Diengdoh CS2 | Competitive" \
  +rcon_password "use-a-real-one" \
  +sv_lan 0

game_type + game_mode together pick the ruleset — 0 1 is Competitive, 0 0 is Casual, 1 2 is Deathmatch. Get them wrong and you'll swear the map is loading the wrong rules; it's these two. -usercon enables RCON at all; without it rcon_password does nothing.

Server config that you don't want on the command line goes in game/csgo/cfg/server.cfg (yes, still csgo/), read automatically at map load.

Ports and ufw

The game port is 27015 UDP (and TCP for RCON). That's the one that has to be open:

ufw allow 27015/udp
ufw allow 27015/tcp                       # RCON, if you expose it
ufw allow from 203.0.113.10 to any port 27015 proto tcp   # better: lock RCON to your IP

As always, don't hand RCON to the whole internet — it's full server control. Firewall basics: /ufw-firewall-rules-ubuntu/.

Plugins: Metamod + CounterStrikeSharp

Vanilla is fine for a pug server. For admin commands, custom modes, retakes and the rest, the modern stack is Metamod:Source (the loader) plus CounterStrikeSharp (write plugins in C#). SourceMod, the CS:GO workhorse, still isn't fully there for CS2 — CounterStrikeSharp is where the active development is.

Install order matters: Metamod first, then CounterStrikeSharp on top. Drop both into game/csgo/addons/, add the Metamod line to gameinfo.gi as their docs show, and confirm with meta list in the console. The number-one "plugins don't load" cause is a missing or mis-indented gameinfo.gi edit — Valve resets that file on some updates, so re-check it after a patch.

systemd unit

tmux for a quick test; systemd for anything real so it restarts on crash and survives reboots:

# /etc/systemd/system/cs2.service
[Unit]
Description=Counter-Strike 2 Dedicated Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=steam
WorkingDirectory=/home/steam/cs2/game/bin/linuxsteamrt64
ExecStartPre=/usr/games/steamcmd +force_install_dir /home/steam/cs2 +login anonymous +app_update 730 validate +quit
ExecStart=/home/steam/cs2/game/bin/linuxsteamrt64/cs2 -dedicated -usercon -port 27015 \
  +sv_setsteamaccount YOUR_GSLT_TOKEN +map de_dust2 +game_type 0 +game_mode 1 \
  +hostname "Diengdoh CS2" +rcon_password "use-a-real-one"
Restart=on-failure
RestartSec=10
KillSignal=SIGTERM
TimeoutStopSec=60

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now cs2
journalctl -u cs2 -f

The ExecStartPre re-validates on every start so you're never a patch behind — drop it on a modded box where a surprise update would break your addons mid-session. More on units: /systemd-service-unit-file/.

Gotchas

  • No GSLT, no public server. Runs locally, invisible in the browser, drops players. It's the first thing to check when "the server works but nobody can join".
  • Wrong cs2 path. The binary is under game/bin/linuxsteamrt64/, not the install root. Old CS:GO srcds_run scripts point at a launcher that no longer exists.
  • game_type/game_mode mismatch. These pick the ruleset, not the map. Competitive is 0 1. Wrong pair = "why is buy time / round logic wrong".
  • 35 GB and monthly-ish updates. Size the disk for the install plus a workshop map or two, and expect Valve to push updates that occasionally require re-touching gameinfo.gi.
  • VAC kick loop after an update. Always a half-finished app_update. Re-run with validate.

Verify

ss -tulpn | grep 27015                      # port bound?
journalctl -u cs2 --no-pager | grep -i "GC Connection established"   # talking to Steam

In game, open the console and connect your-ip:27015. If it's in the community browser with your hostname, GSLT and ports are right. Building a game host? The same SteamCMD + systemd recipe runs /valheim-dedicated-server-linux/ and the heavier /rust-dedicated-server-linux/; for Minecraft networks see /minecraft-java-server-linux/.


Related posts