Skip to content

Instantly share code, notes, and snippets.

@JM1
Last active May 19, 2024 07:54
Show Gist options
  • Save JM1/350cd57ac9dfb1bf94de89e56df104ef to your computer and use it in GitHub Desktop.
Save JM1/350cd57ac9dfb1bf94de89e56df104ef to your computer and use it in GitHub Desktop.
Butane config for Fedora CoreOS 39 and later which will run a Counter Strike 2 dedicated server in a Podman container.
# Copyright (c) 2024 Jakob Meng, <jakobmeng@web.de>
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# A Butane config [0] for Fedora CoreOS 39 and later [1] which will run a Counter Strike 2 dedicated server [2] in a
# Podman container.
#
# First, customize all configuration settings marked with a TODO below. Then use Butane to translate it into a Ignition
# config [3]. With CoreOS Installer, embed it into a ISO or PXE image for Fedora CoreOS and/or to install Fedora CoreOS
# to bare metal [4] or a libvirt [5] virtual machine or a QEMU virtual machine [6].
#
# Ref.:
# [0] https://coreos.github.io/butane/specs/
# [1] https://docs.fedoraproject.org/en-US/fedora-coreos/
# [2] https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers
# [3] https://docs.fedoraproject.org/en-US/fedora-coreos/producing-ign/
# [4] https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/
# [5] https://docs.fedoraproject.org/en-US/fedora-coreos/provisioning-libvirt/
# [6] https://docs.fedoraproject.org/en-US/fedora-coreos/provisioning-qemu/
variant: fcos
version: 1.4.0
passwd:
users:
- name: gamemaster
# TODO: Replace with your SSH keys.
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2E...
# TODO: Uncomment to grant administrative privileges
#groups:
# - sudo
# - wheel
storage:
directories:
- path: /home/gamemaster/.config
mode: 0755
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/.config/systemd
mode: 0755
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/.config/systemd/user
mode: 0755
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/.config/systemd/user/default.target.wants
mode: 0755
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/steamcmd
mode: 0755
user:
name: gamemaster
group:
name: gamemaster
files:
# TODO: Adapt network configuration.
- path: /etc/NetworkManager/system-connections/first.nmconnection
mode: 0600
contents:
inline: |
# 2024 Jakob Meng, <jakobmeng@web.de>
#
# Network configuration
#
# This example assigns a static ip address, similar to
# $> nmcli con add con-name "first" ifname enxdeadbeef1337 type ethernet ip4 192.168.0.66/16 gw4 192.168.0.1
# $> nmcli con mod "first" ipv4.dns "192.168.0.1"
# $> nmcli con mod "first" ipv6.method "disabled"
# $> nmcli con up "first"
#
# Ref.: https://www.networkmanager.dev/docs/api/latest/nm-settings-nmcli.html
[connection]
id=first
type=ethernet
# NOTE: Kernel command line argument net.ifname-policy=mac has to be set when
# interface names should be based on the device's persistent MAC address.
interface-name=enxdeadbeef1337
[ethernet]
[ipv4]
address1=192.168.0.66/16,192.168.0.1
dns=192.168.0.1;
method=manual
[ipv6]
addr-gen-mode=default
method=disabled
- path: /etc/sudoers.d/sudoers
mode: 0440
contents:
inline: |
# 2024 Jakob Meng, <jakobmeng@web.de>
gamemaster ALL=(ALL) NOPASSWD: /usr/sbin/poweroff, /usr/sbin/reboot
- path: /etc/ssh/sshd_config.d/99-disable-password-authentication.conf
mode: 0644
contents:
inline: |
# 2023 Jakob Meng, <jakobmeng@web.de>
PasswordAuthentication no
- path: /var/lib/systemd/linger/gamemaster
mode: 0644
- path: /home/gamemaster/.config/systemd/user/steamcmd.service
mode: 0644
contents:
inline: |
# Copyright (c) 2024 Jakob Meng, <jakobmeng@web.de>
# SPDX-License-Identifier: LGPL-2.1-or-later
# ~/.config/systemd/user/steamcmd.service
[Unit]
Description=Counter Strike 2 dedicated server
Wants=network-online.target
After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
RestartSec=1min
# Grant time to build image
TimeoutStartSec=900
ExecStartPre=/usr/bin/podman build --pull=always -t steamcmd:rawhide "steamcmd/"
ExecStartPre=/usr/bin/podman volume create --ignore "steamcmd"
ExecStart=/usr/bin/bash -c ' \
max_uid_count=$(grep -e "^$(id -n -u):" /etc/subuid | cut -d ':' -f 3); \
[ -n "$max_uid_count" ] || exit 125; \
exec /usr/bin/podman run \
--cidfile=%t/%n.ctr-id \
--cgroups=no-conmon \
--sdnotify=conmon \
--detach \
--name "steamcmd" \
--replace \
--init \
--tty \
--interactive \
--uidmap "$UID:0:1" \
--uidmap "0:1:$UID" \
--uidmap "$((UID+1)):$((UID+1)):$((max_uid_count-UID))" \
--publish '27000-27100:27000-27100/tcp' \
--publish '27000-27100:27000-27100/udp' \
--tmpfs /run:exec \
--tmpfs /run/lock \
--tmpfs /tmp:size=50% \
-v "steamcmd:/home/gamer/Steam/:z" \
-v "$HOME/steamcmd/entrypoint.sh:/usr/local/bin/entrypoint.sh:ro,z" \
-v "$HOME/steamcmd/:/home/gamer/steamcmd/:ro,z" \
"steamcmd:rawhide" \
'
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm --ignore --cidfile=%t/%n.ctr-id --force
Type=notify
NotifyAccess=all
[Install]
WantedBy=default.target
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/steamcmd/Dockerfile
mode: 0644
contents:
inline: |
# Copyright (c) 2024 Jakob Meng, <jakobmeng@web.de>
# SPDX-License-Identifier: LGPL-2.1-or-later
# ~/steamcmd/Dockerfile
FROM registry.fedoraproject.org/fedora:rawhide
RUN dnf -y upgrade && \
dnf install -y curl iputils man-db psmisc shadow-utils vim tzdata && \
dnf install -y glibc.i686 libstdc++.i686 && \
dnf clean all
RUN useradd --create-home --shell /bin/bash gamer
USER gamer
RUN mkdir -p /home/gamer/Steam/
USER ROOT
VOLUME /home/gamer/Steam/
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD []
USER gamer
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/steamcmd/entrypoint.sh
mode: 0755
contents:
inline: |
#!/bin/bash
# vim:set tabstop=8 shiftwidth=4 expandtab:
# kate: space-indent on; indent-width 4;
#
# Copyright (c) 2022-2024 Jakob Meng, <jakobmeng@web.de>
# SPDX-License-Identifier: LGPL-2.1-or-later
# ~/steamcmd/entrypoint.sh
#
# Ref.:
# https://developer.valvesoftware.com/wiki/SteamCMD
# https://developer.valvesoftware.com/wiki/Counter-Strike_2/Dedicated_Servers
# https://developer.valvesoftware.com/wiki/List_of_Counter-Strike_2_console_commands_and_variables
set -euxo pipefail
error() {
echo "ERROR: $*" 1>&2
}
if [ "$(id -u)" -eq 0 ]; then
error "Please do not run as root"
exit 125
fi
export STEAM_DIR="$HOME/Steam"
export STEAM_APP="cs2-ds"
export STEAM_APP_DIR="$STEAM_DIR/_games/$STEAM_APP"
export STEAM_APP_ID="730"
cd "$STEAM_DIR"
if [ ! -e "./steamcmd.sh" ]; then
curl --fail --silent --show-error --location \
'https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz' | tar -xzf -
"./steamcmd.sh" +quit
fi
if [ ! -e "$STEAM_APP_DIR" ]; then
# Install
"./steamcmd.sh" +force_install_dir "$STEAM_APP_DIR" +login anonymous +app_update "$STEAM_APP_ID" validate +quit
else
# Update only
"./steamcmd.sh" +force_install_dir "$STEAM_APP_DIR" +login anonymous +app_update "$STEAM_APP_ID" +quit
fi
# Workaround for issue with SteamCMD
if [ ! -e "$HOME/.steam/sdk64/steamclient.so" ]; then
mkdir -p "$HOME/.steam/sdk64"
ln -sfT "$STEAM_DIR/linux64/steamclient.so" "$HOME/.steam/sdk64/steamclient.so"
fi
if [ ! -L "$STEAM_APP_DIR/game/csgo/cfg/server.cfg" ]; then
rm -f "$STEAM_APP_DIR/game/csgo/cfg/server.cfg"
ln -s "$HOME/steamcmd/server.cfg" "$STEAM_APP_DIR/game/csgo/cfg/server.cfg"
fi
app_args=()
# Steam Web API Key (e.g. for Workshop maps)
# Ref.: https://steamcommunity.com/dev/apikey
# TODO: Enter Steam Web API Key.
app_args+=(-authkey "01234567890ABCDEF01234567890ABCD")
# Steam Game Server Login Token
# Ref.: https://steamcommunity.com/dev/managegameservers
# TODO: Enter Steam Game Server Login Token.
app_args+=(+sv_setsteamaccount "01234567890ABCDEF01234567890ABCD")
# Set the configuration of game type and mode based on game alias like "deathmatch".
app_args+=(+game_alias competitive)
# or
#app_args+=(+game_mode 1 +game_type 0)
#app_args+=(+game_alias wingman)
# or
#app_args+=(+game_mode 2 +game_type 0)
#app_args+=(+game_alias casual)
# or
#app_args+=(+game_mode 0 +game_type 0)
#app_args+=(+game_alias deathmatch)
# or
#app_args+=(+game_mode 2 +game_type 1)
#app_args+=(+game_alias custom)
# or
#app_args+=(+game_mode 0 +game_type 3)
# Load a new map.
app_args+=(+map de_dust2)
# Specify a map group.
app_args+=(+mapgroup mg_active)
# Host a workshop map collection as a mapgroup
#app_args+=(+host_workshop_collection 2284573502)
# Get the latest version of the map and host it on this server.
#app_args+=(+host_workshop_map 125439851)
exec "$STEAM_APP_DIR/game/bin/linuxsteamrt64/cs2" \
-dedicated \
-console \
-usercon \
-maxplayers 32 \
-port "27015" \
+tv_port "27020" \
+clientport "27005" \
-ip "0" \
"${app_args[@]}" \
+exec "server.cfg"
user:
name: gamemaster
group:
name: gamemaster
- path: /home/gamemaster/steamcmd/server.cfg
mode: 0644
contents:
# TODO: Adapt server.cfg.
inline: |
// Copyright (c) 2020-2024 Jakob Meng, <jakobmeng@web.de>
// SPDX-License-Identifier: LGPL-2.1-or-later
// ~/steamcmd/server.cfg
//
// Counter-Strike 2 formerly known as Counter-Strike: Global Offensive
//
// Ref.:
// https://developer.valvesoftware.com/wiki/List_of_Counter-Strike_2_console_commands_and_variables
// https://totalcsgo.com/commands/server
// https://github.com/GameServerManagers/Game-Server-Configs/blob/master/CounterStrikeGlobalOffensive/server.cfg
// https://github.com/CM2Walki/CSGO/blob/master/etc/cfg.tar.gz
// https://github.com/bjerrecs/CSGO-Config-Templates/blob/master/csgo/cfg/server.cfg
// .................................. Basic ................................. //
// Name of the server.
// TODO: Define server name.
hostname "CS2 competitive de_dust2 mg_active"
// Remote console password.
// TODO: Define RCON password.
rcon_password "secret"
// Server password for entry into multiplayer games.
//sv_password ""
// Server is a lan server ( no heartbeat, no authentication, no non-class C addresses )
sv_lan 0
// Allow cheats on server.
sv_cheats 0
// Server tags. Used to provide extra information to clients when they're browsing for servers. Separate tags with a comma.
sv_tags ""
// The region of the world to report this server in.
// 0 - US East, 1 - US West, 2 - South America, 3 - Europe, 4 - Asia, 5 - Australia, 6 - Middle East, 7 - Africa
sv_region 3
// Puts the server into extremely low CPU usage mode when no clients connected
sv_hibernate_when_empty 1
// ............................. Server Logging ............................. //
// Enables logging to file, console, and udp < on | off >.
log on
// Log server bans in the server logs.
sv_logbans 1
// Display log information to the server console.
sv_logecho 1
// Log server information in the log file.
sv_logfile 1
// One file log - Log server information to only one file.
sv_log_onefile false
// ................................ Ban List ................................ //
// User ban - Server banlist based on user steam ID.
// Recommended: exec banned_user.cfg
exec banned_user.cfg
// IP ban - Server banlist based on user IP.
// Recommended: exec banned_ip.cfg
exec banned_ip.cfg
// Writes a list of permanently-banned user IDs to banned_user.cfg.
writeid
// Save the ban list to banned_ip.cfg.
writeip
user:
name: gamemaster
group:
name: gamemaster
links:
- path: /home/gamemaster/.config/systemd/user/default.target.wants/steamcmd.service
user:
name: gamemaster
group:
name: gamemaster
target: /home/gamemaster/.config/systemd/user/steamcmd.service
hard: false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment