Counter-Strike 2 dedicated servers run on Linux and are downloaded with SteamCMD, Valve's command-line Steam client. A server of your own lets you host private matches, practice sessions or a public community server with your own rules and maps. In this tutorial you will install the CS2 server on Ubuntu 24.04, register it with a Game Server Login Token (GSLT), configure the game mode and server.cfg, run it as a systemd service and open the firewall.
Prerequisites
To follow this guide you need:
- A server running Ubuntu 24.04 LTS (x86_64), for example a CubePath VPS. 2 CPU cores and 4 GB of RAM are enough for a 5v5 match; CS2 benefits from fast single-core performance.
- At least 70 GB of free disk space. The server files are about as large as the game client.
- A non-root user with
sudoprivileges. - A Steam account that owns Counter-Strike 2 (free to play) and is not limited, to create the GSLT.
Step 1 - Installing SteamCMD
SteamCMD is in Ubuntu's multiverse repository and depends on 32-bit libraries. Enable both and install it:
sudo add-apt-repository multiverse
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install steamcmd
Accept the Steam license agreement when prompted by selecting I AGREE. The binary is installed as /usr/games/steamcmd.
Step 2 - Creating a dedicated user and downloading CS2
Create an unprivileged user to own the files and run the server:
sudo useradd -m -s /bin/bash steam
sudo -iu steam
The CS2 dedicated server is downloaded through app 730, the same app ID as the game, and can be fetched anonymously. +force_install_dir must come before +login:
/usr/games/steamcmd +force_install_dir /home/steam/cs2 +login anonymous +app_update 730 validate +quit
The download is large and takes a while. When it finishes you should see:
Success! App '730' fully installed.
Confirm that the server binary exists:
ls /home/steam/cs2/game/bin/linuxsteamrt64/cs2
Step 3 - Linking the Steam client library
The CS2 server loads the Steam API from ~/.steam/sdk64/steamclient.so. SteamCMD ships that library but does not put it there, and without it the server fails to start with an error about steamclient.so. Still as the steam user, locate the 64-bit copy that SteamCMD downloaded:
find ~ -path '*steamcmd/linux64/steamclient.so'
/home/steam/.local/share/Steam/steamcmd/linux64/steamclient.so
Link it into place, using the path that find printed on your system:
mkdir -p ~/.steam/sdk64
ln -sf /home/steam/.local/share/Steam/steamcmd/linux64/steamclient.so ~/.steam/sdk64/steamclient.so
ls -l ~/.steam/sdk64/
Step 4 - Configuring server.cfg
server.cfg holds settings that apply to the server regardless of game mode, and CS2 runs it every time a map loads. Create it in the game's config directory:
nano /home/steam/cs2/game/csgo/cfg/server.cfg
hostname "CubePath CS2 Server"
sv_password "your_join_password"
rcon_password "your_strong_rcon_password"
sv_lan 0
sv_cheats 0
mp_autoteambalance 1
mp_limitteams 1
hostnameis the name shown in server browsers.sv_passwordmakes the server private. Set it to""for a public server.rcon_passwordenables remote administration. Use a long, unique value, because RCON has full control over the server.
Leave the steam user:
exit
Step 5 - Creating a Game Server Login Token
Without a GSLT the server only accepts connections from the local network. Create one at steamcommunity.com/dev/managegameservers, enter 730 as the App ID and a memo such as the server's hostname, and copy the token.
Store the token in an environment file readable only by root, instead of in the unit file, which every user on the server can read:
sudo nano /etc/cs2.env
GSLT=your_gslt_token
sudo chmod 600 /etc/cs2.env
A token can only be used by one server at a time. Create a separate token for each server you run.
Step 6 - Choosing the game mode
CS2 selects the mode from two variables, game_type and game_mode, passed on the command line:
| Mode | game_type | game_mode |
|---|---|---|
| Casual | 0 | 0 |
| Competitive | 0 | 1 |
| Wingman | 0 | 2 |
| Arms Race | 1 | 0 |
| Deathmatch | 1 | 2 |
This guide sets up a competitive server on de_dust2. Mode-specific rules come from the game's own gamemode_*.cfg files. To override a rule for one mode, create a file ending in _server.cfg next to it, for example game/csgo/cfg/gamemode_competitive_server.cfg, which runs after the defaults for that mode.
Step 7 - Creating the systemd service
Create a systemd unit that updates the server before each start, runs it as the steam user and restarts it if it crashes:
sudo nano /etc/systemd/system/cs2.service
[Unit]
Description=Counter-Strike 2 dedicated server
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=steam
Group=steam
EnvironmentFile=/etc/cs2.env
WorkingDirectory=/home/steam/cs2/game/bin/linuxsteamrt64
ExecStartPre=-/usr/games/steamcmd +force_install_dir /home/steam/cs2 +login anonymous +app_update 730 +quit
ExecStart=/home/steam/cs2/game/bin/linuxsteamrt64/cs2 -dedicated -usercon -port 27015 -maxplayers 10 +game_type 0 +game_mode 1 +map de_dust2 +sv_setsteamaccount ${GSLT}
TimeoutStartSec=1800
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
What the flags do:
-dedicatedstarts the server without a client, and-userconenables RCON.-port 27015is the game port and-maxplayers 10caps the number of player slots.+sv_setsteamaccount ${GSLT}passes the token from/etc/cs2.env; systemd substitutes the variable.- The leading
-onExecStartPrelets the server start even if Steam is unreachable. When Valve releases a CS2 update, clients cannot join an outdated server, and a restart is enough to update it.
Reload systemd and start the server:
sudo systemctl daemon-reload
sudo systemctl enable --now cs2
Step 8 - Verifying the server and opening the firewall
Follow the log while the map loads:
sudo journalctl -u cs2 -f
Look for errors about steamclient.so or about the token. When the server is ready, confirm it is listening on port 27015:
sudo ss -ulpn | grep 27015
UNCONN 0 0 0.0.0.0:27015 0.0.0.0:* users:(("cs2",pid=6012,fd=...))
The game uses UDP 27015, and RCON connects over TCP on the same port. If UFW is enabled, allow the game traffic:
sudo ufw allow 27015/udp
Only open TCP 27015 if you want to use RCON from outside, and preferably only from your own IP:
sudo ufw allow from your_admin_ip to any port 27015 proto tcp
To join, enable the developer console in CS2 (Settings > Game > Enable Developer Console), open it with the ~ key and run:
password your_join_password
connect your_server_ip:27015
Step 9 - Administering the server with RCON
From the in-game console you can run server commands remotely. Point RCON at the server, authenticate and send commands:
rcon_address your_server_ip:27015
rcon_password your_strong_rcon_password
rcon status
rcon changelevel de_mirage
rcon mp_restartgame 1
status lists connected players, changelevel switches map, and mp_restartgame 1 restarts the match after one second.
Troubleshooting
- The service fails with an error loading
steamclient.so. The symlink from Step 3 is missing or points to a file that does not exist. Check it withsudo -u steam ls -lL /home/steam/.steam/sdk64/steamclient.so. - Players outside your network cannot join, or the server is LAN only. The GSLT is missing, invalid or already in use by another server. Check the log for token errors and regenerate the token on the Steam page if needed.
- "Server is running an older version" when connecting. Restart the service to pull the latest update:
sudo systemctl restart cs2. - Settings in
server.cfgare ignored. A mode config may set the same variable later. Move mode-specific rules intogamemode_<mode>_server.cfg.
Conclusion
You now have a Counter-Strike 2 dedicated server on Ubuntu 24.04, registered with a GSLT, running under systemd and updated automatically on restart. As next steps, you can run a second server on another port with its own token and unit file, host community maps with host_workshop_map and a workshop ID, or install a server plugin framework such as Metamod:Source with CounterStrikeSharp to add admin tools and match management.
