Deployment guide

Freeciv

Overview

Freeciv is a free and open-source, turn-based empire-building strategy game. freeciv-server is its dedicated multiplayer server, the headless companion to the desktop game.

This guide covers deploying and using the Freeciv 3.2 dedicated multiplayer game server on Ubuntu 24.04 from the SecureAnyCloud image on Azure Marketplace. Your players keep using their normal Freeciv client and connect to your VM's address instead of a public server. They get their own lobby where they can chat, take a player slot, set up the ruleset and play a full game. The entire rules engine runs on your host, which holds the world, resolves every turn and relays state to the clients.

This image ships the server, not the game. There is no desktop client, graphical interface or web interface on this VM. You do everything in this guide over SSH, and your players use the in-game lobby chat from a connected Freeciv client. Your players supply their own copy of the game.

Only the server half of Freeciv's data is redistributed. Freeciv's own build system splits its data tree into server data and client data. This image is a server-only build. It installs the rulesets, nation definitions and scenarios that the rules engine needs, and none of the tilesets, sound sets, music sets, themes or national flag artwork, which belong to the client.

Everything on this VM is covered by Freeciv's GNU General Public License version 2. The license text ships at /usr/share/doc/freeciv-server/COPYING, alongside a manifest at /usr/share/doc/freeciv-server/LICENCE-MANIFEST.txt that names every data directory installed.

Client version compatibility is required. Freeciv's network protocol is capability-gated. This server is built from the 3.2.5 upstream source release and admits the 3.2.x client series only. A 3.1 client, or an older one, is cleanly refused with the server's own explanation rather than half connecting. Ubuntu 24.04's own repository carries only the older 3.1 line, which is why this image builds 3.2 from source.

What you get:

  • freeciv-server 3.2.5, built from the official upstream source release with the server target only, verified against a pinned SHA-256 checksum before extraction, and running under systemd as freeciv-server.service
  • The full set of server rulesets, including civ2civ3, classic, multiplayer, civ1, civ2, sandbox and alien, plus the nation definitions and the bundled map scenarios
  • freecivctl, a root-only wrapper that drives the server console
  • freeciv-selfcheck, a bundled command that proves the server end to end by driving Freeciv's real wire protocol as independent clients and creating and starting a real game
  • Ubuntu 24.04 LTS, patched at build time, with unattended security upgrades enabled
  • No network administrator password, so there is nothing to leak. Freeciv has no password-protected remote console. Its only remote privilege path is the hack access level, which is granted solely to a client that can read a challenge file the server writes inside its own state directory. Neither remote clients nor other local users can read that file.
  • No connection can escalate itself. The configuration this VM generates on first boot sets cmdlevel basic first and cmdlevel basic new, so every network connection, including the very first to arrive, is capped at the basic command access level. The basic level covers normal play: chat, taking a player and voting. It cannot run privileged server commands.
  • Local-only administration. You drive the server console with sudo freecivctl, which writes to a FIFO inside a runtime directory reachable only by root and the service account. Nothing on the network can reach it.
  • The server cannot start before first boot has configured it. freeciv-server.service is enabled so it survives reboots, but it carries two start-up conditions: the first-boot ready marker and the server configuration. Neither exists in the shipped image, so the game port cannot be bound by a server that carries configuration written on somebody else's machine.
  • One port and nothing else. TCP 5556 is the only listener this product opens. LAN announcement is disabled, and the server does not advertise itself to the public Freeciv metaserver, so your VM is never listed publicly unless you choose to change that.
  • Unprivileged server. The server runs as the dedicated freeciv system account under a hardened systemd unit.

Key facts

  • Platform: Ubuntu 24.04 LTS on Azure
  • Default administrative user: azureuser
  • Game port: 5556/tcp
  • Accepted client versions: 3.2.x
  • Server binary: /usr/local/bin/freeciv-server
  • Server configuration: /etc/freeciv/sac.serv
  • Server data: /usr/local/share/freeciv/
  • Connection details: /root/freeciv-credentials.txt

Prerequisites

  • An active Azure subscription, an SSH public key, and a VNet and subnet in the target region.
  • A subscription to this listing on Azure Marketplace.
  • A Network Security Group that allows TCP 22 for administration and TCP 5556 for the game itself. Your players connect to 5556, so it must be reachable from wherever they are. No other port needs to be opened.
  • A copy of Freeciv 3.2.x on each player's machine. The server admits that series only.

Recommended virtual machine size: Standard_B2s with 2 vCPU and 4 GB RAM comfortably hosts a community lobby and a full game. Unlike a pure relay, a Freeciv server simulates the whole world and resolves every turn, and the artificial intelligence (AI) players are the heaviest part of that work. For a large map with many AI players, or for several concurrent games, choose Standard_D2s_v5 or above.

Deploy the virtual machine

To deploy from the Azure Portal, select the image from Azure Marketplace, choose your VM size and supply your SSH public key for the azureuser account. To deploy from the Azure CLI instead, run these commands on your own workstation, not on the VM:

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:freeciv-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-resource-group \
  --name my-freeciv-vm \
  --image sac1647283583153:freeciv-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
az vm open-port --resource-group my-resource-group --name my-freeciv-vm --port 5556

Once the VM is running, connect over SSH:

ssh azureuser@<vm-ip>

Confirm the server is healthy

The server starts automatically once first boot has written this VM's configuration. Check the service and confirm the version:

systemctl is-active freeciv-server

Expected output

active
freeciv-server --version

Expected output

Freeciv version 3.2.5

Next, confirm the network posture. Exactly one port belongs to this product, and it is the game port:

ss -tln | grep 5556

Expected output

LISTEN 0 1024 0.0.0.0:5556 0.0.0.0:* LISTEN 0 1024 [::]:5556 [::]:*

Retrieve your connection details

First boot writes a root-only file that describes what your players need. It contains no password, because this server has none:

sudo cat /root/freeciv-credentials.txt

Expected output

# Freeciv 3.2.5 dedicated multiplayer server — generated on this VM's # first boot by sac. # # THIS SERVER HAS NO NETWORK ADMINISTRATOR PASSWORD, BY DESIGN. ... FREECIV_URL=freeciv://10.0.0.4:5556 freeciv.host=10.0.0.4 freeciv.port=5556 freeciv.version=3.2.5 freeciv.client_series_required=3.2.x

The address recorded in the file is the address the VM sees for itself. If your players are outside the VNet, give them the VM's public IP address or DNS name instead, with the same port. To query the public address from the VM, run:

