Use case · Game server

Running an Insurgency: Sandstorm dedicated server on bare metal

An Insurgency: Sandstorm dedicated server is New World Interactive's server build, installed through SteamCMD as app 581330 with an anonymous login and started on Linux as InsurgencyServer-Linux-Shipping with a map, a scenario and a player cap in one travel URL. The official Server Admin Guide uses game port 27102 and query port 27131. Stats and experience on a community server need a Steam game server login token, a GameStats token and no server password.

See the machines

What the server is

Sandstorm's server ships as a separate Steam app, 581330, distinct from the game (581320). The Server Admin Guide, which New World Interactive moved from its old support site to mod.io, installs it with login anonymous and app_update 581330 validate, so no personal Steam account sits on the box. On Linux the binary is Insurgency/Binaries/Linux/InsurgencyServer-Linux-Shipping under the install directory; on Windows it is InsurgencyServer.exe.

The first argument is a travel URL: map, then ?Scenario=, then other travel parameters such as ?MaxPlayers= and ?Password=. The guide's example is Oilfield?Scenario=Scenario_Refinery_Push_Security?MaxPlayers=28 followed by -Port=27102 -QueryPort=27131 -log -hostname="My Server". A misspelt map or scenario falls back to Farmhouse, which is the first thing to check when the server boots into the wrong level.

The three ports involved

PurposeGuide's valueSet byExpose
Game connections27102 (UDP per the parameter table)-Port=Yes
Steam server queries27131-QueryPort=Yes
RCON (Source RCON protocol)27015 in the example-RconListenPort= or ListenPort= under [Rcon]No: loopback plus an SSH tunnel

The guide's firewall steps open both TCP and UDP on the game and query ports, and the install below does the same. The machine takes a public IPv4 directly, so the setup has no home router and no port forwarding step: the host firewall is the only gate. RCON speaks the Source RCON protocol, which Valve documents as TCP.

Sizing the machine

New World Interactive publishes no CPU, memory or disk figures for the server, so none appear here. What drives the load is known from the guide's own settings: the player cap in the travel URL, bots on coop modes (bBots and BotQuota in Game.ini), and how many instances share the machine. Our rule, not the guide's: install it, run a full match at your intended player count with bots, watch top and free -m, check the install size with du -sh, then size with headroom for a second instance.

Architecture matters more than generation. Valve documents SteamCMD for x86-64 Linux and the guide ships only an x86 Linux server binary, so our recommendation is an x86 line from the game server range and leave out the ARM lines, the X-Gene cartridge included, which boots Ubuntu 16.04 or 18.04 only. Neither source mentions ARM; that step is our inference. The Xeon processor list gives each chip's cores and launch date if you are choosing between lines.

Every dedicated server includes an unmetered port and one IPv4: 1 Gbps on 10 of the 18 configurable lines, 500 Mbps on the rest. Rack servers and blades carry an out-of-band controller (iLO, iDRAC or a BMC) with a browser console once you add a console login. A racked machine is live about 30 minutes after the order is approved; a build to order takes 4-24 hours. Choose whichever of the five locations sits closest to your player base; each has a test IP to ping first.

Install and firewall

Valve's SteamCMD page calls running it as root a security risk; a dedicated sandstorm account owns the install instead. Run this as your sudo user on Ubuntu or Debian from the Linux images. The firewall order is deliberate: IPv6 on before any rule, SSH allowed before ufw is enabled, game ports last.

sudo apt update && sudo apt install -y lib32gcc-s1 curl ufw
sudo useradd -m -s /bin/bash sandstorm
sudo -u sandstorm bash -c 'mkdir -p /home/sandstorm/steamcmd && cd /home/sandstorm/steamcmd && curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf -'
sudo -u sandstorm bash -c '/home/sandstorm/steamcmd/steamcmd.sh +force_install_dir /home/sandstorm/server +login anonymous +app_update 581330 validate +quit'
sudo -u sandstorm bash -c 'cd /home/sandstorm/server && mkdir -p Insurgency/Saved/Config/LinuxServer Insurgency/Config/Server && touch Insurgency/Saved/Config/LinuxServer/Game.ini Insurgency/Saved/Config/LinuxServer/Engine.ini Insurgency/Config/Server/Admins.txt Insurgency/Config/Server/MapCycle.txt && chmod 600 Insurgency/Saved/Config/LinuxServer/Game.ini'

sudo sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
sudo ufw allow OpenSSH
sudo ufw --force enable
sudo ufw allow 27102
sudo ufw allow 27131
sudo ufw status verbose

force_install_dir precedes login, as Valve orders it. Game.ini is set to 600 because it will hold the RCON password. Nothing else on the machine, RCON included, is reachable from outside.

Launch script, tokens and systemd

The guide launches from a shell script; this one adds the two tokens from environment variables. Save it as /home/sandstorm/server/start.sh, owned by sandstorm:

cd /home/sandstorm/server
exec Insurgency/Binaries/Linux/InsurgencyServer-Linux-Shipping 'Oilfield?Scenario=Scenario_Refinery_Push_Security?MaxPlayers=28' -Port=27102 -QueryPort=27131 -log -hostname="My Server" -GSLTToken="$GSLT" -GameStatsToken="$GAMESTATS" -GameStats

Run sudo mkdir -p /etc/sandstorm first, since sudoedit will not create the folder, then create /etc/sandstorm/tokens.env with sudoedit, holding two lines, GSLT= and GAMESTATS= with your values, then sudo chmod 600 it so only root reads it. The guide documents both tokens only as command-line switches, so while the server runs they are visible in the process list (ps) to anyone with a shell on the box; keep the machine single-user, and check whether the server log repeats its command line before you share a log. Save the unit as /etc/systemd/system/sandstorm.service:

[Unit]
Description=Insurgency: Sandstorm dedicated server
After=network-online.target
Wants=network-online.target

[Service]
User=sandstorm
Group=sandstorm
WorkingDirectory=/home/sandstorm/server
EnvironmentFile=/etc/sandstorm/tokens.env
ExecStartPre=-/home/sandstorm/steamcmd/steamcmd.sh +force_install_dir /home/sandstorm/server +login anonymous +app_update 581330 +quit
ExecStart=/bin/bash /home/sandstorm/server/start.sh
Restart=on-failure
TimeoutStartSec=1800

[Install]
WantedBy=multi-user.target

Then sudo systemctl daemon-reload && sudo systemctl enable --now sandstorm. The minus sign on ExecStartPre lets the server start when an update check fails; it does not cover a hung update, which is what TimeoutStartSec=1800 is for, since the default 90 seconds includes the update. Every restart is now an update, the same app_update 581330 the guide uses.

Config files and where they live

FilePath under the installHolds
Game.iniInsurgency/Saved/Config/LinuxServerGame mode options, voting, [Rcon]
Engine.iniInsurgency/Saved/Config/LinuxServerEngine settings
Admins.txtInsurgency/Config/ServerOne steamID64 per line
MapCycle.txtInsurgency/Config/ServerOne scenario per line
Motd.txtInsurgency/Config/ServerPlain-text loading-screen message

The guide says to create any of these that are missing. New admins take effect after a restart or a level change; -AdminList=, -MapCycle= and -motd= point the server at other file names. Without a map cycle the server rotates through all Versus scenarios. One caveat: the newer modded-server guide on mod.io names the admin and map files Admins.ini and MapCycle.ini, while the vanilla guide says .txt. If entries seem ignored, check which name your build reads.

For RCON, put bEnabled=True, Password=, ListenPort=27015 (the guide's example port), bUseBroadcastAddress=False and ListenAddressOverride=127.0.0.1 under [Rcon] in Game.ini, so the password stays out of the command line. Our reading of the RCON options the guide lists: with bUseBroadcastAddress off, ListenAddressOverride is the address RCON binds to, so the socket should listen on loopback only. Confirm it after a restart with sudo ss -tlnp | grep 27015, which should show 127.0.0.1. Reach it with ssh -L 27015:127.0.0.1:27015 you@server and any Source RCON client. The guide bans an address for 30 minutes after 3 failed logins by default. Its separate RCON page reports server crashes when a third-party RCON wrapper connected, so keep RCON disabled when nobody needs it.

Stats, GSLT and official rules

  1. Generate a GSLT on the Steam page for managing game server accounts, entering app ID 581320, the game, not the server app. Steam requires the account to own the game, have a phone number linked and be in good standing. Use one token per server.
  2. Generate a GameStats token at New World Interactive's GameStats token generator after signing in with Steam.
  3. Launch with -GSLTToken=, -GameStatsToken= and -GameStats, the opt-in without which the server does not report.
  4. Leave ?Password= out of the travel URL: the guide allows stats only on a server without a password.

The guide ties the GSLT to stats authentication; it does not say a server without one is hidden from the browser. A mostly vanilla server can add -ruleset=OfficialRules to show under the official rules filter, which locks the options you can change.

Mods, updates and limits

The vanilla guide now covers unmodded servers only and points to a separate modded-server guide. That guide registers the server with a mod.io account: the emailed code passed as -SecurityCode= on the first launch and -SecurityCode=none on every launch after, mods subscribed on the mod.io website, and -mods with -ModDownloadTravelTo= on the launch line. Its Linux walkthrough is a video rather than text, and it says the mod.io SDK officially supports one client or server per account on one machine.

Keep copies of Game.ini, Engine.ini, the files in Insurgency/Config/Server, start.sh and the unit file on another machine; a reinstall restores everything else from SteamCMD. When something breaks, the browser console on a rack server gets you in without SSH, and support answers around the clock. Skip this route if you would rather click through a hosting panel: you get root and a shell, and the setup above is yours to run.

Questions

Which SteamCMD app ID installs the Sandstorm server?

581330, with login anonymous. The game itself is 581320, and the guide says that is the ID to enter when generating a GSLT for the server, not 581330.

What ports does the server need open?

The guide's example uses 27102 for game traffic and 27131 for Steam queries, and its firewall steps open TCP and UDP on both. RCON, if enabled, uses the port you set (27015 in the guide's example); bind it to loopback rather than opening it.

Does it run on Linux?

Yes. The guide gives a Linux launch line using Insurgency/Binaries/Linux/InsurgencyServer-Linux-Shipping and Linux config paths under Insurgency/Saved/Config/LinuxServer. Use an x86 machine: the guide documents only an x86 Linux build, and we would not plan on the ARM lines for it.

Why does my server not grant XP?

Stats need -GSLTToken= carrying a GSLT issued against the game's app ID, 581320, -GameStatsToken= with your GameStats token, the -GameStats switch, and no server password. Missing any one of the four keeps the server from reporting.

Can I run two servers on one machine?

Give each its own -Port, -QueryPort, RCON port and GSLT, since the guide asks for a unique token per server. Measure the first instance under a full match before adding the second.

Put your Sandstorm server on its own machine

Pick an x86 line close to your player base; ready servers go live about 30 minutes after approval.

See the machines

Related on Server Room

Other use cases