Freeciv 3.2.7 on AWS User Guide
Overview
This guide covers launching and using the Freeciv 3.2.7 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg game server listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Freeciv is a free, open source turn based strategy game of empire building: players found cities, research technologies, trade, negotiate and go to war, from the stone age to the space race. It is played across the internet against other people and computer players, and a dedicated server is what hosts those games.
This image ships the dedicated server, not the game client. freeciv-server is a headless network service. Your players install Freeciv 3.2 on their own computers and choose Connect to Network Game with this instance's address. The image is built from the official Freeciv 3.2.7 source release with every client and graphics component switched off, so no client artwork, sound or music is on the image; only the server rulesets, nations and scenarios the game engine needs.
The cloudimg image adds:
- No administrator password, and no network path to one. Freeciv has no password protected remote console. Its only remote privilege path is the
hackaccess level, which needs a challenge file only the server account can read, and the server file this instance writes at first boot caps every network connection at thebasicaccess level (cmdlevel basic firstandcmdlevel basic new), so no player, not even the first to arrive, can reach theadminorhacklevel. One thing stays open, as in every Freeciv server: abasicplayer may call a vote on actrllevel command (for examplekick,loador a game setting), and the vote passes when most connected players agree, so on an open server a lone player can carry one. Restrict TCP 5556 to your players, or switch on player accounts (step 6). - A root only console. Administration is local, over SSH, through
sudo freecivctl, which writes to the server's console through a channel in a root owned directory that the server account cannot alter. - Anonymous players by default, password protected accounts on one command. Freeciv's own default is anonymous play: anyone who reaches the game port can join under any name not in use.
sudo freeciv-auth onswitches on Freeciv's account database, so each player name is claimed with a password on first login and guests are refused. Step 6 shows both. - A contained service. The server runs as the
freecivsystem account (no shell, no password, no capabilities) under a sandboxed systemd unit. The binary, the rulesets and the configuration are owned by root, so the service cannot change its own code or settings. - Loopback only outbound connections. A game server does not need to reach anything: players connect in. A firewall rule keyed to the
freecivaccount lets it open new connections only to the instance itself, on IPv4 and IPv6, so a ruleset Lua script cannot reach the instance metadata service, your VPC or the internet. Replies to players are not affected. The server unit is also denied the metadata and link local addresses by systemd, and the AMI requires IMDSv2. - Nothing until first boot, and only your instance's own state after it. The image binds nothing. First boot writes this instance's server file and connection details, starts the server and waits for the game port. No game, save, account or address from the build is on the image.
- A self check you can run.
sudo freeciv-selfcheckspeaks Freeciv's real wire protocol: genuine clients join, an incompatible client and a privilege escalation are refused, and a real game is created and started on a private second instance so your live lobby is never disturbed. - Exactly the ports players need. TCP 5556 for players and TCP 22 for SSH.
- A pinned, checked source. The official
freeciv-3.2.7.tar.xz, verified against upstream's published SHA-256 before it is built. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: freeciv-server 3.2.7 (/usr/local/bin/freeciv-server) with its server data under /usr/local/share/freeciv, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The compiler and every development package used to build it were removed before the image was captured.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet.
- A public IPv4 address on the instance (auto assigned or an Elastic IP), so players on the internet can reach it.
- A security group that allows TCP 5556 from your players (usually anywhere) and TCP 22 (SSH) from your own networks only. Freeciv uses TCP only.
- Your players need a Freeciv 3.2.x client. Freeciv's network protocol is version gated, and 3.1 or older clients are refused with the reason.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Freeciv 3.2.7 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above. A Freeciv server is light; m5.large leaves room for large maps and many computer players.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--associate-public-ip-address \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=freeciv}]'
The security group rules, from the AWS CLI:
aws ec2 authorize-security-group-ingress --group-id <your-security-group> \
--ip-permissions 'IpProtocol=tcp,FromPort=5556,ToPort=5556,IpRanges=[{CidrIp=0.0.0.0/0}]' \
'IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp=<your-mgmt-cidr>}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| Freeciv 3.2.7 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check first boot and read your connection details
On first boot the instance writes its own server file, starts the server and waits for the game port to come up. Give it a minute after the instance reports running, then check it:
systemctl is-active freeciv-server.service cloudimg-freeciv-egress.service
Both should report active. Then check the server version and the account it runs as:
freeciv-server --version
ps -o user=,args= -C freeciv-server
Expected output
Freeciv version 3.2.7
freeciv /usr/local/bin/freeciv-server --port 5556 --read /etc/freeciv/cloudimg.serv --saves /var/lib/freeciv/saves --scenarios /var/lib/freeciv/scenarios --Announce none

Read this instance's connection details:
sudo cat /root/freeciv-credentials.txt
The file is 0600 root:root and was written on your instance. It holds the address players connect to (read with IMDSv2) and no password, because none exists. Its explanatory comment lines are left out here:
freeciv.host=<server-ip>
freeciv.private_ip=<private-ip>
freeciv.port=5556
freeciv.version=3.2.7
freeciv.client_series_required=3.2.x
If the instance has no public IPv4, freeciv.host shows the private address, which only works inside your VPC or VPN.

Step 4: Prove the server really hosts games
A listening socket is not proof that a game server works, so the image ships a checker that speaks Freeciv's real wire protocol. It joins the live server as a genuine client, confirms an incompatible client and a privilege escalation are refused, then creates and starts a real game on a private second instance on port 5599 so your live lobby is never disturbed:
sudo freeciv-selfcheck
Expected output (abridged)
[freeciv-selfcheck] 1. Checking the server binary reports the pinned upstream version
OK: Freeciv version 3.2.7
[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 <private-ip>: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.
Server version: 3.2.7 Client version: 2.6.0. Upgrading may help!
[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 (the live game is never disturbed)
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: cloudimgalpha ... command access level basic | cloudimgbravo ...
[freeciv-selfcheck] 8. Checking a lobby message from one client is relayed live to the other
OK: the server relayed 'cloudimg-c05f3ae45afb' from cloudimgalpha to cloudimgbravo
[freeciv-selfcheck] 9. Creating an AI player and STARTING the game from the server console
OK: server console: > cloudimgAI has been added as an AI-controlled player (classic). | > 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 (alpha 3597 packets, bravo 3597 packets)
[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.7 dedicated server verified end to end ...
It is safe to run at any time, including during a game: the half that creates and starts a game runs against a private instance with its own throwaway state, stopped again when the check finishes.

Step 5: Point your players at the server
Each player opens their own Freeciv 3.2.x client and:
- Chooses Connect to Network Game from the start screen.
- Enters
freeciv.hostfrom the connection details as the server and5556as the port. - Enters the name they want to play under and connects.
They arrive in your lobby and the server gives each of them a player slot. The group agrees a ruleset and settings and one of them starts the game, or you start it from the console (Step 7). Empty slots are filled with computer players (aifill 5).
If a player is refused, the reason is almost always the client version. The server tells them so explicitly.
Step 6: Player authentication (anonymous by default)
By default players are anonymous. That is Freeciv's own default: anyone who can reach TCP 5556 can join your lobby under any player name not already connected. They cannot reach the admin or hack level (the basic cap above holds either way), but they can take a seat in your game and call votes on ctrl level commands such as kick or load. For a server open to the internet, either restrict TCP 5556 in your security group to your players' addresses, or switch on Freeciv's account database:
sudo freeciv-auth status
Expected output
configured: OFF (anonymous play)
server: running WITHOUT authentication (anonymous)
sudo freeciv-auth on
The server restarts with authentication. From then on:
- A new player name is claimed by the password its first user chooses, at their first login (Freeciv asks for it twice and enforces a minimum length).
- A returning player must give that password; a wrong one is refused.
- Guests are refused.
- Passwords are stored as hashes (Freeciv's own unsalted MD5 format) in
/var/lib/freeciv/players.sqlite, which only the server account can read. Ask players to choose a password they use nowhere else.
No account exists until a player creates one, and none is shipped in the image.
sudo freeciv-auth status
Expected output
configured: ON (/etc/freeciv/fcdb.conf)
server: running WITH authentication
To return to anonymous play run sudo freeciv-auth off. The account database is kept, so turning authentication back on restores the same accounts. To forget every account, stop the server, remove the database as the server account and start it again:
sudo systemctl stop freeciv-server
sudo -u freeciv rm -f /var/lib/freeciv/players.sqlite
sudo systemctl start freeciv-server

Step 7: Run the server console
Everything the Freeciv server manual describes can be driven from the shell with freecivctl. It sends one command to the running server and prints what the server said back. It is root only (0750 root:root):
sudo freecivctl list connections
Expected output
> List of connections to server:
------------------------------------------------------------------------------
<no connections>
------------------------------------------------------------------------------
Useful commands include help, show, list players, create <name> to add a computer player, remove <name>, cut <connection> to disconnect a player, save <name> to write a savegame and start to begin the game.
Server settings change live with set, and take effect immediately:
sudo freecivctl set aifill 8
| Setting | What it does |
|---|---|
aifill |
How many player slots are filled with computer players |
timeout |
Seconds each turn is allowed before it ends automatically, 0 for no limit |
size |
How large the world is |
skilllevel |
Difficulty of the computer players |
endturn |
The turn the game finishes on |
To make a change permanent, add the same console command to the server file this instance wrote at first boot, then restart the service. The file is root owned and read by the server at start up:
sudo cat /etc/freeciv/cloudimg.serv
sudo systemctl restart freeciv-server
A player cannot run server commands
That is intended: every network connection is capped at basic, which can play, chat and call a vote on a ctrl level command but cannot run one directly. Run privileged commands yourself with sudo freecivctl. If you deliberately want to hand one connected player control, raise that connection only, temporarily, with sudo freecivctl cmdlevel ctrl <player-name>. Never change the cmdlevel basic first or cmdlevel basic new lines, which would hand that power to whoever connects next.
Step 8: Rulesets, saves and logs
The image installs Freeciv's full server ruleset set. civ2civ3 is the upstream default; multiplayer is tuned for games between people. Switch before a game starts:
sudo freecivctl rulesetdir multiplayer
Savegames go under the server's own state directory, and the server also autosaves as a game progresses:
sudo freecivctl save mygame
sudo ls -la /var/lib/freeciv/saves/
Load one back with sudo freecivctl load mygame before the game starts. The server's console output goes to the systemd journal:
sudo journalctl -u freeciv-server -n 50 --no-pager
Step 9: Security checks
The server account cannot reach the instance metadata service or the internet. You can confirm it yourself:
sudo setpriv --reuid=freeciv --regid=freeciv --init-groups curl -s -m 5 -o /dev/null -X PUT http://169.254.169.254/latest/api/token -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' && echo REACHED || echo refused
sudo setpriv --reuid=freeciv --regid=freeciv --init-groups curl -s -m 5 -o /dev/null https://1.1.1.1/ && echo REACHED || echo refused
Expected output
refused
refused
The egress rule and the systemd metadata block:
sudo iptables -S CLOUDIMG-FREECIV-EGRESS
systemctl show -p IPAddressDeny freeciv-server
Only SSH and the game port listen beyond loopback:
sudo ss -Htlnp | grep -v -E '127\.0\.0\.|\[::1\]'

Step 10: Server components
| Component | Version | Purpose |
|---|---|---|
| freeciv-server | 3.2.7 | The dedicated multiplayer game server |
| Freeciv server data | 3.2.7 | Rulesets, nations, scenarios and ruleset Lua scripts |
| Ubuntu | 24.04 LTS | Base operating system |
| Path | Purpose |
|---|---|
/usr/local/bin/freeciv-server |
The server binary |
/usr/local/share/freeciv/ |
Rulesets, nations and scenarios |
/etc/freeciv/cloudimg.serv |
This instance's server file (root owned) |
/etc/freeciv/fcdb.conf |
Present only while authentication is on |
/var/lib/freeciv/ |
Savegames, autosaves, the account database and server state |
/run/freeciv-console/console.in |
The root only console channel |
/usr/local/sbin/freecivctl |
Server console wrapper |
/usr/local/sbin/freeciv-auth |
Player authentication on, off and status |
/usr/local/sbin/freeciv-selfcheck |
End to end protocol checker |
/root/freeciv-credentials.txt |
This instance's connection details |
/usr/share/doc/freeciv-server/ |
GPL 2.0 licence, data manifest, third party notices and build record |
/var/log/cloudimg-firstboot.log |
First boot log |
| Port | Protocol | Purpose |
|---|---|---|
| 22 | TCP | SSH administration |
| 5556 | TCP | Freeciv game port |
Step 11: Security recommendations
- Restrict SSH. Limit TCP 22 to your own addresses and leave TCP 5556 as the only broadly reachable port.
- Decide who may play. Players are anonymous by default. Turn on
freeciv-authfor a server open to the internet, or limit TCP 5556 to your players' addresses. - Leave the access level capped. Raise a specific player's level deliberately and temporarily rather than changing the
cmdleveldefaults. - Keep administration on SSH.
freecivctlis the full server console; do not expose it another way. - Keep the instance patched. Unattended security upgrades are enabled; reboot after kernel updates.
- Watch the disk if games run long. Savegames accumulate under
/var/lib/freeciv/saves/.
Troubleshooting
Players are refused with a message about a missing capability. Their client is not in the 3.2.x series. Ask them to install Freeciv 3.2.
Nothing answers on port 5556. Check systemctl is-active freeciv-server. If it is not active, check first boot finished: ls /var/lib/cloudimg/ should show freeciv-firstboot.done and freeciv-ready, and /var/log/cloudimg-firstboot.log says what happened. If the service is active, check the security group allows TCP 5556 and that ss -tln | grep 5556 shows the server listening.
freecivctl says the console channel is missing. The channel lives in /run and is recreated each time the service starts, so the server is not running. Read sudo journalctl -u freeciv-server -n 50 --no-pager.
A player forgot their password. With authentication on, remove that one account from the database while the server is stopped (sudo systemctl stop freeciv-server, then sudo -u freeciv sqlite3 /var/lib/freeciv/players.sqlite "DELETE FROM fcdb_auth WHERE name='<player-name>'" if you install the sqlite3 package, then start it again), or forget every account as shown in Step 6.
The self check reports an error. Read the numbered step that failed; it names the assertion. Another process holding the checker's scratch ports 5599 or 5598 also makes it fail.
Support and licensing
- cloudimg support: support@cloudimg.co.uk
- 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 or later; the licence text, a manifest of the installed data and the notices of the bundled Lua, LuaSQL and tolua components are in /usr/share/doc/freeciv-server/. cloudimg is not affiliated with, endorsed by, or sponsored by the Freeciv project; this image packages the unmodified upstream dedicated server. cloudimg charges for the hardening, first boot setup and support described here.