PUB=$(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2021-02-01&format=text")
echo "public : ${PUB:-none reported by instance metadata}"
echo "private: $(hostname -I | awk '{print $1}')"

Expected output

public : none reported by instance metadata private: 10.0.0.4

Azure's instance metadata returns an empty public address for a Standard SKU public IP, which is why the connection details file records the private address. If the query comes back empty, read the public address from the VM's Overview page in the Azure Portal, or run az vm list-ip-addresses from your workstation. Give your players that address with port 5556.

Prove the server really hosts games

A listening socket does not prove that a game server works, so this image ships a checker that speaks Freeciv's real wire protocol. It connects genuine clients and confirms that an incompatible client and a privilege escalation are both refused. It then creates and starts a real game on a private second instance, so your live lobby is never disturbed:

sudo freeciv-selfcheck

Expected output

[freeciv-selfcheck] 1. Checking the server binary reports the pinned upstream version OK: Freeciv version 3.2.5 [freeciv-selfcheck] 2. Checking the live service is active and bound on this VM's routable address OK: freeciv-server.service active, TCP 5556 listening [freeciv-selfcheck] 3. Joining the LIVE server as a real protocol client at 10.0.0.4:5556 OK: admitted by the live server, header widened, 3330 packets received [freeciv-selfcheck] 4. Checking an incompatible client version is refused by the live server OK: refused, server said: The client is missing a capability that this server needs. [freeciv-selfcheck] 5. Checking network escalation to the 'hack' administrator level is refused OK: hack access refused (reply: you_have_hack=false) [freeciv-selfcheck] 6. Starting an isolated server instance on port 5599 for the game-lifecycle proof OK: isolated instance listening on 5599 [freeciv-selfcheck] 7. Connecting TWO fully independent clients to the same server OK: both clients joined; server lists them [freeciv-selfcheck] 8. Checking a lobby message from one client is relayed live to the other OK: the server relayed 'sac-...' from sacalpha to sacbravo [freeciv-selfcheck] 9. Creating an AI player and STARTING the game from the server console OK: server console: > Starting game. [freeciv-selfcheck] 10. Checking both connected clients are participants in the running game OK: game running with both clients and the AI as players [freeciv-selfcheck] 11. Checking the administrative control plane is local only OK: console FIFO mode 660 in a 750 directory, state dir 750, network connections capped at 'basic' FREECIV_SELFCHECK_OK: Freeciv 3.2.5 dedicated server verified end to end

The checker is safe to run at any time, including while a game is in progress. The half that creates and starts a game runs against a private instance on its own port with its own throwaway state, and that instance is stopped again when the check finishes.

Point your players at the server

Each player opens their own Freeciv 3.2.x client and does the following:

  • Chooses Connect to Network Game from the start screen.
  • Enters your server's address in the host field and 5556 as the port.
  • Enters the name they want to play under, then connects.

Players arrive in your lobby, and the server gives each of them a player slot automatically. From there the group agrees a ruleset and settings in the usual way, and one of them starts the game. You can also start it yourself from the server console, as shown below.

If a player is refused, the reason is almost always the client version. The server says so explicitly rather than failing silently.

Run the server console

You can drive everything the Freeciv server manual describes from the shell with freecivctl. It sends one command to the running server and prints the server's reply:

sudo freecivctl list players

Expected output

> List of players: ------------------------------------------------------------------------------ AI*1 [#ff0000]: Team 1, user Unassigned AI, classic, difficulty level Easy ------------------------------------------------------------------------------
sudo freecivctl list connections

Expected output

> List of connections to server: ------------------------------------------------------------------------------ <no connections> ------------------------------------------------------------------------------

Useful commands are help, show, list scenarios, create <name> to add an AI player, remove <name>, cut <connection> to disconnect a player, save <name> to write a savegame, and start to begin the game.

Change the server settings

Change server settings live with the set command. The change takes effect immediately:

sudo freecivctl set aifill 8

The settings most operators change first:

  • aifill: how many player slots are filled with artificial intelligence players
  • timeout: seconds each turn is allowed before it ends automatically, 0 for no limit
  • size or mapsize: how large the world is
  • skilllevel: difficulty of the artificial intelligence players
  • endturn: the turn the game finishes on

To make a change permanent, add it to the configuration this VM generated at first boot and restart the service. The file is a list of server console commands that run at start-up:

sudo cat /etc/freeciv/sac.serv

Edit the file with your preferred editor, then apply the change:

sudo systemctl restart freeciv-server

Choose a different ruleset

The image installs Freeciv's full set of server rulesets. civ2civ3 is the upstream default, and multiplayer is tuned for human-versus-human games:

sudo freecivctl list rulesets

Switch the ruleset before a game starts:

sudo freecivctl rulesetdir multiplayer

To make the ruleset the default for every restart, add the same line to /etc/freeciv/sac.serv.

Save and load games

The server writes savegames under its own state directory:

sudo freecivctl save mygame
sudo ls -la /var/lib/freeciv/saves/

Expected output

> Game saved as /var/lib/freeciv/saves/mygame.sav.zst -rw-r----- 1 freeciv freeciv 3394 Aug 7 12:21 mygame.sav.zst

The server also autosaves as a game progresses, into the same directory.

To bring a saved game back, use the console load <name> command. Alternatively, start the server from the savegame by adding --file /var/lib/freeciv/saves/<name>.sav.zst to the ExecStart line in /usr/local/sbin/freeciv-server-run.

Load a savegame into the ruleset it was created under. Freeciv reads the ruleset back out of the savegame, so loading one into a server whose ruleset directory has since changed can be refused.

Server components

  • freeciv-server 3.2.5: the dedicated multiplayer game server
  • Freeciv server data 3.2.5: rulesets, nation definitions and scenarios that the rules engine needs
  • Ubuntu 24.04 LTS: base operating system

Filesystem layout

  • /usr/local/bin/freeciv-server: the server binary
  • /usr/local/share/freeciv/: rulesets, nations and scenarios
  • /etc/freeciv/sac.serv: this VM's server configuration
  • /var/lib/freeciv/: savegames, autosaves and server state
  • /run/freeciv/console.in: the root-only server console channel
  • /usr/local/sbin/freecivctl: server console wrapper
  • /usr/local/sbin/freeciv-selfcheck: end-to-end protocol checker
  • /root/freeciv-credentials.txt: this VM's connection details
  • /usr/share/doc/freeciv-server/: GPL 2.0 license text and data manifest

Network ports

  • 22/tcp: SSH administration
  • 5556/tcp: Freeciv game port, the only listener this product opens

Managing the service

sudo systemctl status freeciv-server
sudo systemctl restart freeciv-server
sudo journalctl -u freeciv-server -n 50 --no-pager

Scripts and log files

  • /usr/local/sbin/freeciv-firstboot.sh: first-boot configuration script
  • /var/log/sac/sac-firstboot.log: first-boot log
  • /var/lib/sac/config/sac-build-versions: pinned upstream version and source checksum

The server's own console output goes to the systemd journal, not to a log file.

On startup

On the very first boot, the image writes this VM's server configuration, releases the two start-up gates and starts freeciv-server.service. It then waits for the game port to bind and records the connection details. On every later boot, the server simply starts.

Troubleshooting

Players are refused with a message about a missing capability

The player's client is not in the 3.2.x series. Freeciv's protocol is capability-gated, and a 3.1 or older client cannot negotiate with a 3.2 server. Ask the player to install Freeciv 3.2.x. The refusal message names both versions.

Nothing answers on port 5556

Check the service and the start-up gates in order:

systemctl is-active freeciv-server

If the service is inactive, check whether first boot completed:

ls -la /var/lib/sac/data/

You should see both freeciv-firstboot.done and freeciv-ready. If either is missing, first boot did not finish. Read /var/log/sac/sac-firstboot.log.

If the service is active but players still cannot reach it, the port is probably not open in your Network Security Group. Confirm that the server itself is listening:

ss -tln | grep 5556

freecivctl says the console channel is not present

The FIFO lives on tmpfs and is recreated each time the service starts, so this message means the server is not running. Check the service:

sudo journalctl -u freeciv-server -n 50 --no-pager

A player cannot run server commands

This is intended. Every network connection is capped at the basic access level, so privileged commands are refused. Run them yourself with sudo freecivctl instead.

To hand a connected player control deliberately, raise that one connection's level from the console with sudo freecivctl cmdlevel ctrl NAME, substituting the name the player connected under. The ctrl level lets the player change settings and start the game, and the higher admin and hack levels give progressively more of the server.

Grant a level only to a named connection you trust, and only temporarily. Never change the cmdlevel first or cmdlevel new defaults in the configuration, because that hands the power to whoever connects next.

The self check reports an error

Read the numbered step that failed. It names the exact assertion. Common causes are that the service is not active, or that another process already holds the checker's scratch port 5599.

Security recommendations

  • Restrict SSH. Limit TCP 22 in your Network Security Group to your own address, and leave TCP 5556 as the only broadly reachable port.
  • Leave the access level capped. cmdlevel basic first and cmdlevel basic new stop an arriving connection from taking control of your server. Raise a specific player's level deliberately and temporarily rather than changing those defaults.
  • Keep administration on SSH. freecivctl is root-only because it is the full server console. Do not expose it another way.
  • Keep the VM patched. Unattended security upgrades are enabled. Reboot after kernel updates.
  • Watch the disk if you enable frequent autosaves. Savegames accumulate under /var/lib/freeciv/saves/.

Support

SecureAnyCloud support: sales@secureanycloud.com

Freeciv server manual: https://www.freeciv.org/wiki/Server_Manual

Freeciv project: https://www.freeciv.org/

Freeciv is free software published under the GNU General Public License version 2. SecureAnyCloud is not affiliated with, endorsed by or sponsored by the Freeciv project. This image packages the unmodified upstream dedicated server.

Deploy on Azure

Launch Freeciv 3.2 Compatible Dedicated Multiplayer Game Server on Ubuntu 24.04 on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure