Hardening a new FiveM server: the checklist we would run on day one
In short
Hardening a new FiveM server means fixing five things before players arrive: the host (key-based SSH only, a firewall that exposes only the game and query ports, and FXServer running as an unprivileged user), the database (a dedicated account scoped to one schema, never reachable from the internet), credentials (unique secrets per service, stored outside the resource tree and never committed), permissions (an ACE configuration written explicitly rather than inherited from a template, with no wildcard admin), and resource intake (every resource reviewed or scanned before installation, its origin recorded, and re-checked on update). Add tested backups and one written incident contact, and you have removed the causes of almost every compromise we see.
Key takeaways
- Run FXServer as an unprivileged user; a compromised resource then owns a service account, not the machine.
- Give the server its own database account limited to its own schema — never the root credentials.
- Write your ACE configuration deliberately. Inherited template permissions are how players end up with console access.
- Record where every resource came from at install time; provenance you did not write down is provenance you do not have.
- A backup you have never restored is a plan, not a backup.
The cheapest hour of security work you will ever spend is the one before the first player connects. Nothing is in production, nothing needs a maintenance window, and every decision is still reversible. This is what we would do with that hour.
1. The host
- Disable password authentication for SSH and use keys. This single change removes the entire category of brute-force compromise.
- Firewall by default-deny. Expose the game port, the query port and your administrative access path. Nothing else needs to be reachable from the internet.
- Run FXServer as a dedicated unprivileged user, not root and not your own login. A malicious resource inherits that user's rights — make them small.
- Keep the panel, if you use one, off the public internet or behind an authenticating proxy. Panels are a standing target and are frequently the actual entry point.
- Enable automatic security updates for the operating system. Unpatched hosts get compromised through paths that have nothing to do with FiveM.
2. The database
- 1Create a dedicated database user for the server, with rights only on its own schema. No GRANT ALL, no root, no shared account across servers.
- 2Bind MySQL/MariaDB to localhost or a private network. A database reachable from the internet will be found, quickly.
- 3Use a long random password you did not reuse, and store it where the resource tree cannot leak it.
- 4Take an automated backup, then restore it once into a scratch database to prove it works.
- 5Log slow and failed queries. They are often the first visible sign that something is enumerating your data.
3. Credentials and configuration
Server-side Lua can read your configuration, so treat every secret in it as one backdoor away from public. That does not mean secrets can be avoided — it means their blast radius has to be planned.
- One secret per service. Reuse turns a single resource compromise into an account takeover everywhere.
- Keep server.cfg out of any repository, and check that a .gitignore actually covers it before the first commit rather than after.
- Give Discord bots the minimum permissions they need, and separate the alerting webhook from anything that grants moderation power.
- Write down where each key came from and how to rotate it. Under incident pressure, the missing knowledge is always 'how do I regenerate this'.
4. Permissions (ACE) written on purpose
Most FiveM permission problems are inherited: a template server.cfg with a broad add_ace, copied forward through three generations of server, granting far more than anyone intended. Write yours from scratch and keep it short enough to read in one screen.
# Groups, defined once
add_ace group.admin command allow
add_ace group.moderator command.kick allow
add_ace group.moderator command.ban allow
# People, named individually
add_principal identifier.license:REPLACE_ME group.admin
# Nobody inherits anything by default
remove_ace resource.example command allow- No wildcard command grants to a group that includes anyone but you.
- Grant resources the specific ACEs they need, not blanket command access.
- Review the principal list quarterly and remove people who left. Access that outlives the relationship is a standing risk.
- After any incident, re-read this file — a backdoor's ace grants persist in configuration even after the resource is gone.
5. Resource intake — the control that matters most
Everything above hardens the environment. This one addresses how compromises actually happen: an operator installs code they did not review. Make intake a process, not an impulse.
- 1
Record provenance at install time
Where did this come from, which version, who approved it, on what date. A spreadsheet is enough. Without it, you cannot tell later what is original.
- 2
Review or scan before installation, always
Read the manifest and the server scripts, or run an automated scan and read the evidence. The point is that the decision happens before the code has your credentials.
- 3
Keep the original archive
It is your diff baseline and the artefact you send to a scanner or a disclosure contact if something surfaces later.
- 4
Re-check on every update
The version you approved is not the version installed by an auto-updater last night. Treat updates as new installs.
- 5
Refuse what you cannot establish
Leaked and cracked resources have by definition passed through someone who modified them. No amount of hardening compensates for deliberately installing that.
6. The things you will be glad you did
- A tested restore. Not a backup — a restore you have actually performed at least once.
- Monitoring that alerts a human. An unread dashboard is not monitoring.
- An out-of-band contact route for your admin team that does not depend on the server or a bot running on it.
- A one-page incident runbook. During an incident nobody reads a wiki; they read the page that says what to do first.
- A note of who to contact for responsible disclosure, so a researcher who finds something in your setup has somewhere to send it.
None of this is exotic and none of it requires a security team. It requires deciding, once, that installation is a decision and access is granted deliberately. Servers that are compromised almost never lost to a clever attack; they lost to a resource nobody read, running as root, with a database password that was also the panel password.
Frequently asked questions
How do I secure a new FiveM server?
Before opening to players: use key-based SSH and a default-deny firewall, run FXServer as an unprivileged user rather than root, give the database its own scoped account that is not reachable from the internet, use unique secrets per service, write your ACE permissions explicitly instead of copying a template, and review or scan every resource before installing it. Add a tested backup restore and you have covered the causes of almost every compromise.
Should FiveM run as root?
No. Server-side Lua executes with the privileges of the FXServer process, so running as root means any malicious or compromised resource owns the whole machine — the panel, other game servers, and any credentials stored on it. Create a dedicated unprivileged user for the server and keep its file permissions tight.
How often should I re-scan FiveM resources I already installed?
On every update, because the version you reviewed is not the version an auto-updater may have installed since. For a production server, periodic re-checking of the whole resource set is worth automating — a one-time scan describes what you installed, while continuous monitoring describes what is running now.